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 #include "tcuCommandLine.hpp"
40
41 #include "vkImageUtil.hpp"
42 #include "vkMemUtil.hpp"
43 #include "vkPrograms.hpp"
44 #include "vkQueryUtil.hpp"
45 #include "vkDeviceUtil.hpp"
46 #include "vkRefUtil.hpp"
47 #include "vktTestCase.hpp"
48 #include "vktTestCaseUtil.hpp"
49 #include "vktTestGroupUtil.hpp"
50 #include "vkTypeUtil.hpp"
51 #include "vkCmdUtil.hpp"
52 #include "vkObjUtil.hpp"
53 #include "vkBuilderUtil.hpp"
54 #include "vkImageWithMemory.hpp"
55 #include "vkBufferWithMemory.hpp"
56 #include "vkBarrierUtil.hpp"
57
58 #include "pipeline/vktPipelineImageUtil.hpp" // required for compressed image blit
59 #include "vktCustomInstancesDevices.hpp"
60 #include "vkSafetyCriticalUtil.hpp"
61
62 #include <set>
63 #include <array>
64 #include <algorithm>
65 #include <iterator>
66 #include <limits>
67 #include <sstream>
68
69 #ifdef CTS_USES_VULKANSC
70 // VulkanSC has VK_KHR_copy_commands2 entry points, but not core entry points.
71 #define cmdCopyImage2 cmdCopyImage2KHR
72 #define cmdCopyBuffer2 cmdCopyBuffer2KHR
73 #define cmdCopyImageToBuffer2 cmdCopyImageToBuffer2KHR
74 #define cmdCopyBufferToImage2 cmdCopyBufferToImage2KHR
75 #define cmdBlitImage2 cmdBlitImage2KHR
76 #define cmdResolveImage2 cmdResolveImage2KHR
77 #endif // CTS_USES_VULKANSC
78
79 namespace vkt
80 {
81
82 namespace api
83 {
84
85 namespace
86 {
87
88 enum FillMode
89 {
90 FILL_MODE_GRADIENT = 0,
91 FILL_MODE_PYRAMID,
92 FILL_MODE_WHITE,
93 FILL_MODE_BLACK,
94 FILL_MODE_RED,
95 FILL_MODE_MULTISAMPLE,
96 FILL_MODE_BLUE_RED_X,
97 FILL_MODE_BLUE_RED_Y,
98 FILL_MODE_BLUE_RED_Z,
99
100 FILL_MODE_LAST
101 };
102
103 enum MirrorModeBits
104 {
105 MIRROR_MODE_X = (1 << 0),
106 MIRROR_MODE_Y = (1 << 1),
107 MIRROR_MODE_Z = (1 << 2),
108 MIRROR_MODE_LAST = (1 << 3),
109 };
110
111 using MirrorMode = uint32_t;
112
113 enum AllocationKind
114 {
115 ALLOCATION_KIND_SUBALLOCATED,
116 ALLOCATION_KIND_DEDICATED,
117 };
118
119 // In the case of testing new extension, add a flag to this enum and
120 // handle it in the checkExtensionSupport() function
121 enum ExtensionUseBits
122 {
123 NONE = 0,
124 COPY_COMMANDS_2 = (1 << 0),
125 SEPARATE_DEPTH_STENCIL_LAYOUT = (1 << 1),
126 MAINTENANCE_1 = (1 << 2),
127 MAINTENANCE_5 = (1 << 3),
128 SPARSE_BINDING = (1 << 4),
129 };
130
131 template <typename Type>
132 class BinaryCompare
133 {
134 public:
operator ()(const Type & a,const Type & b) const135 bool operator()(const Type &a, const Type &b) const
136 {
137 return deMemCmp(&a, &b, sizeof(Type)) < 0;
138 }
139 };
140
141 typedef std::set<vk::VkFormat, BinaryCompare<vk::VkFormat>> FormatSet;
142
143 FormatSet dedicatedAllocationImageToImageFormatsToTestSet;
144 FormatSet dedicatedAllocationBlittingFormatsToTestSet;
145
146 using namespace vk;
147
148 const int32_t defaultSize = 64;
149 const int32_t defaultHalfSize = defaultSize / 2;
150 const int32_t defaultQuarterSize = defaultSize / 4;
151 const int32_t defaultSixteenthSize = defaultSize / 16;
152 const int32_t defaultQuarterSquaredSize = defaultQuarterSize * defaultQuarterSize;
153 const uint32_t defaultRootSize = static_cast<uint32_t>(deSqrt(defaultSize));
154 const VkExtent3D defaultExtent = {defaultSize, defaultSize, 1};
155 const VkExtent3D defaultHalfExtent = {defaultHalfSize, defaultHalfSize, 1};
156 const VkExtent3D defaultQuarterExtent = {defaultQuarterSize, defaultQuarterSize, 1};
157 const VkExtent3D defaultRootExtent = {defaultRootSize, defaultRootSize, 1};
158 const VkExtent3D default1dExtent = {defaultSize, 1, 1};
159 const VkExtent3D default1dQuarterSquaredExtent = {defaultQuarterSquaredSize, 1, 1};
160 const VkExtent3D default3dExtent = {defaultQuarterSize, defaultQuarterSize, defaultQuarterSize};
161 const VkExtent3D default3dSmallExtent = {defaultSixteenthSize, defaultSixteenthSize, defaultSixteenthSize};
162
163 const VkImageSubresourceLayers defaultSourceLayer = {
164 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
165 0u, // uint32_t mipLevel;
166 0u, // uint32_t baseArrayLayer;
167 1u, // uint32_t layerCount;
168 };
169
convertvkImageCopyTovkImageCopy2KHR(VkImageCopy imageCopy)170 VkImageCopy2KHR convertvkImageCopyTovkImageCopy2KHR(VkImageCopy imageCopy)
171 {
172 const VkImageCopy2KHR imageCopy2 = {
173 VK_STRUCTURE_TYPE_IMAGE_COPY_2_KHR, // VkStructureType sType;
174 DE_NULL, // const void* pNext;
175 imageCopy.srcSubresource, // VkImageSubresourceLayers srcSubresource;
176 imageCopy.srcOffset, // VkOffset3D srcOffset;
177 imageCopy.dstSubresource, // VkImageSubresourceLayers dstSubresource;
178 imageCopy.dstOffset, // VkOffset3D dstOffset;
179 imageCopy.extent // VkExtent3D extent;
180 };
181 return imageCopy2;
182 }
convertvkBufferCopyTovkBufferCopy2KHR(VkBufferCopy bufferCopy)183 VkBufferCopy2KHR convertvkBufferCopyTovkBufferCopy2KHR(VkBufferCopy bufferCopy)
184 {
185 const VkBufferCopy2KHR bufferCopy2 = {
186 VK_STRUCTURE_TYPE_BUFFER_COPY_2_KHR, // VkStructureType sType;
187 DE_NULL, // const void* pNext;
188 bufferCopy.srcOffset, // VkDeviceSize srcOffset;
189 bufferCopy.dstOffset, // VkDeviceSize dstOffset;
190 bufferCopy.size, // VkDeviceSize size;
191 };
192 return bufferCopy2;
193 }
194
convertvkBufferImageCopyTovkBufferImageCopy2KHR(VkBufferImageCopy bufferImageCopy)195 VkBufferImageCopy2KHR convertvkBufferImageCopyTovkBufferImageCopy2KHR(VkBufferImageCopy bufferImageCopy)
196 {
197 const VkBufferImageCopy2KHR bufferImageCopy2 = {
198 VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2_KHR, // VkStructureType sType;
199 DE_NULL, // const void* pNext;
200 bufferImageCopy.bufferOffset, // VkDeviceSize bufferOffset;
201 bufferImageCopy.bufferRowLength, // uint32_t bufferRowLength;
202 bufferImageCopy.bufferImageHeight, // uint32_t bufferImageHeight;
203 bufferImageCopy.imageSubresource, // VkImageSubresourceLayers imageSubresource;
204 bufferImageCopy.imageOffset, // VkOffset3D imageOffset;
205 bufferImageCopy.imageExtent // VkExtent3D imageExtent;
206 };
207 return bufferImageCopy2;
208 }
209
convertvkImageBlitTovkImageBlit2KHR(VkImageBlit imageBlit)210 VkImageBlit2KHR convertvkImageBlitTovkImageBlit2KHR(VkImageBlit imageBlit)
211 {
212 const VkImageBlit2KHR imageBlit2 = {VK_STRUCTURE_TYPE_IMAGE_BLIT_2_KHR, // VkStructureType sType;
213 DE_NULL, // const void* pNext;
214 imageBlit.srcSubresource, // VkImageSubresourceLayers srcSubresource;
215 { // VkOffset3D srcOffsets[2];
216 {
217 imageBlit.srcOffsets[0].x, // VkOffset3D srcOffsets[0].x;
218 imageBlit.srcOffsets[0].y, // VkOffset3D srcOffsets[0].y;
219 imageBlit.srcOffsets[0].z // VkOffset3D srcOffsets[0].z;
220 },
221 {
222 imageBlit.srcOffsets[1].x, // VkOffset3D srcOffsets[1].x;
223 imageBlit.srcOffsets[1].y, // VkOffset3D srcOffsets[1].y;
224 imageBlit.srcOffsets[1].z // VkOffset3D srcOffsets[1].z;
225 }},
226 imageBlit.dstSubresource, // VkImageSubresourceLayers dstSubresource;
227 { // VkOffset3D srcOffsets[2];
228 {
229 imageBlit.dstOffsets[0].x, // VkOffset3D dstOffsets[0].x;
230 imageBlit.dstOffsets[0].y, // VkOffset3D dstOffsets[0].y;
231 imageBlit.dstOffsets[0].z // VkOffset3D dstOffsets[0].z;
232 },
233 {
234 imageBlit.dstOffsets[1].x, // VkOffset3D dstOffsets[1].x;
235 imageBlit.dstOffsets[1].y, // VkOffset3D dstOffsets[1].y;
236 imageBlit.dstOffsets[1].z // VkOffset3D dstOffsets[1].z;
237 }}};
238 return imageBlit2;
239 }
240
convertvkImageResolveTovkImageResolve2KHR(VkImageResolve imageResolve)241 VkImageResolve2KHR convertvkImageResolveTovkImageResolve2KHR(VkImageResolve imageResolve)
242 {
243 const VkImageResolve2KHR imageResolve2 = {
244 VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR, // VkStructureType sType;
245 DE_NULL, // const void* pNext;
246 imageResolve.srcSubresource, // VkImageSubresourceLayers srcSubresource;
247 imageResolve.srcOffset, // VkOffset3D srcOffset;
248 imageResolve.dstSubresource, // VkImageSubresourceLayers dstSubresource;
249 imageResolve.dstOffset, // VkOffset3D dstOffset;
250 imageResolve.extent // VkExtent3D extent;
251 };
252 return imageResolve2;
253 }
254
getAspectFlags(tcu::TextureFormat format)255 VkImageAspectFlags getAspectFlags(tcu::TextureFormat format)
256 {
257 VkImageAspectFlags aspectFlag = 0;
258 aspectFlag |= (tcu::hasDepthComponent(format.order) ? VK_IMAGE_ASPECT_DEPTH_BIT : 0);
259 aspectFlag |= (tcu::hasStencilComponent(format.order) ? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
260
261 if (!aspectFlag)
262 aspectFlag = VK_IMAGE_ASPECT_COLOR_BIT;
263
264 return aspectFlag;
265 }
266
getAspectFlags(VkFormat format)267 VkImageAspectFlags getAspectFlags(VkFormat format)
268 {
269 if (isCompressedFormat(format))
270 return VK_IMAGE_ASPECT_COLOR_BIT;
271 else
272 return getAspectFlags(mapVkFormat(format));
273 }
274
getSizeCompatibleTcuTextureFormat(VkFormat format)275 tcu::TextureFormat getSizeCompatibleTcuTextureFormat(VkFormat format)
276 {
277 if (isCompressedFormat(format))
278 return (getBlockSizeInBytes(format) == 8) ? mapVkFormat(VK_FORMAT_R16G16B16A16_UINT) :
279 mapVkFormat(VK_FORMAT_R32G32B32A32_UINT);
280 else
281 return mapVkFormat(format);
282 }
283
284 // This is effectively same as vk::isFloatFormat(mapTextureFormat(format))
285 // except that it supports some formats that are not mappable to VkFormat.
286 // When we are checking combined depth and stencil formats, each aspect is
287 // checked separately, and in some cases we construct PBA with a format that
288 // is not mappable to VkFormat.
isFloatFormat(tcu::TextureFormat format)289 bool isFloatFormat(tcu::TextureFormat format)
290 {
291 return tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
292 }
293
294 union CopyRegion
295 {
296 VkBufferCopy bufferCopy;
297 VkImageCopy imageCopy;
298 VkBufferImageCopy bufferImageCopy;
299 VkImageBlit imageBlit;
300 VkImageResolve imageResolve;
301 };
302
303 struct ImageParms
304 {
305 VkImageType imageType;
306 VkFormat format;
307 VkExtent3D extent;
308 VkImageTiling tiling;
309 VkImageLayout operationLayout;
310 VkImageCreateFlags createFlags;
311 FillMode fillMode;
312
texelBlockDimensionsvkt::api::__anonbd1d8d730111::ImageParms313 std::pair<uint32_t, uint32_t> texelBlockDimensions() const
314 {
315 const bool isCompressed = isCompressedFormat(format);
316 const uint32_t blockWidth = (isCompressed) ? getBlockWidth(format) : 1u;
317 const uint32_t blockHeight = (isCompressed) ? getBlockHeight(format) : 1u;
318 return std::make_pair(blockWidth, blockHeight);
319 }
320 };
321
322 enum class QueueSelectionOptions
323 {
324 Universal = 0,
325 ComputeOnly,
326 TransferOnly
327 };
328
329 struct CustomDeviceData
330 {
331 Move<VkDevice> device;
332 de::MovePtr<Allocator> allocator;
333 uint32_t queueFamilyIndex{0};
334 };
335
336 struct BufferParams
337 {
338 VkDeviceSize size;
339 FillMode fillMode;
340 };
341
342 struct TestParams
343 {
344 union Data
345 {
346 BufferParams buffer;
347 ImageParms image;
348 } src, dst;
349
350 std::vector<CopyRegion> regions;
351
352 union
353 {
354 VkFilter filter;
355 VkSampleCountFlagBits samples;
356 };
357
358 AllocationKind allocationKind;
359 uint32_t extensionFlags;
360 QueueSelectionOptions queueSelection;
361 uint32_t mipLevels;
362 uint32_t arrayLayers;
363 bool singleCommand;
364 uint32_t barrierCount;
365 bool
366 clearDestinationWithRed; // Used for CopyImageToImage tests to clear dst image with vec4(1.0f, 0.0f, 0.0f, 1.0f)
367 bool imageOffset;
368 bool useSecondaryCmdBuffer;
369 bool useSparseBinding;
370
TestParamsvkt::api::__anonbd1d8d730111::TestParams371 TestParams(void)
372 {
373 allocationKind = ALLOCATION_KIND_DEDICATED;
374 extensionFlags = NONE;
375 queueSelection = QueueSelectionOptions::Universal;
376 mipLevels = 1u;
377 arrayLayers = 1u;
378 singleCommand = true;
379 barrierCount = 1u;
380 src.image.createFlags = VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM;
381 dst.image.createFlags = VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM;
382 src.buffer.fillMode = FILL_MODE_GRADIENT;
383 src.image.fillMode = FILL_MODE_GRADIENT;
384 dst.buffer.fillMode = FILL_MODE_GRADIENT;
385 dst.image.fillMode = FILL_MODE_WHITE;
386 clearDestinationWithRed = false;
387 samples = VK_SAMPLE_COUNT_1_BIT;
388 imageOffset = false;
389 useSecondaryCmdBuffer = false;
390 useSparseBinding = false;
391 }
392
usesNonUniversalQueuevkt::api::__anonbd1d8d730111::TestParams393 bool usesNonUniversalQueue() const
394 {
395 return queueSelection != QueueSelectionOptions::Universal;
396 }
397 };
398
allocateBuffer(const InstanceInterface & vki,const DeviceInterface & vkd,const VkPhysicalDevice & physDevice,const VkDevice device,const VkBuffer & buffer,const MemoryRequirement requirement,Allocator & allocator,AllocationKind allocationKind)399 de::MovePtr<Allocation> allocateBuffer(const InstanceInterface &vki, const DeviceInterface &vkd,
400 const VkPhysicalDevice &physDevice, const VkDevice device,
401 const VkBuffer &buffer, const MemoryRequirement requirement,
402 Allocator &allocator, AllocationKind allocationKind)
403 {
404 switch (allocationKind)
405 {
406 case ALLOCATION_KIND_SUBALLOCATED:
407 {
408 const VkMemoryRequirements memoryRequirements = getBufferMemoryRequirements(vkd, device, buffer);
409
410 return allocator.allocate(memoryRequirements, requirement);
411 }
412
413 case ALLOCATION_KIND_DEDICATED:
414 {
415 return allocateDedicated(vki, vkd, physDevice, device, buffer, requirement);
416 }
417
418 default:
419 {
420 TCU_THROW(InternalError, "Invalid allocation kind");
421 }
422 }
423 }
424
allocateImage(const InstanceInterface & vki,const DeviceInterface & vkd,const VkPhysicalDevice & physDevice,const VkDevice device,const VkImage & image,const MemoryRequirement requirement,Allocator & allocator,AllocationKind allocationKind,const uint32_t offset)425 de::MovePtr<Allocation> allocateImage(const InstanceInterface &vki, const DeviceInterface &vkd,
426 const VkPhysicalDevice &physDevice, const VkDevice device, const VkImage &image,
427 const MemoryRequirement requirement, Allocator &allocator,
428 AllocationKind allocationKind, const uint32_t offset)
429 {
430 switch (allocationKind)
431 {
432 case ALLOCATION_KIND_SUBALLOCATED:
433 {
434 VkMemoryRequirements memoryRequirements = getImageMemoryRequirements(vkd, device, image);
435 memoryRequirements.size += offset;
436
437 return allocator.allocate(memoryRequirements, requirement);
438 }
439
440 case ALLOCATION_KIND_DEDICATED:
441 {
442 VkMemoryRequirements memoryRequirements = getImageMemoryRequirements(vkd, device, image);
443 memoryRequirements.size += offset;
444
445 const VkMemoryDedicatedAllocateInfo dedicatedAllocationInfo = {
446 VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, // VkStructureType sType
447 DE_NULL, // const void* pNext
448 image, // VkImage image
449 DE_NULL // VkBuffer buffer
450 };
451
452 return allocateExtended(vki, vkd, physDevice, device, memoryRequirements, requirement,
453 &dedicatedAllocationInfo);
454 }
455
456 default:
457 {
458 TCU_THROW(InternalError, "Invalid allocation kind");
459 }
460 }
461 }
462
checkExtensionSupport(Context & context,uint32_t flags)463 void checkExtensionSupport(Context &context, uint32_t flags)
464 {
465 if (flags & COPY_COMMANDS_2)
466 {
467 if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
468 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
469 }
470
471 if (flags & SEPARATE_DEPTH_STENCIL_LAYOUT)
472 {
473 if (!context.isDeviceFunctionalitySupported("VK_KHR_separate_depth_stencil_layouts"))
474 TCU_THROW(NotSupportedError, "VK_KHR_separate_depth_stencil_layouts is not supported");
475 }
476
477 if (flags & MAINTENANCE_1)
478 {
479 if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance1"))
480 TCU_THROW(NotSupportedError, "VK_KHR_maintenance1 is not supported");
481 }
482
483 if (flags & MAINTENANCE_5)
484 {
485 if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance5"))
486 TCU_THROW(NotSupportedError, "VK_KHR_maintenance5 is not supported");
487 }
488
489 if (flags & SPARSE_BINDING)
490 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SPARSE_BINDING);
491 }
492
getArraySize(const ImageParms & parms)493 inline uint32_t getArraySize(const ImageParms &parms)
494 {
495 return (parms.imageType != VK_IMAGE_TYPE_3D) ? parms.extent.depth : 1u;
496 }
497
getCreateFlags(const ImageParms & parms)498 inline VkImageCreateFlags getCreateFlags(const ImageParms &parms)
499 {
500 if (parms.createFlags == VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM)
501 return parms.imageType == VK_IMAGE_TYPE_2D && parms.extent.depth % 6 == 0 ?
502 VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT :
503 0;
504 else
505 return parms.createFlags;
506 }
507
getExtent3D(const ImageParms & parms,uint32_t mipLevel=0u)508 inline VkExtent3D getExtent3D(const ImageParms &parms, uint32_t mipLevel = 0u)
509 {
510 const bool isCompressed = isCompressedFormat(parms.format);
511 const uint32_t blockWidth = (isCompressed) ? getBlockWidth(parms.format) : 1u;
512 const uint32_t blockHeight = (isCompressed) ? getBlockHeight(parms.format) : 1u;
513
514 if (isCompressed && mipLevel != 0u)
515 DE_FATAL("Not implemented");
516
517 const VkExtent3D extent = {
518 (parms.extent.width >> mipLevel) * blockWidth,
519 (parms.imageType != VK_IMAGE_TYPE_1D) ? ((parms.extent.height >> mipLevel) * blockHeight) : 1u,
520 (parms.imageType == VK_IMAGE_TYPE_3D) ? parms.extent.depth : 1u,
521 };
522 return extent;
523 }
524
mapCombinedToDepthTransferFormat(const tcu::TextureFormat & combinedFormat)525 const tcu::TextureFormat mapCombinedToDepthTransferFormat(const tcu::TextureFormat &combinedFormat)
526 {
527 tcu::TextureFormat format;
528 switch (combinedFormat.type)
529 {
530 case tcu::TextureFormat::UNORM_INT16:
531 case tcu::TextureFormat::UNSIGNED_INT_16_8_8:
532 format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
533 break;
534 case tcu::TextureFormat::UNSIGNED_INT_24_8_REV:
535 format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNSIGNED_INT_24_8_REV);
536 break;
537 case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
538 case tcu::TextureFormat::FLOAT:
539 format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT);
540 break;
541 default:
542 DE_ASSERT(false);
543 break;
544 }
545 return format;
546 }
547
548 class CopiesAndBlittingTestInstance : public vkt::TestInstance
549 {
550 public:
551 CopiesAndBlittingTestInstance(Context &context, TestParams testParams);
552 virtual tcu::TestStatus iterate(void) = 0;
553
554 protected:
555 const TestParams m_params;
556 VkDevice m_device;
557 Allocator *m_allocator;
558 VkQueue m_universalQueue{VK_NULL_HANDLE};
559 Move<VkCommandPool> m_universalCmdPool;
560 Move<VkCommandBuffer> m_universalCmdBuffer;
561 VkQueue m_otherQueue{VK_NULL_HANDLE}; // Dedicated compute/transfer queue
562 Move<VkCommandPool> m_otherCmdPool; // Dedicated compute/transfer command bool & buffer
563 Move<VkCommandBuffer> m_otherCmdBuffer;
564 Move<VkCommandPool> m_secondaryCmdPool;
565 Move<VkCommandBuffer> m_secondaryCmdBuffer;
566 Move<VkCommandPool> m_sparseCmdPool;
567 Move<VkCommandBuffer> m_sparseCmdBuffer;
568
569 de::MovePtr<tcu::TextureLevel> m_sourceTextureLevel;
570 de::MovePtr<tcu::TextureLevel> m_destinationTextureLevel;
571 de::MovePtr<tcu::TextureLevel> m_expectedTextureLevel[16];
572
573 // For tests that use multiple queues, this will be a >1 sized array containing the queue familiy indices,
574 // used for setting up concurrently accessed resources.
575 std::vector<uint32_t> m_queueFamilyIndices;
576
577 void generateBuffer(tcu::PixelBufferAccess buffer, int width, int height, int depth = 1,
578 FillMode = FILL_MODE_GRADIENT);
579 virtual void generateExpectedResult(void);
580 void uploadBuffer(const tcu::ConstPixelBufferAccess &bufferAccess, const Allocation &bufferAlloc);
581 void uploadImage(const tcu::ConstPixelBufferAccess &src, VkImage dst, const ImageParms &parms,
582 const uint32_t mipLevels = 1u);
583 virtual tcu::TestStatus checkTestResult(tcu::ConstPixelBufferAccess result);
584 virtual void copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst,
585 CopyRegion region, uint32_t mipLevel = 0u) = 0;
calculateSize(tcu::ConstPixelBufferAccess src) const586 uint32_t calculateSize(tcu::ConstPixelBufferAccess src) const
587 {
588 return src.getWidth() * src.getHeight() * src.getDepth() * tcu::getPixelSize(src.getFormat());
589 }
590
591 de::MovePtr<tcu::TextureLevel> readImage(vk::VkImage image, const ImageParms &imageParms,
592 const uint32_t mipLevel = 0u);
593
594 using ExecutionCtx = std::tuple<VkQueue, VkCommandBuffer, VkCommandPool>;
activeExecutionCtx()595 ExecutionCtx activeExecutionCtx()
596 {
597 if (m_params.queueSelection != QueueSelectionOptions::Universal)
598 {
599 return std::make_tuple(m_otherQueue, *m_otherCmdBuffer, *m_otherCmdPool);
600 }
601 else
602 {
603 return std::make_tuple(m_universalQueue, *m_universalCmdBuffer, *m_universalCmdPool);
604 }
605 }
606
activeQueueFamilyIndex() const607 uint32_t activeQueueFamilyIndex() const
608 {
609 int familyIndex = -1;
610 switch (m_params.queueSelection)
611 {
612 case QueueSelectionOptions::ComputeOnly:
613 familyIndex = m_context.getComputeQueueFamilyIndex();
614 break;
615 case QueueSelectionOptions::TransferOnly:
616 familyIndex = m_context.getTransferQueueFamilyIndex();
617 break;
618 case QueueSelectionOptions::Universal:
619 familyIndex = m_context.getUniversalQueueFamilyIndex();
620 break;
621 }
622 TCU_CHECK_INTERNAL(familyIndex >= 0);
623 return (uint32_t)familyIndex;
624 }
625
626 private:
627 void uploadImageAspect(const tcu::ConstPixelBufferAccess &src, const VkImage &dst, const ImageParms &parms,
628 const uint32_t mipLevels = 1u);
629 void readImageAspect(vk::VkImage src, const tcu::PixelBufferAccess &dst, const ImageParms &parms,
630 const uint32_t mipLevel = 0u);
631 };
632
CopiesAndBlittingTestInstance(Context & context,TestParams testParams)633 CopiesAndBlittingTestInstance::CopiesAndBlittingTestInstance(Context &context, TestParams testParams)
634 : vkt::TestInstance(context)
635 , m_params(testParams)
636 {
637 // Store default device, queue and allocator. Some tests override these with custom device and queue.
638 m_device = context.getDevice();
639 m_allocator = &context.getDefaultAllocator();
640
641 const DeviceInterface &vk = context.getDeviceInterface();
642
643 int queueFamilyIdx = context.getUniversalQueueFamilyIndex();
644 m_queueFamilyIndices.push_back(queueFamilyIdx);
645
646 switch (m_params.queueSelection)
647 {
648 case QueueSelectionOptions::ComputeOnly:
649 {
650 m_otherQueue = context.getComputeQueue();
651 queueFamilyIdx = context.getComputeQueueFamilyIndex();
652 TCU_CHECK_INTERNAL(queueFamilyIdx != -1);
653 m_queueFamilyIndices.push_back(queueFamilyIdx);
654 m_otherCmdPool =
655 createCommandPool(vk, m_device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIdx);
656 m_otherCmdBuffer = allocateCommandBuffer(vk, m_device, *m_otherCmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
657 break;
658 }
659 case QueueSelectionOptions::TransferOnly:
660 {
661 m_otherQueue = context.getTransferQueue();
662 queueFamilyIdx = context.getTransferQueueFamilyIndex();
663 TCU_CHECK_INTERNAL(queueFamilyIdx != -1);
664 m_queueFamilyIndices.push_back(queueFamilyIdx);
665 m_otherCmdPool =
666 createCommandPool(vk, m_device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIdx);
667 m_otherCmdBuffer = allocateCommandBuffer(vk, m_device, *m_otherCmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
668 break;
669 }
670 case QueueSelectionOptions::Universal:
671 {
672 break; // Unconditionally created below.
673 }
674 }
675
676 m_universalQueue = context.getUniversalQueue();
677 m_universalCmdPool = createCommandPool(vk, m_device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
678 context.getUniversalQueueFamilyIndex());
679 m_universalCmdBuffer = allocateCommandBuffer(vk, m_device, *m_universalCmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
680
681 if (m_params.useSecondaryCmdBuffer)
682 {
683 m_secondaryCmdPool =
684 createCommandPool(vk, m_device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIdx);
685 m_secondaryCmdBuffer =
686 allocateCommandBuffer(vk, m_device, *m_secondaryCmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
687 }
688 }
689
generateBuffer(tcu::PixelBufferAccess buffer,int width,int height,int depth,FillMode mode)690 void CopiesAndBlittingTestInstance::generateBuffer(tcu::PixelBufferAccess buffer, int width, int height, int depth,
691 FillMode mode)
692 {
693 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(buffer.getFormat().type);
694 tcu::Vec4 maxValue(1.0f);
695
696 if (buffer.getFormat().order == tcu::TextureFormat::S)
697 {
698 // Stencil-only is stored in the first component. Stencil is always 8 bits.
699 maxValue.x() = 1 << 8;
700 }
701 else if (buffer.getFormat().order == tcu::TextureFormat::DS)
702 {
703 // In a combined format, fillWithComponentGradients expects stencil in the fourth component.
704 maxValue.w() = 1 << 8;
705 }
706 else if (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
707 channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
708 {
709 // The tcu::Vectors we use as pixels are 32-bit, so clamp to that.
710 const tcu::IVec4 bits = tcu::min(tcu::getTextureFormatBitDepth(buffer.getFormat()), tcu::IVec4(32));
711 const int signBit = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? 1 : 0);
712
713 for (int i = 0; i < 4; ++i)
714 {
715 if (bits[i] != 0)
716 maxValue[i] = static_cast<float>((uint64_t(1) << (bits[i] - signBit)) - 1);
717 }
718 }
719
720 if (mode == FILL_MODE_GRADIENT)
721 {
722 tcu::fillWithComponentGradients2(buffer, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), maxValue);
723 return;
724 }
725
726 if (mode == FILL_MODE_PYRAMID)
727 {
728 tcu::fillWithComponentGradients3(buffer, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), maxValue);
729 return;
730 }
731
732 const tcu::Vec4 redColor(maxValue.x(), 0.0, 0.0, maxValue.w());
733 const tcu::Vec4 greenColor(0.0, maxValue.y(), 0.0, maxValue.w());
734 const tcu::Vec4 blueColor(0.0, 0.0, maxValue.z(), maxValue.w());
735 const tcu::Vec4 whiteColor(maxValue.x(), maxValue.y(), maxValue.z(), maxValue.w());
736 const tcu::Vec4 blackColor(0.0f, 0.0f, 0.0f, 0.0f);
737
738 for (int z = 0; z < depth; ++z)
739 for (int y = 0; y < height; ++y)
740 for (int x = 0; x < width; ++x)
741 {
742 switch (mode)
743 {
744 case FILL_MODE_WHITE:
745 if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
746 {
747 buffer.setPixDepth(1.0f, x, y, z);
748 if (tcu::hasStencilComponent(buffer.getFormat().order))
749 buffer.setPixStencil(255, x, y, z);
750 }
751 else
752 buffer.setPixel(whiteColor, x, y, z);
753 break;
754
755 case FILL_MODE_BLACK:
756 if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
757 {
758 buffer.setPixDepth(0.0f, x, y, z);
759 if (tcu::hasStencilComponent(buffer.getFormat().order))
760 buffer.setPixStencil(0, x, y, z);
761 }
762 else
763 buffer.setPixel(blackColor, x, y, z);
764 break;
765
766 case FILL_MODE_RED:
767 if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
768 {
769 buffer.setPixDepth(redColor[0], x, y, z);
770 if (tcu::hasStencilComponent(buffer.getFormat().order))
771 buffer.setPixStencil((int)redColor[3], x, y, z);
772 }
773 else
774 buffer.setPixel(redColor, x, y, z);
775 break;
776
777 case FILL_MODE_BLUE_RED_X:
778 case FILL_MODE_BLUE_RED_Y:
779 case FILL_MODE_BLUE_RED_Z:
780 bool useBlue;
781 switch (mode)
782 {
783 case FILL_MODE_BLUE_RED_X:
784 useBlue = (x & 1);
785 break;
786 case FILL_MODE_BLUE_RED_Y:
787 useBlue = (y & 1);
788 break;
789 case FILL_MODE_BLUE_RED_Z:
790 useBlue = (z & 1);
791 break;
792 default:
793 DE_ASSERT(false);
794 break;
795 }
796 if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
797 {
798 buffer.setPixDepth((useBlue ? blueColor[0] : redColor[0]), x, y, z);
799 if (tcu::hasStencilComponent(buffer.getFormat().order))
800 buffer.setPixStencil((useBlue ? (int)blueColor[3] : (int)redColor[3]), x, y, z);
801 }
802 else
803 buffer.setPixel((useBlue ? blueColor : redColor), x, y, z);
804 break;
805
806 case FILL_MODE_MULTISAMPLE:
807 {
808 float xScaled = static_cast<float>(x) / static_cast<float>(width);
809 float yScaled = static_cast<float>(y) / static_cast<float>(height);
810 buffer.setPixel((xScaled == yScaled) ? tcu::Vec4(0.0, 0.5, 0.5, 1.0) :
811 ((xScaled > yScaled) ? greenColor : blueColor),
812 x, y, z);
813 break;
814 }
815
816 default:
817 break;
818 }
819 }
820 }
821
uploadBuffer(const tcu::ConstPixelBufferAccess & bufferAccess,const Allocation & bufferAlloc)822 void CopiesAndBlittingTestInstance::uploadBuffer(const tcu::ConstPixelBufferAccess &bufferAccess,
823 const Allocation &bufferAlloc)
824 {
825 const DeviceInterface &vk = m_context.getDeviceInterface();
826 const uint32_t bufferSize = calculateSize(bufferAccess);
827
828 // Write buffer data
829 deMemcpy(bufferAlloc.getHostPtr(), bufferAccess.getDataPtr(), bufferSize);
830 flushAlloc(vk, m_device, bufferAlloc);
831 }
832
uploadImageAspect(const tcu::ConstPixelBufferAccess & imageAccess,const VkImage & image,const ImageParms & parms,const uint32_t mipLevels)833 void CopiesAndBlittingTestInstance::uploadImageAspect(const tcu::ConstPixelBufferAccess &imageAccess,
834 const VkImage &image, const ImageParms &parms,
835 const uint32_t mipLevels)
836 {
837 const InstanceInterface &vki = m_context.getInstanceInterface();
838 const DeviceInterface &vk = m_context.getDeviceInterface();
839 const VkPhysicalDevice vkPhysDevice = m_context.getPhysicalDevice();
840 const VkDevice vkDevice = m_device;
841 Allocator &memAlloc = *m_allocator;
842 Move<VkBuffer> buffer;
843 const uint32_t bufferSize = calculateSize(imageAccess);
844 de::MovePtr<Allocation> bufferAlloc;
845 const uint32_t arraySize = getArraySize(parms);
846 const VkExtent3D imageExtent = getExtent3D(parms);
847 std::vector<VkBufferImageCopy> copyRegions;
848
849 // Create source buffer
850 {
851 const VkBufferCreateInfo bufferParams = {
852 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
853 DE_NULL, // const void* pNext;
854 0u, // VkBufferCreateFlags flags;
855 bufferSize, // VkDeviceSize size;
856 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage;
857 m_queueFamilyIndices.size() > 1 ? VK_SHARING_MODE_CONCURRENT :
858 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
859 (uint32_t)m_queueFamilyIndices.size(), // uint32_t queueFamilyIndexCount;
860 m_queueFamilyIndices.data(), // const uint32_t* pQueueFamilyIndices;
861 };
862
863 buffer = createBuffer(vk, vkDevice, &bufferParams);
864 bufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *buffer, MemoryRequirement::HostVisible, memAlloc,
865 m_params.allocationKind);
866 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
867 }
868
869 // Barriers for copying buffer to image
870 const VkBufferMemoryBarrier preBufferBarrier =
871 makeBufferMemoryBarrier(VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, *buffer, 0u, bufferSize);
872
873 const VkImageAspectFlags formatAspect = (m_params.extensionFlags & SEPARATE_DEPTH_STENCIL_LAYOUT) ?
874 getAspectFlags(imageAccess.getFormat()) :
875 getAspectFlags(parms.format);
876 const bool skipPreImageBarrier = (m_params.extensionFlags & SEPARATE_DEPTH_STENCIL_LAYOUT) ?
877 false :
878 ((formatAspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) &&
879 getAspectFlags(imageAccess.getFormat()) == VK_IMAGE_ASPECT_STENCIL_BIT));
880
881 const VkImageMemoryBarrier preImageBarrier = makeImageMemoryBarrier(
882 0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, image,
883 makeImageSubresourceRange(formatAspect, 0u, mipLevels, 0u, arraySize));
884
885 const VkImageMemoryBarrier postImageBarrier =
886 makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT,
887 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, image,
888 makeImageSubresourceRange(formatAspect, 0u, mipLevels, 0u, arraySize));
889
890 uint32_t blockWidth, blockHeight;
891 std::tie(blockWidth, blockHeight) = parms.texelBlockDimensions();
892
893 for (uint32_t mipLevelNdx = 0; mipLevelNdx < mipLevels; mipLevelNdx++)
894 {
895 const VkExtent3D copyExtent =
896 makeExtent3D(imageExtent.width >> mipLevelNdx, imageExtent.height >> mipLevelNdx, imageExtent.depth);
897 uint32_t rowLength = ((copyExtent.width + blockWidth - 1) / blockWidth) * blockWidth;
898 uint32_t imageHeight = ((copyExtent.height + blockHeight - 1) / blockHeight) * blockHeight;
899 const VkBufferImageCopy copyRegion = {
900 0u, // VkDeviceSize bufferOffset;
901 rowLength, // uint32_t bufferRowLength;
902 imageHeight, // uint32_t bufferImageHeight;
903 {
904 getAspectFlags(imageAccess.getFormat()), // VkImageAspectFlags aspect;
905 mipLevelNdx, // uint32_t mipLevel;
906 0u, // uint32_t baseArrayLayer;
907 arraySize, // uint32_t layerCount;
908 }, // VkImageSubresourceLayers imageSubresource;
909 {0, 0, 0}, // VkOffset3D imageOffset;
910 copyExtent // VkExtent3D imageExtent;
911 };
912
913 copyRegions.push_back(copyRegion);
914 }
915
916 // Write buffer data
917 deMemcpy(bufferAlloc->getHostPtr(), imageAccess.getDataPtr(), bufferSize);
918 flushAlloc(vk, vkDevice, *bufferAlloc);
919
920 // Copy buffer to image on the universal queue, since not all image aspects may be transferred on dedicated queues.
921 beginCommandBuffer(vk, *m_universalCmdBuffer);
922 vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
923 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 1, &preBufferBarrier,
924 (skipPreImageBarrier ? 0 : 1), (skipPreImageBarrier ? DE_NULL : &preImageBarrier));
925 vk.cmdCopyBufferToImage(*m_universalCmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
926 (uint32_t)copyRegions.size(), ©Regions[0]);
927 vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
928 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
929 (const VkBufferMemoryBarrier *)DE_NULL, 1, &postImageBarrier);
930 endCommandBuffer(vk, *m_universalCmdBuffer);
931
932 submitCommandsAndWait(vk, vkDevice, m_universalQueue, *m_universalCmdBuffer);
933 m_context.resetCommandPoolForVKSC(vkDevice, *m_universalCmdPool);
934 }
935
uploadImage(const tcu::ConstPixelBufferAccess & src,VkImage dst,const ImageParms & parms,const uint32_t mipLevels)936 void CopiesAndBlittingTestInstance::uploadImage(const tcu::ConstPixelBufferAccess &src, VkImage dst,
937 const ImageParms &parms, const uint32_t mipLevels)
938 {
939 if (tcu::isCombinedDepthStencilType(src.getFormat().type))
940 {
941 if (tcu::hasDepthComponent(src.getFormat().order))
942 {
943 tcu::TextureLevel depthTexture(mapCombinedToDepthTransferFormat(src.getFormat()), src.getWidth(),
944 src.getHeight(), src.getDepth());
945 tcu::copy(depthTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH));
946 uploadImageAspect(depthTexture.getAccess(), dst, parms, mipLevels);
947 }
948
949 if (tcu::hasStencilComponent(src.getFormat().order))
950 {
951 tcu::TextureLevel stencilTexture(
952 tcu::getEffectiveDepthStencilTextureFormat(src.getFormat(), tcu::Sampler::MODE_STENCIL), src.getWidth(),
953 src.getHeight(), src.getDepth());
954 tcu::copy(stencilTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL));
955 uploadImageAspect(stencilTexture.getAccess(), dst, parms, mipLevels);
956 }
957 }
958 else
959 uploadImageAspect(src, dst, parms, mipLevels);
960 }
961
checkTestResult(tcu::ConstPixelBufferAccess result)962 tcu::TestStatus CopiesAndBlittingTestInstance::checkTestResult(tcu::ConstPixelBufferAccess result)
963 {
964 const tcu::ConstPixelBufferAccess expected = m_expectedTextureLevel[0]->getAccess();
965
966 if (isFloatFormat(result.getFormat()))
967 {
968 const tcu::Vec4 threshold(0.0f);
969 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected,
970 result, threshold, tcu::COMPARE_LOG_RESULT))
971 return tcu::TestStatus::fail("CopiesAndBlitting test");
972 }
973 else
974 {
975 const tcu::UVec4 threshold(0u);
976 if (tcu::hasDepthComponent(result.getFormat().order) || tcu::hasStencilComponent(result.getFormat().order))
977 {
978 if (!tcu::dsThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected,
979 result, 0.1f, tcu::COMPARE_LOG_RESULT))
980 return tcu::TestStatus::fail("CopiesAndBlitting test");
981 }
982 else
983 {
984 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected,
985 result, threshold, tcu::COMPARE_LOG_RESULT))
986 return tcu::TestStatus::fail("CopiesAndBlitting test");
987 }
988 }
989
990 return tcu::TestStatus::pass("CopiesAndBlitting test");
991 }
992
generateExpectedResult(void)993 void CopiesAndBlittingTestInstance::generateExpectedResult(void)
994 {
995 const tcu::ConstPixelBufferAccess src = m_sourceTextureLevel->getAccess();
996 const tcu::ConstPixelBufferAccess dst = m_destinationTextureLevel->getAccess();
997
998 m_expectedTextureLevel[0] = de::MovePtr<tcu::TextureLevel>(
999 new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
1000 tcu::copy(m_expectedTextureLevel[0]->getAccess(), dst);
1001
1002 for (uint32_t i = 0; i < m_params.regions.size(); i++)
1003 copyRegionToTextureLevel(src, m_expectedTextureLevel[0]->getAccess(), m_params.regions[i]);
1004 }
1005
readImageAspect(vk::VkImage image,const tcu::PixelBufferAccess & dst,const ImageParms & imageParms,const uint32_t mipLevel)1006 void CopiesAndBlittingTestInstance::readImageAspect(vk::VkImage image, const tcu::PixelBufferAccess &dst,
1007 const ImageParms &imageParms, const uint32_t mipLevel)
1008 {
1009 const InstanceInterface &vki = m_context.getInstanceInterface();
1010 const DeviceInterface &vk = m_context.getDeviceInterface();
1011 const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
1012 const VkDevice device = m_device;
1013 Allocator &allocator = *m_allocator;
1014
1015 Move<VkBuffer> buffer;
1016 de::MovePtr<Allocation> bufferAlloc;
1017 const VkDeviceSize pixelDataSize = calculateSize(dst);
1018 const VkExtent3D imageExtent = getExtent3D(imageParms, mipLevel);
1019
1020 // Create destination buffer
1021 {
1022 const VkBufferCreateInfo bufferParams = {
1023 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1024 DE_NULL, // const void* pNext;
1025 0u, // VkBufferCreateFlags flags;
1026 pixelDataSize, // VkDeviceSize size;
1027 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
1028 m_queueFamilyIndices.size() > 1 ? VK_SHARING_MODE_CONCURRENT :
1029 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1030 (uint32_t)m_queueFamilyIndices.size(), // uint32_t queueFamilyIndexCount;
1031 m_queueFamilyIndices.data(), // const uint32_t* pQueueFamilyIndices;
1032 };
1033
1034 buffer = createBuffer(vk, device, &bufferParams);
1035 bufferAlloc = allocateBuffer(vki, vk, physDevice, device, *buffer, MemoryRequirement::HostVisible, allocator,
1036 m_params.allocationKind);
1037 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
1038
1039 deMemset(bufferAlloc->getHostPtr(), 0, static_cast<size_t>(pixelDataSize));
1040 flushAlloc(vk, device, *bufferAlloc);
1041 }
1042
1043 // Barriers for copying image to buffer
1044 const VkImageAspectFlags formatAspect = getAspectFlags(imageParms.format);
1045 const VkImageMemoryBarrier imageBarrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1046 DE_NULL, // const void* pNext;
1047 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1048 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
1049 imageParms.operationLayout, // VkImageLayout oldLayout;
1050 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout;
1051 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
1052 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
1053 image, // VkImage image;
1054 {
1055 // VkImageSubresourceRange subresourceRange;
1056 formatAspect, // VkImageAspectFlags aspectMask;
1057 mipLevel, // uint32_t baseMipLevel;
1058 1u, // uint32_t mipLevels;
1059 0u, // uint32_t baseArraySlice;
1060 getArraySize(imageParms) // uint32_t arraySize;
1061 }};
1062
1063 const VkBufferMemoryBarrier bufferBarrier = {
1064 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
1065 DE_NULL, // const void* pNext;
1066 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1067 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
1068 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
1069 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
1070 *buffer, // VkBuffer buffer;
1071 0u, // VkDeviceSize offset;
1072 pixelDataSize // VkDeviceSize size;
1073 };
1074
1075 const VkImageMemoryBarrier postImageBarrier = {
1076 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1077 DE_NULL, // const void* pNext;
1078 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags srcAccessMask;
1079 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1080 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout oldLayout;
1081 imageParms.operationLayout, // VkImageLayout newLayout;
1082 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
1083 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
1084 image, // VkImage image;
1085 {
1086 formatAspect, // VkImageAspectFlags aspectMask;
1087 mipLevel, // uint32_t baseMipLevel;
1088 1u, // uint32_t mipLevels;
1089 0u, // uint32_t baseArraySlice;
1090 getArraySize(imageParms) // uint32_t arraySize;
1091 } // VkImageSubresourceRange subresourceRange;
1092 };
1093
1094 // Copy image to buffer
1095 const bool isCompressed = isCompressedFormat(imageParms.format);
1096 const uint32_t blockWidth = (isCompressed) ? getBlockWidth(imageParms.format) : 1u;
1097 const uint32_t blockHeight = (isCompressed) ? getBlockHeight(imageParms.format) : 1u;
1098 uint32_t rowLength = ((imageExtent.width + blockWidth - 1) / blockWidth) * blockWidth;
1099 uint32_t imageHeight = ((imageExtent.height + blockHeight - 1) / blockHeight) * blockHeight;
1100
1101 // Copy image to buffer - note that there are cases where m_params.dst.image.format is not the same as dst.getFormat()
1102 const VkImageAspectFlags aspect = isCompressedFormat(m_params.dst.image.format) ?
1103 static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_COLOR_BIT) :
1104 getAspectFlags(dst.getFormat());
1105 const VkBufferImageCopy copyRegion = {
1106 0u, // VkDeviceSize bufferOffset;
1107 rowLength, // uint32_t bufferRowLength;
1108 imageHeight, // uint32_t bufferImageHeight;
1109 {
1110 aspect, // VkImageAspectFlags aspect;
1111 mipLevel, // uint32_t mipLevel;
1112 0u, // uint32_t baseArrayLayer;
1113 getArraySize(imageParms), // uint32_t layerCount;
1114 }, // VkImageSubresourceLayers imageSubresource;
1115 {0, 0, 0}, // VkOffset3D imageOffset;
1116 imageExtent // VkExtent3D imageExtent;
1117 };
1118
1119 beginCommandBuffer(vk, *m_universalCmdBuffer);
1120 vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1121 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
1122 (const VkBufferMemoryBarrier *)DE_NULL, 1, &imageBarrier);
1123 vk.cmdCopyImageToBuffer(*m_universalCmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u,
1124 ©Region);
1125 vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
1126 VK_PIPELINE_STAGE_HOST_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0,
1127 (const VkMemoryBarrier *)DE_NULL, 1, &bufferBarrier, 1, &postImageBarrier);
1128 endCommandBuffer(vk, *m_universalCmdBuffer);
1129
1130 submitCommandsAndWait(vk, device, m_universalQueue, *m_universalCmdBuffer);
1131 m_context.resetCommandPoolForVKSC(device, *m_universalCmdPool);
1132
1133 // Read buffer data
1134 invalidateAlloc(vk, device, *bufferAlloc);
1135 tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferAlloc->getHostPtr()));
1136 }
1137
readImage(vk::VkImage image,const ImageParms & parms,const uint32_t mipLevel)1138 de::MovePtr<tcu::TextureLevel> CopiesAndBlittingTestInstance::readImage(vk::VkImage image, const ImageParms &parms,
1139 const uint32_t mipLevel)
1140 {
1141 const tcu::TextureFormat imageFormat = getSizeCompatibleTcuTextureFormat(parms.format);
1142 de::MovePtr<tcu::TextureLevel> resultLevel(new tcu::TextureLevel(
1143 imageFormat, parms.extent.width >> mipLevel, parms.extent.height >> mipLevel, parms.extent.depth));
1144
1145 if (tcu::isCombinedDepthStencilType(imageFormat.type))
1146 {
1147 if (tcu::hasDepthComponent(imageFormat.order))
1148 {
1149 tcu::TextureLevel depthTexture(mapCombinedToDepthTransferFormat(imageFormat),
1150 parms.extent.width >> mipLevel, parms.extent.height >> mipLevel,
1151 parms.extent.depth);
1152 readImageAspect(image, depthTexture.getAccess(), parms, mipLevel);
1153 tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_DEPTH),
1154 depthTexture.getAccess());
1155 }
1156
1157 if (tcu::hasStencilComponent(imageFormat.order))
1158 {
1159 tcu::TextureLevel stencilTexture(
1160 tcu::getEffectiveDepthStencilTextureFormat(imageFormat, tcu::Sampler::MODE_STENCIL),
1161 parms.extent.width >> mipLevel, parms.extent.height >> mipLevel, parms.extent.depth);
1162 readImageAspect(image, stencilTexture.getAccess(), parms, mipLevel);
1163 tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_STENCIL),
1164 stencilTexture.getAccess());
1165 }
1166 }
1167 else
1168 readImageAspect(image, resultLevel->getAccess(), parms, mipLevel);
1169
1170 return resultLevel;
1171 }
1172
1173 // Copy from image to image.
1174
1175 class CopyImageToImage final : public CopiesAndBlittingTestInstance
1176 {
1177 public:
1178 CopyImageToImage(Context &context, TestParams params);
1179 tcu::TestStatus iterate(void) override;
1180
1181 private:
1182 tcu::TestStatus checkTestResult(tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess()) override;
1183 void copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region,
1184 uint32_t mipLevel = 0u) override;
1185
1186 Move<VkImage> m_source;
1187 de::MovePtr<Allocation> m_sourceImageAlloc;
1188 Move<VkImage> m_destination;
1189 de::MovePtr<Allocation> m_destinationImageAlloc;
1190 std::vector<de::SharedPtr<Allocation>> m_sparseAllocations;
1191 Move<VkSemaphore> m_sparseSemaphore;
1192 };
1193
CopyImageToImage(Context & context,TestParams params)1194 CopyImageToImage::CopyImageToImage(Context &context, TestParams params) : CopiesAndBlittingTestInstance(context, params)
1195 {
1196 const InstanceInterface &vki = context.getInstanceInterface();
1197 const DeviceInterface &vk = context.getDeviceInterface();
1198 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
1199
1200 // Create source image
1201 {
1202 VkImageCreateInfo sourceImageParams = {
1203 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1204 DE_NULL, // const void* pNext;
1205 getCreateFlags(m_params.src.image), // VkImageCreateFlags flags;
1206 m_params.src.image.imageType, // VkImageType imageType;
1207 m_params.src.image.format, // VkFormat format;
1208 getExtent3D(m_params.src.image), // VkExtent3D extent;
1209 1u, // uint32_t mipLevels;
1210 getArraySize(m_params.src.image), // uint32_t arraySize;
1211 VK_SAMPLE_COUNT_1_BIT, // uint32_t samples;
1212 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1213 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
1214 m_queueFamilyIndices.size() > 1 ? VK_SHARING_MODE_CONCURRENT :
1215 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1216 (uint32_t)m_queueFamilyIndices.size(), // uint32_t queueFamilyIndexCount;
1217 m_queueFamilyIndices.data(), // const uint32_t* pQueueFamilyIndices;
1218 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
1219 };
1220
1221 #ifndef CTS_USES_VULKANSC
1222 if (!params.useSparseBinding)
1223 {
1224 #endif
1225 m_source = createImage(vk, m_device, &sourceImageParams);
1226 m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, m_device, *m_source, MemoryRequirement::Any,
1227 *m_allocator, m_params.allocationKind, 0u);
1228 VK_CHECK(vk.bindImageMemory(m_device, *m_source, m_sourceImageAlloc->getMemory(),
1229 m_sourceImageAlloc->getOffset()));
1230 #ifndef CTS_USES_VULKANSC
1231 }
1232 else
1233 {
1234 sourceImageParams.flags |=
1235 (vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT | vk::VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT);
1236 vk::VkImageFormatProperties imageFormatProperties;
1237 if (vki.getPhysicalDeviceImageFormatProperties(vkPhysDevice, sourceImageParams.format,
1238 sourceImageParams.imageType, sourceImageParams.tiling,
1239 sourceImageParams.usage, sourceImageParams.flags,
1240 &imageFormatProperties) == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
1241 {
1242 TCU_THROW(NotSupportedError, "Image format not supported");
1243 }
1244 m_source = createImage(
1245 vk, m_device,
1246 &sourceImageParams); //de::MovePtr<SparseImage>(new SparseImage(vk, vk, vkPhysDevice, vki, sourceImageParams, m_queue, *m_allocator, mapVkFormat(sourceImageParams.format)));
1247 m_sparseSemaphore = createSemaphore(vk, m_device);
1248 allocateAndBindSparseImage(vk, m_device, vkPhysDevice, vki, sourceImageParams, m_sparseSemaphore.get(),
1249 context.getSparseQueue(), *m_allocator, m_sparseAllocations,
1250 mapVkFormat(sourceImageParams.format), m_source.get());
1251 }
1252 #endif
1253 }
1254
1255 // Create destination image
1256 {
1257 const VkImageCreateInfo destinationImageParams = {
1258 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1259 DE_NULL, // const void* pNext;
1260 getCreateFlags(m_params.dst.image), // VkImageCreateFlags flags;
1261 m_params.dst.image.imageType, // VkImageType imageType;
1262 m_params.dst.image.format, // VkFormat format;
1263 getExtent3D(m_params.dst.image), // VkExtent3D extent;
1264 1u, // uint32_t mipLevels;
1265 getArraySize(m_params.dst.image), // uint32_t arraySize;
1266 VK_SAMPLE_COUNT_1_BIT, // uint32_t samples;
1267 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1268 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
1269 m_queueFamilyIndices.size() > 1 ? VK_SHARING_MODE_CONCURRENT :
1270 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1271 (uint32_t)m_queueFamilyIndices.size(), // uint32_t queueFamilyIndexCount;
1272 m_queueFamilyIndices.data(), // const uint32_t* pQueueFamilyIndices;
1273 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
1274 };
1275
1276 m_destination = createImage(vk, m_device, &destinationImageParams);
1277 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, m_device, *m_destination, MemoryRequirement::Any,
1278 *m_allocator, m_params.allocationKind, 0u);
1279 VK_CHECK(vk.bindImageMemory(m_device, *m_destination, m_destinationImageAlloc->getMemory(),
1280 m_destinationImageAlloc->getOffset()));
1281 }
1282 }
1283
iterate(void)1284 tcu::TestStatus CopyImageToImage::iterate(void)
1285 {
1286 const bool srcCompressed = isCompressedFormat(m_params.src.image.format);
1287 const bool dstCompressed = isCompressedFormat(m_params.dst.image.format);
1288
1289 const tcu::TextureFormat srcTcuFormat = getSizeCompatibleTcuTextureFormat(m_params.src.image.format);
1290 const tcu::TextureFormat dstTcuFormat = getSizeCompatibleTcuTextureFormat(m_params.dst.image.format);
1291
1292 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(
1293 new tcu::TextureLevel(srcTcuFormat, (int)m_params.src.image.extent.width, (int)m_params.src.image.extent.height,
1294 (int)m_params.src.image.extent.depth));
1295 generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height,
1296 m_params.src.image.extent.depth, m_params.src.image.fillMode);
1297 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(
1298 new tcu::TextureLevel(dstTcuFormat, (int)m_params.dst.image.extent.width, (int)m_params.dst.image.extent.height,
1299 (int)m_params.dst.image.extent.depth));
1300 generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width,
1301 m_params.dst.image.extent.height, m_params.dst.image.extent.depth,
1302 m_params.clearDestinationWithRed ? FILL_MODE_RED : m_params.dst.image.fillMode);
1303 generateExpectedResult();
1304
1305 uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
1306 uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
1307
1308 const DeviceInterface &vk = m_context.getDeviceInterface();
1309 const VkDevice vkDevice = m_device;
1310
1311 VkQueue queue = VK_NULL_HANDLE;
1312 VkCommandBuffer cmdbuf = VK_NULL_HANDLE;
1313 VkCommandPool cmdpool = VK_NULL_HANDLE;
1314 std::tie(queue, cmdbuf, cmdpool) = activeExecutionCtx();
1315
1316 std::vector<VkImageCopy> imageCopies;
1317 std::vector<VkImageCopy2KHR> imageCopies2KHR;
1318 for (uint32_t i = 0; i < m_params.regions.size(); i++)
1319 {
1320 VkImageCopy imageCopy = m_params.regions[i].imageCopy;
1321
1322 // When copying between compressed and uncompressed formats the extent
1323 // members represent the texel dimensions of the source image.
1324 if (srcCompressed)
1325 {
1326 const uint32_t blockWidth = getBlockWidth(m_params.src.image.format);
1327 const uint32_t blockHeight = getBlockHeight(m_params.src.image.format);
1328
1329 imageCopy.srcOffset.x *= blockWidth;
1330 imageCopy.extent.width *= blockWidth;
1331
1332 // VUID-vkCmdCopyImage-srcImage-00146
1333 if (m_params.src.image.imageType != vk::VK_IMAGE_TYPE_1D)
1334 {
1335 imageCopy.srcOffset.y *= blockHeight;
1336 imageCopy.extent.height *= blockHeight;
1337 }
1338 }
1339
1340 if (dstCompressed)
1341 {
1342 const uint32_t blockWidth = getBlockWidth(m_params.dst.image.format);
1343 const uint32_t blockHeight = getBlockHeight(m_params.dst.image.format);
1344
1345 imageCopy.dstOffset.x *= blockWidth;
1346
1347 // VUID-vkCmdCopyImage-dstImage-00152
1348 if (m_params.dst.image.imageType != vk::VK_IMAGE_TYPE_1D)
1349 {
1350 imageCopy.dstOffset.y *= blockHeight;
1351 }
1352 }
1353
1354 if (!(m_params.extensionFlags & COPY_COMMANDS_2))
1355 {
1356 imageCopies.push_back(imageCopy);
1357 }
1358 else
1359 {
1360 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
1361 imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
1362 }
1363 }
1364
1365 VkImageMemoryBarrier imageBarriers[] = {
1366 // source image
1367 {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1368 DE_NULL, // const void* pNext;
1369 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1370 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
1371 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1372 m_params.src.image.operationLayout, // VkImageLayout newLayout;
1373 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
1374 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
1375 m_source.get(), // VkImage image;
1376 {
1377 // VkImageSubresourceRange subresourceRange;
1378 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
1379 0u, // uint32_t baseMipLevel;
1380 1u, // uint32_t mipLevels;
1381 0u, // uint32_t baseArraySlice;
1382 getArraySize(m_params.src.image) // uint32_t arraySize;
1383 }},
1384 // destination image
1385 {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1386 DE_NULL, // const void* pNext;
1387 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1388 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1389 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1390 m_params.dst.image.operationLayout, // VkImageLayout newLayout;
1391 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
1392 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
1393 m_destination.get(), // VkImage image;
1394 {
1395 // VkImageSubresourceRange subresourceRange;
1396 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
1397 0u, // uint32_t baseMipLevel;
1398 1u, // uint32_t mipLevels;
1399 0u, // uint32_t baseArraySlice;
1400 getArraySize(m_params.dst.image) // uint32_t arraySize;
1401 }},
1402 };
1403
1404 VkCommandBuffer recordingBuf = cmdbuf;
1405 if (m_params.useSecondaryCmdBuffer)
1406 {
1407 beginSecondaryCommandBuffer(vk, *m_secondaryCmdBuffer);
1408 recordingBuf = *m_secondaryCmdBuffer;
1409 }
1410 else
1411 {
1412 beginCommandBuffer(vk, cmdbuf);
1413 }
1414
1415 vk.cmdPipelineBarrier(recordingBuf, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1416 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
1417 (const VkBufferMemoryBarrier *)DE_NULL, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers);
1418
1419 if (m_params.clearDestinationWithRed)
1420 {
1421 VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u};
1422 VkClearColorValue clearColor;
1423
1424 clearColor.float32[0] = 1.0f;
1425 clearColor.float32[1] = 0.0f;
1426 clearColor.float32[2] = 0.0f;
1427 clearColor.float32[3] = 1.0f;
1428 vk.cmdClearColorImage(recordingBuf, m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1u,
1429 &range);
1430 imageBarriers[0].oldLayout = imageBarriers[0].newLayout;
1431 imageBarriers[1].oldLayout = imageBarriers[1].newLayout;
1432 vk.cmdPipelineBarrier(recordingBuf, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1433 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
1434 (const VkBufferMemoryBarrier *)DE_NULL, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers);
1435 }
1436
1437 if (!(m_params.extensionFlags & COPY_COMMANDS_2))
1438 {
1439 vk.cmdCopyImage(recordingBuf, m_source.get(), m_params.src.image.operationLayout, m_destination.get(),
1440 m_params.dst.image.operationLayout, (uint32_t)imageCopies.size(), imageCopies.data());
1441 }
1442 else
1443 {
1444 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
1445 const VkCopyImageInfo2KHR copyImageInfo2KHR = {
1446 VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR, // VkStructureType sType;
1447 DE_NULL, // const void* pNext;
1448 m_source.get(), // VkImage srcImage;
1449 m_params.src.image.operationLayout, // VkImageLayout srcImageLayout;
1450 m_destination.get(), // VkImage dstImage;
1451 m_params.dst.image.operationLayout, // VkImageLayout dstImageLayout;
1452 (uint32_t)imageCopies2KHR.size(), // uint32_t regionCount;
1453 imageCopies2KHR.data() // const VkImageCopy2KHR* pRegions;
1454 };
1455
1456 vk.cmdCopyImage2(recordingBuf, ©ImageInfo2KHR);
1457 }
1458
1459 endCommandBuffer(vk, recordingBuf);
1460
1461 if (m_params.useSecondaryCmdBuffer)
1462 {
1463 beginCommandBuffer(vk, cmdbuf);
1464 vk.cmdExecuteCommands(cmdbuf, 1, &recordingBuf);
1465 endCommandBuffer(vk, cmdbuf);
1466 }
1467
1468 submitCommandsAndWait(vk, vkDevice, queue, cmdbuf);
1469 m_context.resetCommandPoolForVKSC(vkDevice, cmdpool);
1470
1471 if (m_params.useSecondaryCmdBuffer)
1472 m_context.resetCommandPoolForVKSC(vkDevice, *m_secondaryCmdPool);
1473
1474 de::MovePtr<tcu::TextureLevel> resultTextureLevel = readImage(*m_destination, m_params.dst.image);
1475
1476 return checkTestResult(resultTextureLevel->getAccess());
1477 }
1478
checkTestResult(tcu::ConstPixelBufferAccess result)1479 tcu::TestStatus CopyImageToImage::checkTestResult(tcu::ConstPixelBufferAccess result)
1480 {
1481 const tcu::Vec4 fThreshold(0.0f);
1482 const tcu::UVec4 uThreshold(0u);
1483
1484 if (tcu::isCombinedDepthStencilType(result.getFormat().type))
1485 {
1486 if (tcu::hasDepthComponent(result.getFormat().order))
1487 {
1488 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_DEPTH;
1489 const tcu::ConstPixelBufferAccess depthResult = tcu::getEffectiveDepthStencilAccess(result, mode);
1490 const tcu::ConstPixelBufferAccess expectedResult =
1491 tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
1492
1493 if (isFloatFormat(result.getFormat()))
1494 {
1495 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison",
1496 expectedResult, depthResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1497 return tcu::TestStatus::fail("CopiesAndBlitting test");
1498 }
1499 else
1500 {
1501 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison",
1502 expectedResult, depthResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1503 return tcu::TestStatus::fail("CopiesAndBlitting test");
1504 }
1505 }
1506
1507 if (tcu::hasStencilComponent(result.getFormat().order))
1508 {
1509 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_STENCIL;
1510 const tcu::ConstPixelBufferAccess stencilResult = tcu::getEffectiveDepthStencilAccess(result, mode);
1511 const tcu::ConstPixelBufferAccess expectedResult =
1512 tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
1513
1514 if (isFloatFormat(result.getFormat()))
1515 {
1516 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison",
1517 expectedResult, stencilResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1518 return tcu::TestStatus::fail("CopiesAndBlitting test");
1519 }
1520 else
1521 {
1522 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison",
1523 expectedResult, stencilResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1524 return tcu::TestStatus::fail("CopiesAndBlitting test");
1525 }
1526 }
1527 }
1528 else
1529 {
1530 if (!tcu::bitwiseCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison",
1531 m_expectedTextureLevel[0]->getAccess(), result, tcu::COMPARE_LOG_RESULT))
1532 return tcu::TestStatus::fail("CopiesAndBlitting test");
1533 }
1534
1535 return tcu::TestStatus::pass("CopiesAndBlitting test");
1536 }
1537
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,uint32_t mipLevel)1538 void CopyImageToImage::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst,
1539 CopyRegion region, uint32_t mipLevel)
1540 {
1541 DE_UNREF(mipLevel);
1542
1543 VkOffset3D srcOffset = region.imageCopy.srcOffset;
1544 VkOffset3D dstOffset = region.imageCopy.dstOffset;
1545 VkExtent3D extent = region.imageCopy.extent;
1546
1547 if (region.imageCopy.dstSubresource.baseArrayLayer > region.imageCopy.srcSubresource.baseArrayLayer)
1548 {
1549 dstOffset.z = srcOffset.z;
1550 extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.srcSubresource.layerCount);
1551 }
1552
1553 if (region.imageCopy.dstSubresource.baseArrayLayer < region.imageCopy.srcSubresource.baseArrayLayer)
1554 {
1555 srcOffset.z = dstOffset.z;
1556 extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.srcSubresource.layerCount);
1557 }
1558
1559 if (tcu::isCombinedDepthStencilType(src.getFormat().type))
1560 {
1561 DE_ASSERT(src.getFormat() == dst.getFormat());
1562
1563 // Copy depth.
1564 if (tcu::hasDepthComponent(src.getFormat().order))
1565 {
1566 const tcu::ConstPixelBufferAccess srcSubRegion =
1567 getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z,
1568 extent.width, extent.height, extent.depth),
1569 tcu::Sampler::MODE_DEPTH);
1570 const tcu::PixelBufferAccess dstSubRegion =
1571 getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z,
1572 extent.width, extent.height, extent.depth),
1573 tcu::Sampler::MODE_DEPTH);
1574 tcu::copy(dstSubRegion, srcSubRegion);
1575 }
1576
1577 // Copy stencil.
1578 if (tcu::hasStencilComponent(src.getFormat().order))
1579 {
1580 const tcu::ConstPixelBufferAccess srcSubRegion =
1581 getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z,
1582 extent.width, extent.height, extent.depth),
1583 tcu::Sampler::MODE_STENCIL);
1584 const tcu::PixelBufferAccess dstSubRegion =
1585 getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z,
1586 extent.width, extent.height, extent.depth),
1587 tcu::Sampler::MODE_STENCIL);
1588 tcu::copy(dstSubRegion, srcSubRegion);
1589 }
1590 }
1591 else
1592 {
1593 const tcu::ConstPixelBufferAccess srcSubRegion =
1594 tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
1595 // CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
1596 const tcu::PixelBufferAccess dstWithSrcFormat(srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
1597 const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(
1598 dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
1599
1600 tcu::copy(dstSubRegion, srcSubRegion);
1601 }
1602 }
1603
1604 class CopyImageToImageTestCase : public vkt::TestCase
1605 {
1606 public:
CopyImageToImageTestCase(tcu::TestContext & testCtx,const std::string & name,const TestParams params)1607 CopyImageToImageTestCase(tcu::TestContext &testCtx, const std::string &name, const TestParams params)
1608 : vkt::TestCase(testCtx, name)
1609 , m_params(params)
1610 {
1611 }
1612
createInstance(Context & context) const1613 virtual TestInstance *createInstance(Context &context) const
1614 {
1615 return new CopyImageToImage(context, m_params);
1616 }
1617
checkSupport(Context & context) const1618 virtual void checkSupport(Context &context) const
1619 {
1620 if (m_params.allocationKind == ALLOCATION_KIND_DEDICATED)
1621 {
1622 if (!context.isDeviceFunctionalitySupported("VK_KHR_dedicated_allocation"))
1623 TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported");
1624 }
1625
1626 #ifndef CTS_USES_VULKANSC
1627 if (m_params.src.image.format == VK_FORMAT_A8_UNORM_KHR ||
1628 m_params.dst.image.format == VK_FORMAT_A8_UNORM_KHR ||
1629 m_params.src.image.format == VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR ||
1630 m_params.dst.image.format == VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR)
1631 context.requireDeviceFunctionality("VK_KHR_maintenance5");
1632 #endif // CTS_USES_VULKANSC
1633
1634 checkExtensionSupport(context, m_params.extensionFlags);
1635
1636 const VkPhysicalDeviceLimits limits = context.getDeviceProperties().limits;
1637 VkImageFormatProperties properties;
1638
1639 if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
1640 context.getPhysicalDevice(), m_params.src.image.format, m_params.src.image.imageType,
1641 VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
1642 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
1643 (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
1644 context.getPhysicalDevice(), m_params.dst.image.format, m_params.dst.image.imageType,
1645 VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0,
1646 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
1647 {
1648 TCU_THROW(NotSupportedError, "Format not supported");
1649 }
1650
1651 // Check maxImageDimension1D
1652 {
1653 if (m_params.src.image.imageType == VK_IMAGE_TYPE_1D &&
1654 m_params.src.image.extent.width > limits.maxImageDimension1D)
1655 TCU_THROW(NotSupportedError, "Requested 1D src image dimensions not supported");
1656
1657 if (m_params.dst.image.imageType == VK_IMAGE_TYPE_1D &&
1658 m_params.dst.image.extent.width > limits.maxImageDimension1D)
1659 TCU_THROW(NotSupportedError, "Requested 1D dst image dimensions not supported");
1660 }
1661
1662 // Check maxImageDimension2D
1663 {
1664 if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D &&
1665 (m_params.src.image.extent.width > limits.maxImageDimension2D ||
1666 m_params.src.image.extent.height > limits.maxImageDimension2D))
1667 {
1668 TCU_THROW(NotSupportedError, "Requested 2D src image dimensions not supported");
1669 }
1670
1671 if (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D &&
1672 (m_params.dst.image.extent.width > limits.maxImageDimension2D ||
1673 m_params.dst.image.extent.height > limits.maxImageDimension2D))
1674 {
1675 TCU_THROW(NotSupportedError, "Requested 2D dst image dimensions not supported");
1676 }
1677 }
1678
1679 // Check maxImageDimension3D
1680 {
1681 if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D &&
1682 (m_params.src.image.extent.width > limits.maxImageDimension3D ||
1683 m_params.src.image.extent.height > limits.maxImageDimension3D ||
1684 m_params.src.image.extent.depth > limits.maxImageDimension3D))
1685 {
1686 TCU_THROW(NotSupportedError, "Requested 3D src image dimensions not supported");
1687 }
1688
1689 if (m_params.dst.image.imageType == VK_IMAGE_TYPE_3D &&
1690 (m_params.dst.image.extent.width > limits.maxImageDimension3D ||
1691 m_params.dst.image.extent.height > limits.maxImageDimension3D ||
1692 m_params.src.image.extent.depth > limits.maxImageDimension3D))
1693 {
1694 TCU_THROW(NotSupportedError, "Requested 3D dst image dimensions not supported");
1695 }
1696 }
1697 }
1698
1699 private:
1700 TestParams m_params;
1701 };
1702
1703 class CopyImageToImageMipmap : public CopiesAndBlittingTestInstance
1704 {
1705 public:
1706 CopyImageToImageMipmap(Context &context, TestParams params);
1707 virtual tcu::TestStatus iterate(void);
1708
1709 protected:
1710 tcu::TestStatus checkResult(tcu::ConstPixelBufferAccess result, tcu::ConstPixelBufferAccess expected);
1711
1712 private:
1713 Move<VkImage> m_source;
1714 de::MovePtr<Allocation> m_sourceImageAlloc;
1715 Move<VkImage> m_destination;
1716 de::MovePtr<Allocation> m_destinationImageAlloc;
1717 std::vector<de::SharedPtr<Allocation>> m_sparseAllocations;
1718 Move<VkSemaphore> m_sparseSemaphore;
1719
1720 virtual void copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst,
1721 CopyRegion region, uint32_t mipLevel = 0u);
1722 };
1723
CopyImageToImageMipmap(Context & context,TestParams params)1724 CopyImageToImageMipmap::CopyImageToImageMipmap(Context &context, TestParams params)
1725 : CopiesAndBlittingTestInstance(context, params)
1726 {
1727 const InstanceInterface &vki = context.getInstanceInterface();
1728 const DeviceInterface &vk = context.getDeviceInterface();
1729 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
1730
1731 // Create source image
1732 {
1733 VkImageCreateInfo sourceImageParams = {
1734 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1735 DE_NULL, // const void* pNext;
1736 getCreateFlags(m_params.src.image), // VkImageCreateFlags flags;
1737 m_params.src.image.imageType, // VkImageType imageType;
1738 m_params.src.image.format, // VkFormat format;
1739 getExtent3D(m_params.src.image), // VkExtent3D extent;
1740 params.mipLevels, // uint32_t mipLevels;
1741 getArraySize(m_params.src.image), // uint32_t arraySize;
1742 VK_SAMPLE_COUNT_1_BIT, // uint32_t samples;
1743 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1744 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
1745 m_queueFamilyIndices.size() > 1 ? VK_SHARING_MODE_CONCURRENT :
1746 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1747 (uint32_t)m_queueFamilyIndices.size(), // uint32_t queueFamilyIndexCount;
1748 m_queueFamilyIndices.data(), // const uint32_t* pQueueFamilyIndices;
1749 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
1750 };
1751
1752 #ifndef CTS_USES_VULKANSC
1753 if (!params.useSparseBinding)
1754 {
1755 #endif
1756 m_source = createImage(vk, m_device, &sourceImageParams);
1757 m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, m_device, *m_source, MemoryRequirement::Any,
1758 *m_allocator, m_params.allocationKind, 0u);
1759 VK_CHECK(vk.bindImageMemory(m_device, *m_source, m_sourceImageAlloc->getMemory(),
1760 m_sourceImageAlloc->getOffset()));
1761 #ifndef CTS_USES_VULKANSC
1762 }
1763 else
1764 {
1765 sourceImageParams.flags |=
1766 (vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT | vk::VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT);
1767 vk::VkImageFormatProperties imageFormatProperties;
1768 if (vki.getPhysicalDeviceImageFormatProperties(vkPhysDevice, sourceImageParams.format,
1769 sourceImageParams.imageType, sourceImageParams.tiling,
1770 sourceImageParams.usage, sourceImageParams.flags,
1771 &imageFormatProperties) == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
1772 {
1773 TCU_THROW(NotSupportedError, "Image format not supported");
1774 }
1775 m_source = createImage(
1776 vk, m_device,
1777 &sourceImageParams); //de::MovePtr<SparseImage>(new SparseImage(vk, vk, vkPhysDevice, vki, sourceImageParams, m_queue, *m_allocator, mapVkFormat(sourceImageParams.format)));
1778 m_sparseSemaphore = createSemaphore(vk, m_device);
1779 allocateAndBindSparseImage(vk, m_device, vkPhysDevice, vki, sourceImageParams, m_sparseSemaphore.get(),
1780 context.getSparseQueue(), *m_allocator, m_sparseAllocations,
1781 mapVkFormat(sourceImageParams.format), m_source.get());
1782 }
1783 #endif
1784 }
1785
1786 // Create destination image
1787 {
1788 const VkImageCreateInfo destinationImageParams = {
1789 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1790 DE_NULL, // const void* pNext;
1791 getCreateFlags(m_params.dst.image), // VkImageCreateFlags flags;
1792 m_params.dst.image.imageType, // VkImageType imageType;
1793 m_params.dst.image.format, // VkFormat format;
1794 getExtent3D(m_params.dst.image), // VkExtent3D extent;
1795 params.mipLevels, // uint32_t mipLevels;
1796 getArraySize(m_params.dst.image), // uint32_t arraySize;
1797 VK_SAMPLE_COUNT_1_BIT, // uint32_t samples;
1798 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1799 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
1800 m_queueFamilyIndices.size() > 1 ? VK_SHARING_MODE_CONCURRENT :
1801 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1802 (uint32_t)m_queueFamilyIndices.size(), // uint32_t queueFamilyIndexCount;
1803 m_queueFamilyIndices.data(), // const uint32_t* pQueueFamilyIndices;
1804 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
1805 };
1806
1807 m_destination = createImage(vk, m_device, &destinationImageParams);
1808 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, m_device, *m_destination, MemoryRequirement::Any,
1809 *m_allocator, m_params.allocationKind, 0u);
1810 VK_CHECK(vk.bindImageMemory(m_device, *m_destination, m_destinationImageAlloc->getMemory(),
1811 m_destinationImageAlloc->getOffset()));
1812 }
1813 }
1814
iterate(void)1815 tcu::TestStatus CopyImageToImageMipmap::iterate(void)
1816 {
1817 const tcu::TextureFormat srcTcuFormat = getSizeCompatibleTcuTextureFormat(m_params.src.image.format);
1818 const tcu::TextureFormat dstTcuFormat = getSizeCompatibleTcuTextureFormat(m_params.dst.image.format);
1819
1820 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(
1821 new tcu::TextureLevel(srcTcuFormat, (int)m_params.src.image.extent.width, (int)m_params.src.image.extent.height,
1822 (int)m_params.src.image.extent.depth));
1823 generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height,
1824 m_params.src.image.extent.depth, m_params.src.image.fillMode);
1825 uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image, m_params.mipLevels);
1826
1827 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(
1828 new tcu::TextureLevel(dstTcuFormat, (int)m_params.dst.image.extent.width, (int)m_params.dst.image.extent.height,
1829 (int)m_params.dst.image.extent.depth));
1830 generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width,
1831 m_params.dst.image.extent.height, m_params.dst.image.extent.depth, FILL_MODE_RED);
1832 uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, m_params.mipLevels);
1833
1834 const DeviceInterface &vk = m_context.getDeviceInterface();
1835 const VkDevice vkDevice = m_device;
1836 VkQueue queue = VK_NULL_HANDLE;
1837 VkCommandBuffer commandBuffer = VK_NULL_HANDLE;
1838 VkCommandPool commandPool = VK_NULL_HANDLE;
1839 std::tie(queue, commandBuffer, commandPool) = activeExecutionCtx();
1840
1841 std::vector<VkImageCopy> imageCopies;
1842 std::vector<VkImageCopy2KHR> imageCopies2KHR;
1843 for (uint32_t i = 0; i < m_params.regions.size(); i++)
1844 {
1845 VkImageCopy imageCopy = m_params.regions[i].imageCopy;
1846 uint32_t blockWidth, blockHeight;
1847 std::tie(blockWidth, blockHeight) = m_params.src.image.texelBlockDimensions();
1848 if (blockWidth != 1 || blockHeight != 1)
1849 {
1850 imageCopy.srcOffset.x *= blockWidth;
1851 imageCopy.srcOffset.y *= blockHeight;
1852 // When copying between compressed and uncompressed formats the extent
1853 // members represent the texel dimensions of the source image.
1854 imageCopy.extent.width *= blockWidth;
1855 imageCopy.extent.height *= blockHeight;
1856 }
1857
1858 std::tie(blockWidth, blockHeight) = m_params.dst.image.texelBlockDimensions();
1859 if (blockWidth != 1 || blockHeight != 1)
1860 {
1861 imageCopy.dstOffset.x *= blockWidth;
1862 imageCopy.dstOffset.y *= blockHeight;
1863 }
1864
1865 if (!(m_params.extensionFlags & COPY_COMMANDS_2))
1866 {
1867 imageCopies.push_back(imageCopy);
1868 }
1869 else
1870 {
1871 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
1872 imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
1873 }
1874 }
1875
1876 VkImageMemoryBarrier imageBarriers[] = {
1877 // source image
1878 {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1879 DE_NULL, // const void* pNext;
1880 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1881 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
1882 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1883 m_params.src.image.operationLayout, // VkImageLayout newLayout;
1884 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
1885 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
1886 m_source.get(), // VkImage image;
1887 {
1888 // VkImageSubresourceRange subresourceRange;
1889 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
1890 0u, // uint32_t baseMipLevel;
1891 m_params.mipLevels, // uint32_t mipLevels;
1892 0u, // uint32_t baseArraySlice;
1893 getArraySize(m_params.src.image) // uint32_t arraySize;
1894 }},
1895 // destination image
1896 {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1897 DE_NULL, // const void* pNext;
1898 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1899 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1900 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1901 m_params.dst.image.operationLayout, // VkImageLayout newLayout;
1902 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
1903 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
1904 m_destination.get(), // VkImage image;
1905 {
1906 // VkImageSubresourceRange subresourceRange;
1907 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
1908 0u, // uint32_t baseMipLevel;
1909 m_params.mipLevels, // uint32_t mipLevels;
1910 0u, // uint32_t baseArraySlice;
1911 getArraySize(m_params.dst.image) // uint32_t arraySize;
1912 }},
1913 };
1914
1915 beginCommandBuffer(vk, commandBuffer);
1916 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1917 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
1918 (const VkBufferMemoryBarrier *)DE_NULL, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers);
1919
1920 if (!(m_params.extensionFlags & COPY_COMMANDS_2))
1921 {
1922 vk.cmdCopyImage(commandBuffer, m_source.get(), m_params.src.image.operationLayout, m_destination.get(),
1923 m_params.dst.image.operationLayout, (uint32_t)imageCopies.size(), imageCopies.data());
1924 }
1925 else
1926 {
1927 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
1928 const VkCopyImageInfo2KHR copyImageInfo2KHR = {
1929 VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR, // VkStructureType sType;
1930 DE_NULL, // const void* pNext;
1931 m_source.get(), // VkImage srcImage;
1932 m_params.src.image.operationLayout, // VkImageLayout srcImageLayout;
1933 m_destination.get(), // VkImage dstImage;
1934 m_params.dst.image.operationLayout, // VkImageLayout dstImageLayout;
1935 (uint32_t)imageCopies2KHR.size(), // uint32_t regionCount;
1936 imageCopies2KHR.data() // const VkImageCopy2KHR* pRegions;
1937 };
1938
1939 vk.cmdCopyImage2(commandBuffer, ©ImageInfo2KHR);
1940 }
1941
1942 endCommandBuffer(vk, commandBuffer);
1943
1944 submitCommandsAndWait(vk, vkDevice, queue, commandBuffer);
1945 m_context.resetCommandPoolForVKSC(vkDevice, commandPool);
1946
1947 for (uint32_t miplevel = 0; miplevel < m_params.mipLevels; miplevel++)
1948 {
1949 de::MovePtr<tcu::TextureLevel> resultTextureLevel = readImage(*m_destination, m_params.dst.image, miplevel);
1950 de::MovePtr<tcu::TextureLevel> expectedTextureLevel = readImage(*m_source, m_params.src.image, miplevel);
1951
1952 tcu::TestStatus result = checkResult(resultTextureLevel->getAccess(), expectedTextureLevel->getAccess());
1953 if (result.getCode() != QP_TEST_RESULT_PASS)
1954 return result;
1955 }
1956 return tcu::TestStatus::pass("Pass");
1957 }
1958
checkResult(tcu::ConstPixelBufferAccess result,tcu::ConstPixelBufferAccess expected)1959 tcu::TestStatus CopyImageToImageMipmap::checkResult(tcu::ConstPixelBufferAccess result,
1960 tcu::ConstPixelBufferAccess expected)
1961 {
1962 const tcu::Vec4 fThreshold(0.0f);
1963 const tcu::UVec4 uThreshold(0u);
1964
1965 if (tcu::isCombinedDepthStencilType(result.getFormat().type))
1966 {
1967 if (tcu::hasDepthComponent(result.getFormat().order))
1968 {
1969 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_DEPTH;
1970 const tcu::ConstPixelBufferAccess depthResult = tcu::getEffectiveDepthStencilAccess(result, mode);
1971 const tcu::ConstPixelBufferAccess expectedResult = tcu::getEffectiveDepthStencilAccess(expected, mode);
1972
1973 if (isFloatFormat(result.getFormat()))
1974 {
1975 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison",
1976 expectedResult, depthResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1977 return tcu::TestStatus::fail("CopiesAndBlitting test");
1978 }
1979 else
1980 {
1981 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison",
1982 expectedResult, depthResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1983 return tcu::TestStatus::fail("CopiesAndBlitting test");
1984 }
1985 }
1986
1987 if (tcu::hasStencilComponent(result.getFormat().order))
1988 {
1989 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_STENCIL;
1990 const tcu::ConstPixelBufferAccess stencilResult = tcu::getEffectiveDepthStencilAccess(result, mode);
1991 const tcu::ConstPixelBufferAccess expectedResult = tcu::getEffectiveDepthStencilAccess(expected, mode);
1992
1993 if (isFloatFormat(result.getFormat()))
1994 {
1995 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison",
1996 expectedResult, stencilResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1997 return tcu::TestStatus::fail("CopiesAndBlitting test");
1998 }
1999 else
2000 {
2001 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison",
2002 expectedResult, stencilResult, uThreshold, tcu::COMPARE_LOG_RESULT))
2003 return tcu::TestStatus::fail("CopiesAndBlitting test");
2004 }
2005 }
2006 }
2007 else
2008 {
2009 if (isFloatFormat(result.getFormat()))
2010 {
2011 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison",
2012 expected, result, fThreshold, tcu::COMPARE_LOG_RESULT))
2013 return tcu::TestStatus::fail("CopiesAndBlitting test");
2014 }
2015 else if (isSnormFormat(mapTextureFormat(result.getFormat())))
2016 {
2017 // There may be an ambiguity between two possible binary representations of 1.0.
2018 // Get rid of that by expanding the data to floats and re-normalizing again.
2019
2020 tcu::TextureLevel resultSnorm(result.getFormat(), result.getWidth(), result.getHeight(), result.getDepth());
2021 {
2022 tcu::TextureLevel resultFloat(
2023 tcu::TextureFormat(resultSnorm.getFormat().order, tcu::TextureFormat::FLOAT),
2024 resultSnorm.getWidth(), resultSnorm.getHeight(), resultSnorm.getDepth());
2025
2026 tcu::copy(resultFloat.getAccess(), result);
2027 tcu::copy(resultSnorm, resultFloat.getAccess());
2028 }
2029
2030 tcu::TextureLevel expectedSnorm(expected.getFormat(), expected.getWidth(), expected.getHeight(),
2031 expected.getDepth());
2032
2033 {
2034 tcu::TextureLevel expectedFloat(
2035 tcu::TextureFormat(expectedSnorm.getFormat().order, tcu::TextureFormat::FLOAT),
2036 expectedSnorm.getWidth(), expectedSnorm.getHeight(), expectedSnorm.getDepth());
2037
2038 tcu::copy(expectedFloat.getAccess(), m_expectedTextureLevel[0]->getAccess());
2039 tcu::copy(expectedSnorm, expectedFloat.getAccess());
2040 }
2041
2042 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison",
2043 expectedSnorm.getAccess(), resultSnorm.getAccess(), uThreshold,
2044 tcu::COMPARE_LOG_RESULT))
2045 return tcu::TestStatus::fail("CopiesAndBlitting test");
2046 }
2047 else
2048 {
2049 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected,
2050 result, uThreshold, tcu::COMPARE_LOG_RESULT))
2051 return tcu::TestStatus::fail("CopiesAndBlitting test");
2052 }
2053 }
2054
2055 return tcu::TestStatus::pass("CopiesAndBlitting test");
2056 }
2057
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,uint32_t mipLevel)2058 void CopyImageToImageMipmap::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst,
2059 CopyRegion region, uint32_t mipLevel)
2060 {
2061 DE_UNREF(mipLevel);
2062
2063 VkOffset3D srcOffset = region.imageCopy.srcOffset;
2064 VkOffset3D dstOffset = region.imageCopy.dstOffset;
2065 VkExtent3D extent = region.imageCopy.extent;
2066
2067 if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && m_params.dst.image.imageType == VK_IMAGE_TYPE_2D)
2068 {
2069 dstOffset.z = srcOffset.z;
2070 extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.dstSubresource.layerCount);
2071 }
2072 if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && m_params.dst.image.imageType == VK_IMAGE_TYPE_3D)
2073 {
2074 srcOffset.z = dstOffset.z;
2075 extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.srcSubresource.layerCount);
2076 }
2077
2078 if (tcu::isCombinedDepthStencilType(src.getFormat().type))
2079 {
2080 DE_ASSERT(src.getFormat() == dst.getFormat());
2081
2082 // Copy depth.
2083 if (tcu::hasDepthComponent(src.getFormat().order))
2084 {
2085 const tcu::ConstPixelBufferAccess srcSubRegion =
2086 getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z,
2087 extent.width, extent.height, extent.depth),
2088 tcu::Sampler::MODE_DEPTH);
2089 const tcu::PixelBufferAccess dstSubRegion =
2090 getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z,
2091 extent.width, extent.height, extent.depth),
2092 tcu::Sampler::MODE_DEPTH);
2093 tcu::copy(dstSubRegion, srcSubRegion);
2094 }
2095
2096 // Copy stencil.
2097 if (tcu::hasStencilComponent(src.getFormat().order))
2098 {
2099 const tcu::ConstPixelBufferAccess srcSubRegion =
2100 getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z,
2101 extent.width, extent.height, extent.depth),
2102 tcu::Sampler::MODE_STENCIL);
2103 const tcu::PixelBufferAccess dstSubRegion =
2104 getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z,
2105 extent.width, extent.height, extent.depth),
2106 tcu::Sampler::MODE_STENCIL);
2107 tcu::copy(dstSubRegion, srcSubRegion);
2108 }
2109 }
2110 else
2111 {
2112 const tcu::ConstPixelBufferAccess srcSubRegion =
2113 tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
2114 // CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
2115 const tcu::PixelBufferAccess dstWithSrcFormat(srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
2116 const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(
2117 dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
2118
2119 tcu::copy(dstSubRegion, srcSubRegion);
2120 }
2121 }
2122
2123 class CopyImageToImageMipmapTestCase : public vkt::TestCase
2124 {
2125 public:
CopyImageToImageMipmapTestCase(tcu::TestContext & testCtx,const std::string & name,const TestParams params)2126 CopyImageToImageMipmapTestCase(tcu::TestContext &testCtx, const std::string &name, const TestParams params)
2127 : vkt::TestCase(testCtx, name)
2128 , m_params(params)
2129 {
2130 }
2131
createInstance(Context & context) const2132 virtual TestInstance *createInstance(Context &context) const
2133 {
2134 return new CopyImageToImageMipmap(context, m_params);
2135 }
2136
checkSupport(Context & context) const2137 virtual void checkSupport(Context &context) const
2138 {
2139 if (m_params.allocationKind == ALLOCATION_KIND_DEDICATED)
2140 {
2141 if (!context.isDeviceFunctionalitySupported("VK_KHR_dedicated_allocation"))
2142 TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported");
2143 }
2144
2145 checkExtensionSupport(context, m_params.extensionFlags);
2146
2147 const VkPhysicalDeviceLimits limits = context.getDeviceProperties().limits;
2148 VkImageFormatProperties properties;
2149
2150 if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
2151 context.getPhysicalDevice(), m_params.src.image.format, m_params.src.image.imageType,
2152 VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
2153 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
2154 (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
2155 context.getPhysicalDevice(), m_params.dst.image.format, m_params.dst.image.imageType,
2156 VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0,
2157 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
2158 {
2159 TCU_THROW(NotSupportedError, "Format not supported");
2160 }
2161
2162 // Check maxImageDimension1D
2163 {
2164 if (m_params.src.image.imageType == VK_IMAGE_TYPE_1D &&
2165 m_params.src.image.extent.width > limits.maxImageDimension1D)
2166 TCU_THROW(NotSupportedError, "Requested 1D src image dimensions not supported");
2167
2168 if (m_params.dst.image.imageType == VK_IMAGE_TYPE_1D &&
2169 m_params.dst.image.extent.width > limits.maxImageDimension1D)
2170 TCU_THROW(NotSupportedError, "Requested 1D dst image dimensions not supported");
2171 }
2172
2173 // Check maxImageDimension2D
2174 {
2175 if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D &&
2176 (m_params.src.image.extent.width > limits.maxImageDimension2D ||
2177 m_params.src.image.extent.height > limits.maxImageDimension2D))
2178 {
2179 TCU_THROW(NotSupportedError, "Requested 2D src image dimensions not supported");
2180 }
2181
2182 if (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D &&
2183 (m_params.dst.image.extent.width > limits.maxImageDimension2D ||
2184 m_params.dst.image.extent.height > limits.maxImageDimension2D))
2185 {
2186 TCU_THROW(NotSupportedError, "Requested 2D dst image dimensions not supported");
2187 }
2188 }
2189
2190 // Check maxImageDimension3D
2191 {
2192 if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D &&
2193 (m_params.src.image.extent.width > limits.maxImageDimension3D ||
2194 m_params.src.image.extent.height > limits.maxImageDimension3D ||
2195 m_params.src.image.extent.depth > limits.maxImageDimension3D))
2196 {
2197 TCU_THROW(NotSupportedError, "Requested 3D src image dimensions not supported");
2198 }
2199
2200 if (m_params.dst.image.imageType == VK_IMAGE_TYPE_3D &&
2201 (m_params.dst.image.extent.width > limits.maxImageDimension3D ||
2202 m_params.dst.image.extent.height > limits.maxImageDimension3D ||
2203 m_params.src.image.extent.depth > limits.maxImageDimension3D))
2204 {
2205 TCU_THROW(NotSupportedError, "Requested 3D dst image dimensions not supported");
2206 }
2207 }
2208 }
2209
2210 private:
2211 TestParams m_params;
2212 };
2213
2214 // Copy from buffer to buffer.
2215
2216 class CopyBufferToBuffer : public CopiesAndBlittingTestInstance
2217 {
2218 public:
2219 CopyBufferToBuffer(Context &context, TestParams params);
2220 virtual tcu::TestStatus iterate(void);
2221
2222 private:
2223 virtual void copyRegionToTextureLevel(tcu::ConstPixelBufferAccess, tcu::PixelBufferAccess, CopyRegion,
2224 uint32_t mipLevel = 0u);
2225 Move<VkBuffer> m_source;
2226 de::MovePtr<Allocation> m_sourceBufferAlloc;
2227 Move<VkBuffer> m_destination;
2228 de::MovePtr<Allocation> m_destinationBufferAlloc;
2229 };
2230
CopyBufferToBuffer(Context & context,TestParams params)2231 CopyBufferToBuffer::CopyBufferToBuffer(Context &context, TestParams params)
2232 : CopiesAndBlittingTestInstance(context, params)
2233 {
2234 const InstanceInterface &vki = context.getInstanceInterface();
2235 const DeviceInterface &vk = context.getDeviceInterface();
2236 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
2237
2238 // Create source buffer
2239 {
2240 const VkBufferCreateInfo sourceBufferParams = {
2241 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2242 DE_NULL, // const void* pNext;
2243 0u, // VkBufferCreateFlags flags;
2244 m_params.src.buffer.size, // VkDeviceSize size;
2245 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage;
2246 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2247 0u, // uint32_t queueFamilyIndexCount;
2248 (const uint32_t *)DE_NULL, // const uint32_t* pQueueFamilyIndices;
2249 };
2250
2251 m_source = createBuffer(vk, m_device, &sourceBufferParams);
2252 m_sourceBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, m_device, *m_source, MemoryRequirement::HostVisible,
2253 *m_allocator, m_params.allocationKind);
2254 VK_CHECK(vk.bindBufferMemory(m_device, *m_source, m_sourceBufferAlloc->getMemory(),
2255 m_sourceBufferAlloc->getOffset()));
2256 }
2257
2258 // Create destination buffer
2259 {
2260 const VkBufferCreateInfo destinationBufferParams = {
2261 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2262 DE_NULL, // const void* pNext;
2263 0u, // VkBufferCreateFlags flags;
2264 m_params.dst.buffer.size, // VkDeviceSize size;
2265 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
2266 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2267 0u, // uint32_t queueFamilyIndexCount;
2268 (const uint32_t *)DE_NULL, // const uint32_t* pQueueFamilyIndices;
2269 };
2270
2271 m_destination = createBuffer(vk, m_device, &destinationBufferParams);
2272 m_destinationBufferAlloc =
2273 allocateBuffer(vki, vk, vkPhysDevice, m_device, *m_destination, MemoryRequirement::HostVisible,
2274 *m_allocator, m_params.allocationKind);
2275 VK_CHECK(vk.bindBufferMemory(m_device, *m_destination, m_destinationBufferAlloc->getMemory(),
2276 m_destinationBufferAlloc->getOffset()));
2277 }
2278 }
2279
iterate(void)2280 tcu::TestStatus CopyBufferToBuffer::iterate(void)
2281 {
2282 const int srcLevelWidth = (int)(m_params.src.buffer.size /
2283 4); // Here the format is VK_FORMAT_R32_UINT, we need to divide the buffer size by 4
2284 m_sourceTextureLevel =
2285 de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), srcLevelWidth, 1));
2286 generateBuffer(m_sourceTextureLevel->getAccess(), srcLevelWidth, 1, 1, FILL_MODE_RED);
2287
2288 const int dstLevelWidth = (int)(m_params.dst.buffer.size / 4);
2289 m_destinationTextureLevel =
2290 de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
2291 generateBuffer(m_destinationTextureLevel->getAccess(), dstLevelWidth, 1, 1, FILL_MODE_BLACK);
2292
2293 generateExpectedResult();
2294
2295 uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
2296 uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
2297
2298 const DeviceInterface &vk = m_context.getDeviceInterface();
2299 VkQueue queue = VK_NULL_HANDLE;
2300 VkCommandBuffer commandBuffer = VK_NULL_HANDLE;
2301 VkCommandPool commandPool = VK_NULL_HANDLE;
2302 std::tie(queue, commandBuffer, commandPool) = activeExecutionCtx();
2303
2304 const VkBufferMemoryBarrier srcBufferBarrier = {
2305 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
2306 DE_NULL, // const void* pNext;
2307 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask;
2308 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
2309 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
2310 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
2311 *m_source, // VkBuffer buffer;
2312 0u, // VkDeviceSize offset;
2313 m_params.src.buffer.size // VkDeviceSize size;
2314 };
2315
2316 const VkBufferMemoryBarrier dstBufferBarrier = {
2317 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
2318 DE_NULL, // const void* pNext;
2319 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
2320 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
2321 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
2322 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
2323 *m_destination, // VkBuffer buffer;
2324 0u, // VkDeviceSize offset;
2325 m_params.dst.buffer.size // VkDeviceSize size;
2326 };
2327
2328 std::vector<VkBufferCopy> bufferCopies;
2329 std::vector<VkBufferCopy2KHR> bufferCopies2KHR;
2330 for (uint32_t i = 0; i < m_params.regions.size(); i++)
2331 {
2332 if (!(m_params.extensionFlags & COPY_COMMANDS_2))
2333 {
2334 bufferCopies.push_back(m_params.regions[i].bufferCopy);
2335 }
2336 else
2337 {
2338 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
2339 bufferCopies2KHR.push_back(convertvkBufferCopyTovkBufferCopy2KHR(m_params.regions[i].bufferCopy));
2340 }
2341 }
2342
2343 beginCommandBuffer(vk, commandBuffer);
2344 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
2345 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 1, &srcBufferBarrier, 0,
2346 (const VkImageMemoryBarrier *)DE_NULL);
2347
2348 if (!(m_params.extensionFlags & COPY_COMMANDS_2))
2349 {
2350 vk.cmdCopyBuffer(commandBuffer, m_source.get(), m_destination.get(), (uint32_t)m_params.regions.size(),
2351 &bufferCopies[0]);
2352 }
2353 else
2354 {
2355 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
2356 const VkCopyBufferInfo2KHR copyBufferInfo2KHR = {
2357 VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2_KHR, // VkStructureType sType;
2358 DE_NULL, // const void* pNext;
2359 m_source.get(), // VkBuffer srcBuffer;
2360 m_destination.get(), // VkBuffer dstBuffer;
2361 (uint32_t)m_params.regions.size(), // uint32_t regionCount;
2362 &bufferCopies2KHR[0] // const VkBufferCopy2KHR* pRegions;
2363 };
2364
2365 vk.cmdCopyBuffer2(commandBuffer, ©BufferInfo2KHR);
2366 }
2367
2368 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
2369 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 1, &dstBufferBarrier, 0,
2370 (const VkImageMemoryBarrier *)DE_NULL);
2371 endCommandBuffer(vk, commandBuffer);
2372 submitCommandsAndWait(vk, m_device, queue, commandBuffer);
2373 m_context.resetCommandPoolForVKSC(m_device, commandPool);
2374
2375 // Read buffer data
2376 de::MovePtr<tcu::TextureLevel> resultLevel(
2377 new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
2378 invalidateAlloc(vk, m_device, *m_destinationBufferAlloc);
2379 tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(),
2380 m_destinationBufferAlloc->getHostPtr()));
2381
2382 return checkTestResult(resultLevel->getAccess());
2383 }
2384
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,uint32_t mipLevel)2385 void CopyBufferToBuffer::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst,
2386 CopyRegion region, uint32_t mipLevel)
2387 {
2388 DE_UNREF(mipLevel);
2389
2390 deMemcpy((uint8_t *)dst.getDataPtr() + region.bufferCopy.dstOffset,
2391 (uint8_t *)src.getDataPtr() + region.bufferCopy.srcOffset, (size_t)region.bufferCopy.size);
2392 }
2393
2394 class BufferToBufferTestCase : public vkt::TestCase
2395 {
2396 public:
BufferToBufferTestCase(tcu::TestContext & testCtx,const std::string & name,const TestParams params)2397 BufferToBufferTestCase(tcu::TestContext &testCtx, const std::string &name, const TestParams params)
2398 : vkt::TestCase(testCtx, name)
2399 , m_params(params)
2400 {
2401 }
2402
createInstance(Context & context) const2403 virtual TestInstance *createInstance(Context &context) const
2404 {
2405 return new CopyBufferToBuffer(context, m_params);
2406 }
2407
checkSupport(Context & context) const2408 virtual void checkSupport(Context &context) const
2409 {
2410 checkExtensionSupport(context, m_params.extensionFlags);
2411 }
2412
2413 private:
2414 TestParams m_params;
2415 };
2416
2417 // Copy from image to buffer.
2418
2419 class CopyImageToBuffer : public CopiesAndBlittingTestInstance
2420 {
2421 public:
2422 CopyImageToBuffer(Context &context, TestParams testParams);
2423 virtual tcu::TestStatus iterate(void);
2424
2425 private:
2426 virtual void copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst,
2427 CopyRegion region, uint32_t mipLevel = 0u);
2428
2429 tcu::TextureFormat m_textureFormat;
2430 VkDeviceSize m_bufferSize;
2431
2432 Move<VkImage> m_source;
2433 de::MovePtr<Allocation> m_sourceImageAlloc;
2434 Move<VkBuffer> m_destination;
2435 de::MovePtr<Allocation> m_destinationBufferAlloc;
2436
2437 std::vector<de::SharedPtr<Allocation>> m_sparseAllocations;
2438 Move<VkSemaphore> m_sparseSemaphore;
2439 };
2440
CopyImageToBuffer(Context & context,TestParams testParams)2441 CopyImageToBuffer::CopyImageToBuffer(Context &context, TestParams testParams)
2442 : CopiesAndBlittingTestInstance(context, testParams)
2443 , m_textureFormat(mapVkFormat(testParams.src.image.format))
2444 , m_bufferSize(m_params.dst.buffer.size * tcu::getPixelSize(m_textureFormat))
2445 {
2446 const InstanceInterface &vki = context.getInstanceInterface();
2447 const DeviceInterface &vk = context.getDeviceInterface();
2448 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
2449
2450 // Create source image
2451 {
2452 VkImageCreateInfo sourceImageParams = {
2453 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
2454 DE_NULL, // const void* pNext;
2455 getCreateFlags(m_params.src.image), // VkImageCreateFlags flags;
2456 m_params.src.image.imageType, // VkImageType imageType;
2457 m_params.src.image.format, // VkFormat format;
2458 getExtent3D(m_params.src.image), // VkExtent3D extent;
2459 1u, // uint32_t mipLevels;
2460 getArraySize(m_params.src.image), // uint32_t arraySize;
2461 VK_SAMPLE_COUNT_1_BIT, // uint32_t samples;
2462 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
2463 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
2464 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2465 0u, // uint32_t queueFamilyIndexCount;
2466 (const uint32_t *)DE_NULL, // const uint32_t* pQueueFamilyIndices;
2467 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
2468 };
2469
2470 #ifndef CTS_USES_VULKANSC
2471 if (!testParams.useSparseBinding)
2472 {
2473 #endif
2474 m_source = createImage(vk, m_device, &sourceImageParams);
2475 m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, m_device, *m_source, MemoryRequirement::Any,
2476 *m_allocator, m_params.allocationKind, 0u);
2477 VK_CHECK(vk.bindImageMemory(m_device, *m_source, m_sourceImageAlloc->getMemory(),
2478 m_sourceImageAlloc->getOffset()));
2479 #ifndef CTS_USES_VULKANSC
2480 }
2481 else
2482 {
2483 sourceImageParams.flags |=
2484 (vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT | vk::VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT);
2485 vk::VkImageFormatProperties imageFormatProperties;
2486 if (vki.getPhysicalDeviceImageFormatProperties(vkPhysDevice, sourceImageParams.format,
2487 sourceImageParams.imageType, sourceImageParams.tiling,
2488 sourceImageParams.usage, sourceImageParams.flags,
2489 &imageFormatProperties) == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
2490 {
2491 TCU_THROW(NotSupportedError, "Image format not supported");
2492 }
2493 m_source = createImage(
2494 vk, m_device,
2495 &sourceImageParams); //de::MovePtr<SparseImage>(new SparseImage(vk, vk, vkPhysDevice, vki, sourceImageParams, m_queue, *m_allocator, mapVkFormat(sourceImageParams.format)));
2496 m_sparseSemaphore = createSemaphore(vk, m_device);
2497 allocateAndBindSparseImage(vk, m_device, vkPhysDevice, vki, sourceImageParams, m_sparseSemaphore.get(),
2498 context.getSparseQueue(), *m_allocator, m_sparseAllocations,
2499 mapVkFormat(sourceImageParams.format), m_source.get());
2500 }
2501 #endif
2502 }
2503
2504 // Create destination buffer
2505 {
2506 const VkBufferCreateInfo destinationBufferParams = {
2507 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2508 DE_NULL, // const void* pNext;
2509 0u, // VkBufferCreateFlags flags;
2510 m_bufferSize, // VkDeviceSize size;
2511 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
2512 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2513 0u, // uint32_t queueFamilyIndexCount;
2514 (const uint32_t *)DE_NULL, // const uint32_t* pQueueFamilyIndices;
2515 };
2516
2517 m_destination = createBuffer(vk, m_device, &destinationBufferParams);
2518 m_destinationBufferAlloc =
2519 allocateBuffer(vki, vk, vkPhysDevice, m_device, *m_destination, MemoryRequirement::HostVisible,
2520 *m_allocator, m_params.allocationKind);
2521 VK_CHECK(vk.bindBufferMemory(m_device, *m_destination, m_destinationBufferAlloc->getMemory(),
2522 m_destinationBufferAlloc->getOffset()));
2523 }
2524 }
2525
iterate(void)2526 tcu::TestStatus CopyImageToBuffer::iterate(void)
2527 {
2528 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(
2529 new tcu::TextureLevel(m_textureFormat, m_params.src.image.extent.width, m_params.src.image.extent.height,
2530 m_params.src.image.extent.depth));
2531 generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height,
2532 m_params.src.image.extent.depth, m_params.src.image.fillMode);
2533 m_destinationTextureLevel =
2534 de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
2535 generateBuffer(m_destinationTextureLevel->getAccess(), (int)m_params.dst.buffer.size, 1, 1,
2536 m_params.dst.buffer.fillMode);
2537
2538 generateExpectedResult();
2539
2540 uploadImage(m_sourceTextureLevel->getAccess(), *m_source, m_params.src.image);
2541 uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
2542
2543 const DeviceInterface &vk = m_context.getDeviceInterface();
2544 const VkDevice vkDevice = m_device;
2545 VkQueue queue = VK_NULL_HANDLE;
2546 VkCommandBuffer commandBuffer = VK_NULL_HANDLE;
2547 VkCommandPool commandPool = VK_NULL_HANDLE;
2548 std::tie(queue, commandBuffer, commandPool) = activeExecutionCtx();
2549
2550 // Barriers for copying image to buffer
2551 const VkImageMemoryBarrier imageBarrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
2552 DE_NULL, // const void* pNext;
2553 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
2554 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
2555 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
2556 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout;
2557 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
2558 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
2559 *m_source, // VkImage image;
2560 {
2561 // VkImageSubresourceRange subresourceRange;
2562 getAspectFlags(m_textureFormat), // VkImageAspectFlags aspectMask;
2563 0u, // uint32_t baseMipLevel;
2564 1u, // uint32_t mipLevels;
2565 0u, // uint32_t baseArraySlice;
2566 getArraySize(m_params.src.image) // uint32_t arraySize;
2567 }};
2568
2569 const VkBufferMemoryBarrier bufferBarrier = {
2570 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
2571 DE_NULL, // const void* pNext;
2572 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
2573 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
2574 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
2575 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
2576 *m_destination, // VkBuffer buffer;
2577 0u, // VkDeviceSize offset;
2578 m_bufferSize // VkDeviceSize size;
2579 };
2580
2581 // Copy from image to buffer
2582 std::vector<VkBufferImageCopy> bufferImageCopies;
2583 std::vector<VkBufferImageCopy2KHR> bufferImageCopies2KHR;
2584 for (uint32_t i = 0; i < m_params.regions.size(); i++)
2585 {
2586 if (!(m_params.extensionFlags & COPY_COMMANDS_2))
2587 {
2588 bufferImageCopies.push_back(m_params.regions[i].bufferImageCopy);
2589 }
2590 else
2591 {
2592 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
2593 bufferImageCopies2KHR.push_back(
2594 convertvkBufferImageCopyTovkBufferImageCopy2KHR(m_params.regions[i].bufferImageCopy));
2595 }
2596 }
2597
2598 beginCommandBuffer(vk, commandBuffer);
2599 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
2600 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
2601 (const VkBufferMemoryBarrier *)DE_NULL, 1, &imageBarrier);
2602
2603 if (!(m_params.extensionFlags & COPY_COMMANDS_2))
2604 {
2605 vk.cmdCopyImageToBuffer(commandBuffer, m_source.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
2606 m_destination.get(), (uint32_t)m_params.regions.size(), &bufferImageCopies[0]);
2607 }
2608 else
2609 {
2610 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
2611 const VkCopyImageToBufferInfo2KHR copyImageToBufferInfo2KHR = {
2612 VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2_KHR, // VkStructureType sType;
2613 DE_NULL, // const void* pNext;
2614 m_source.get(), // VkImage srcImage;
2615 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout srcImageLayout;
2616 m_destination.get(), // VkBuffer dstBuffer;
2617 (uint32_t)m_params.regions.size(), // uint32_t regionCount;
2618 &bufferImageCopies2KHR[0] // const VkBufferImageCopy2KHR* pRegions;
2619 };
2620
2621 vk.cmdCopyImageToBuffer2(commandBuffer, ©ImageToBufferInfo2KHR);
2622 }
2623
2624 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
2625 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 1, &bufferBarrier, 0,
2626 (const VkImageMemoryBarrier *)DE_NULL);
2627 endCommandBuffer(vk, commandBuffer);
2628
2629 submitCommandsAndWait(vk, vkDevice, queue, commandBuffer);
2630 m_context.resetCommandPoolForVKSC(vkDevice, commandPool);
2631
2632 // Read buffer data
2633 de::MovePtr<tcu::TextureLevel> resultLevel(
2634 new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
2635 invalidateAlloc(vk, vkDevice, *m_destinationBufferAlloc);
2636 tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(),
2637 m_destinationBufferAlloc->getHostPtr()));
2638
2639 return checkTestResult(resultLevel->getAccess());
2640 }
2641
2642 class CopyImageToBufferTestCase : public vkt::TestCase
2643 {
2644 public:
CopyImageToBufferTestCase(tcu::TestContext & testCtx,const std::string & name,const TestParams params)2645 CopyImageToBufferTestCase(tcu::TestContext &testCtx, const std::string &name, const TestParams params)
2646 : vkt::TestCase(testCtx, name)
2647 , m_params(params)
2648 {
2649 }
2650
createInstance(Context & context) const2651 virtual TestInstance *createInstance(Context &context) const
2652 {
2653 return new CopyImageToBuffer(context, m_params);
2654 }
2655
checkSupport(Context & context) const2656 virtual void checkSupport(Context &context) const
2657 {
2658 checkExtensionSupport(context, m_params.extensionFlags);
2659 }
2660
2661 private:
2662 TestParams m_params;
2663 };
2664
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,uint32_t mipLevel)2665 void CopyImageToBuffer::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst,
2666 CopyRegion region, uint32_t mipLevel)
2667 {
2668 DE_UNREF(mipLevel);
2669
2670 uint32_t rowLength = region.bufferImageCopy.bufferRowLength;
2671 if (!rowLength)
2672 rowLength = region.bufferImageCopy.imageExtent.width;
2673
2674 uint32_t imageHeight = region.bufferImageCopy.bufferImageHeight;
2675 if (!imageHeight)
2676 imageHeight = region.bufferImageCopy.imageExtent.height;
2677
2678 const int texelSize = src.getFormat().getPixelSize();
2679 const VkExtent3D extent = region.bufferImageCopy.imageExtent;
2680 const VkOffset3D srcOffset = region.bufferImageCopy.imageOffset;
2681 const int texelOffset = (int)region.bufferImageCopy.bufferOffset / texelSize;
2682 const uint32_t baseArrayLayer = region.bufferImageCopy.imageSubresource.baseArrayLayer;
2683
2684 for (uint32_t z = 0; z < extent.depth; z++)
2685 {
2686 for (uint32_t y = 0; y < extent.height; y++)
2687 {
2688 int texelIndex = texelOffset + (z * imageHeight + y) * rowLength;
2689 const tcu::ConstPixelBufferAccess srcSubRegion =
2690 tcu::getSubregion(src, srcOffset.x, srcOffset.y + y, srcOffset.z + z + baseArrayLayer,
2691 region.bufferImageCopy.imageExtent.width, 1, 1);
2692 const tcu::PixelBufferAccess dstSubRegion =
2693 tcu::getSubregion(dst, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
2694 tcu::copy(dstSubRegion, srcSubRegion);
2695 }
2696 }
2697 }
2698
2699 // Copy levels from compressed mipmap images into a buffer.
2700 class CopyCompressedImageToBuffer final : public CopiesAndBlittingTestInstance
2701 {
2702 public:
2703 CopyCompressedImageToBuffer(Context &context, TestParams testParams);
2704
2705 virtual tcu::TestStatus iterate(void) override;
2706
2707 private:
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess,tcu::PixelBufferAccess,CopyRegion,uint32_t)2708 virtual void copyRegionToTextureLevel(tcu::ConstPixelBufferAccess, tcu::PixelBufferAccess, CopyRegion,
2709 uint32_t) override
2710 {
2711 TCU_THROW(InternalError, "copyRegionToTextureLevel not implemented for CopyCompressedImageToBuffer");
2712 }
2713
2714 // Contains a randomly generated compressed texture pyramid.
2715 using TestTexture2DSp = de::SharedPtr<pipeline::TestTexture2DArray>;
2716 TestTexture2DSp m_texture;
2717 de::MovePtr<ImageWithMemory> m_source;
2718 de::MovePtr<BufferWithMemory> m_sourceBuffer;
2719 de::MovePtr<BufferWithMemory> m_destination;
2720 };
2721
CopyCompressedImageToBuffer(Context & context,TestParams testParams)2722 CopyCompressedImageToBuffer::CopyCompressedImageToBuffer(Context &context, TestParams testParams)
2723 : CopiesAndBlittingTestInstance(context, testParams)
2724 , m_texture(TestTexture2DSp(new pipeline::TestTexture2DArray(
2725 mapVkCompressedFormat(testParams.src.image.format), testParams.src.image.extent.width,
2726 testParams.src.image.extent.height, testParams.arrayLayers)))
2727 {
2728 }
2729
iterate(void)2730 tcu::TestStatus CopyCompressedImageToBuffer::iterate(void)
2731 {
2732 const DeviceInterface &vk = m_context.getDeviceInterface();
2733 const VkDevice vkDevice = m_device;
2734 Allocator &memAlloc = *m_allocator;
2735 const ImageParms &srcImageParams = m_params.src.image;
2736
2737 VkQueue queue = VK_NULL_HANDLE;
2738 VkCommandBuffer commandBuffer = VK_NULL_HANDLE;
2739 VkCommandPool commandPool = VK_NULL_HANDLE;
2740 std::tie(queue, commandBuffer, commandPool) = activeExecutionCtx();
2741
2742 // Create source image, containing all the mip levels.
2743 {
2744 const VkImageCreateInfo sourceImageParams = {
2745 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
2746 DE_NULL, // const void* pNext;
2747 getCreateFlags(m_params.src.image), // VkImageCreateFlags flags;
2748 m_params.src.image.imageType, // VkImageType imageType;
2749 m_params.src.image.format, // VkFormat format;
2750 m_params.src.image.extent, // VkExtent3D extent;
2751 (uint32_t)m_texture->getNumLevels(), // uint32_t mipLevels;
2752 m_params.arrayLayers, // uint32_t arraySize;
2753 VK_SAMPLE_COUNT_1_BIT, // uint32_t samples;
2754 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
2755 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
2756 m_queueFamilyIndices.size() > 1 ? VK_SHARING_MODE_CONCURRENT :
2757 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2758 (uint32_t)m_queueFamilyIndices.size(), // uint32_t queueFamilyIndexCount;
2759 m_queueFamilyIndices.data(), // const uint32_t* pQueueFamilyIndices;
2760 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
2761 };
2762
2763 m_source = de::MovePtr<ImageWithMemory>(
2764 new ImageWithMemory(vk, vkDevice, memAlloc, sourceImageParams, vk::MemoryRequirement::Any));
2765 }
2766
2767 // Upload the compressed image.
2768 // FIXME: This could be a utility.
2769 // pipeline::uploadTestTexture(vk, vkDevice, queue, queueFamilyIndex, memAlloc, *m_texture, m_source->get(), vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
2770 // Does not allow using an external command pool, the utilities there could fruitfully be generalised.
2771 m_sourceBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(
2772 vk, vkDevice, memAlloc, makeBufferCreateInfo(m_texture->getCompressedSize(), VK_BUFFER_USAGE_TRANSFER_SRC_BIT),
2773 vk::MemoryRequirement::HostVisible));
2774 m_texture->write(reinterpret_cast<uint8_t *>(m_sourceBuffer->getAllocation().getHostPtr()));
2775 flushAlloc(vk, vkDevice, m_sourceBuffer->getAllocation());
2776 std::vector<VkBufferImageCopy> copyRegions = m_texture->getBufferCopyRegions();
2777 copyBufferToImage(vk, vkDevice, queue, activeQueueFamilyIndex(), m_sourceBuffer->get(),
2778 m_texture->getCompressedSize(), copyRegions, nullptr, VK_IMAGE_ASPECT_COLOR_BIT,
2779 m_texture->getNumLevels(), m_texture->getArraySize(), m_source->get(),
2780 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_READ_BIT,
2781 &commandPool, 0);
2782
2783 // VKSC requires static allocation, so allocate a large enough buffer for each individual mip level of
2784 // the compressed source image, rather than creating a corresponding buffer for each level in the loop
2785 // below.
2786 auto level0BuferSize = m_texture->getCompressedLevel(0, 0).getDataSize();
2787 m_destination = de::MovePtr<BufferWithMemory>(new BufferWithMemory(
2788 vk, vkDevice, memAlloc, makeBufferCreateInfo(level0BuferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT),
2789 MemoryRequirement::HostVisible));
2790
2791 // Copy each miplevel of the uploaded image into a buffer, and
2792 // check the buffer matches the appropriate test texture level.
2793 for (uint32_t mipLevelToCheckIdx = 0; mipLevelToCheckIdx < (uint32_t)m_texture->getNumLevels();
2794 mipLevelToCheckIdx++)
2795 for (uint32_t arrayLayerToCheckIdx = 0; arrayLayerToCheckIdx < (uint32_t)m_texture->getArraySize();
2796 arrayLayerToCheckIdx++)
2797 {
2798 const tcu::CompressedTexture compressedMipLevelToCheck =
2799 m_texture->getCompressedLevel(mipLevelToCheckIdx, arrayLayerToCheckIdx);
2800 uint32_t bufferSize = compressedMipLevelToCheck.getDataSize();
2801
2802 // Clear the buffer to zero before copying into it as a precaution.
2803 deMemset(m_destination->getAllocation().getHostPtr(), 0, bufferSize);
2804 flushAlloc(vk, vkDevice, m_destination->getAllocation());
2805
2806 // Barrier to get the source image's selected mip-level / layer in the right format for transfer.
2807 const auto imageBarrier = makeImageMemoryBarrier(
2808 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
2809 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_source->get(),
2810 {
2811 // VkImageSubresourceRange subresourceRange;
2812 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
2813 mipLevelToCheckIdx, // uint32_t baseMipLevel;
2814 1u, // uint32_t mipLevels;
2815 arrayLayerToCheckIdx, // uint32_t baseArraySlice;
2816 1u, // uint32_t arraySize;
2817 });
2818
2819 // Barrier to wait for the transfer from image to buffer to complete.
2820 const auto bufferBarrier = makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
2821 m_destination->get(), 0, bufferSize);
2822
2823 // Copy from image to buffer
2824 VkBufferImageCopy copyRegion;
2825 copyRegion = makeBufferImageCopy(
2826 mipLevelExtents(srcImageParams.extent, mipLevelToCheckIdx),
2827 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, mipLevelToCheckIdx, arrayLayerToCheckIdx, 1));
2828
2829 VkBufferImageCopy bufferImageCopy;
2830 VkBufferImageCopy2KHR bufferImageCopy2KHR;
2831 if (!(m_params.extensionFlags & COPY_COMMANDS_2))
2832 {
2833 bufferImageCopy = copyRegion;
2834 }
2835 else
2836 {
2837 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
2838 bufferImageCopy2KHR = convertvkBufferImageCopyTovkBufferImageCopy2KHR(copyRegion);
2839 }
2840
2841 beginCommandBuffer(vk, commandBuffer);
2842 // Transition the selected miplevel to the right format for the transfer.
2843 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
2844 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
2845 (const VkBufferMemoryBarrier *)DE_NULL, 1, &imageBarrier);
2846
2847 // Copy the mip level to the buffer.
2848 if (!(m_params.extensionFlags & COPY_COMMANDS_2))
2849 {
2850 vk.cmdCopyImageToBuffer(commandBuffer, m_source->get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
2851 m_destination->get(), 1u, &bufferImageCopy);
2852 }
2853 else
2854 {
2855 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
2856 const VkCopyImageToBufferInfo2KHR copyImageToBufferInfo2KHR = {
2857 VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2_KHR, // VkStructureType sType;
2858 DE_NULL, // const void* pNext;
2859 m_source->get(), // VkImage srcImage;
2860 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout srcImageLayout;
2861 m_destination->get(), // VkBuffer dstBuffer;
2862 1u, // uint32_t regionCount;
2863 &bufferImageCopy2KHR // const VkBufferImageCopy2KHR* pRegions;
2864 };
2865
2866 vk.cmdCopyImageToBuffer2(commandBuffer, ©ImageToBufferInfo2KHR);
2867 }
2868
2869 // Prepare to read from the host visible barrier.
2870 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
2871 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 1, &bufferBarrier, 0,
2872 (const VkImageMemoryBarrier *)DE_NULL);
2873 endCommandBuffer(vk, commandBuffer);
2874
2875 submitCommandsAndWait(vk, vkDevice, queue, commandBuffer);
2876 m_context.resetCommandPoolForVKSC(vkDevice, commandPool);
2877
2878 invalidateAlloc(vk, vkDevice, m_destination->getAllocation());
2879 // Read and compare buffer data.
2880 const uint8_t *referenceData = (uint8_t *)compressedMipLevelToCheck.getData();
2881 const uint8_t *resultData = (uint8_t *)m_destination->getAllocation().getHostPtr();
2882 int result = deMemCmp(referenceData, resultData, bufferSize);
2883 if (result != 0)
2884 {
2885 std::ostringstream msg;
2886 msg << "Incorrect data retrieved for mip level " << mipLevelToCheckIdx << ", layer "
2887 << arrayLayerToCheckIdx << " - extents (" << compressedMipLevelToCheck.getWidth() << ", "
2888 << compressedMipLevelToCheck.getHeight() << ")";
2889 return tcu::TestStatus::fail(msg.str());
2890 }
2891 }
2892
2893 return tcu::TestStatus::pass("OK");
2894 }
2895
2896 class CopyCompressedImageToBufferTestCase : public vkt::TestCase
2897 {
2898 public:
CopyCompressedImageToBufferTestCase(tcu::TestContext & testCtx,const std::string & name,const TestParams params)2899 CopyCompressedImageToBufferTestCase(tcu::TestContext &testCtx, const std::string &name, const TestParams params)
2900 : vkt::TestCase(testCtx, name)
2901 , m_params(params)
2902 {
2903 }
2904
createInstance(Context & context) const2905 virtual TestInstance *createInstance(Context &context) const
2906 {
2907 return new CopyCompressedImageToBuffer(context, m_params);
2908 }
2909 virtual void checkSupport(Context &context) const;
2910
2911 private:
2912 TestParams m_params;
2913 };
2914
checkSupport(Context & context) const2915 void CopyCompressedImageToBufferTestCase::checkSupport(Context &context) const
2916 {
2917 DE_ASSERT(m_params.src.image.tiling == VK_IMAGE_TILING_OPTIMAL);
2918 DE_ASSERT(m_params.src.image.imageType == vk::VK_IMAGE_TYPE_2D);
2919
2920 checkExtensionSupport(context, m_params.extensionFlags);
2921
2922 VkFormatProperties formatProps;
2923 context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(),
2924 m_params.src.image.format, &formatProps);
2925
2926 VkImageFormatProperties imageFormatProperties;
2927
2928 const auto &instance = context.getInstanceInterface();
2929 if (instance.getPhysicalDeviceImageFormatProperties(context.getPhysicalDevice(), m_params.src.image.format,
2930 m_params.src.image.imageType, VK_IMAGE_TILING_OPTIMAL,
2931 VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
2932 &imageFormatProperties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
2933 {
2934 TCU_THROW(NotSupportedError, "Format not supported");
2935 }
2936
2937 if (!(formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT))
2938 TCU_THROW(NotSupportedError, "TRANSFER_SRC is not supported on this image type");
2939 }
2940
2941 // Copy from buffer to image.
2942
2943 class CopyBufferToImage : public CopiesAndBlittingTestInstance
2944 {
2945 public:
2946 CopyBufferToImage(Context &context, TestParams testParams);
2947 virtual tcu::TestStatus iterate(void);
2948
2949 private:
2950 virtual void copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst,
2951 CopyRegion region, uint32_t mipLevel = 0u);
2952
2953 tcu::TextureFormat m_textureFormat;
2954 VkDeviceSize m_bufferSize;
2955
2956 Move<VkBuffer> m_source;
2957 de::MovePtr<Allocation> m_sourceBufferAlloc;
2958 Move<VkImage> m_destination;
2959 de::MovePtr<Allocation> m_destinationImageAlloc;
2960 std::vector<de::SharedPtr<Allocation>> m_sparseAllocations;
2961 Move<VkSemaphore> m_sparseSemaphore;
2962 };
2963
CopyBufferToImage(Context & context,TestParams testParams)2964 CopyBufferToImage::CopyBufferToImage(Context &context, TestParams testParams)
2965 : CopiesAndBlittingTestInstance(context, testParams)
2966 , m_textureFormat(mapVkFormat(testParams.dst.image.format))
2967 , m_bufferSize(m_params.src.buffer.size * tcu::getPixelSize(m_textureFormat))
2968 {
2969 const InstanceInterface &vki = context.getInstanceInterface();
2970 const DeviceInterface &vk = context.getDeviceInterface();
2971 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
2972
2973 // Create source buffer
2974 {
2975 const VkBufferCreateInfo sourceBufferParams = {
2976 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2977 DE_NULL, // const void* pNext;
2978 0u, // VkBufferCreateFlags flags;
2979 m_bufferSize, // VkDeviceSize size;
2980 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage;
2981 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2982 0u, // uint32_t queueFamilyIndexCount;
2983 (const uint32_t *)DE_NULL, // const uint32_t* pQueueFamilyIndices;
2984 };
2985
2986 m_source = createBuffer(vk, m_device, &sourceBufferParams);
2987 m_sourceBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, m_device, *m_source, MemoryRequirement::HostVisible,
2988 *m_allocator, m_params.allocationKind);
2989 VK_CHECK(vk.bindBufferMemory(m_device, *m_source, m_sourceBufferAlloc->getMemory(),
2990 m_sourceBufferAlloc->getOffset()));
2991 }
2992
2993 // Create destination image
2994 {
2995 VkImageCreateInfo destinationImageParams = {
2996 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
2997 DE_NULL, // const void* pNext;
2998 getCreateFlags(m_params.dst.image), // VkImageCreateFlags flags;
2999 m_params.dst.image.imageType, // VkImageType imageType;
3000 m_params.dst.image.format, // VkFormat format;
3001 getExtent3D(m_params.dst.image), // VkExtent3D extent;
3002 1u, // uint32_t mipLevels;
3003 getArraySize(m_params.dst.image), // uint32_t arraySize;
3004 VK_SAMPLE_COUNT_1_BIT, // uint32_t samples;
3005 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
3006 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
3007 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
3008 0u, // uint32_t queueFamilyIndexCount;
3009 (const uint32_t *)DE_NULL, // const uint32_t* pQueueFamilyIndices;
3010 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
3011 };
3012
3013 #ifndef CTS_USES_VULKANSC
3014 if (!testParams.useSparseBinding)
3015 {
3016 #endif
3017 m_destination = createImage(vk, m_device, &destinationImageParams);
3018 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, m_device, *m_destination,
3019 MemoryRequirement::Any, *m_allocator, m_params.allocationKind, 0u);
3020 VK_CHECK(vk.bindImageMemory(m_device, *m_destination, m_destinationImageAlloc->getMemory(),
3021 m_destinationImageAlloc->getOffset()));
3022 #ifndef CTS_USES_VULKANSC
3023 }
3024 else
3025 {
3026 destinationImageParams.flags |=
3027 (vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT | vk::VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT);
3028 vk::VkImageFormatProperties imageFormatProperties;
3029 if (vki.getPhysicalDeviceImageFormatProperties(
3030 vkPhysDevice, destinationImageParams.format, destinationImageParams.imageType,
3031 destinationImageParams.tiling, destinationImageParams.usage, destinationImageParams.flags,
3032 &imageFormatProperties) == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
3033 {
3034 TCU_THROW(NotSupportedError, "Image format not supported");
3035 }
3036 m_destination = createImage(vk, m_device, &destinationImageParams);
3037 m_sparseSemaphore = createSemaphore(vk, m_device);
3038 allocateAndBindSparseImage(vk, m_device, vkPhysDevice, vki, destinationImageParams, m_sparseSemaphore.get(),
3039 context.getSparseQueue(), *m_allocator, m_sparseAllocations,
3040 mapVkFormat(destinationImageParams.format), m_destination.get());
3041 }
3042 #endif
3043 }
3044 }
3045
iterate(void)3046 tcu::TestStatus CopyBufferToImage::iterate(void)
3047 {
3048 m_sourceTextureLevel =
3049 de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.src.buffer.size, 1));
3050 generateBuffer(m_sourceTextureLevel->getAccess(), (int)m_params.src.buffer.size, 1, 1,
3051 m_params.src.buffer.fillMode);
3052 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(
3053 new tcu::TextureLevel(m_textureFormat, m_params.dst.image.extent.width, m_params.dst.image.extent.height,
3054 m_params.dst.image.extent.depth));
3055
3056 generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width,
3057 m_params.dst.image.extent.height, m_params.dst.image.extent.depth, m_params.dst.image.fillMode);
3058
3059 generateExpectedResult();
3060
3061 uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
3062 uploadImage(m_destinationTextureLevel->getAccess(), *m_destination, m_params.dst.image);
3063
3064 const DeviceInterface &vk = m_context.getDeviceInterface();
3065 const VkDevice vkDevice = m_device;
3066 VkQueue queue = VK_NULL_HANDLE;
3067 VkCommandBuffer commandBuffer = VK_NULL_HANDLE;
3068 VkCommandPool commandPool = VK_NULL_HANDLE;
3069 std::tie(queue, commandBuffer, commandPool) = activeExecutionCtx();
3070
3071 const VkImageMemoryBarrier imageBarrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
3072 DE_NULL, // const void* pNext;
3073 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
3074 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
3075 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
3076 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
3077 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
3078 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
3079 *m_destination, // VkImage image;
3080 {
3081 // VkImageSubresourceRange subresourceRange;
3082 getAspectFlags(m_textureFormat), // VkImageAspectFlags aspectMask;
3083 0u, // uint32_t baseMipLevel;
3084 1u, // uint32_t mipLevels;
3085 0u, // uint32_t baseArraySlice;
3086 getArraySize(m_params.dst.image) // uint32_t arraySize;
3087 }};
3088
3089 // Copy from buffer to image
3090 std::vector<VkBufferImageCopy> bufferImageCopies;
3091 std::vector<VkBufferImageCopy2KHR> bufferImageCopies2KHR;
3092 for (uint32_t i = 0; i < m_params.regions.size(); i++)
3093 {
3094 if (!(m_params.extensionFlags & COPY_COMMANDS_2))
3095 {
3096 bufferImageCopies.push_back(m_params.regions[i].bufferImageCopy);
3097 }
3098 else
3099 {
3100 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
3101 bufferImageCopies2KHR.push_back(
3102 convertvkBufferImageCopyTovkBufferImageCopy2KHR(m_params.regions[i].bufferImageCopy));
3103 }
3104 }
3105
3106 beginCommandBuffer(vk, commandBuffer);
3107 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
3108 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
3109 (const VkBufferMemoryBarrier *)DE_NULL, 1, &imageBarrier);
3110
3111 if (!(m_params.extensionFlags & COPY_COMMANDS_2))
3112 {
3113 vk.cmdCopyBufferToImage(commandBuffer, m_source.get(), m_destination.get(),
3114 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (uint32_t)m_params.regions.size(),
3115 bufferImageCopies.data());
3116 }
3117 else
3118 {
3119 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
3120 const VkCopyBufferToImageInfo2KHR copyBufferToImageInfo2KHR = {
3121 VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR, // VkStructureType sType;
3122 DE_NULL, // const void* pNext;
3123 m_source.get(), // VkBuffer srcBuffer;
3124 m_destination.get(), // VkImage dstImage;
3125 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout dstImageLayout;
3126 (uint32_t)m_params.regions.size(), // uint32_t regionCount;
3127 bufferImageCopies2KHR.data() // const VkBufferImageCopy2KHR* pRegions;
3128 };
3129
3130 vk.cmdCopyBufferToImage2(commandBuffer, ©BufferToImageInfo2KHR);
3131 }
3132
3133 endCommandBuffer(vk, commandBuffer);
3134
3135 submitCommandsAndWait(vk, vkDevice, queue, commandBuffer);
3136 m_context.resetCommandPoolForVKSC(vkDevice, commandPool);
3137
3138 de::MovePtr<tcu::TextureLevel> resultLevel = readImage(*m_destination, m_params.dst.image);
3139 return checkTestResult(resultLevel->getAccess());
3140 }
3141
3142 class CopyBufferToImageTestCase : public vkt::TestCase
3143 {
3144 public:
CopyBufferToImageTestCase(tcu::TestContext & testCtx,const std::string & name,const TestParams params)3145 CopyBufferToImageTestCase(tcu::TestContext &testCtx, const std::string &name, const TestParams params)
3146 : vkt::TestCase(testCtx, name)
3147 , m_params(params)
3148 {
3149 }
3150
~CopyBufferToImageTestCase(void)3151 virtual ~CopyBufferToImageTestCase(void)
3152 {
3153 }
3154
createInstance(Context & context) const3155 virtual TestInstance *createInstance(Context &context) const
3156 {
3157 return new CopyBufferToImage(context, m_params);
3158 }
3159
checkSupport(Context & context) const3160 virtual void checkSupport(Context &context) const
3161 {
3162 checkExtensionSupport(context, m_params.extensionFlags);
3163 }
3164
3165 private:
3166 TestParams m_params;
3167 };
3168
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,uint32_t mipLevel)3169 void CopyBufferToImage::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst,
3170 CopyRegion region, uint32_t mipLevel)
3171 {
3172 DE_UNREF(mipLevel);
3173
3174 uint32_t rowLength = region.bufferImageCopy.bufferRowLength;
3175 if (!rowLength)
3176 rowLength = region.bufferImageCopy.imageExtent.width;
3177
3178 uint32_t imageHeight = region.bufferImageCopy.bufferImageHeight;
3179 if (!imageHeight)
3180 imageHeight = region.bufferImageCopy.imageExtent.height;
3181
3182 const int texelSize = dst.getFormat().getPixelSize();
3183 const VkExtent3D extent = region.bufferImageCopy.imageExtent;
3184 const VkOffset3D dstOffset = region.bufferImageCopy.imageOffset;
3185 const int texelOffset = (int)region.bufferImageCopy.bufferOffset / texelSize;
3186 const uint32_t baseArrayLayer = region.bufferImageCopy.imageSubresource.baseArrayLayer;
3187
3188 for (uint32_t z = 0; z < extent.depth; z++)
3189 {
3190 for (uint32_t y = 0; y < extent.height; y++)
3191 {
3192 int texelIndex = texelOffset + (z * imageHeight + y) * rowLength;
3193 const tcu::ConstPixelBufferAccess srcSubRegion =
3194 tcu::getSubregion(src, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
3195 const tcu::PixelBufferAccess dstSubRegion =
3196 tcu::getSubregion(dst, dstOffset.x, dstOffset.y + y, dstOffset.z + z + baseArrayLayer,
3197 region.bufferImageCopy.imageExtent.width, 1, 1);
3198 tcu::copy(dstSubRegion, srcSubRegion);
3199 }
3200 }
3201 }
3202
3203 class CopyBufferToDepthStencil : public CopiesAndBlittingTestInstance
3204 {
3205 public:
3206 CopyBufferToDepthStencil(Context &context, TestParams testParams);
3207 virtual tcu::TestStatus iterate(void);
3208
3209 private:
3210 virtual void copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst,
3211 CopyRegion region, uint32_t mipLevel = 0u);
3212
3213 tcu::TextureFormat m_textureFormat;
3214 VkDeviceSize m_bufferSize;
3215
3216 Move<VkBuffer> m_source;
3217 de::MovePtr<Allocation> m_sourceBufferAlloc;
3218 Move<VkImage> m_destination;
3219 de::MovePtr<Allocation> m_destinationImageAlloc;
3220 std::vector<de::SharedPtr<Allocation>> m_sparseAllocations;
3221 Move<VkSemaphore> m_sparseSemaphore;
3222 };
3223
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,uint32_t mipLevel)3224 void CopyBufferToDepthStencil::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst,
3225 CopyRegion region, uint32_t mipLevel)
3226 {
3227 DE_UNREF(mipLevel);
3228
3229 uint32_t rowLength = region.bufferImageCopy.bufferRowLength;
3230 if (!rowLength)
3231 rowLength = region.bufferImageCopy.imageExtent.width;
3232
3233 uint32_t imageHeight = region.bufferImageCopy.bufferImageHeight;
3234 if (!imageHeight)
3235 imageHeight = region.bufferImageCopy.imageExtent.height;
3236
3237 const int texelSize = dst.getFormat().getPixelSize();
3238 const VkExtent3D extent = region.bufferImageCopy.imageExtent;
3239 const VkOffset3D dstOffset = region.bufferImageCopy.imageOffset;
3240 const int texelOffset = (int)region.bufferImageCopy.bufferOffset / texelSize;
3241
3242 for (uint32_t z = 0; z < extent.depth; z++)
3243 {
3244 for (uint32_t y = 0; y < extent.height; y++)
3245 {
3246 int texelIndex = texelOffset + (z * imageHeight + y) * rowLength;
3247 const tcu::ConstPixelBufferAccess srcSubRegion =
3248 tcu::getSubregion(src, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
3249 const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(
3250 dst, dstOffset.x, dstOffset.y + y, dstOffset.z + z, region.bufferImageCopy.imageExtent.width, 1, 1);
3251
3252 if (region.bufferImageCopy.imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)
3253 {
3254 tcu::copy(dstSubRegion, tcu::getEffectiveDepthStencilAccess(srcSubRegion, tcu::Sampler::MODE_DEPTH),
3255 false);
3256 }
3257 else
3258 {
3259 tcu::copy(dstSubRegion, tcu::getEffectiveDepthStencilAccess(srcSubRegion, tcu::Sampler::MODE_STENCIL),
3260 false);
3261 }
3262 }
3263 }
3264 }
3265
isSupportedDepthStencilFormat(const InstanceInterface & vki,const VkPhysicalDevice physDevice,const VkFormat format)3266 bool isSupportedDepthStencilFormat(const InstanceInterface &vki, const VkPhysicalDevice physDevice,
3267 const VkFormat format)
3268 {
3269 VkFormatProperties formatProps;
3270 vki.getPhysicalDeviceFormatProperties(physDevice, format, &formatProps);
3271 return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0;
3272 }
3273
CopyBufferToDepthStencil(Context & context,TestParams testParams)3274 CopyBufferToDepthStencil::CopyBufferToDepthStencil(Context &context, TestParams testParams)
3275 : CopiesAndBlittingTestInstance(context, testParams)
3276 , m_textureFormat(mapVkFormat(testParams.dst.image.format))
3277 , m_bufferSize(0)
3278 {
3279 const InstanceInterface &vki = context.getInstanceInterface();
3280 const DeviceInterface &vk = context.getDeviceInterface();
3281 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
3282 const VkDevice vkDevice = m_device;
3283 Allocator &memAlloc = context.getDefaultAllocator();
3284 const bool hasDepth = tcu::hasDepthComponent(mapVkFormat(m_params.dst.image.format).order);
3285 const bool hasStencil = tcu::hasStencilComponent(mapVkFormat(m_params.dst.image.format).order);
3286
3287 if (!isSupportedDepthStencilFormat(vki, vkPhysDevice, testParams.dst.image.format))
3288 {
3289 TCU_THROW(NotSupportedError, "Image format not supported.");
3290 }
3291
3292 if (hasDepth)
3293 {
3294 glw::GLuint texelSize = m_textureFormat.getPixelSize();
3295 if (texelSize > sizeof(float))
3296 {
3297 // We must have D32F_S8 format, depth must be packed so we only need
3298 // to allocate space for the D32F part. Stencil will be separate
3299 texelSize = sizeof(float);
3300 }
3301 m_bufferSize += static_cast<VkDeviceSize>(m_params.dst.image.extent.width) *
3302 static_cast<VkDeviceSize>(m_params.dst.image.extent.height) *
3303 static_cast<VkDeviceSize>(texelSize);
3304 }
3305 if (hasStencil)
3306 {
3307 // Stencil is always 8bits and packed.
3308 m_bufferSize += static_cast<VkDeviceSize>(m_params.dst.image.extent.width) *
3309 static_cast<VkDeviceSize>(m_params.dst.image.extent.height);
3310 }
3311
3312 // Create source buffer, this is where the depth & stencil data will go that's used by test's regions.
3313 {
3314 const VkBufferCreateInfo sourceBufferParams = {
3315 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
3316 DE_NULL, // const void* pNext;
3317 0u, // VkBufferCreateFlags flags;
3318 m_bufferSize, // VkDeviceSize size;
3319 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage;
3320 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
3321 0u, // uint32_t queueFamilyIndexCount;
3322 (const uint32_t *)DE_NULL, // const uint32_t* pQueueFamilyIndices;
3323 };
3324
3325 m_source = createBuffer(vk, vkDevice, &sourceBufferParams);
3326 m_sourceBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible,
3327 memAlloc, m_params.allocationKind);
3328 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(),
3329 m_sourceBufferAlloc->getOffset()));
3330 }
3331
3332 // Create destination image
3333 {
3334 VkImageCreateInfo destinationImageParams = {
3335 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
3336 DE_NULL, // const void* pNext;
3337 getCreateFlags(m_params.dst.image), // VkImageCreateFlags flags;
3338 m_params.dst.image.imageType, // VkImageType imageType;
3339 m_params.dst.image.format, // VkFormat format;
3340 getExtent3D(m_params.dst.image), // VkExtent3D extent;
3341 1u, // uint32_t mipLevels;
3342 getArraySize(m_params.dst.image), // uint32_t arraySize;
3343 VK_SAMPLE_COUNT_1_BIT, // uint32_t samples;
3344 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
3345 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
3346 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
3347 0u, // uint32_t queueFamilyIndexCount;
3348 (const uint32_t *)DE_NULL, // const uint32_t* pQueueFamilyIndices;
3349 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
3350 };
3351
3352 #ifndef CTS_USES_VULKANSC
3353 if (!testParams.useSparseBinding)
3354 {
3355 #endif
3356 m_destination = createImage(vk, m_device, &destinationImageParams);
3357 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, m_device, *m_destination,
3358 MemoryRequirement::Any, *m_allocator, m_params.allocationKind, 0u);
3359 VK_CHECK(vk.bindImageMemory(m_device, *m_destination, m_destinationImageAlloc->getMemory(),
3360 m_destinationImageAlloc->getOffset()));
3361 #ifndef CTS_USES_VULKANSC
3362 }
3363 else
3364 {
3365 destinationImageParams.flags |=
3366 (vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT | vk::VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT);
3367 vk::VkImageFormatProperties imageFormatProperties;
3368 if (vki.getPhysicalDeviceImageFormatProperties(
3369 vkPhysDevice, destinationImageParams.format, destinationImageParams.imageType,
3370 destinationImageParams.tiling, destinationImageParams.usage, destinationImageParams.flags,
3371 &imageFormatProperties) == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
3372 {
3373 TCU_THROW(NotSupportedError, "Image format not supported");
3374 }
3375 m_destination = createImage(vk, m_device, &destinationImageParams);
3376 m_sparseSemaphore = createSemaphore(vk, m_device);
3377 allocateAndBindSparseImage(vk, m_device, vkPhysDevice, vki, destinationImageParams, m_sparseSemaphore.get(),
3378 context.getSparseQueue(), *m_allocator, m_sparseAllocations,
3379 mapVkFormat(destinationImageParams.format), m_destination.get());
3380 }
3381 #endif
3382 }
3383 }
3384
iterate(void)3385 tcu::TestStatus CopyBufferToDepthStencil::iterate(void)
3386 {
3387 // Create source depth/stencil content. Treat as 1D texture to get different pattern
3388 m_sourceTextureLevel =
3389 de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.src.buffer.size, 1));
3390 // Fill buffer with linear gradiant
3391 generateBuffer(m_sourceTextureLevel->getAccess(), (int)m_params.src.buffer.size, 1, 1);
3392
3393 // Create image layer for depth/stencil
3394 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(
3395 new tcu::TextureLevel(m_textureFormat, m_params.dst.image.extent.width, m_params.dst.image.extent.height,
3396 m_params.dst.image.extent.depth));
3397
3398 // Fill image layer with 2D gradiant
3399 generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width,
3400 m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
3401
3402 // Fill m_extendedTextureLevel with copy of m_destinationTextureLevel
3403 // Then iterate over each of the regions given in m_params.regions and copy m_sourceTextureLevel content to m_extendedTextureLevel
3404 // This emulates what the HW will be doing.
3405 generateExpectedResult();
3406
3407 // Upload our source depth/stencil content to the source buffer
3408 // This is the buffer that will be used by region commands
3409 std::vector<VkBufferImageCopy> bufferImageCopies;
3410 std::vector<VkBufferImageCopy2KHR> bufferImageCopies2KHR;
3411 VkDeviceSize bufferOffset = 0;
3412 const VkDevice vkDevice = m_device;
3413 const DeviceInterface &vk = m_context.getDeviceInterface();
3414 char *dstPtr = reinterpret_cast<char *>(m_sourceBufferAlloc->getHostPtr());
3415 bool depthLoaded = false;
3416 bool stencilLoaded = false;
3417 VkDeviceSize depthOffset = 0;
3418 VkDeviceSize stencilOffset = 0;
3419
3420 // To be able to test ordering depth & stencil differently
3421 // we take the given copy regions and use that as the desired order
3422 // and copy the appropriate data into place and compute the appropriate
3423 // data offsets to be used in the copy command.
3424 for (uint32_t i = 0; i < m_params.regions.size(); i++)
3425 {
3426 tcu::ConstPixelBufferAccess bufferAccess = m_sourceTextureLevel->getAccess();
3427 uint32_t bufferSize = bufferAccess.getWidth() * bufferAccess.getHeight() * bufferAccess.getDepth();
3428 VkBufferImageCopy copyData = m_params.regions[i].bufferImageCopy;
3429 char *srcPtr;
3430
3431 if (copyData.imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT && !depthLoaded)
3432 {
3433 // Create level that is same component as depth buffer (e.g. D16, D24, D32F)
3434 tcu::TextureLevel depthTexture(mapCombinedToDepthTransferFormat(bufferAccess.getFormat()),
3435 bufferAccess.getWidth(), bufferAccess.getHeight(), bufferAccess.getDepth());
3436 bufferSize *= tcu::getPixelSize(depthTexture.getFormat());
3437 // Copy depth component only from source data. This gives us packed depth-only data.
3438 tcu::copy(depthTexture.getAccess(),
3439 tcu::getEffectiveDepthStencilAccess(bufferAccess, tcu::Sampler::MODE_DEPTH));
3440 srcPtr = (char *)depthTexture.getAccess().getDataPtr();
3441 // Copy packed depth-only data to output buffer
3442 deMemcpy(dstPtr, srcPtr, bufferSize);
3443 depthLoaded = true;
3444 depthOffset = bufferOffset;
3445 dstPtr += bufferSize;
3446 bufferOffset += bufferSize;
3447 copyData.bufferOffset += depthOffset;
3448 }
3449 else if (!stencilLoaded)
3450 {
3451 // Create level that is same component as stencil buffer (always 8-bits)
3452 tcu::TextureLevel stencilTexture(
3453 tcu::getEffectiveDepthStencilTextureFormat(bufferAccess.getFormat(), tcu::Sampler::MODE_STENCIL),
3454 bufferAccess.getWidth(), bufferAccess.getHeight(), bufferAccess.getDepth());
3455 // Copy stencil component only from source data. This gives us packed stencil-only data.
3456 tcu::copy(stencilTexture.getAccess(),
3457 tcu::getEffectiveDepthStencilAccess(bufferAccess, tcu::Sampler::MODE_STENCIL));
3458 srcPtr = (char *)stencilTexture.getAccess().getDataPtr();
3459 // Copy packed stencil-only data to output buffer
3460 deMemcpy(dstPtr, srcPtr, bufferSize);
3461 stencilLoaded = true;
3462 stencilOffset = bufferOffset;
3463 dstPtr += bufferSize;
3464 bufferOffset += bufferSize;
3465
3466 // Reference image generation uses pixel offsets based on buffer offset.
3467 // We need to adjust the offset now that the stencil data is not interleaved.
3468 copyData.bufferOffset /= tcu::getPixelSize(m_textureFormat);
3469
3470 copyData.bufferOffset += stencilOffset;
3471 }
3472
3473 if (!(m_params.extensionFlags & COPY_COMMANDS_2))
3474 {
3475 bufferImageCopies.push_back(copyData);
3476 }
3477 else
3478 {
3479 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
3480 bufferImageCopies2KHR.push_back(convertvkBufferImageCopyTovkBufferImageCopy2KHR(copyData));
3481 }
3482 }
3483
3484 flushAlloc(vk, vkDevice, *m_sourceBufferAlloc);
3485
3486 // Upload the depth/stencil data from m_destinationTextureLevel to initialize
3487 // depth and stencil to known values.
3488 // Uses uploadImageAspect so makes its own buffers for depth and stencil
3489 // aspects (as needed) and copies them with independent vkCmdCopyBufferToImage commands.
3490 uploadImage(m_destinationTextureLevel->getAccess(), *m_destination, m_params.dst.image);
3491
3492 const VkImageMemoryBarrier imageBarrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
3493 DE_NULL, // const void* pNext;
3494 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
3495 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
3496 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
3497 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
3498 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
3499 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
3500 *m_destination, // VkImage image;
3501 {
3502 // VkImageSubresourceRange subresourceRange;
3503 getAspectFlags(m_textureFormat), // VkImageAspectFlags aspectMask;
3504 0u, // uint32_t baseMipLevel;
3505 1u, // uint32_t mipLevels;
3506 0u, // uint32_t baseArraySlice;
3507 1u // uint32_t arraySize;
3508 }};
3509
3510 // Copy from buffer to depth/stencil image
3511
3512 beginCommandBuffer(vk, *m_universalCmdBuffer);
3513 vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
3514 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
3515 (const VkBufferMemoryBarrier *)DE_NULL, 1, &imageBarrier);
3516
3517 if (!(m_params.extensionFlags & COPY_COMMANDS_2))
3518 {
3519 if (m_params.singleCommand)
3520 {
3521 // Issue a single copy command with regions defined by the test.
3522 vk.cmdCopyBufferToImage(*m_universalCmdBuffer, m_source.get(), m_destination.get(),
3523 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (uint32_t)m_params.regions.size(),
3524 bufferImageCopies.data());
3525 }
3526 else
3527 {
3528 // Issue a a copy command per region defined by the test.
3529 for (uint32_t i = 0; i < bufferImageCopies.size(); i++)
3530 {
3531 if (i > 0)
3532 vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
3533 VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0,
3534 (const VkMemoryBarrier *)DE_NULL, 0, (const VkBufferMemoryBarrier *)DE_NULL,
3535 1, &imageBarrier);
3536
3537 vk.cmdCopyBufferToImage(*m_universalCmdBuffer, m_source.get(), m_destination.get(),
3538 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferImageCopies[i]);
3539 }
3540 }
3541 }
3542 else
3543 {
3544 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
3545
3546 if (m_params.singleCommand)
3547 {
3548 // Issue a single copy command with regions defined by the test.
3549 const VkCopyBufferToImageInfo2KHR copyBufferToImageInfo2KHR = {
3550 VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR, // VkStructureType sType;
3551 DE_NULL, // const void* pNext;
3552 m_source.get(), // VkBuffer srcBuffer;
3553 m_destination.get(), // VkImage dstImage;
3554 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout dstImageLayout;
3555 (uint32_t)m_params.regions.size(), // uint32_t regionCount;
3556 bufferImageCopies2KHR.data() // const VkBufferImageCopy2KHR* pRegions;
3557 };
3558 vk.cmdCopyBufferToImage2(*m_universalCmdBuffer, ©BufferToImageInfo2KHR);
3559 }
3560 else
3561 {
3562 // Issue a a copy command per region defined by the test.
3563 for (uint32_t i = 0; i < bufferImageCopies2KHR.size(); i++)
3564 {
3565 if (i > 0)
3566 vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
3567 VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0,
3568 (const VkMemoryBarrier *)DE_NULL, 0, (const VkBufferMemoryBarrier *)DE_NULL,
3569 1, &imageBarrier);
3570
3571 const VkCopyBufferToImageInfo2KHR copyBufferToImageInfo2KHR = {
3572 VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR, // VkStructureType sType;
3573 DE_NULL, // const void* pNext;
3574 m_source.get(), // VkBuffer srcBuffer;
3575 m_destination.get(), // VkImage dstImage;
3576 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout dstImageLayout;
3577 1, // uint32_t regionCount;
3578 &bufferImageCopies2KHR[i] // const VkBufferImageCopy2KHR* pRegions;
3579 };
3580 // Issue a single copy command with regions defined by the test.
3581 vk.cmdCopyBufferToImage2(*m_universalCmdBuffer, ©BufferToImageInfo2KHR);
3582 }
3583 }
3584 }
3585
3586 endCommandBuffer(vk, *m_universalCmdBuffer);
3587
3588 submitCommandsAndWait(vk, vkDevice, m_universalQueue, *m_universalCmdBuffer);
3589 m_context.resetCommandPoolForVKSC(vkDevice, *m_universalCmdPool);
3590
3591 de::MovePtr<tcu::TextureLevel> resultLevel = readImage(*m_destination, m_params.dst.image);
3592
3593 // For combined depth/stencil formats both aspects are checked even when the test only
3594 // copies one. Clear such aspects here for both the result and the reference.
3595 if (tcu::hasDepthComponent(m_textureFormat.order) && !depthLoaded)
3596 {
3597 tcu::clearDepth(m_expectedTextureLevel[0]->getAccess(), 0.0f);
3598 tcu::clearDepth(resultLevel->getAccess(), 0.0f);
3599 }
3600 if (tcu::hasStencilComponent(m_textureFormat.order) && !stencilLoaded)
3601 {
3602 tcu::clearStencil(m_expectedTextureLevel[0]->getAccess(), 0);
3603 tcu::clearStencil(resultLevel->getAccess(), 0);
3604 }
3605
3606 return checkTestResult(resultLevel->getAccess());
3607 }
3608
3609 class CopyBufferToDepthStencilTestCase : public vkt::TestCase
3610 {
3611 public:
CopyBufferToDepthStencilTestCase(tcu::TestContext & testCtx,const std::string & name,const TestParams params)3612 CopyBufferToDepthStencilTestCase(tcu::TestContext &testCtx, const std::string &name, const TestParams params)
3613 : vkt::TestCase(testCtx, name)
3614 , m_params(params)
3615 {
3616 }
3617
~CopyBufferToDepthStencilTestCase(void)3618 virtual ~CopyBufferToDepthStencilTestCase(void)
3619 {
3620 }
3621
createInstance(Context & context) const3622 virtual TestInstance *createInstance(Context &context) const
3623 {
3624 return new CopyBufferToDepthStencil(context, m_params);
3625 }
3626
checkSupport(Context & context) const3627 virtual void checkSupport(Context &context) const
3628 {
3629 checkExtensionSupport(context, m_params.extensionFlags);
3630 }
3631
3632 private:
3633 TestParams m_params;
3634 };
3635
3636 // CompressedTextureForBlit is a helper class that stores compressed texture data.
3637 // Implementation is based on pipeline::TestTexture2D but it allocates only one level
3638 // and has special cases needed for blits to some formats.
3639
3640 class CompressedTextureForBlit
3641 {
3642 public:
3643 CompressedTextureForBlit(const tcu::CompressedTexFormat &srcFormat, int width, int height, int depth);
3644
3645 tcu::PixelBufferAccess getDecompressedAccess() const;
3646 const tcu::CompressedTexture &getCompressedTexture() const;
3647
3648 protected:
3649 tcu::CompressedTexture m_compressedTexture;
3650 de::ArrayBuffer<uint8_t> m_decompressedData;
3651 tcu::PixelBufferAccess m_decompressedAccess;
3652 };
3653
CompressedTextureForBlit(const tcu::CompressedTexFormat & srcFormat,int width,int height,int depth)3654 CompressedTextureForBlit::CompressedTextureForBlit(const tcu::CompressedTexFormat &srcFormat, int width, int height,
3655 int depth)
3656 : m_compressedTexture(srcFormat, width, height, depth)
3657 {
3658 de::Random random(123);
3659
3660 const int compressedDataSize(m_compressedTexture.getDataSize());
3661 uint8_t *compressedData((uint8_t *)m_compressedTexture.getData());
3662
3663 tcu::TextureFormat decompressedSrcFormat(tcu::getUncompressedFormat(srcFormat));
3664 const int decompressedDataSize(tcu::getPixelSize(decompressedSrcFormat) * width * height * depth);
3665
3666 // generate random data for compresed textre
3667 if (tcu::isAstcFormat(srcFormat))
3668 {
3669 // comparison doesn't currently handle invalid blocks correctly so we use only valid blocks
3670 tcu::astc::generateRandomValidBlocks(compressedData, compressedDataSize / tcu::astc::BLOCK_SIZE_BYTES,
3671 srcFormat, tcu::TexDecompressionParams::ASTCMODE_LDR, random.getUint32());
3672 }
3673 else if ((srcFormat == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK) ||
3674 (srcFormat == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK))
3675 {
3676 // special case - when we are blitting compressed floating-point image we can't have both big and small values
3677 // in compressed image; to resolve this we are constructing source texture out of set of predefined compressed
3678 // blocks that after decompression will have components in proper range
3679
3680 typedef std::array<uint32_t, 4> BC6HBlock;
3681 DE_STATIC_ASSERT(sizeof(BC6HBlock) == (4 * sizeof(uint32_t)));
3682 std::vector<BC6HBlock> validBlocks;
3683
3684 if (srcFormat == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK)
3685 {
3686 // define set of few valid blocks that contain values from <0; 1> range
3687 validBlocks = {
3688 {{1686671500, 3957317723, 3010132342, 2420137890}}, {{3538027716, 298848033, 1925786021, 2022072301}},
3689 {{2614043466, 1636155440, 1023731774, 1894349986}}, {{3433039318, 1294346072, 1587319645, 1738449906}},
3690 {{1386298160, 1639492154, 1273285776, 361562050}}, {{1310110688, 526460754, 3630858047, 537617591}},
3691 {{3270356556, 2432993217, 2415924417, 1792488857}}, {{1204947583, 353249154, 3739153467, 2068076443}},
3692 };
3693 }
3694 else
3695 {
3696 // define set of few valid blocks that contain values from <-1; 1> range
3697 validBlocks = {
3698 {{2120678840, 3264271120, 4065378848, 3479743703}}, {{1479697556, 3480872527, 3369382558, 568252340}},
3699 {{1301480032, 1607738094, 3055221704, 3663953681}}, {{3531657186, 2285472028, 1429601507, 1969308187}},
3700 {{73229044, 650504649, 1120954865, 2626631975}}, {{3872486086, 15326178, 2565171269, 2857722432}},
3701 {{1301480032, 1607738094, 3055221704, 3663953681}}, {{73229044, 650504649, 1120954865, 2626631975}},
3702 };
3703 }
3704
3705 uint32_t *compressedDataUint32 = reinterpret_cast<uint32_t *>(compressedData);
3706 const int blocksCount = compressedDataSize / static_cast<int>(sizeof(BC6HBlock));
3707
3708 // fill data using randomly selected valid blocks
3709 for (int blockNdx = 0; blockNdx < blocksCount; blockNdx++)
3710 {
3711 uint32_t selectedBlock = random.getUint32() % static_cast<uint32_t>(validBlocks.size());
3712 deMemcpy(compressedDataUint32, validBlocks[selectedBlock].data(), sizeof(BC6HBlock));
3713 compressedDataUint32 += 4;
3714 }
3715 }
3716 else if (srcFormat != tcu::COMPRESSEDTEXFORMAT_ETC1_RGB8)
3717 {
3718 // random initial values cause assertion during the decompression in case of COMPRESSEDTEXFORMAT_ETC1_RGB8 format
3719 for (int byteNdx = 0; byteNdx < compressedDataSize; byteNdx++)
3720 compressedData[byteNdx] = 0xFF & random.getUint32();
3721 }
3722
3723 // alocate space for decompressed texture
3724 m_decompressedData.setStorage(decompressedDataSize);
3725 m_decompressedAccess =
3726 tcu::PixelBufferAccess(decompressedSrcFormat, width, height, depth, m_decompressedData.getPtr());
3727
3728 // store decompressed data
3729 m_compressedTexture.decompress(m_decompressedAccess,
3730 tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR));
3731 }
3732
getDecompressedAccess() const3733 tcu::PixelBufferAccess CompressedTextureForBlit::getDecompressedAccess() const
3734 {
3735 return m_decompressedAccess;
3736 }
3737
getCompressedTexture() const3738 const tcu::CompressedTexture &CompressedTextureForBlit::getCompressedTexture() const
3739 {
3740 return m_compressedTexture;
3741 }
3742
3743 // Copy from image to image with scaling.
3744
3745 class BlittingImages : public CopiesAndBlittingTestInstance
3746 {
3747 public:
3748 BlittingImages(Context &context, TestParams params);
3749 virtual tcu::TestStatus iterate(void);
3750
3751 protected:
3752 virtual tcu::TestStatus checkTestResult(tcu::ConstPixelBufferAccess result);
3753 virtual void copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst,
3754 CopyRegion region, uint32_t mipLevel = 0u);
3755 virtual void generateExpectedResult(void);
3756 void uploadCompressedImage(const VkImage &image, const ImageParms &parms);
3757
3758 private:
3759 bool checkNonNearestFilteredResult(const tcu::ConstPixelBufferAccess &result,
3760 const tcu::ConstPixelBufferAccess &clampedReference,
3761 const tcu::ConstPixelBufferAccess &unclampedReference,
3762 const tcu::TextureFormat &sourceFormat);
3763 bool checkNearestFilteredResult(const tcu::ConstPixelBufferAccess &result,
3764 const tcu::ConstPixelBufferAccess &source);
3765
3766 bool checkCompressedNonNearestFilteredResult(const tcu::ConstPixelBufferAccess &result,
3767 const tcu::ConstPixelBufferAccess &clampedReference,
3768 const tcu::ConstPixelBufferAccess &unclampedReference,
3769 const tcu::CompressedTexFormat format);
3770 bool checkCompressedNearestFilteredResult(const tcu::ConstPixelBufferAccess &result,
3771 const tcu::ConstPixelBufferAccess &source,
3772 const tcu::CompressedTexFormat format);
3773
3774 Move<VkImage> m_source;
3775 de::MovePtr<Allocation> m_sourceImageAlloc;
3776 Move<VkImage> m_destination;
3777 de::MovePtr<Allocation> m_destinationImageAlloc;
3778 std::vector<de::SharedPtr<Allocation>> m_sparseAllocations;
3779 Move<VkSemaphore> m_sparseSemaphore;
3780
3781 de::MovePtr<tcu::TextureLevel> m_unclampedExpectedTextureLevel;
3782
3783 // helper used only when bliting from compressed formats
3784 typedef de::SharedPtr<CompressedTextureForBlit> CompressedTextureForBlitSp;
3785 CompressedTextureForBlitSp m_sourceCompressedTexture;
3786 CompressedTextureForBlitSp m_destinationCompressedTexture;
3787 };
3788
BlittingImages(Context & context,TestParams params)3789 BlittingImages::BlittingImages(Context &context, TestParams params) : CopiesAndBlittingTestInstance(context, params)
3790 {
3791 const InstanceInterface &vki = context.getInstanceInterface();
3792 const DeviceInterface &vk = context.getDeviceInterface();
3793 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
3794 const VkDevice vkDevice = m_device;
3795 Allocator &memAlloc = context.getDefaultAllocator();
3796
3797 // Create source image
3798 {
3799 VkImageCreateInfo sourceImageParams = {
3800 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
3801 DE_NULL, // const void* pNext;
3802 getCreateFlags(m_params.src.image), // VkImageCreateFlags flags;
3803 m_params.src.image.imageType, // VkImageType imageType;
3804 m_params.src.image.format, // VkFormat format;
3805 getExtent3D(m_params.src.image), // VkExtent3D extent;
3806 1u, // uint32_t mipLevels;
3807 getArraySize(m_params.src.image), // uint32_t arraySize;
3808 VK_SAMPLE_COUNT_1_BIT, // uint32_t samples;
3809 m_params.src.image.tiling, // VkImageTiling tiling;
3810 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
3811 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
3812 0u, // uint32_t queueFamilyIndexCount;
3813 (const uint32_t *)DE_NULL, // const uint32_t* pQueueFamilyIndices;
3814 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
3815 };
3816
3817 #ifndef CTS_USES_VULKANSC
3818 if (!params.useSparseBinding)
3819 {
3820 #endif
3821 m_source = createImage(vk, m_device, &sourceImageParams);
3822 m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, m_device, *m_source, MemoryRequirement::Any,
3823 *m_allocator, m_params.allocationKind, 0u);
3824 VK_CHECK(vk.bindImageMemory(m_device, *m_source, m_sourceImageAlloc->getMemory(),
3825 m_sourceImageAlloc->getOffset()));
3826 #ifndef CTS_USES_VULKANSC
3827 }
3828 else
3829 {
3830 sourceImageParams.flags |=
3831 (vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT | vk::VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT);
3832 vk::VkImageFormatProperties imageFormatProperties;
3833 if (vki.getPhysicalDeviceImageFormatProperties(vkPhysDevice, sourceImageParams.format,
3834 sourceImageParams.imageType, sourceImageParams.tiling,
3835 sourceImageParams.usage, sourceImageParams.flags,
3836 &imageFormatProperties) == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
3837 {
3838 TCU_THROW(NotSupportedError, "Image format not supported");
3839 }
3840 m_source = createImage(
3841 vk, m_device,
3842 &sourceImageParams); //de::MovePtr<SparseImage>(new SparseImage(vk, vk, vkPhysDevice, vki, sourceImageParams, m_queue, *m_allocator, mapVkFormat(sourceImageParams.format)));
3843 m_sparseSemaphore = createSemaphore(vk, m_device);
3844 allocateAndBindSparseImage(vk, m_device, vkPhysDevice, vki, sourceImageParams, m_sparseSemaphore.get(),
3845 context.getSparseQueue(), *m_allocator, m_sparseAllocations,
3846 mapVkFormat(sourceImageParams.format), m_source.get());
3847 }
3848 #endif
3849 }
3850
3851 // Create destination image
3852 {
3853 const VkImageCreateInfo destinationImageParams = {
3854 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
3855 DE_NULL, // const void* pNext;
3856 getCreateFlags(m_params.dst.image), // VkImageCreateFlags flags;
3857 m_params.dst.image.imageType, // VkImageType imageType;
3858 m_params.dst.image.format, // VkFormat format;
3859 getExtent3D(m_params.dst.image), // VkExtent3D extent;
3860 1u, // uint32_t mipLevels;
3861 getArraySize(m_params.dst.image), // uint32_t arraySize;
3862 VK_SAMPLE_COUNT_1_BIT, // uint32_t samples;
3863 m_params.dst.image.tiling, // VkImageTiling tiling;
3864 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
3865 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
3866 0u, // uint32_t queueFamilyIndexCount;
3867 (const uint32_t *)DE_NULL, // const uint32_t* pQueueFamilyIndices;
3868 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
3869 };
3870
3871 m_destination = createImage(vk, vkDevice, &destinationImageParams);
3872 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any,
3873 memAlloc, m_params.allocationKind, 0u);
3874 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(),
3875 m_destinationImageAlloc->getOffset()));
3876 }
3877 }
3878
iterate(void)3879 tcu::TestStatus BlittingImages::iterate(void)
3880 {
3881 const DeviceInterface &vk = m_context.getDeviceInterface();
3882 const VkDevice vkDevice = m_device;
3883 const ImageParms &srcImageParams = m_params.src.image;
3884 const int srcWidth = static_cast<int>(srcImageParams.extent.width);
3885 const int srcHeight = static_cast<int>(srcImageParams.extent.height);
3886 const int srcDepth = static_cast<int>(srcImageParams.extent.depth);
3887 const ImageParms &dstImageParams = m_params.dst.image;
3888 const int dstWidth = static_cast<int>(dstImageParams.extent.width);
3889 const int dstHeight = static_cast<int>(dstImageParams.extent.height);
3890 const int dstDepth = static_cast<int>(dstImageParams.extent.depth);
3891
3892 std::vector<VkImageBlit> regions;
3893 std::vector<VkImageBlit2KHR> regions2KHR;
3894
3895 // setup blit regions - they are also needed for reference generation
3896 if (!(m_params.extensionFlags & COPY_COMMANDS_2))
3897 {
3898 regions.reserve(m_params.regions.size());
3899 for (const auto &r : m_params.regions)
3900 regions.push_back(r.imageBlit);
3901 }
3902 else
3903 {
3904 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
3905 regions2KHR.reserve(m_params.regions.size());
3906 for (const auto &r : m_params.regions)
3907 regions2KHR.push_back(convertvkImageBlitTovkImageBlit2KHR(r.imageBlit));
3908 }
3909
3910 // generate source image
3911 if (isCompressedFormat(srcImageParams.format))
3912 {
3913 // for compressed images srcImageParams.fillMode is not used - we are using random data
3914 tcu::CompressedTexFormat compressedFormat = mapVkCompressedFormat(srcImageParams.format);
3915 m_sourceCompressedTexture =
3916 CompressedTextureForBlitSp(new CompressedTextureForBlit(compressedFormat, srcWidth, srcHeight, srcDepth));
3917 uploadCompressedImage(m_source.get(), srcImageParams);
3918 }
3919 else
3920 {
3921 // non-compressed image is filled with selected fillMode
3922 const tcu::TextureFormat srcTcuFormat = mapVkFormat(srcImageParams.format);
3923 m_sourceTextureLevel =
3924 de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat, srcWidth, srcHeight, srcDepth));
3925 generateBuffer(m_sourceTextureLevel->getAccess(), srcWidth, srcHeight, srcDepth, srcImageParams.fillMode);
3926 uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), srcImageParams);
3927 }
3928
3929 // generate destination image
3930 if (isCompressedFormat(dstImageParams.format))
3931 {
3932 // compressed images are filled with random data
3933 tcu::CompressedTexFormat compressedFormat = mapVkCompressedFormat(dstImageParams.format);
3934 m_destinationCompressedTexture =
3935 CompressedTextureForBlitSp(new CompressedTextureForBlit(compressedFormat, srcWidth, srcHeight, srcDepth));
3936 uploadCompressedImage(m_destination.get(), dstImageParams);
3937 }
3938 else
3939 {
3940 // non-compressed image is filled with white background
3941 const tcu::TextureFormat dstTcuFormat = mapVkFormat(dstImageParams.format);
3942 m_destinationTextureLevel =
3943 de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat, dstWidth, dstHeight, dstDepth));
3944 generateBuffer(m_destinationTextureLevel->getAccess(), dstWidth, dstHeight, dstDepth, dstImageParams.fillMode);
3945 uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), dstImageParams);
3946 }
3947
3948 generateExpectedResult();
3949
3950 // Barriers for copying images to buffer
3951 const VkImageMemoryBarrier imageBarriers[]{
3952 {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
3953 DE_NULL, // const void* pNext;
3954 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
3955 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
3956 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
3957 srcImageParams.operationLayout, // VkImageLayout newLayout;
3958 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
3959 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
3960 m_source.get(), // VkImage image;
3961 {
3962 // VkImageSubresourceRange subresourceRange;
3963 getAspectFlags(srcImageParams.format), // VkImageAspectFlags aspectMask;
3964 0u, // uint32_t baseMipLevel;
3965 1u, // uint32_t mipLevels;
3966 0u, // uint32_t baseArraySlice;
3967 getArraySize(m_params.src.image) // uint32_t arraySize;
3968 }},
3969 {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
3970 DE_NULL, // const void* pNext;
3971 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
3972 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
3973 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
3974 dstImageParams.operationLayout, // VkImageLayout newLayout;
3975 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
3976 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
3977 m_destination.get(), // VkImage image;
3978 {
3979 // VkImageSubresourceRange subresourceRange;
3980 getAspectFlags(dstImageParams.format), // VkImageAspectFlags aspectMask;
3981 0u, // uint32_t baseMipLevel;
3982 1u, // uint32_t mipLevels;
3983 0u, // uint32_t baseArraySlice;
3984 getArraySize(m_params.dst.image) // uint32_t arraySize;
3985 }}};
3986
3987 beginCommandBuffer(vk, *m_universalCmdBuffer);
3988 vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
3989 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
3990 (const VkBufferMemoryBarrier *)DE_NULL, 2, imageBarriers);
3991
3992 if (!(m_params.extensionFlags & COPY_COMMANDS_2))
3993 {
3994 vk.cmdBlitImage(*m_universalCmdBuffer, m_source.get(), srcImageParams.operationLayout, m_destination.get(),
3995 dstImageParams.operationLayout, (uint32_t)m_params.regions.size(), ®ions[0],
3996 m_params.filter);
3997 }
3998 else
3999 {
4000 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
4001 const VkBlitImageInfo2KHR blitImageInfo2KHR{
4002 VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR, // VkStructureType sType;
4003 DE_NULL, // const void* pNext;
4004 m_source.get(), // VkImage srcImage;
4005 srcImageParams.operationLayout, // VkImageLayout srcImageLayout;
4006 m_destination.get(), // VkImage dstImage;
4007 dstImageParams.operationLayout, // VkImageLayout dstImageLayout;
4008 (uint32_t)m_params.regions.size(), // uint32_t regionCount;
4009 ®ions2KHR[0], // const VkImageBlit2KHR* pRegions;
4010 m_params.filter, // VkFilter filter;
4011 };
4012 vk.cmdBlitImage2(*m_universalCmdBuffer, &blitImageInfo2KHR);
4013 }
4014
4015 endCommandBuffer(vk, *m_universalCmdBuffer);
4016 submitCommandsAndWait(vk, vkDevice, m_universalQueue, *m_universalCmdBuffer);
4017 m_context.resetCommandPoolForVKSC(vkDevice, *m_universalCmdPool);
4018
4019 de::MovePtr<tcu::TextureLevel> resultLevel = readImage(*m_destination, dstImageParams);
4020 tcu::PixelBufferAccess resultAccess = resultLevel->getAccess();
4021
4022 // if blit was done to a compressed format we need to decompress it to be able to verify it
4023 if (m_destinationCompressedTexture)
4024 {
4025 uint8_t *const compressedDataSrc(static_cast<uint8_t *>(resultAccess.getDataPtr()));
4026 const tcu::CompressedTexFormat dstCompressedFormat(mapVkCompressedFormat(dstImageParams.format));
4027 tcu::TextureLevel decompressedLevel(getUncompressedFormat(dstCompressedFormat), dstWidth, dstHeight, dstDepth);
4028 tcu::PixelBufferAccess decompressedAccess(decompressedLevel.getAccess());
4029
4030 tcu::decompress(decompressedAccess, dstCompressedFormat, compressedDataSrc);
4031
4032 return checkTestResult(decompressedAccess);
4033 }
4034
4035 return checkTestResult(resultAccess);
4036 }
4037
calculateFloatConversionError(int srcBits)4038 static float calculateFloatConversionError(int srcBits)
4039 {
4040 if (srcBits > 0)
4041 {
4042 const int clampedBits = de::clamp<int>(srcBits, 0, 32);
4043 const float srcMaxValue = de::max((float)(1ULL << clampedBits) - 1.0f, 1.0f);
4044 const float error = 1.0f / srcMaxValue;
4045
4046 return de::clamp<float>(error, 0.0f, 1.0f);
4047 }
4048 else
4049 return 1.0f;
4050 }
4051
getFormatThreshold(const tcu::TextureFormat & format)4052 tcu::Vec4 getFormatThreshold(const tcu::TextureFormat &format)
4053 {
4054 tcu::Vec4 threshold(0.01f);
4055
4056 switch (format.type)
4057 {
4058 case tcu::TextureFormat::HALF_FLOAT:
4059 threshold = tcu::Vec4(0.005f);
4060 break;
4061
4062 case tcu::TextureFormat::FLOAT:
4063 case tcu::TextureFormat::FLOAT64:
4064 threshold = tcu::Vec4(0.001f);
4065 break;
4066
4067 case tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
4068 threshold = tcu::Vec4(0.02f, 0.02f, 0.0625f, 1.0f);
4069 break;
4070
4071 case tcu::TextureFormat::UNSIGNED_INT_999_E5_REV:
4072 threshold = tcu::Vec4(0.05f, 0.05f, 0.05f, 1.0f);
4073 break;
4074
4075 case tcu::TextureFormat::UNORM_INT_1010102_REV:
4076 threshold = tcu::Vec4(0.002f, 0.002f, 0.002f, 0.3f);
4077 break;
4078
4079 case tcu::TextureFormat::UNORM_INT8:
4080 threshold = tcu::Vec4(0.008f, 0.008f, 0.008f, 0.008f);
4081 break;
4082
4083 default:
4084 const tcu::IVec4 bits = tcu::getTextureFormatMantissaBitDepth(format);
4085 threshold = tcu::Vec4(calculateFloatConversionError(bits.x()), calculateFloatConversionError(bits.y()),
4086 calculateFloatConversionError(bits.z()), calculateFloatConversionError(bits.w()));
4087 }
4088
4089 // Return value matching the channel order specified by the format
4090 if (format.order == tcu::TextureFormat::BGR || format.order == tcu::TextureFormat::BGRA)
4091 return threshold.swizzle(2, 1, 0, 3);
4092 else
4093 return threshold;
4094 }
4095
getCompressedFormatThreshold(const tcu::CompressedTexFormat & format)4096 tcu::Vec4 getCompressedFormatThreshold(const tcu::CompressedTexFormat &format)
4097 {
4098 bool isSigned(false);
4099 tcu::IVec4 bitDepth(0);
4100
4101 switch (format)
4102 {
4103 case tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_R11:
4104 bitDepth = {7, 0, 0, 0};
4105 isSigned = true;
4106 break;
4107
4108 case tcu::COMPRESSEDTEXFORMAT_EAC_R11:
4109 bitDepth = {8, 0, 0, 0};
4110 break;
4111
4112 case tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11:
4113 bitDepth = {7, 7, 0, 0};
4114 isSigned = true;
4115 break;
4116
4117 case tcu::COMPRESSEDTEXFORMAT_EAC_RG11:
4118 bitDepth = {8, 8, 0, 0};
4119 break;
4120
4121 case tcu::COMPRESSEDTEXFORMAT_ETC1_RGB8:
4122 case tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8:
4123 case tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8:
4124 bitDepth = {8, 8, 8, 0};
4125 break;
4126
4127 case tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
4128 case tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
4129 bitDepth = {8, 8, 8, 1};
4130 break;
4131
4132 case tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8:
4133 case tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8:
4134 case tcu::COMPRESSEDTEXFORMAT_ASTC_4x4_RGBA:
4135 case tcu::COMPRESSEDTEXFORMAT_ASTC_5x4_RGBA:
4136 case tcu::COMPRESSEDTEXFORMAT_ASTC_5x5_RGBA:
4137 case tcu::COMPRESSEDTEXFORMAT_ASTC_6x5_RGBA:
4138 case tcu::COMPRESSEDTEXFORMAT_ASTC_6x6_RGBA:
4139 case tcu::COMPRESSEDTEXFORMAT_ASTC_8x5_RGBA:
4140 case tcu::COMPRESSEDTEXFORMAT_ASTC_8x6_RGBA:
4141 case tcu::COMPRESSEDTEXFORMAT_ASTC_8x8_RGBA:
4142 case tcu::COMPRESSEDTEXFORMAT_ASTC_10x5_RGBA:
4143 case tcu::COMPRESSEDTEXFORMAT_ASTC_10x6_RGBA:
4144 case tcu::COMPRESSEDTEXFORMAT_ASTC_10x8_RGBA:
4145 case tcu::COMPRESSEDTEXFORMAT_ASTC_10x10_RGBA:
4146 case tcu::COMPRESSEDTEXFORMAT_ASTC_12x10_RGBA:
4147 case tcu::COMPRESSEDTEXFORMAT_ASTC_12x12_RGBA:
4148 case tcu::COMPRESSEDTEXFORMAT_ASTC_4x4_SRGB8_ALPHA8:
4149 case tcu::COMPRESSEDTEXFORMAT_ASTC_5x4_SRGB8_ALPHA8:
4150 case tcu::COMPRESSEDTEXFORMAT_ASTC_5x5_SRGB8_ALPHA8:
4151 case tcu::COMPRESSEDTEXFORMAT_ASTC_6x5_SRGB8_ALPHA8:
4152 case tcu::COMPRESSEDTEXFORMAT_ASTC_6x6_SRGB8_ALPHA8:
4153 case tcu::COMPRESSEDTEXFORMAT_ASTC_8x5_SRGB8_ALPHA8:
4154 case tcu::COMPRESSEDTEXFORMAT_ASTC_8x6_SRGB8_ALPHA8:
4155 case tcu::COMPRESSEDTEXFORMAT_ASTC_8x8_SRGB8_ALPHA8:
4156 case tcu::COMPRESSEDTEXFORMAT_ASTC_10x5_SRGB8_ALPHA8:
4157 case tcu::COMPRESSEDTEXFORMAT_ASTC_10x6_SRGB8_ALPHA8:
4158 case tcu::COMPRESSEDTEXFORMAT_ASTC_10x8_SRGB8_ALPHA8:
4159 case tcu::COMPRESSEDTEXFORMAT_ASTC_10x10_SRGB8_ALPHA8:
4160 case tcu::COMPRESSEDTEXFORMAT_ASTC_12x10_SRGB8_ALPHA8:
4161 case tcu::COMPRESSEDTEXFORMAT_ASTC_12x12_SRGB8_ALPHA8:
4162 bitDepth = {8, 8, 8, 8};
4163 break;
4164
4165 case tcu::COMPRESSEDTEXFORMAT_BC1_RGB_UNORM_BLOCK:
4166 case tcu::COMPRESSEDTEXFORMAT_BC1_RGB_SRGB_BLOCK:
4167 case tcu::COMPRESSEDTEXFORMAT_BC2_UNORM_BLOCK:
4168 case tcu::COMPRESSEDTEXFORMAT_BC2_SRGB_BLOCK:
4169 case tcu::COMPRESSEDTEXFORMAT_BC3_UNORM_BLOCK:
4170 case tcu::COMPRESSEDTEXFORMAT_BC3_SRGB_BLOCK:
4171 bitDepth = {5, 6, 5, 0};
4172 break;
4173
4174 case tcu::COMPRESSEDTEXFORMAT_BC1_RGBA_UNORM_BLOCK:
4175 case tcu::COMPRESSEDTEXFORMAT_BC1_RGBA_SRGB_BLOCK:
4176 case tcu::COMPRESSEDTEXFORMAT_BC7_UNORM_BLOCK:
4177 case tcu::COMPRESSEDTEXFORMAT_BC7_SRGB_BLOCK:
4178 bitDepth = {5, 5, 5, 1};
4179 break;
4180
4181 case tcu::COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK:
4182 bitDepth = {7, 0, 0, 0};
4183 isSigned = true;
4184 break;
4185
4186 case tcu::COMPRESSEDTEXFORMAT_BC4_UNORM_BLOCK:
4187 bitDepth = {8, 0, 0, 0};
4188 break;
4189
4190 case tcu::COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK:
4191 bitDepth = {7, 7, 0, 0};
4192 isSigned = true;
4193 break;
4194
4195 case tcu::COMPRESSEDTEXFORMAT_BC5_UNORM_BLOCK:
4196 bitDepth = {8, 8, 0, 0};
4197 break;
4198
4199 case tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK:
4200 return tcu::Vec4(0.01f);
4201 case tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK:
4202 return tcu::Vec4(0.005f);
4203
4204 default:
4205 DE_ASSERT(false);
4206 }
4207
4208 const float range = isSigned ? 1.0f - (-1.0f) : 1.0f - 0.0f;
4209 tcu::Vec4 v;
4210 for (int i = 0; i < 4; ++i)
4211 {
4212 if (bitDepth[i] == 0)
4213 v[i] = 1.0f;
4214 else
4215 v[i] = range / static_cast<float>((1 << bitDepth[i]) - 1);
4216 }
4217 return v;
4218 }
4219
checkNonNearestFilteredResult(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & clampedExpected,const tcu::ConstPixelBufferAccess & unclampedExpected,const tcu::TextureFormat & srcFormat)4220 bool BlittingImages::checkNonNearestFilteredResult(const tcu::ConstPixelBufferAccess &result,
4221 const tcu::ConstPixelBufferAccess &clampedExpected,
4222 const tcu::ConstPixelBufferAccess &unclampedExpected,
4223 const tcu::TextureFormat &srcFormat)
4224 {
4225 tcu::TestLog &log(m_context.getTestContext().getLog());
4226 const tcu::TextureFormat dstFormat = result.getFormat();
4227 const tcu::TextureChannelClass dstChannelClass = tcu::getTextureChannelClass(dstFormat.type);
4228 const tcu::TextureChannelClass srcChannelClass = tcu::getTextureChannelClass(srcFormat.type);
4229 bool isOk = false;
4230
4231 log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
4232
4233 // if either of srcImage or dstImage stores values as a signed/unsigned integer,
4234 // the other must also store values a signed/unsigned integer
4235 // e.g. blit unorm to uscaled is not allowed as uscaled formats store data as integers
4236 // despite the fact that both formats are sampled as floats
4237 bool dstImageIsIntClass = dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
4238 dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
4239 bool srcImageIsIntClass = srcChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
4240 srcChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
4241 if (dstImageIsIntClass != srcImageIsIntClass)
4242 {
4243 log << tcu::TestLog::EndSection;
4244 return false;
4245 }
4246
4247 if (isFloatFormat(dstFormat))
4248 {
4249 const bool srcIsSRGB = tcu::isSRGB(srcFormat);
4250 const tcu::Vec4 srcMaxDiff = getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2.0f : 1.0f);
4251 const tcu::Vec4 dstMaxDiff = getFormatThreshold(dstFormat);
4252 const tcu::Vec4 threshold =
4253 (srcMaxDiff + dstMaxDiff) * ((m_params.filter == VK_FILTER_CUBIC_EXT) ? 1.5f : 1.0f);
4254
4255 isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold,
4256 tcu::COMPARE_LOG_RESULT);
4257 log << tcu::TestLog::EndSection;
4258
4259 if (!isOk)
4260 {
4261 log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
4262 isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold,
4263 tcu::COMPARE_LOG_RESULT);
4264 log << tcu::TestLog::EndSection;
4265 }
4266 }
4267 else
4268 {
4269 tcu::UVec4 threshold;
4270 // Calculate threshold depending on channel width of destination format.
4271 const tcu::IVec4 dstBitDepth = tcu::getTextureFormatBitDepth(dstFormat);
4272 const tcu::IVec4 srcBitDepth = tcu::getTextureFormatBitDepth(srcFormat);
4273 for (uint32_t i = 0; i < 4; ++i)
4274 {
4275 DE_ASSERT(dstBitDepth[i] < std::numeric_limits<uint64_t>::digits);
4276 DE_ASSERT(srcBitDepth[i] < std::numeric_limits<uint64_t>::digits);
4277 uint64_t threshold64 =
4278 1 + de::max(((UINT64_C(1) << dstBitDepth[i]) - 1) /
4279 de::clamp((UINT64_C(1) << srcBitDepth[i]) - 1, UINT64_C(1), UINT64_C(256)),
4280 UINT64_C(1));
4281 DE_ASSERT(threshold64 <= std::numeric_limits<uint32_t>::max());
4282 threshold[i] = static_cast<uint32_t>(threshold64);
4283 }
4284
4285 isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold,
4286 tcu::COMPARE_LOG_RESULT);
4287 log << tcu::TestLog::EndSection;
4288
4289 if (!isOk)
4290 {
4291 log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
4292 isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold,
4293 tcu::COMPARE_LOG_RESULT);
4294 log << tcu::TestLog::EndSection;
4295 }
4296 }
4297
4298 return isOk;
4299 }
4300
checkCompressedNonNearestFilteredResult(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & clampedReference,const tcu::ConstPixelBufferAccess & unclampedReference,const tcu::CompressedTexFormat format)4301 bool BlittingImages::checkCompressedNonNearestFilteredResult(const tcu::ConstPixelBufferAccess &result,
4302 const tcu::ConstPixelBufferAccess &clampedReference,
4303 const tcu::ConstPixelBufferAccess &unclampedReference,
4304 const tcu::CompressedTexFormat format)
4305 {
4306 tcu::TestLog &log = m_context.getTestContext().getLog();
4307 const tcu::TextureFormat dstFormat = result.getFormat();
4308
4309 // there are rare cases wher one or few pixels have slightly bigger error
4310 // in one of channels this accepted error allows those casses to pass
4311 const tcu::Vec4 acceptedError(0.06f);
4312
4313 const tcu::Vec4 srcMaxDiff = getCompressedFormatThreshold(format);
4314 const tcu::Vec4 dstMaxDiff =
4315 m_destinationCompressedTexture ?
4316 getCompressedFormatThreshold(m_destinationCompressedTexture->getCompressedTexture().getFormat()) :
4317 getFormatThreshold(dstFormat);
4318 const tcu::Vec4 threshold =
4319 (srcMaxDiff + dstMaxDiff) * ((m_params.filter == VK_FILTER_CUBIC_EXT) ? 1.5f : 1.0f) + acceptedError;
4320
4321 bool filteredResultVerification(false);
4322 tcu::Vec4 filteredResultMinValue(-6e6);
4323 tcu::Vec4 filteredResultMaxValue(6e6);
4324 tcu::TextureLevel filteredResult;
4325 tcu::TextureLevel filteredClampedReference;
4326 tcu::TextureLevel filteredUnclampedReference;
4327
4328 if (((format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK) ||
4329 (format == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK)))
4330 {
4331 if ((dstFormat.type == tcu::TextureFormat::FLOAT) || (dstFormat.type == tcu::TextureFormat::HALF_FLOAT))
4332 {
4333 // for compressed formats we are using random data and for bc6h formats
4334 // this will give us also large color values; when we are bliting to
4335 // a format that accepts large values we can end up with large diferences
4336 // betwean filtered result and reference; to avoid that we need to remove
4337 // values that are to big from verification
4338 filteredResultVerification = true;
4339 filteredResultMinValue = tcu::Vec4(-10.0f);
4340 filteredResultMaxValue = tcu::Vec4(10.0f);
4341 }
4342 else if (dstFormat.type == tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV)
4343 {
4344 // we need to clamp some formats to <0;1> range as it has
4345 // small precision for big numbers compared to reference
4346 filteredResultVerification = true;
4347 filteredResultMinValue = tcu::Vec4(0.0f);
4348 filteredResultMaxValue = tcu::Vec4(1.0f);
4349 }
4350 // else don't use filtered verification
4351 }
4352
4353 if (filteredResultVerification)
4354 {
4355 filteredResult.setStorage(dstFormat, result.getWidth(), result.getHeight(), result.getDepth());
4356 tcu::PixelBufferAccess filteredResultAcccess(filteredResult.getAccess());
4357
4358 filteredClampedReference.setStorage(dstFormat, result.getWidth(), result.getHeight(), result.getDepth());
4359 tcu::PixelBufferAccess filteredClampedAcccess(filteredClampedReference.getAccess());
4360
4361 filteredUnclampedReference.setStorage(dstFormat, result.getWidth(), result.getHeight(), result.getDepth());
4362 tcu::PixelBufferAccess filteredUnclampedResultAcccess(filteredUnclampedReference.getAccess());
4363
4364 for (int32_t z = 0; z < result.getDepth(); z++)
4365 for (int32_t y = 0; y < result.getHeight(); y++)
4366 for (int32_t x = 0; x < result.getWidth(); x++)
4367 {
4368 tcu::Vec4 resultTexel = result.getPixel(x, y, z);
4369 tcu::Vec4 clampedReferenceTexel = clampedReference.getPixel(x, y, z);
4370 tcu::Vec4 unclampedReferenceTexel = unclampedReference.getPixel(x, y, z);
4371
4372 resultTexel = tcu::clamp(resultTexel, filteredResultMinValue, filteredResultMaxValue);
4373 clampedReferenceTexel =
4374 tcu::clamp(clampedReferenceTexel, filteredResultMinValue, filteredResultMaxValue);
4375 unclampedReferenceTexel =
4376 tcu::clamp(unclampedReferenceTexel, filteredResultMinValue, filteredResultMaxValue);
4377
4378 filteredResultAcccess.setPixel(resultTexel, x, y, z);
4379 filteredClampedAcccess.setPixel(clampedReferenceTexel, x, y, z);
4380 filteredUnclampedResultAcccess.setPixel(unclampedReferenceTexel, x, y, z);
4381 }
4382 }
4383
4384 const tcu::ConstPixelBufferAccess clampedRef =
4385 filteredResultVerification ? filteredClampedReference.getAccess() : clampedReference;
4386 const tcu::ConstPixelBufferAccess res = filteredResultVerification ? filteredResult.getAccess() : result;
4387
4388 log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
4389 bool isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedRef, res, threshold,
4390 tcu::COMPARE_LOG_RESULT);
4391 log << tcu::TestLog::EndSection;
4392
4393 if (!isOk)
4394 {
4395 const tcu::ConstPixelBufferAccess unclampedRef =
4396 filteredResultVerification ? filteredUnclampedReference.getAccess() : unclampedReference;
4397
4398 log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
4399 isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedRef, res, threshold,
4400 tcu::COMPARE_LOG_RESULT);
4401 log << tcu::TestLog::EndSection;
4402 }
4403
4404 return isOk;
4405 }
4406
4407 //! Utility to encapsulate coordinate computation and loops.
4408 struct CompareEachPixelInEachRegion
4409 {
4410 protected:
getUsedZRangevkt::api::__anonbd1d8d730111::CompareEachPixelInEachRegion4411 void getUsedZRange(int32_t range[2], const ImageParms &imgParams, const VkImageSubresourceLayers &layers,
4412 const VkOffset3D offsets[2]) const
4413 {
4414 if (imgParams.imageType == VK_IMAGE_TYPE_3D)
4415 {
4416 range[0] = offsets[0].z;
4417 range[1] = offsets[1].z;
4418 }
4419 else if (imgParams.imageType == VK_IMAGE_TYPE_2D)
4420 {
4421 range[0] = static_cast<int32_t>(layers.baseArrayLayer);
4422 range[1] =
4423 static_cast<int32_t>(layers.baseArrayLayer + ((layers.layerCount == VK_REMAINING_ARRAY_LAYERS) ?
4424 (getArraySize(imgParams) - layers.baseArrayLayer) :
4425 layers.layerCount));
4426 }
4427 else
4428 {
4429 range[0] = 0;
4430 range[1] = 1;
4431 }
4432 }
4433
4434 public:
~CompareEachPixelInEachRegionvkt::api::__anonbd1d8d730111::CompareEachPixelInEachRegion4435 virtual ~CompareEachPixelInEachRegion(void)
4436 {
4437 }
4438 virtual bool compare(const void *pUserData, const int x, const int y, const int z,
4439 const tcu::Vec3 &srcNormCoord) const = 0;
4440
forEachvkt::api::__anonbd1d8d730111::CompareEachPixelInEachRegion4441 bool forEach(const void *pUserData, const TestParams ¶ms, const int sourceWidth, const int sourceHeight,
4442 const int sourceDepth, const tcu::PixelBufferAccess &errorMask) const
4443 {
4444 bool compareOk = true;
4445
4446 for (std::vector<CopyRegion>::const_iterator regionIter = params.regions.begin();
4447 regionIter != params.regions.end(); ++regionIter)
4448 {
4449 const VkImageBlit &blit = regionIter->imageBlit;
4450
4451 int32_t srcZ[2];
4452 int32_t dstZ[2];
4453
4454 getUsedZRange(srcZ, params.src.image, blit.srcSubresource, blit.srcOffsets);
4455 getUsedZRange(dstZ, params.dst.image, blit.dstSubresource, blit.dstOffsets);
4456
4457 const int xStart = deMin32(blit.dstOffsets[0].x, blit.dstOffsets[1].x);
4458 const int yStart = deMin32(blit.dstOffsets[0].y, blit.dstOffsets[1].y);
4459 const int zStart = deMin32(dstZ[0], dstZ[1]);
4460 const int xEnd = deMax32(blit.dstOffsets[0].x, blit.dstOffsets[1].x);
4461 const int yEnd = deMax32(blit.dstOffsets[0].y, blit.dstOffsets[1].y);
4462 const int zEnd = deMax32(dstZ[0], dstZ[1]);
4463 const float xScale = static_cast<float>(blit.srcOffsets[1].x - blit.srcOffsets[0].x) /
4464 static_cast<float>(blit.dstOffsets[1].x - blit.dstOffsets[0].x);
4465 const float yScale = static_cast<float>(blit.srcOffsets[1].y - blit.srcOffsets[0].y) /
4466 static_cast<float>(blit.dstOffsets[1].y - blit.dstOffsets[0].y);
4467 const float zScale = static_cast<float>(srcZ[1] - srcZ[0]) / static_cast<float>(dstZ[1] - dstZ[0]);
4468 const float srcInvW = 1.0f / static_cast<float>(sourceWidth);
4469 const float srcInvH = 1.0f / static_cast<float>(sourceHeight);
4470 const float srcInvD = 1.0f / static_cast<float>(sourceDepth);
4471
4472 for (int z = zStart; z < zEnd; z++)
4473 for (int y = yStart; y < yEnd; y++)
4474 for (int x = xStart; x < xEnd; x++)
4475 {
4476 const tcu::Vec3 srcNormCoord(
4477 (xScale * (static_cast<float>(x - blit.dstOffsets[0].x) + 0.5f) +
4478 static_cast<float>(blit.srcOffsets[0].x)) *
4479 srcInvW,
4480 (yScale * (static_cast<float>(y - blit.dstOffsets[0].y) + 0.5f) +
4481 static_cast<float>(blit.srcOffsets[0].y)) *
4482 srcInvH,
4483 (zScale * (static_cast<float>(z - dstZ[0]) + 0.5f) + static_cast<float>(srcZ[0])) *
4484 srcInvD);
4485
4486 if (!compare(pUserData, x, y, z, srcNormCoord))
4487 {
4488 errorMask.setPixel(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y, z);
4489 compareOk = false;
4490 }
4491 }
4492 }
4493 return compareOk;
4494 }
4495 };
4496
getFloatOrFixedPointFormatThreshold(const tcu::TextureFormat & format)4497 tcu::Vec4 getFloatOrFixedPointFormatThreshold(const tcu::TextureFormat &format)
4498 {
4499 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
4500 const tcu::IVec4 bitDepth = tcu::getTextureFormatBitDepth(format);
4501
4502 if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
4503 {
4504 return getFormatThreshold(format);
4505 }
4506 else if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
4507 channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT)
4508 {
4509 const bool isSigned = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT);
4510 const float range = isSigned ? 1.0f - (-1.0f) : 1.0f - 0.0f;
4511
4512 tcu::Vec4 v;
4513 for (int i = 0; i < 4; ++i)
4514 {
4515 if (bitDepth[i] == 0)
4516 v[i] = 1.0f;
4517 else
4518 v[i] = range / static_cast<float>((1 << bitDepth[i]) - 1);
4519 }
4520 return v;
4521 }
4522 else
4523 {
4524 DE_ASSERT(0);
4525 return tcu::Vec4();
4526 }
4527 }
4528
floatNearestBlitCompare(const tcu::ConstPixelBufferAccess & source,const tcu::ConstPixelBufferAccess & result,const tcu::Vec4 & sourceThreshold,const tcu::Vec4 & resultThreshold,const tcu::PixelBufferAccess & errorMask,const TestParams & params)4529 bool floatNearestBlitCompare(const tcu::ConstPixelBufferAccess &source, const tcu::ConstPixelBufferAccess &result,
4530 const tcu::Vec4 &sourceThreshold, const tcu::Vec4 &resultThreshold,
4531 const tcu::PixelBufferAccess &errorMask, const TestParams ¶ms)
4532 {
4533 const tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
4534 tcu::Sampler::NEAREST, tcu::Sampler::NEAREST, 0.0f, true, tcu::Sampler::COMPAREMODE_NONE,
4535 0, tcu::Vec4(0.0f), true);
4536 const tcu::IVec4 dstBitDepth(tcu::getTextureFormatBitDepth(result.getFormat()));
4537 tcu::LookupPrecision precision;
4538
4539 precision.colorMask = tcu::notEqual(dstBitDepth, tcu::IVec4(0));
4540 precision.colorThreshold = tcu::max(sourceThreshold, resultThreshold);
4541
4542 const struct Capture
4543 {
4544 const tcu::ConstPixelBufferAccess &source;
4545 const tcu::ConstPixelBufferAccess &result;
4546 const tcu::Sampler &sampler;
4547 const tcu::LookupPrecision &precision;
4548 const TestParams ¶ms;
4549 const bool isSRGB;
4550 } capture = {source, result, sampler, precision, params, tcu::isSRGB(result.getFormat())};
4551
4552 const struct Loop : CompareEachPixelInEachRegion
4553 {
4554 Loop(void)
4555 {
4556 }
4557
4558 bool compare(const void *pUserData, const int x, const int y, const int z, const tcu::Vec3 &srcNormCoord) const
4559 {
4560 const Capture &c = *static_cast<const Capture *>(pUserData);
4561 const tcu::TexLookupScaleMode lookupScaleDontCare = tcu::TEX_LOOKUP_SCALE_MINIFY;
4562 tcu::Vec4 dstColor = c.result.getPixel(x, y, z);
4563
4564 // TexLookupVerifier performs a conversion to linear space, so we have to as well
4565 if (c.isSRGB)
4566 dstColor = tcu::sRGBToLinear(dstColor);
4567
4568 return tcu::isLevel3DLookupResultValid(c.source, c.sampler, lookupScaleDontCare, c.precision, srcNormCoord,
4569 dstColor);
4570 }
4571 } loop;
4572
4573 return loop.forEach(&capture, params, source.getWidth(), source.getHeight(), source.getDepth(), errorMask);
4574 }
4575
intNearestBlitCompare(const tcu::ConstPixelBufferAccess & source,const tcu::ConstPixelBufferAccess & result,const tcu::PixelBufferAccess & errorMask,const TestParams & params)4576 bool intNearestBlitCompare(const tcu::ConstPixelBufferAccess &source, const tcu::ConstPixelBufferAccess &result,
4577 const tcu::PixelBufferAccess &errorMask, const TestParams ¶ms)
4578 {
4579 const tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
4580 tcu::Sampler::NEAREST, tcu::Sampler::NEAREST, 0.0f, true, tcu::Sampler::COMPAREMODE_NONE,
4581 0, tcu::Vec4(0.0f), true);
4582 tcu::IntLookupPrecision precision;
4583
4584 {
4585 const tcu::IVec4 srcBitDepth = tcu::getTextureFormatBitDepth(source.getFormat());
4586 const tcu::IVec4 dstBitDepth = tcu::getTextureFormatBitDepth(result.getFormat());
4587
4588 for (uint32_t i = 0; i < 4; ++i)
4589 {
4590 precision.colorThreshold[i] = de::max(de::max(srcBitDepth[i] / 8, dstBitDepth[i] / 8), 1);
4591 precision.colorMask[i] = dstBitDepth[i] != 0;
4592 }
4593 }
4594
4595 // Prepare a source image with a matching (converted) pixel format. Ideally, we would've used a wrapper that
4596 // does the conversion on the fly without wasting memory, but this approach is more straightforward.
4597 tcu::TextureLevel convertedSourceTexture(result.getFormat(), source.getWidth(), source.getHeight(),
4598 source.getDepth());
4599 const tcu::PixelBufferAccess convertedSource = convertedSourceTexture.getAccess();
4600
4601 for (int z = 0; z < source.getDepth(); ++z)
4602 for (int y = 0; y < source.getHeight(); ++y)
4603 for (int x = 0; x < source.getWidth(); ++x)
4604 convertedSource.setPixel(source.getPixelInt(x, y, z), x, y,
4605 z); // will be clamped to max. representable value
4606
4607 const struct Capture
4608 {
4609 const tcu::ConstPixelBufferAccess &source;
4610 const tcu::ConstPixelBufferAccess &result;
4611 const tcu::Sampler &sampler;
4612 const tcu::IntLookupPrecision &precision;
4613 } capture = {convertedSource, result, sampler, precision};
4614
4615 const struct Loop : CompareEachPixelInEachRegion
4616 {
4617 Loop(void)
4618 {
4619 }
4620
4621 bool compare(const void *pUserData, const int x, const int y, const int z, const tcu::Vec3 &srcNormCoord) const
4622 {
4623 const Capture &c = *static_cast<const Capture *>(pUserData);
4624 const tcu::TexLookupScaleMode lookupScaleDontCare = tcu::TEX_LOOKUP_SCALE_MINIFY;
4625 const tcu::IVec4 dstColor = c.result.getPixelInt(x, y, z);
4626
4627 return tcu::isLevel3DLookupResultValid(c.source, c.sampler, lookupScaleDontCare, c.precision, srcNormCoord,
4628 dstColor);
4629 }
4630 } loop;
4631
4632 return loop.forEach(&capture, params, source.getWidth(), source.getHeight(), source.getDepth(), errorMask);
4633 }
4634
checkNearestFilteredResult(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & source)4635 bool BlittingImages::checkNearestFilteredResult(const tcu::ConstPixelBufferAccess &result,
4636 const tcu::ConstPixelBufferAccess &source)
4637 {
4638 tcu::TestLog &log(m_context.getTestContext().getLog());
4639 const tcu::TextureFormat dstFormat = result.getFormat();
4640 const tcu::TextureFormat srcFormat = source.getFormat();
4641 const tcu::TextureChannelClass dstChannelClass = tcu::getTextureChannelClass(dstFormat.type);
4642 const tcu::TextureChannelClass srcChannelClass = tcu::getTextureChannelClass(srcFormat.type);
4643
4644 tcu::TextureLevel errorMaskStorage(tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8),
4645 result.getWidth(), result.getHeight(), result.getDepth());
4646 tcu::PixelBufferAccess errorMask = errorMaskStorage.getAccess();
4647 tcu::Vec4 pixelBias(0.0f, 0.0f, 0.0f, 0.0f);
4648 tcu::Vec4 pixelScale(1.0f, 1.0f, 1.0f, 1.0f);
4649 bool ok = false;
4650
4651 tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
4652
4653 // if either of srcImage or dstImage stores values as a signed/unsigned integer,
4654 // the other must also store values a signed/unsigned integer
4655 // e.g. blit unorm to uscaled is not allowed as uscaled formats store data as integers
4656 // despite the fact that both formats are sampled as floats
4657 bool dstImageIsIntClass = dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
4658 dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
4659 bool srcImageIsIntClass = srcChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
4660 srcChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
4661 if (dstImageIsIntClass != srcImageIsIntClass)
4662 return false;
4663
4664 if (dstImageIsIntClass)
4665 {
4666 ok = intNearestBlitCompare(source, result, errorMask, m_params);
4667 }
4668 else
4669 {
4670 const tcu::Vec4 srcMaxDiff = getFloatOrFixedPointFormatThreshold(source.getFormat());
4671 const tcu::Vec4 dstMaxDiff = getFloatOrFixedPointFormatThreshold(result.getFormat());
4672 ok = floatNearestBlitCompare(source, result, srcMaxDiff, dstMaxDiff, errorMask, m_params);
4673 }
4674
4675 if (result.getFormat() != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
4676 tcu::computePixelScaleBias(result, pixelScale, pixelBias);
4677
4678 if (!ok)
4679 {
4680 log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
4681 << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
4682 << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask) << tcu::TestLog::EndImageSet;
4683 }
4684 else
4685 {
4686 log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
4687 << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias) << tcu::TestLog::EndImageSet;
4688 }
4689
4690 return ok;
4691 }
4692
checkCompressedNearestFilteredResult(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & source,const tcu::CompressedTexFormat format)4693 bool BlittingImages::checkCompressedNearestFilteredResult(const tcu::ConstPixelBufferAccess &result,
4694 const tcu::ConstPixelBufferAccess &source,
4695 const tcu::CompressedTexFormat format)
4696 {
4697 tcu::TestLog &log(m_context.getTestContext().getLog());
4698 tcu::TextureFormat errorMaskFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8);
4699 tcu::TextureLevel errorMaskStorage(errorMaskFormat, result.getWidth(), result.getHeight(), result.getDepth());
4700 tcu::PixelBufferAccess errorMask(errorMaskStorage.getAccess());
4701 tcu::Vec4 pixelBias(0.0f, 0.0f, 0.0f, 0.0f);
4702 tcu::Vec4 pixelScale(1.0f, 1.0f, 1.0f, 1.0f);
4703 const tcu::TextureFormat &resultFormat(result.getFormat());
4704 VkFormat nativeResultFormat(mapTextureFormat(resultFormat));
4705
4706 // there are rare cases wher one or few pixels have slightly bigger error
4707 // in one of channels this accepted error allows those casses to pass
4708 const tcu::Vec4 acceptedError(0.04f);
4709 const tcu::Vec4 srcMaxDiff(acceptedError + getCompressedFormatThreshold(format));
4710 const tcu::Vec4 dstMaxDiff(
4711 acceptedError +
4712 (m_destinationCompressedTexture ?
4713 getCompressedFormatThreshold(m_destinationCompressedTexture->getCompressedTexture().getFormat()) :
4714 getFloatOrFixedPointFormatThreshold(resultFormat)));
4715
4716 tcu::TextureLevel clampedSourceLevel;
4717 bool clampSource(false);
4718 tcu::Vec4 clampSourceMinValue(-1.0f);
4719 tcu::Vec4 clampSourceMaxValue(1.0f);
4720 tcu::TextureLevel clampedResultLevel;
4721 bool clampResult(false);
4722
4723 tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
4724
4725 if (resultFormat != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
4726 tcu::computePixelScaleBias(result, pixelScale, pixelBias);
4727
4728 log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
4729 << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias);
4730
4731 // for compressed formats source buffer access is not actual compressed format
4732 // but equivalent uncompressed format that is some cases needs additional
4733 // modifications so that sampling it will produce valid reference
4734 if ((format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK) ||
4735 (format == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK))
4736 {
4737 if (resultFormat.type == tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV)
4738 {
4739 // for compressed formats we are using random data and for some formats it
4740 // can be outside of <-1;1> range - for cases where result is not a float
4741 // format we need to clamp source to <-1;1> range as this will be done on
4742 // the device but not in software sampler in framework
4743 clampSource = true;
4744 // for this format we also need to clamp the result as precision of
4745 // this format is smaller then precision of calculations in framework;
4746 // the biger color valus are the bigger errors can be
4747 clampResult = true;
4748
4749 if (format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK)
4750 clampSourceMinValue = tcu::Vec4(0.0f);
4751 }
4752 else if ((resultFormat.type != tcu::TextureFormat::FLOAT) &&
4753 (resultFormat.type != tcu::TextureFormat::HALF_FLOAT))
4754 {
4755 // clamp source for all non float formats
4756 clampSource = true;
4757 }
4758 }
4759
4760 if (isUnormFormat(nativeResultFormat) || isUfloatFormat(nativeResultFormat))
4761 {
4762 // when tested compressed format is signed but the result format
4763 // is unsigned we need to clamp source to <0; x> so that proper
4764 // reference is calculated
4765 if ((format == tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_R11) ||
4766 (format == tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11) ||
4767 (format == tcu::COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK) ||
4768 (format == tcu::COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK) ||
4769 (format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK))
4770 {
4771 clampSource = true;
4772 clampSourceMinValue = tcu::Vec4(0.0f);
4773 }
4774 }
4775
4776 if (clampSource || clampResult)
4777 {
4778 if (clampSource)
4779 {
4780 clampedSourceLevel.setStorage(source.getFormat(), source.getWidth(), source.getHeight(), source.getDepth());
4781 tcu::PixelBufferAccess clampedSourceAcccess(clampedSourceLevel.getAccess());
4782
4783 for (int32_t z = 0; z < source.getDepth(); z++)
4784 for (int32_t y = 0; y < source.getHeight(); y++)
4785 for (int32_t x = 0; x < source.getWidth(); x++)
4786 {
4787 tcu::Vec4 texel = source.getPixel(x, y, z);
4788 texel = tcu::clamp(texel, tcu::Vec4(clampSourceMinValue), tcu::Vec4(clampSourceMaxValue));
4789 clampedSourceAcccess.setPixel(texel, x, y, z);
4790 }
4791 }
4792
4793 if (clampResult)
4794 {
4795 clampedResultLevel.setStorage(result.getFormat(), result.getWidth(), result.getHeight(), result.getDepth());
4796 tcu::PixelBufferAccess clampedResultAcccess(clampedResultLevel.getAccess());
4797
4798 for (int32_t z = 0; z < result.getDepth(); z++)
4799 for (int32_t y = 0; y < result.getHeight(); y++)
4800 for (int32_t x = 0; x < result.getWidth(); x++)
4801 {
4802 tcu::Vec4 texel = result.getPixel(x, y, z);
4803 texel = tcu::clamp(texel, tcu::Vec4(-1.0f), tcu::Vec4(1.0f));
4804 clampedResultAcccess.setPixel(texel, x, y, z);
4805 }
4806 }
4807 }
4808
4809 const tcu::ConstPixelBufferAccess src = clampSource ? clampedSourceLevel.getAccess() : source;
4810 const tcu::ConstPixelBufferAccess res = clampResult ? clampedResultLevel.getAccess() : result;
4811
4812 if (floatNearestBlitCompare(src, res, srcMaxDiff, dstMaxDiff, errorMask, m_params))
4813 {
4814 log << tcu::TestLog::EndImageSet;
4815 return true;
4816 }
4817
4818 log << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask) << tcu::TestLog::EndImageSet;
4819 return false;
4820 }
4821
checkTestResult(tcu::ConstPixelBufferAccess result)4822 tcu::TestStatus BlittingImages::checkTestResult(tcu::ConstPixelBufferAccess result)
4823 {
4824 DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR ||
4825 m_params.filter == VK_FILTER_CUBIC_EXT);
4826 const std::string failMessage("Result image is incorrect");
4827
4828 if (m_params.filter != VK_FILTER_NEAREST)
4829 {
4830 if (tcu::isCombinedDepthStencilType(result.getFormat().type))
4831 {
4832 if (tcu::hasDepthComponent(result.getFormat().order))
4833 {
4834 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_DEPTH;
4835 const tcu::ConstPixelBufferAccess depthResult = tcu::getEffectiveDepthStencilAccess(result, mode);
4836 const tcu::ConstPixelBufferAccess clampedExpected =
4837 tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
4838 const tcu::ConstPixelBufferAccess unclampedExpected =
4839 tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode);
4840 const tcu::TextureFormat sourceFormat =
4841 tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode);
4842
4843 if (!checkNonNearestFilteredResult(depthResult, clampedExpected, unclampedExpected, sourceFormat))
4844 return tcu::TestStatus::fail(failMessage);
4845 }
4846
4847 if (tcu::hasStencilComponent(result.getFormat().order))
4848 {
4849 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_STENCIL;
4850 const tcu::ConstPixelBufferAccess stencilResult = tcu::getEffectiveDepthStencilAccess(result, mode);
4851 const tcu::ConstPixelBufferAccess clampedExpected =
4852 tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
4853 const tcu::ConstPixelBufferAccess unclampedExpected =
4854 tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode);
4855 const tcu::TextureFormat sourceFormat =
4856 tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode);
4857
4858 if (!checkNonNearestFilteredResult(stencilResult, clampedExpected, unclampedExpected, sourceFormat))
4859 return tcu::TestStatus::fail(failMessage);
4860 }
4861 }
4862 else if (m_sourceCompressedTexture)
4863 {
4864 const tcu::CompressedTexture &compressedLevel = m_sourceCompressedTexture->getCompressedTexture();
4865 if (!checkCompressedNonNearestFilteredResult(result, m_expectedTextureLevel[0]->getAccess(),
4866 m_unclampedExpectedTextureLevel->getAccess(),
4867 compressedLevel.getFormat()))
4868 return tcu::TestStatus::fail(failMessage);
4869 }
4870 else
4871 {
4872 const tcu::TextureFormat sourceFormat = mapVkFormat(m_params.src.image.format);
4873 if (!checkNonNearestFilteredResult(result, m_expectedTextureLevel[0]->getAccess(),
4874 m_unclampedExpectedTextureLevel->getAccess(), sourceFormat))
4875 return tcu::TestStatus::fail(failMessage);
4876 }
4877 }
4878 else // NEAREST filtering
4879 {
4880 if (tcu::isCombinedDepthStencilType(result.getFormat().type))
4881 {
4882 if (tcu::hasDepthComponent(result.getFormat().order))
4883 {
4884 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_DEPTH;
4885 const tcu::ConstPixelBufferAccess depthResult = tcu::getEffectiveDepthStencilAccess(result, mode);
4886 const tcu::ConstPixelBufferAccess depthSource =
4887 tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode);
4888
4889 if (!checkNearestFilteredResult(depthResult, depthSource))
4890 return tcu::TestStatus::fail(failMessage);
4891 }
4892
4893 if (tcu::hasStencilComponent(result.getFormat().order))
4894 {
4895 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_STENCIL;
4896 const tcu::ConstPixelBufferAccess stencilResult = tcu::getEffectiveDepthStencilAccess(result, mode);
4897 const tcu::ConstPixelBufferAccess stencilSource =
4898 tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode);
4899
4900 if (!checkNearestFilteredResult(stencilResult, stencilSource))
4901 return tcu::TestStatus::fail(failMessage);
4902 }
4903 }
4904 else if (m_sourceCompressedTexture)
4905 {
4906 const tcu::CompressedTexture &compressedLevel = m_sourceCompressedTexture->getCompressedTexture();
4907 const tcu::PixelBufferAccess &decompressedLevel = m_sourceCompressedTexture->getDecompressedAccess();
4908
4909 if (!checkCompressedNearestFilteredResult(result, decompressedLevel, compressedLevel.getFormat()))
4910 return tcu::TestStatus::fail(failMessage);
4911 }
4912 else if (!checkNearestFilteredResult(result, m_sourceTextureLevel->getAccess()))
4913 return tcu::TestStatus::fail(failMessage);
4914 }
4915
4916 return tcu::TestStatus::pass("Pass");
4917 }
4918
linearToSRGBIfNeeded(const tcu::TextureFormat & format,const tcu::Vec4 & color)4919 tcu::Vec4 linearToSRGBIfNeeded(const tcu::TextureFormat &format, const tcu::Vec4 &color)
4920 {
4921 return isSRGB(format) ? linearToSRGB(color) : color;
4922 }
4923
scaleFromWholeSrcBuffer(const tcu::PixelBufferAccess & dst,const tcu::ConstPixelBufferAccess & src,const VkOffset3D regionOffset,const VkOffset3D regionExtent,tcu::Sampler::FilterMode filter,const MirrorMode mirrorMode=0u)4924 void scaleFromWholeSrcBuffer(const tcu::PixelBufferAccess &dst, const tcu::ConstPixelBufferAccess &src,
4925 const VkOffset3D regionOffset, const VkOffset3D regionExtent,
4926 tcu::Sampler::FilterMode filter, const MirrorMode mirrorMode = 0u)
4927 {
4928 DE_ASSERT(filter == tcu::Sampler::LINEAR || filter == tcu::Sampler::CUBIC);
4929
4930 tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, filter,
4931 filter, 0.0f, false, tcu::Sampler::COMPAREMODE_NONE, 0, tcu::Vec4(0.0f), true);
4932
4933 float sX = (float)regionExtent.x / (float)dst.getWidth();
4934 float sY = (float)regionExtent.y / (float)dst.getHeight();
4935 float sZ = (float)regionExtent.z / (float)dst.getDepth();
4936
4937 for (int z = 0; z < dst.getDepth(); z++)
4938 for (int y = 0; y < dst.getHeight(); y++)
4939 for (int x = 0; x < dst.getWidth(); x++)
4940 {
4941 float srcX = ((mirrorMode & MIRROR_MODE_X) != 0) ?
4942 (float)regionExtent.x + (float)regionOffset.x - ((float)x + 0.5f) * sX :
4943 (float)regionOffset.x + ((float)x + 0.5f) * sX;
4944 float srcY = ((mirrorMode & MIRROR_MODE_Y) != 0) ?
4945 (float)regionExtent.y + (float)regionOffset.y - ((float)y + 0.5f) * sY :
4946 (float)regionOffset.y + ((float)y + 0.5f) * sY;
4947 float srcZ = ((mirrorMode & MIRROR_MODE_Z) != 0) ?
4948 (float)regionExtent.z + (float)regionOffset.z - ((float)z + 0.5f) * sZ :
4949 (float)regionOffset.z + ((float)z + 0.5f) * sZ;
4950 if (dst.getDepth() > 1)
4951 dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample3D(sampler, filter, srcX, srcY, srcZ)),
4952 x, y, z);
4953 else
4954 dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample2D(sampler, filter, srcX, srcY, 0)), x,
4955 y);
4956 }
4957 }
4958
blit(const tcu::PixelBufferAccess & dst,const tcu::ConstPixelBufferAccess & src,const tcu::Sampler::FilterMode filter,const MirrorMode mirrorMode)4959 void blit(const tcu::PixelBufferAccess &dst, const tcu::ConstPixelBufferAccess &src,
4960 const tcu::Sampler::FilterMode filter, const MirrorMode mirrorMode)
4961 {
4962 DE_ASSERT(filter == tcu::Sampler::NEAREST || filter == tcu::Sampler::LINEAR || filter == tcu::Sampler::CUBIC);
4963
4964 tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, filter,
4965 filter, 0.0f, false, tcu::Sampler::COMPAREMODE_NONE, 0, tcu::Vec4(0.0f), true);
4966
4967 const float sX = (float)src.getWidth() / (float)dst.getWidth();
4968 const float sY = (float)src.getHeight() / (float)dst.getHeight();
4969 const float sZ = (float)src.getDepth() / (float)dst.getDepth();
4970
4971 const int xOffset = (mirrorMode & MIRROR_MODE_X) ? dst.getWidth() - 1 : 0;
4972 const int yOffset = (mirrorMode & MIRROR_MODE_Y) ? dst.getHeight() - 1 : 0;
4973 const int zOffset = (mirrorMode & MIRROR_MODE_Z) ? dst.getDepth() - 1 : 0;
4974
4975 const int xScale = (mirrorMode & MIRROR_MODE_X) ? -1 : 1;
4976 const int yScale = (mirrorMode & MIRROR_MODE_Y) ? -1 : 1;
4977 const int zScale = (mirrorMode & MIRROR_MODE_Z) ? -1 : 1;
4978
4979 for (int z = 0; z < dst.getDepth(); ++z)
4980 for (int y = 0; y < dst.getHeight(); ++y)
4981 for (int x = 0; x < dst.getWidth(); ++x)
4982 {
4983 dst.setPixel(
4984 linearToSRGBIfNeeded(dst.getFormat(), src.sample3D(sampler, filter, ((float)x + 0.5f) * sX,
4985 ((float)y + 0.5f) * sY, ((float)z + 0.5f) * sZ)),
4986 x * xScale + xOffset, y * yScale + yOffset, z * zScale + zOffset);
4987 }
4988 }
4989
flipCoordinates(CopyRegion & region,const MirrorMode mirrorMode)4990 void flipCoordinates(CopyRegion ®ion, const MirrorMode mirrorMode)
4991 {
4992 const VkOffset3D dstOffset0 = region.imageBlit.dstOffsets[0];
4993 const VkOffset3D dstOffset1 = region.imageBlit.dstOffsets[1];
4994 const VkOffset3D srcOffset0 = region.imageBlit.srcOffsets[0];
4995 const VkOffset3D srcOffset1 = region.imageBlit.srcOffsets[1];
4996
4997 if (mirrorMode != 0u)
4998 {
4999 //sourceRegion
5000 region.imageBlit.srcOffsets[0].x = std::min(srcOffset0.x, srcOffset1.x);
5001 region.imageBlit.srcOffsets[0].y = std::min(srcOffset0.y, srcOffset1.y);
5002 region.imageBlit.srcOffsets[0].z = std::min(srcOffset0.z, srcOffset1.z);
5003
5004 region.imageBlit.srcOffsets[1].x = std::max(srcOffset0.x, srcOffset1.x);
5005 region.imageBlit.srcOffsets[1].y = std::max(srcOffset0.y, srcOffset1.y);
5006 region.imageBlit.srcOffsets[1].z = std::max(srcOffset0.z, srcOffset1.z);
5007
5008 //destinationRegion
5009 region.imageBlit.dstOffsets[0].x = std::min(dstOffset0.x, dstOffset1.x);
5010 region.imageBlit.dstOffsets[0].y = std::min(dstOffset0.y, dstOffset1.y);
5011 region.imageBlit.dstOffsets[0].z = std::min(dstOffset0.z, dstOffset1.z);
5012
5013 region.imageBlit.dstOffsets[1].x = std::max(dstOffset0.x, dstOffset1.x);
5014 region.imageBlit.dstOffsets[1].y = std::max(dstOffset0.y, dstOffset1.y);
5015 region.imageBlit.dstOffsets[1].z = std::max(dstOffset0.z, dstOffset1.z);
5016 }
5017 }
5018
5019 // Mirror X, Y and Z as required by the offset values in the 3 axes.
getMirrorMode(const VkOffset3D from,const VkOffset3D to)5020 MirrorMode getMirrorMode(const VkOffset3D from, const VkOffset3D to)
5021 {
5022 MirrorMode mode = 0u;
5023
5024 if (from.x > to.x)
5025 mode |= MIRROR_MODE_X;
5026
5027 if (from.y > to.y)
5028 mode |= MIRROR_MODE_Y;
5029
5030 if (from.z > to.z)
5031 mode |= MIRROR_MODE_Z;
5032
5033 return mode;
5034 }
5035
5036 // 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)5037 MirrorMode getMirrorMode(const VkOffset3D s1, const VkOffset3D s2, const VkOffset3D d1, const VkOffset3D d2)
5038 {
5039 static const MirrorModeBits kBits[] = {MIRROR_MODE_X, MIRROR_MODE_Y, MIRROR_MODE_Z};
5040
5041 const MirrorMode source = getMirrorMode(s1, s2);
5042 const MirrorMode destination = getMirrorMode(d1, d2);
5043
5044 MirrorMode mode = 0u;
5045
5046 for (int i = 0; i < DE_LENGTH_OF_ARRAY(kBits); ++i)
5047 {
5048 const MirrorModeBits bit = kBits[i];
5049 if ((source & bit) != (destination & bit))
5050 mode |= bit;
5051 }
5052
5053 return mode;
5054 }
5055
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,uint32_t mipLevel)5056 void BlittingImages::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst,
5057 CopyRegion region, uint32_t mipLevel)
5058 {
5059 DE_UNREF(mipLevel);
5060
5061 const MirrorMode mirrorMode = getMirrorMode(region.imageBlit.srcOffsets[0], region.imageBlit.srcOffsets[1],
5062 region.imageBlit.dstOffsets[0], region.imageBlit.dstOffsets[1]);
5063
5064 flipCoordinates(region, mirrorMode);
5065
5066 const VkOffset3D srcOffset = region.imageBlit.srcOffsets[0];
5067 const VkOffset3D srcExtent = {
5068 region.imageBlit.srcOffsets[1].x - srcOffset.x,
5069 region.imageBlit.srcOffsets[1].y - srcOffset.y,
5070 region.imageBlit.srcOffsets[1].z - srcOffset.z,
5071 };
5072 const VkOffset3D dstOffset = region.imageBlit.dstOffsets[0];
5073 const VkOffset3D dstExtent = {
5074 region.imageBlit.dstOffsets[1].x - dstOffset.x,
5075 region.imageBlit.dstOffsets[1].y - dstOffset.y,
5076 region.imageBlit.dstOffsets[1].z - dstOffset.z,
5077 };
5078
5079 tcu::Sampler::FilterMode filter;
5080 switch (m_params.filter)
5081 {
5082 case VK_FILTER_LINEAR:
5083 filter = tcu::Sampler::LINEAR;
5084 break;
5085 case VK_FILTER_CUBIC_EXT:
5086 filter = tcu::Sampler::CUBIC;
5087 break;
5088 case VK_FILTER_NEAREST:
5089 default:
5090 filter = tcu::Sampler::NEAREST;
5091 break;
5092 }
5093
5094 if (tcu::isCombinedDepthStencilType(src.getFormat().type))
5095 {
5096 DE_ASSERT(src.getFormat() == dst.getFormat());
5097
5098 // Scale depth.
5099 if (tcu::hasDepthComponent(src.getFormat().order))
5100 {
5101 const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(
5102 tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, srcExtent.x, srcExtent.y, srcExtent.z),
5103 tcu::Sampler::MODE_DEPTH);
5104 const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(
5105 tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z),
5106 tcu::Sampler::MODE_DEPTH);
5107 tcu::scale(dstSubRegion, srcSubRegion, filter);
5108
5109 if (filter != tcu::Sampler::NEAREST)
5110 {
5111 const tcu::ConstPixelBufferAccess depthSrc =
5112 getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH);
5113 const tcu::PixelBufferAccess unclampedSubRegion = getEffectiveDepthStencilAccess(
5114 tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y,
5115 dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z),
5116 tcu::Sampler::MODE_DEPTH);
5117 scaleFromWholeSrcBuffer(unclampedSubRegion, depthSrc, srcOffset, srcExtent, filter, mirrorMode);
5118 }
5119 }
5120
5121 // Scale stencil.
5122 if (tcu::hasStencilComponent(src.getFormat().order))
5123 {
5124 const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(
5125 tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, srcExtent.x, srcExtent.y, srcExtent.z),
5126 tcu::Sampler::MODE_STENCIL);
5127 const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(
5128 tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z),
5129 tcu::Sampler::MODE_STENCIL);
5130 blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
5131
5132 if (filter != tcu::Sampler::NEAREST)
5133 {
5134 const tcu::ConstPixelBufferAccess stencilSrc =
5135 getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL);
5136 const tcu::PixelBufferAccess unclampedSubRegion = getEffectiveDepthStencilAccess(
5137 tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y,
5138 dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z),
5139 tcu::Sampler::MODE_STENCIL);
5140 scaleFromWholeSrcBuffer(unclampedSubRegion, stencilSrc, srcOffset, srcExtent, filter, mirrorMode);
5141 }
5142 }
5143 }
5144 else
5145 {
5146 const tcu::ConstPixelBufferAccess srcSubRegion =
5147 tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, srcExtent.x, srcExtent.y, srcExtent.z);
5148 const tcu::PixelBufferAccess dstSubRegion =
5149 tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z);
5150 blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
5151
5152 if (filter != tcu::Sampler::NEAREST)
5153 {
5154 const tcu::PixelBufferAccess unclampedSubRegion =
5155 tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstOffset.z,
5156 dstExtent.x, dstExtent.y, dstExtent.z);
5157 scaleFromWholeSrcBuffer(unclampedSubRegion, src, srcOffset, srcExtent, filter, mirrorMode);
5158 }
5159 }
5160 }
5161
generateExpectedResult(void)5162 void BlittingImages::generateExpectedResult(void)
5163 {
5164 const tcu::ConstPixelBufferAccess src = m_sourceCompressedTexture ?
5165 m_sourceCompressedTexture->getDecompressedAccess() :
5166 m_sourceTextureLevel->getAccess();
5167 const tcu::ConstPixelBufferAccess dst = m_destinationCompressedTexture ?
5168 m_destinationCompressedTexture->getDecompressedAccess() :
5169 m_destinationTextureLevel->getAccess();
5170
5171 m_expectedTextureLevel[0] = de::MovePtr<tcu::TextureLevel>(
5172 new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
5173 tcu::copy(m_expectedTextureLevel[0]->getAccess(), dst);
5174
5175 if (m_params.filter != VK_FILTER_NEAREST)
5176 {
5177 m_unclampedExpectedTextureLevel = de::MovePtr<tcu::TextureLevel>(
5178 new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
5179 tcu::copy(m_unclampedExpectedTextureLevel->getAccess(), dst);
5180 }
5181
5182 for (uint32_t i = 0; i < m_params.regions.size(); i++)
5183 {
5184 CopyRegion region = m_params.regions[i];
5185 copyRegionToTextureLevel(src, m_expectedTextureLevel[0]->getAccess(), region);
5186 }
5187 }
5188
uploadCompressedImage(const VkImage & image,const ImageParms & parms)5189 void BlittingImages::uploadCompressedImage(const VkImage &image, const ImageParms &parms)
5190 {
5191 DE_ASSERT(m_sourceCompressedTexture);
5192
5193 const InstanceInterface &vki = m_context.getInstanceInterface();
5194 const DeviceInterface &vk = m_context.getDeviceInterface();
5195 const VkPhysicalDevice vkPhysDevice = m_context.getPhysicalDevice();
5196 const VkDevice vkDevice = m_device;
5197 Allocator &memAlloc = *m_allocator;
5198 Move<VkBuffer> buffer;
5199 const uint32_t bufferSize = m_sourceCompressedTexture->getCompressedTexture().getDataSize();
5200 de::MovePtr<Allocation> bufferAlloc;
5201 const uint32_t arraySize = getArraySize(parms);
5202 const VkExtent3D imageExtent{
5203 parms.extent.width,
5204 (parms.imageType != VK_IMAGE_TYPE_1D) ? parms.extent.height : 1u,
5205 (parms.imageType == VK_IMAGE_TYPE_3D) ? parms.extent.depth : 1u,
5206 };
5207
5208 // Create source buffer
5209 {
5210 const VkBufferCreateInfo bufferParams{
5211 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
5212 DE_NULL, // const void* pNext;
5213 0u, // VkBufferCreateFlags flags;
5214 bufferSize, // VkDeviceSize size;
5215 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage;
5216 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
5217 0u, // uint32_t queueFamilyIndexCount;
5218 (const uint32_t *)DE_NULL, // const uint32_t* pQueueFamilyIndices;
5219 };
5220
5221 buffer = createBuffer(vk, vkDevice, &bufferParams);
5222 bufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *buffer, MemoryRequirement::HostVisible, memAlloc,
5223 m_params.allocationKind);
5224 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
5225 }
5226
5227 // Barriers for copying buffer to image
5228 const VkBufferMemoryBarrier preBufferBarrier{
5229 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
5230 DE_NULL, // const void* pNext;
5231 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask;
5232 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
5233 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
5234 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
5235 *buffer, // VkBuffer buffer;
5236 0u, // VkDeviceSize offset;
5237 bufferSize // VkDeviceSize size;
5238 };
5239
5240 const VkImageMemoryBarrier preImageBarrier{VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
5241 DE_NULL, // const void* pNext;
5242 0u, // VkAccessFlags srcAccessMask;
5243 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
5244 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
5245 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
5246 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
5247 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
5248 image, // VkImage image;
5249 {
5250 // VkImageSubresourceRange subresourceRange;
5251 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect;
5252 0u, // uint32_t baseMipLevel;
5253 1u, // uint32_t mipLevels;
5254 0u, // uint32_t baseArraySlice;
5255 arraySize, // uint32_t arraySize;
5256 }};
5257
5258 const VkImageMemoryBarrier postImageBarrier{VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
5259 DE_NULL, // const void* pNext;
5260 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
5261 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
5262 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
5263 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
5264 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
5265 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
5266 image, // VkImage image;
5267 {
5268 // VkImageSubresourceRange subresourceRange;
5269 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect;
5270 0u, // uint32_t baseMipLevel;
5271 1u, // uint32_t mipLevels;
5272 0u, // uint32_t baseArraySlice;
5273 arraySize, // uint32_t arraySize;
5274 }};
5275
5276 const VkExtent3D copyExtent{imageExtent.width, imageExtent.height, imageExtent.depth};
5277
5278 VkBufferImageCopy copyRegion{
5279 0u, // VkDeviceSize bufferOffset;
5280 copyExtent.width, // uint32_t bufferRowLength;
5281 copyExtent.height, // uint32_t bufferImageHeight;
5282 {
5283 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect;
5284 0u, // uint32_t mipLevel;
5285 0u, // uint32_t baseArrayLayer;
5286 arraySize, // uint32_t layerCount;
5287 }, // VkImageSubresourceLayers imageSubresource;
5288 {0, 0, 0}, // VkOffset3D imageOffset;
5289 copyExtent // VkExtent3D imageExtent;
5290 };
5291
5292 // Write buffer data
5293 deMemcpy(bufferAlloc->getHostPtr(), m_sourceCompressedTexture->getCompressedTexture().getData(), bufferSize);
5294 flushAlloc(vk, vkDevice, *bufferAlloc);
5295
5296 // Copy buffer to image
5297 beginCommandBuffer(vk, *m_universalCmdBuffer);
5298 vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
5299 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 1, &preBufferBarrier, 1,
5300 &preImageBarrier);
5301 vk.cmdCopyBufferToImage(*m_universalCmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u,
5302 ©Region);
5303 vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
5304 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
5305 (const VkBufferMemoryBarrier *)DE_NULL, 1, &postImageBarrier);
5306 endCommandBuffer(vk, *m_universalCmdBuffer);
5307
5308 submitCommandsAndWait(vk, vkDevice, m_universalQueue, *m_universalCmdBuffer);
5309 m_context.resetCommandPoolForVKSC(vkDevice, *m_universalCmdPool);
5310 }
5311
5312 class BlitImageTestCase : public vkt::TestCase
5313 {
5314 public:
BlitImageTestCase(tcu::TestContext & testCtx,const std::string & name,const TestParams params)5315 BlitImageTestCase(tcu::TestContext &testCtx, const std::string &name, const TestParams params)
5316 : vkt::TestCase(testCtx, name)
5317 , m_params(params)
5318 {
5319 }
5320
createInstance(Context & context) const5321 virtual TestInstance *createInstance(Context &context) const
5322 {
5323 return new BlittingImages(context, m_params);
5324 }
5325
checkSupport(Context & context) const5326 virtual void checkSupport(Context &context) const
5327 {
5328
5329 #ifndef CTS_USES_VULKANSC
5330 if (m_params.src.image.format == VK_FORMAT_A8_UNORM_KHR ||
5331 m_params.dst.image.format == VK_FORMAT_A8_UNORM_KHR ||
5332 m_params.src.image.format == VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR ||
5333 m_params.dst.image.format == VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR)
5334 context.requireDeviceFunctionality("VK_KHR_maintenance5");
5335 #endif // CTS_USES_VULKANSC
5336
5337 VkImageFormatProperties properties;
5338 if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
5339 context.getPhysicalDevice(), m_params.src.image.format, m_params.src.image.imageType,
5340 m_params.src.image.tiling, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
5341 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
5342 {
5343 TCU_THROW(NotSupportedError, "Source format not supported");
5344 }
5345 if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
5346 context.getPhysicalDevice(), m_params.dst.image.format, m_params.dst.image.imageType,
5347 m_params.dst.image.tiling, VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0,
5348 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
5349 {
5350 TCU_THROW(NotSupportedError, "Destination format not supported");
5351 }
5352
5353 checkExtensionSupport(context, m_params.extensionFlags);
5354
5355 VkFormatProperties srcFormatProperties;
5356 context.getInstanceInterface().getPhysicalDeviceFormatProperties(
5357 context.getPhysicalDevice(), m_params.src.image.format, &srcFormatProperties);
5358 VkFormatFeatureFlags srcFormatFeatures = m_params.src.image.tiling == VK_IMAGE_TILING_LINEAR ?
5359 srcFormatProperties.linearTilingFeatures :
5360 srcFormatProperties.optimalTilingFeatures;
5361 if (!(srcFormatFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT))
5362 {
5363 TCU_THROW(NotSupportedError, "Format feature blit source not supported");
5364 }
5365
5366 VkFormatProperties dstFormatProperties;
5367 context.getInstanceInterface().getPhysicalDeviceFormatProperties(
5368 context.getPhysicalDevice(), m_params.dst.image.format, &dstFormatProperties);
5369 VkFormatFeatureFlags dstFormatFeatures = m_params.dst.image.tiling == VK_IMAGE_TILING_LINEAR ?
5370 dstFormatProperties.linearTilingFeatures :
5371 dstFormatProperties.optimalTilingFeatures;
5372 if (!(dstFormatFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT))
5373 {
5374 TCU_THROW(NotSupportedError, "Format feature blit destination not supported");
5375 }
5376
5377 if (m_params.filter == VK_FILTER_LINEAR &&
5378 !(srcFormatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
5379 {
5380 TCU_THROW(NotSupportedError, "Source format feature sampled image filter linear not supported");
5381 }
5382
5383 if (m_params.filter == VK_FILTER_CUBIC_EXT)
5384 {
5385 context.requireDeviceFunctionality("VK_EXT_filter_cubic");
5386
5387 if (!(srcFormatFeatures & 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 checkExtensionSupport(context, m_params.extensionFlags);
5394 }
5395
5396 private:
5397 TestParams m_params;
5398 };
5399
5400 class BlittingMipmaps : public CopiesAndBlittingTestInstance
5401 {
5402 public:
5403 BlittingMipmaps(Context &context, TestParams params);
5404 virtual tcu::TestStatus iterate(void);
5405
5406 protected:
5407 virtual tcu::TestStatus checkTestResult(tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess());
5408 virtual void copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst,
5409 CopyRegion region, uint32_t mipLevel = 0u);
5410 virtual void generateExpectedResult(void);
5411
5412 private:
5413 bool checkNonNearestFilteredResult(void);
5414 bool checkNearestFilteredResult(void);
5415
5416 Move<VkImage> m_source;
5417 de::MovePtr<Allocation> m_sourceImageAlloc;
5418 Move<VkImage> m_destination;
5419 de::MovePtr<Allocation> m_destinationImageAlloc;
5420 std::vector<de::SharedPtr<Allocation>> m_sparseAllocations;
5421 Move<VkSemaphore> m_sparseSemaphore;
5422
5423 de::MovePtr<tcu::TextureLevel> m_unclampedExpectedTextureLevel[16];
5424 };
5425
BlittingMipmaps(Context & context,TestParams params)5426 BlittingMipmaps::BlittingMipmaps(Context &context, TestParams params) : CopiesAndBlittingTestInstance(context, params)
5427 {
5428 const InstanceInterface &vki = context.getInstanceInterface();
5429 const DeviceInterface &vk = context.getDeviceInterface();
5430 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
5431 const VkDevice vkDevice = m_device;
5432 Allocator &memAlloc = context.getDefaultAllocator();
5433
5434 // Create source image
5435 {
5436 VkImageCreateInfo sourceImageParams = {
5437 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
5438 DE_NULL, // const void* pNext;
5439 getCreateFlags(m_params.src.image), // VkImageCreateFlags flags;
5440 m_params.src.image.imageType, // VkImageType imageType;
5441 m_params.src.image.format, // VkFormat format;
5442 getExtent3D(m_params.src.image), // VkExtent3D extent;
5443 1u, // uint32_t mipLevels;
5444 getArraySize(m_params.src.image), // uint32_t arraySize;
5445 VK_SAMPLE_COUNT_1_BIT, // uint32_t samples;
5446 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
5447 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
5448 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
5449 0u, // uint32_t queueFamilyIndexCount;
5450 (const uint32_t *)DE_NULL, // const uint32_t* pQueueFamilyIndices;
5451 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
5452 };
5453
5454 #ifndef CTS_USES_VULKANSC
5455 if (!params.useSparseBinding)
5456 {
5457 #endif
5458 m_source = createImage(vk, m_device, &sourceImageParams);
5459 m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, m_device, *m_source, MemoryRequirement::Any,
5460 *m_allocator, m_params.allocationKind, 0u);
5461 VK_CHECK(vk.bindImageMemory(m_device, *m_source, m_sourceImageAlloc->getMemory(),
5462 m_sourceImageAlloc->getOffset()));
5463 #ifndef CTS_USES_VULKANSC
5464 }
5465 else
5466 {
5467 sourceImageParams.flags |=
5468 (vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT | vk::VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT);
5469 vk::VkImageFormatProperties imageFormatProperties;
5470 if (vki.getPhysicalDeviceImageFormatProperties(vkPhysDevice, sourceImageParams.format,
5471 sourceImageParams.imageType, sourceImageParams.tiling,
5472 sourceImageParams.usage, sourceImageParams.flags,
5473 &imageFormatProperties) == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
5474 {
5475 TCU_THROW(NotSupportedError, "Image format not supported");
5476 }
5477 m_source = createImage(
5478 vk, m_device,
5479 &sourceImageParams); //de::MovePtr<SparseImage>(new SparseImage(vk, vk, vkPhysDevice, vki, sourceImageParams, m_queue, *m_allocator, mapVkFormat(sourceImageParams.format)));
5480 m_sparseSemaphore = createSemaphore(vk, m_device);
5481 allocateAndBindSparseImage(vk, m_device, vkPhysDevice, vki, sourceImageParams, m_sparseSemaphore.get(),
5482 context.getSparseQueue(), *m_allocator, m_sparseAllocations,
5483 mapVkFormat(sourceImageParams.format), m_source.get());
5484 }
5485 #endif
5486 }
5487
5488 // Create destination image
5489 {
5490 const VkImageCreateInfo destinationImageParams = {
5491 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
5492 DE_NULL, // const void* pNext;
5493 getCreateFlags(m_params.dst.image), // VkImageCreateFlags flags;
5494 m_params.dst.image.imageType, // VkImageType imageType;
5495 m_params.dst.image.format, // VkFormat format;
5496 getExtent3D(m_params.dst.image), // VkExtent3D extent;
5497 m_params.mipLevels, // uint32_t mipLevels;
5498 getArraySize(m_params.dst.image), // uint32_t arraySize;
5499 VK_SAMPLE_COUNT_1_BIT, // uint32_t samples;
5500 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
5501 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
5502 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
5503 0u, // uint32_t queueFamilyIndexCount;
5504 (const uint32_t *)DE_NULL, // const uint32_t* pQueueFamilyIndices;
5505 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
5506 };
5507
5508 m_destination = createImage(vk, vkDevice, &destinationImageParams);
5509 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any,
5510 memAlloc, m_params.allocationKind, 0u);
5511 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(),
5512 m_destinationImageAlloc->getOffset()));
5513 }
5514 }
5515
iterate(void)5516 tcu::TestStatus BlittingMipmaps::iterate(void)
5517 {
5518 const tcu::TextureFormat srcTcuFormat = mapVkFormat(m_params.src.image.format);
5519 const tcu::TextureFormat dstTcuFormat = mapVkFormat(m_params.dst.image.format);
5520 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(
5521 new tcu::TextureLevel(srcTcuFormat, m_params.src.image.extent.width, m_params.src.image.extent.height,
5522 m_params.src.image.extent.depth));
5523 generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height,
5524 m_params.src.image.extent.depth, m_params.src.image.fillMode);
5525 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(
5526 new tcu::TextureLevel(dstTcuFormat, (int)m_params.dst.image.extent.width, (int)m_params.dst.image.extent.height,
5527 (int)m_params.dst.image.extent.depth));
5528 generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width,
5529 m_params.dst.image.extent.height, m_params.dst.image.extent.depth, m_params.dst.image.fillMode);
5530 generateExpectedResult();
5531
5532 uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
5533
5534 uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, m_params.mipLevels);
5535
5536 const DeviceInterface &vk = m_context.getDeviceInterface();
5537 const VkDevice vkDevice = m_device;
5538
5539 std::vector<VkImageBlit> regions;
5540 std::vector<VkImageBlit2KHR> regions2KHR;
5541 for (uint32_t i = 0; i < m_params.regions.size(); i++)
5542 {
5543 if (!(m_params.extensionFlags & COPY_COMMANDS_2))
5544 {
5545 regions.push_back(m_params.regions[i].imageBlit);
5546 }
5547 else
5548 {
5549 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
5550 regions2KHR.push_back(convertvkImageBlitTovkImageBlit2KHR(m_params.regions[i].imageBlit));
5551 }
5552 }
5553
5554 // Copy source image to mip level 0 when generating mipmaps with multiple blit commands
5555 if (!m_params.singleCommand)
5556 uploadImage(m_sourceTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, 1u);
5557
5558 beginCommandBuffer(vk, *m_universalCmdBuffer);
5559
5560 // Blit all mip levels with a single blit command
5561 if (m_params.singleCommand)
5562 {
5563 {
5564 // Source image layout
5565 const VkImageMemoryBarrier srcImageBarrier = {
5566 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
5567 DE_NULL, // const void* pNext;
5568 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
5569 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
5570 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
5571 m_params.src.image.operationLayout, // VkImageLayout newLayout;
5572 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
5573 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
5574 m_source.get(), // VkImage image;
5575 {
5576 // VkImageSubresourceRange subresourceRange;
5577 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
5578 0u, // uint32_t baseMipLevel;
5579 1u, // uint32_t mipLevels;
5580 0u, // uint32_t baseArraySlice;
5581 getArraySize(m_params.src.image) // uint32_t arraySize;
5582 }};
5583
5584 // Destination image layout
5585 const VkImageMemoryBarrier dstImageBarrier = {
5586 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
5587 DE_NULL, // const void* pNext;
5588 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
5589 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
5590 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
5591 m_params.dst.image.operationLayout, // VkImageLayout newLayout;
5592 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
5593 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
5594 m_destination.get(), // VkImage image;
5595 {
5596 // VkImageSubresourceRange subresourceRange;
5597 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
5598 0u, // uint32_t baseMipLevel;
5599 m_params.mipLevels, // uint32_t mipLevels;
5600 0u, // uint32_t baseArraySlice;
5601 getArraySize(m_params.dst.image) // uint32_t arraySize;
5602 }};
5603
5604 vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
5605 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
5606 (const VkBufferMemoryBarrier *)DE_NULL, 1, &srcImageBarrier);
5607 vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
5608 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
5609 (const VkBufferMemoryBarrier *)DE_NULL, 1, &dstImageBarrier);
5610
5611 if (!(m_params.extensionFlags & COPY_COMMANDS_2))
5612 {
5613 vk.cmdBlitImage(*m_universalCmdBuffer, m_source.get(), m_params.src.image.operationLayout,
5614 m_destination.get(), m_params.dst.image.operationLayout,
5615 (uint32_t)m_params.regions.size(), ®ions[0], m_params.filter);
5616 }
5617 else
5618 {
5619 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
5620 const VkBlitImageInfo2KHR BlitImageInfo2KHR = {
5621 VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR, // VkStructureType sType;
5622 DE_NULL, // const void* pNext;
5623 m_source.get(), // VkImage srcImage;
5624 m_params.src.image.operationLayout, // VkImageLayout srcImageLayout;
5625 m_destination.get(), // VkImage dstImage;
5626 m_params.dst.image.operationLayout, // VkImageLayout dstImageLayout;
5627 (uint32_t)m_params.regions.size(), // uint32_t regionCount;
5628 ®ions2KHR[0], // const VkImageBlit2KHR* pRegions;
5629 m_params.filter // VkFilter filter;
5630 };
5631 vk.cmdBlitImage2(*m_universalCmdBuffer, &BlitImageInfo2KHR);
5632 }
5633 }
5634 }
5635 // Blit mip levels with multiple blit commands
5636 else
5637 {
5638 // Prepare all mip levels for reading
5639 {
5640 for (uint32_t barrierno = 0; barrierno < m_params.barrierCount; barrierno++)
5641 {
5642 VkImageMemoryBarrier preImageBarrier = {
5643 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
5644 DE_NULL, // const void* pNext;
5645 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
5646 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
5647 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
5648 m_params.src.image.operationLayout, // VkImageLayout newLayout;
5649 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
5650 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
5651 m_destination.get(), // VkImage image;
5652 {
5653 // VkImageSubresourceRange subresourceRange;
5654 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
5655 0u, // uint32_t baseMipLevel;
5656 VK_REMAINING_MIP_LEVELS, // uint32_t mipLevels;
5657 0u, // uint32_t baseArraySlice;
5658 getArraySize(m_params.src.image) // uint32_t arraySize;
5659 }};
5660
5661 if (getArraySize(m_params.src.image) == 1)
5662 {
5663 DE_ASSERT(barrierno < m_params.mipLevels);
5664 preImageBarrier.subresourceRange.baseMipLevel = barrierno;
5665 preImageBarrier.subresourceRange.levelCount =
5666 (barrierno + 1 < m_params.barrierCount) ? 1 : VK_REMAINING_MIP_LEVELS;
5667 }
5668 else
5669 {
5670 preImageBarrier.subresourceRange.baseArrayLayer = barrierno;
5671 preImageBarrier.subresourceRange.layerCount =
5672 (barrierno + 1 < m_params.barrierCount) ? 1 : VK_REMAINING_ARRAY_LAYERS;
5673 }
5674 vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
5675 VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0,
5676 (const VkMemoryBarrier *)DE_NULL, 0, (const VkBufferMemoryBarrier *)DE_NULL, 1,
5677 &preImageBarrier);
5678 }
5679 }
5680
5681 for (uint32_t regionNdx = 0u; regionNdx < (uint32_t)m_params.regions.size(); regionNdx++)
5682 {
5683 const uint32_t mipLevel = m_params.regions[regionNdx].imageBlit.dstSubresource.mipLevel;
5684
5685 // Prepare single mip level for writing
5686 const VkImageMemoryBarrier preImageBarrier = {
5687 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
5688 DE_NULL, // const void* pNext;
5689 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags srcAccessMask;
5690 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
5691 m_params.src.image.operationLayout, // VkImageLayout oldLayout;
5692 m_params.dst.image.operationLayout, // VkImageLayout newLayout;
5693 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
5694 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
5695 m_destination.get(), // VkImage image;
5696 {
5697 // VkImageSubresourceRange subresourceRange;
5698 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
5699 mipLevel, // uint32_t baseMipLevel;
5700 1u, // uint32_t mipLevels;
5701 0u, // uint32_t baseArraySlice;
5702 getArraySize(m_params.dst.image) // uint32_t arraySize;
5703 }};
5704
5705 // Prepare single mip level for reading
5706 const VkImageMemoryBarrier postImageBarrier = {
5707 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
5708 DE_NULL, // const void* pNext;
5709 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
5710 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
5711 m_params.dst.image.operationLayout, // VkImageLayout oldLayout;
5712 m_params.src.image.operationLayout, // VkImageLayout newLayout;
5713 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
5714 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
5715 m_destination.get(), // VkImage image;
5716 {
5717 // VkImageSubresourceRange subresourceRange;
5718 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
5719 mipLevel, // uint32_t baseMipLevel;
5720 1u, // uint32_t mipLevels;
5721 0u, // uint32_t baseArraySlice;
5722 getArraySize(m_params.src.image) // uint32_t arraySize;
5723 }};
5724
5725 vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
5726 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
5727 (const VkBufferMemoryBarrier *)DE_NULL, 1, &preImageBarrier);
5728
5729 if (!(m_params.extensionFlags & COPY_COMMANDS_2))
5730 {
5731 vk.cmdBlitImage(*m_universalCmdBuffer, m_destination.get(), m_params.src.image.operationLayout,
5732 m_destination.get(), m_params.dst.image.operationLayout, 1u, ®ions[regionNdx],
5733 m_params.filter);
5734 }
5735 else
5736 {
5737 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
5738 const VkBlitImageInfo2KHR BlitImageInfo2KHR = {
5739 VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR, // VkStructureType sType;
5740 DE_NULL, // const void* pNext;
5741 m_destination.get(), // VkImage srcImage;
5742 m_params.src.image.operationLayout, // VkImageLayout srcImageLayout;
5743 m_destination.get(), // VkImage dstImage;
5744 m_params.dst.image.operationLayout, // VkImageLayout dstImageLayout;
5745 1u, // uint32_t regionCount;
5746 ®ions2KHR[regionNdx], // const VkImageBlit2KHR* pRegions;
5747 m_params.filter // VkFilter filter;
5748 };
5749 vk.cmdBlitImage2(*m_universalCmdBuffer, &BlitImageInfo2KHR);
5750 }
5751
5752 vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
5753 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
5754 (const VkBufferMemoryBarrier *)DE_NULL, 1, &postImageBarrier);
5755 }
5756
5757 // Prepare all mip levels for writing
5758 {
5759 const VkImageMemoryBarrier postImageBarrier = {
5760 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
5761 DE_NULL, // const void* pNext;
5762 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags srcAccessMask;
5763 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
5764 m_params.src.image.operationLayout, // VkImageLayout oldLayout;
5765 m_params.dst.image.operationLayout, // VkImageLayout newLayout;
5766 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
5767 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
5768 m_destination.get(), // VkImage image;
5769 {
5770 // VkImageSubresourceRange subresourceRange;
5771 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
5772 0u, // uint32_t baseMipLevel;
5773 VK_REMAINING_MIP_LEVELS, // uint32_t mipLevels;
5774 0u, // uint32_t baseArraySlice;
5775 getArraySize(m_params.dst.image) // uint32_t arraySize;
5776 }};
5777
5778 vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
5779 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
5780 (const VkBufferMemoryBarrier *)DE_NULL, 1, &postImageBarrier);
5781 }
5782 }
5783
5784 endCommandBuffer(vk, *m_universalCmdBuffer);
5785 submitCommandsAndWait(vk, vkDevice, m_universalQueue, *m_universalCmdBuffer);
5786 m_context.resetCommandPoolForVKSC(vkDevice, *m_universalCmdPool);
5787
5788 return checkTestResult();
5789 }
5790
checkNonNearestFilteredResult(void)5791 bool BlittingMipmaps::checkNonNearestFilteredResult(void)
5792 {
5793 tcu::TestLog &log(m_context.getTestContext().getLog());
5794 bool allLevelsOk = true;
5795
5796 for (uint32_t mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
5797 {
5798 // Update reference results with previous results that have been verified.
5799 // This needs to be done such that accumulated errors don't exceed the fixed threshold.
5800 for (uint32_t i = 0; i < m_params.regions.size(); i++)
5801 {
5802 const CopyRegion region = m_params.regions[i];
5803 const uint32_t srcMipLevel = m_params.regions[i].imageBlit.srcSubresource.mipLevel;
5804 const uint32_t dstMipLevel = m_params.regions[i].imageBlit.dstSubresource.mipLevel;
5805 de::MovePtr<tcu::TextureLevel> prevResultLevel;
5806 tcu::ConstPixelBufferAccess src;
5807 if (srcMipLevel < mipLevelNdx)
5808 {
5809 // Generate expected result from rendered result that was previously verified
5810 prevResultLevel = readImage(*m_destination, m_params.dst.image, srcMipLevel);
5811 src = prevResultLevel->getAccess();
5812 }
5813 else
5814 {
5815 // Previous reference mipmaps might have changed, so recompute expected result
5816 src = m_expectedTextureLevel[srcMipLevel]->getAccess();
5817 }
5818 copyRegionToTextureLevel(src, m_expectedTextureLevel[dstMipLevel]->getAccess(), region, dstMipLevel);
5819 }
5820
5821 de::MovePtr<tcu::TextureLevel> resultLevel = readImage(*m_destination, m_params.dst.image, mipLevelNdx);
5822 const tcu::ConstPixelBufferAccess &resultAccess = resultLevel->getAccess();
5823
5824 const tcu::Sampler::DepthStencilMode mode =
5825 tcu::hasDepthComponent(resultAccess.getFormat().order) ? tcu::Sampler::MODE_DEPTH :
5826 tcu::hasStencilComponent(resultAccess.getFormat().order) ? tcu::Sampler::MODE_STENCIL :
5827 tcu::Sampler::MODE_LAST;
5828 const tcu::ConstPixelBufferAccess result = tcu::hasDepthComponent(resultAccess.getFormat().order) ?
5829 getEffectiveDepthStencilAccess(resultAccess, mode) :
5830 tcu::hasStencilComponent(resultAccess.getFormat().order) ?
5831 getEffectiveDepthStencilAccess(resultAccess, mode) :
5832 resultAccess;
5833 const tcu::ConstPixelBufferAccess clampedLevel =
5834 tcu::hasDepthComponent(resultAccess.getFormat().order) ?
5835 getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
5836 tcu::hasStencilComponent(resultAccess.getFormat().order) ?
5837 getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
5838 m_expectedTextureLevel[mipLevelNdx]->getAccess();
5839 const tcu::ConstPixelBufferAccess unclampedLevel =
5840 tcu::hasDepthComponent(resultAccess.getFormat().order) ?
5841 getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
5842 tcu::hasStencilComponent(resultAccess.getFormat().order) ?
5843 getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
5844 m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess();
5845 const tcu::TextureFormat srcFormat =
5846 tcu::hasDepthComponent(resultAccess.getFormat().order) ?
5847 tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode) :
5848 tcu::hasStencilComponent(resultAccess.getFormat().order) ?
5849 tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode) :
5850 mapVkFormat(m_params.src.image.format);
5851
5852 const tcu::TextureFormat dstFormat = result.getFormat();
5853 bool singleLevelOk = false;
5854 std::vector<CopyRegion> mipLevelRegions;
5855
5856 for (size_t regionNdx = 0u; regionNdx < m_params.regions.size(); regionNdx++)
5857 if (m_params.regions.at(regionNdx).imageBlit.dstSubresource.mipLevel == mipLevelNdx)
5858 mipLevelRegions.push_back(m_params.regions.at(regionNdx));
5859
5860 log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
5861
5862 if (isFloatFormat(dstFormat))
5863 {
5864 const bool srcIsSRGB = tcu::isSRGB(srcFormat);
5865 const tcu::Vec4 srcMaxDiff = getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2.0f : 1.0f);
5866 const tcu::Vec4 dstMaxDiff = getFormatThreshold(dstFormat);
5867 const tcu::Vec4 threshold =
5868 (srcMaxDiff + dstMaxDiff) * ((m_params.filter == VK_FILTER_CUBIC_EXT) ? 1.5f : 1.0f);
5869
5870 singleLevelOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedLevel, result,
5871 threshold, tcu::COMPARE_LOG_RESULT);
5872 log << tcu::TestLog::EndSection;
5873
5874 if (!singleLevelOk)
5875 {
5876 log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
5877 singleLevelOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedLevel, result,
5878 threshold, tcu::COMPARE_LOG_RESULT);
5879 log << tcu::TestLog::EndSection;
5880 }
5881 }
5882 else
5883 {
5884 tcu::UVec4 threshold;
5885 // Calculate threshold depending on channel width of destination format.
5886 const tcu::IVec4 dstBitDepth = tcu::getTextureFormatBitDepth(dstFormat);
5887 const tcu::IVec4 srcBitDepth = tcu::getTextureFormatBitDepth(srcFormat);
5888 for (uint32_t i = 0; i < 4; ++i)
5889 {
5890 DE_ASSERT(dstBitDepth[i] < std::numeric_limits<uint64_t>::digits);
5891 DE_ASSERT(srcBitDepth[i] < std::numeric_limits<uint64_t>::digits);
5892 uint64_t threshold64 =
5893 1 + de::max(((UINT64_C(1) << dstBitDepth[i]) - 1) /
5894 de::clamp((UINT64_C(1) << srcBitDepth[i]) - 1, UINT64_C(1), UINT64_C(256)),
5895 UINT64_C(1));
5896 DE_ASSERT(threshold64 <= std::numeric_limits<uint32_t>::max());
5897 threshold[i] = static_cast<uint32_t>(threshold64);
5898 }
5899
5900 singleLevelOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedLevel, result,
5901 threshold, tcu::COMPARE_LOG_RESULT);
5902 log << tcu::TestLog::EndSection;
5903
5904 if (!singleLevelOk)
5905 {
5906 log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
5907 singleLevelOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", unclampedLevel, result,
5908 threshold, tcu::COMPARE_LOG_RESULT);
5909 log << tcu::TestLog::EndSection;
5910 }
5911 }
5912 allLevelsOk &= singleLevelOk;
5913 }
5914
5915 return allLevelsOk;
5916 }
5917
checkNearestFilteredResult(void)5918 bool BlittingMipmaps::checkNearestFilteredResult(void)
5919 {
5920 bool allLevelsOk = true;
5921 tcu::TestLog &log(m_context.getTestContext().getLog());
5922
5923 for (uint32_t mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
5924 {
5925 de::MovePtr<tcu::TextureLevel> resultLevel = readImage(*m_destination, m_params.dst.image, mipLevelNdx);
5926 const tcu::ConstPixelBufferAccess &resultAccess = resultLevel->getAccess();
5927
5928 const tcu::Sampler::DepthStencilMode mode =
5929 tcu::hasDepthComponent(resultAccess.getFormat().order) ? tcu::Sampler::MODE_DEPTH :
5930 tcu::hasStencilComponent(resultAccess.getFormat().order) ? tcu::Sampler::MODE_STENCIL :
5931 tcu::Sampler::MODE_LAST;
5932 const tcu::ConstPixelBufferAccess result = tcu::hasDepthComponent(resultAccess.getFormat().order) ?
5933 getEffectiveDepthStencilAccess(resultAccess, mode) :
5934 tcu::hasStencilComponent(resultAccess.getFormat().order) ?
5935 getEffectiveDepthStencilAccess(resultAccess, mode) :
5936 resultAccess;
5937 const tcu::ConstPixelBufferAccess source =
5938 (m_params.singleCommand || mipLevelNdx == 0) ? // Read from source image
5939 tcu::hasDepthComponent(resultAccess.getFormat().order) ?
5940 tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode) :
5941 tcu::hasStencilComponent(resultAccess.getFormat().order) ?
5942 tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode) :
5943 m_sourceTextureLevel->getAccess()
5944 // Read from destination image
5945 :
5946 tcu::hasDepthComponent(resultAccess.getFormat().order) ?
5947 tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess(), mode) :
5948 tcu::hasStencilComponent(resultAccess.getFormat().order) ?
5949 tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess(), mode) :
5950 m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess();
5951 const tcu::TextureFormat dstFormat = result.getFormat();
5952 const tcu::TextureChannelClass dstChannelClass = tcu::getTextureChannelClass(dstFormat.type);
5953 bool singleLevelOk = false;
5954 std::vector<CopyRegion> mipLevelRegions;
5955
5956 for (size_t regionNdx = 0u; regionNdx < m_params.regions.size(); regionNdx++)
5957 if (m_params.regions.at(regionNdx).imageBlit.dstSubresource.mipLevel == mipLevelNdx)
5958 mipLevelRegions.push_back(m_params.regions.at(regionNdx));
5959
5960 // Use the calculated regions instead of the original ones.
5961 TestParams newParams = m_params;
5962 newParams.regions = mipLevelRegions;
5963
5964 tcu::TextureLevel errorMaskStorage(tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8),
5965 result.getWidth(), result.getHeight(), result.getDepth());
5966 tcu::PixelBufferAccess errorMask = errorMaskStorage.getAccess();
5967 tcu::Vec4 pixelBias(0.0f, 0.0f, 0.0f, 0.0f);
5968 tcu::Vec4 pixelScale(1.0f, 1.0f, 1.0f, 1.0f);
5969
5970 tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
5971
5972 if (dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
5973 dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
5974 {
5975 singleLevelOk = intNearestBlitCompare(source, result, errorMask, newParams);
5976 }
5977 else
5978 {
5979 const tcu::Vec4 srcMaxDiff = getFloatOrFixedPointFormatThreshold(source.getFormat());
5980 const tcu::Vec4 dstMaxDiff = getFloatOrFixedPointFormatThreshold(result.getFormat());
5981
5982 singleLevelOk = floatNearestBlitCompare(source, result, srcMaxDiff, dstMaxDiff, errorMask, newParams);
5983 }
5984
5985 if (dstFormat != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
5986 tcu::computePixelScaleBias(result, pixelScale, pixelBias);
5987
5988 if (!singleLevelOk)
5989 {
5990 log << tcu::TestLog::ImageSet("Compare", "Result comparsion, level " + de::toString(mipLevelNdx))
5991 << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
5992 << tcu::TestLog::Image("Reference", "Reference", source, pixelScale, pixelBias)
5993 << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask) << tcu::TestLog::EndImageSet;
5994 }
5995 else
5996 {
5997 log << tcu::TestLog::ImageSet("Compare", "Result comparsion, level " + de::toString(mipLevelNdx))
5998 << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias) << tcu::TestLog::EndImageSet;
5999 }
6000
6001 allLevelsOk &= singleLevelOk;
6002 }
6003
6004 return allLevelsOk;
6005 }
6006
checkTestResult(tcu::ConstPixelBufferAccess result)6007 tcu::TestStatus BlittingMipmaps::checkTestResult(tcu::ConstPixelBufferAccess result)
6008 {
6009 DE_UNREF(result);
6010 DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR ||
6011 m_params.filter == VK_FILTER_CUBIC_EXT);
6012 const std::string failMessage("Result image is incorrect");
6013
6014 if (m_params.filter != VK_FILTER_NEAREST)
6015 {
6016 if (!checkNonNearestFilteredResult())
6017 return tcu::TestStatus::fail(failMessage);
6018 }
6019 else // NEAREST filtering
6020 {
6021 if (!checkNearestFilteredResult())
6022 return tcu::TestStatus::fail(failMessage);
6023 }
6024
6025 return tcu::TestStatus::pass("Pass");
6026 }
6027
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,uint32_t mipLevel)6028 void BlittingMipmaps::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst,
6029 CopyRegion region, uint32_t mipLevel)
6030 {
6031 DE_ASSERT(src.getDepth() == dst.getDepth());
6032
6033 const MirrorMode mirrorMode = getMirrorMode(region.imageBlit.srcOffsets[0], region.imageBlit.srcOffsets[1],
6034 region.imageBlit.dstOffsets[0], region.imageBlit.dstOffsets[1]);
6035
6036 flipCoordinates(region, mirrorMode);
6037
6038 const VkOffset3D srcOffset = region.imageBlit.srcOffsets[0];
6039 const VkOffset3D srcExtent = {region.imageBlit.srcOffsets[1].x - srcOffset.x,
6040 region.imageBlit.srcOffsets[1].y - srcOffset.y,
6041 region.imageBlit.srcOffsets[1].z - srcOffset.z};
6042 const VkOffset3D dstOffset = region.imageBlit.dstOffsets[0];
6043 const VkOffset3D dstExtent = {region.imageBlit.dstOffsets[1].x - dstOffset.x,
6044 region.imageBlit.dstOffsets[1].y - dstOffset.y,
6045 region.imageBlit.dstOffsets[1].z - dstOffset.z};
6046
6047 tcu::Sampler::FilterMode filter;
6048 switch (m_params.filter)
6049 {
6050 case VK_FILTER_LINEAR:
6051 filter = tcu::Sampler::LINEAR;
6052 break;
6053 case VK_FILTER_CUBIC_EXT:
6054 filter = tcu::Sampler::CUBIC;
6055 break;
6056 case VK_FILTER_NEAREST:
6057 default:
6058 filter = tcu::Sampler::NEAREST;
6059 break;
6060 }
6061
6062 if (tcu::isCombinedDepthStencilType(src.getFormat().type))
6063 {
6064 DE_ASSERT(src.getFormat() == dst.getFormat());
6065 // Scale depth.
6066 if (tcu::hasDepthComponent(src.getFormat().order))
6067 {
6068 const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(
6069 tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_DEPTH);
6070 const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(
6071 tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH);
6072 tcu::scale(dstSubRegion, srcSubRegion, filter);
6073
6074 if (filter != tcu::Sampler::NEAREST)
6075 {
6076 const tcu::ConstPixelBufferAccess depthSrc =
6077 getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH);
6078 const tcu::PixelBufferAccess unclampedSubRegion = getEffectiveDepthStencilAccess(
6079 tcu::getSubregion(m_unclampedExpectedTextureLevel[0]->getAccess(), dstOffset.x, dstOffset.y,
6080 dstExtent.x, dstExtent.y),
6081 tcu::Sampler::MODE_DEPTH);
6082 scaleFromWholeSrcBuffer(unclampedSubRegion, depthSrc, srcOffset, srcExtent, filter);
6083 }
6084 }
6085
6086 // Scale stencil.
6087 if (tcu::hasStencilComponent(src.getFormat().order))
6088 {
6089 const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(
6090 tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_STENCIL);
6091 const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(
6092 tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
6093 blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
6094
6095 if (filter != tcu::Sampler::NEAREST)
6096 {
6097 const tcu::ConstPixelBufferAccess stencilSrc =
6098 getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL);
6099 const tcu::PixelBufferAccess unclampedSubRegion = getEffectiveDepthStencilAccess(
6100 tcu::getSubregion(m_unclampedExpectedTextureLevel[0]->getAccess(), dstOffset.x, dstOffset.y,
6101 dstExtent.x, dstExtent.y),
6102 tcu::Sampler::MODE_STENCIL);
6103 scaleFromWholeSrcBuffer(unclampedSubRegion, stencilSrc, srcOffset, srcExtent, filter);
6104 }
6105 }
6106 }
6107 else
6108 {
6109 for (int layerNdx = 0u; layerNdx < src.getDepth(); layerNdx++)
6110 {
6111 const tcu::ConstPixelBufferAccess srcSubRegion =
6112 tcu::getSubregion(src, srcOffset.x, srcOffset.y, layerNdx, srcExtent.x, srcExtent.y, 1);
6113 const tcu::PixelBufferAccess dstSubRegion =
6114 tcu::getSubregion(dst, dstOffset.x, dstOffset.y, layerNdx, dstExtent.x, dstExtent.y, 1);
6115 blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
6116
6117 if (filter != tcu::Sampler::NEAREST)
6118 {
6119 const tcu::PixelBufferAccess unclampedSubRegion =
6120 tcu::getSubregion(m_unclampedExpectedTextureLevel[mipLevel]->getAccess(), dstOffset.x, dstOffset.y,
6121 layerNdx, dstExtent.x, dstExtent.y, 1);
6122 scaleFromWholeSrcBuffer(unclampedSubRegion, srcSubRegion, srcOffset, srcExtent, filter);
6123 }
6124 }
6125 }
6126 }
6127
generateExpectedResult(void)6128 void BlittingMipmaps::generateExpectedResult(void)
6129 {
6130 const tcu::ConstPixelBufferAccess src = m_sourceTextureLevel->getAccess();
6131 const tcu::ConstPixelBufferAccess dst = m_destinationTextureLevel->getAccess();
6132
6133 for (uint32_t mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
6134 m_expectedTextureLevel[mipLevelNdx] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(
6135 dst.getFormat(), dst.getWidth() >> mipLevelNdx, dst.getHeight() >> mipLevelNdx, dst.getDepth()));
6136
6137 tcu::copy(m_expectedTextureLevel[0]->getAccess(), src);
6138
6139 if (m_params.filter != VK_FILTER_NEAREST)
6140 {
6141 for (uint32_t mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
6142 m_unclampedExpectedTextureLevel[mipLevelNdx] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(
6143 dst.getFormat(), dst.getWidth() >> mipLevelNdx, dst.getHeight() >> mipLevelNdx, dst.getDepth()));
6144
6145 tcu::copy(m_unclampedExpectedTextureLevel[0]->getAccess(), src);
6146 }
6147
6148 for (uint32_t i = 0; i < m_params.regions.size(); i++)
6149 {
6150 CopyRegion region = m_params.regions[i];
6151 copyRegionToTextureLevel(
6152 m_expectedTextureLevel[m_params.regions[i].imageBlit.srcSubresource.mipLevel]->getAccess(),
6153 m_expectedTextureLevel[m_params.regions[i].imageBlit.dstSubresource.mipLevel]->getAccess(), region,
6154 m_params.regions[i].imageBlit.dstSubresource.mipLevel);
6155 }
6156 }
6157
6158 class BlitMipmapTestCase : public vkt::TestCase
6159 {
6160 public:
BlitMipmapTestCase(tcu::TestContext & testCtx,const std::string & name,const TestParams params)6161 BlitMipmapTestCase(tcu::TestContext &testCtx, const std::string &name, const TestParams params)
6162 : vkt::TestCase(testCtx, name)
6163 , m_params(params)
6164 {
6165 }
6166
createInstance(Context & context) const6167 virtual TestInstance *createInstance(Context &context) const
6168 {
6169 return new BlittingMipmaps(context, m_params);
6170 }
6171
checkSupport(Context & context) const6172 virtual void checkSupport(Context &context) const
6173 {
6174 const InstanceInterface &vki = context.getInstanceInterface();
6175 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
6176 {
6177 VkImageFormatProperties properties;
6178 if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
6179 context.getPhysicalDevice(), m_params.src.image.format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
6180 VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0, &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
6181 {
6182 TCU_THROW(NotSupportedError, "Format not supported");
6183 }
6184 else if ((m_params.src.image.extent.width > properties.maxExtent.width) ||
6185 (m_params.src.image.extent.height > properties.maxExtent.height) ||
6186 (m_params.src.image.extent.depth > properties.maxArrayLayers))
6187 {
6188 TCU_THROW(NotSupportedError, "Image size not supported");
6189 }
6190 }
6191
6192 {
6193 VkImageFormatProperties properties;
6194 if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
6195 context.getPhysicalDevice(), m_params.dst.image.format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
6196 VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0, &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
6197 {
6198 TCU_THROW(NotSupportedError, "Format not supported");
6199 }
6200 else if ((m_params.dst.image.extent.width > properties.maxExtent.width) ||
6201 (m_params.dst.image.extent.height > properties.maxExtent.height) ||
6202 (m_params.dst.image.extent.depth > properties.maxArrayLayers))
6203 {
6204 TCU_THROW(NotSupportedError, "Image size not supported");
6205 }
6206 else if (m_params.mipLevels > properties.maxMipLevels)
6207 {
6208 TCU_THROW(NotSupportedError, "Number of mip levels not supported");
6209 }
6210
6211 checkExtensionSupport(context, m_params.extensionFlags);
6212 }
6213
6214 const VkFormatProperties srcFormatProperties =
6215 getPhysicalDeviceFormatProperties(vki, vkPhysDevice, m_params.src.image.format);
6216 if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT))
6217 {
6218 TCU_THROW(NotSupportedError, "Format feature blit source not supported");
6219 }
6220
6221 const VkFormatProperties dstFormatProperties =
6222 getPhysicalDeviceFormatProperties(vki, vkPhysDevice, m_params.dst.image.format);
6223 if (!(dstFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT))
6224 {
6225 TCU_THROW(NotSupportedError, "Format feature blit destination not supported");
6226 }
6227
6228 if (m_params.filter == VK_FILTER_LINEAR &&
6229 !(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
6230 TCU_THROW(NotSupportedError, "Source format feature sampled image filter linear not supported");
6231
6232 if (m_params.filter == VK_FILTER_CUBIC_EXT)
6233 {
6234 context.requireDeviceFunctionality("VK_EXT_filter_cubic");
6235
6236 if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT))
6237 {
6238 TCU_THROW(NotSupportedError, "Source format feature sampled image filter cubic not supported");
6239 }
6240 }
6241 }
6242
6243 private:
6244 TestParams m_params;
6245 };
6246
6247 // Resolve image to image.
6248
6249 enum ResolveImageToImageOptions
6250 {
6251 NO_OPTIONAL_OPERATION = 0,
6252 COPY_MS_IMAGE_TO_MS_IMAGE,
6253 COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE,
6254 COPY_MS_IMAGE_LAYER_TO_MS_IMAGE,
6255 COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION,
6256 COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB,
6257 COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE,
6258 COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER
6259 };
6260
6261 class ResolveImageToImage : public CopiesAndBlittingTestInstance
6262 {
6263 public:
6264 ResolveImageToImage(Context &context, TestParams params, ResolveImageToImageOptions options);
6265 virtual tcu::TestStatus iterate(void);
6266
shouldVerifyIntermediateResults(ResolveImageToImageOptions option)6267 static inline bool shouldVerifyIntermediateResults(ResolveImageToImageOptions option)
6268 {
6269 return option == COPY_MS_IMAGE_TO_MS_IMAGE || option == COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE ||
6270 option == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE || option == COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE ||
6271 option == COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER;
6272 }
6273
6274 protected:
6275 virtual tcu::TestStatus checkTestResult(tcu::ConstPixelBufferAccess result);
6276 void copyMSImageToMSImage(uint32_t copyArraySize);
6277 tcu::TestStatus checkIntermediateCopy(void);
6278
6279 private:
6280 de::MovePtr<vk::Allocator> m_alternativeAllocator;
6281 Move<VkImage> m_multisampledImage;
6282 de::MovePtr<Allocation> m_multisampledImageAlloc;
6283
6284 Move<VkImage> m_destination;
6285 de::MovePtr<Allocation> m_destinationImageAlloc;
6286 std::vector<de::SharedPtr<Allocation>> m_sparseAllocations;
6287 Move<VkSemaphore> m_sparseSemaphore;
6288
6289 Move<VkImage> m_multisampledCopyImage;
6290 de::MovePtr<Allocation> m_multisampledCopyImageAlloc;
6291 Move<VkImage> m_multisampledCopyNoCabImage;
6292 de::MovePtr<Allocation> m_multisampledCopyImageNoCabAlloc;
6293
6294 const TestParams m_params;
6295 const ResolveImageToImageOptions m_options;
6296
6297 virtual void copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst,
6298 CopyRegion region, uint32_t mipLevel = 0u);
6299 };
6300
ResolveImageToImage(Context & context,TestParams params,const ResolveImageToImageOptions options)6301 ResolveImageToImage::ResolveImageToImage(Context &context, TestParams params, const ResolveImageToImageOptions options)
6302 : CopiesAndBlittingTestInstance(context, params)
6303 , m_params(params)
6304 , m_options(options)
6305 {
6306 const InstanceInterface &vki = m_context.getInstanceInterface();
6307 const DeviceInterface &vk = m_context.getDeviceInterface();
6308
6309 VkQueue queue = VK_NULL_HANDLE;
6310 VkCommandBuffer commandBuffer = VK_NULL_HANDLE;
6311 VkCommandPool commandPool = VK_NULL_HANDLE;
6312 std::tie(queue, commandBuffer, commandPool) = activeExecutionCtx();
6313
6314 Allocator &memAlloc = *m_allocator;
6315 const VkPhysicalDevice vkPhysDevice = m_context.getPhysicalDevice();
6316 const VkDevice vkDevice = m_device;
6317 const VkComponentMapping componentMappingRGBA = {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
6318 VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
6319 Move<VkRenderPass> renderPass;
6320
6321 Move<VkShaderModule> vertexShaderModule =
6322 createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
6323 Move<VkShaderModule> fragmentShaderModule =
6324 createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
6325 std::vector<tcu::Vec4> vertices;
6326
6327 Move<VkBuffer> vertexBuffer;
6328 de::MovePtr<Allocation> vertexBufferAlloc;
6329
6330 Move<VkPipelineLayout> pipelineLayout;
6331 Move<VkPipeline> graphicsPipeline;
6332
6333 const VkSampleCountFlagBits rasterizationSamples = m_params.samples;
6334
6335 // Create color image.
6336 {
6337 VkImageCreateInfo colorImageParams = {
6338 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
6339 DE_NULL, // const void* pNext;
6340 getCreateFlags(m_params.src.image), // VkImageCreateFlags flags;
6341 m_params.src.image.imageType, // VkImageType imageType;
6342 m_params.src.image.format, // VkFormat format;
6343 getExtent3D(m_params.src.image), // VkExtent3D extent;
6344 1u, // uint32_t mipLevels;
6345 getArraySize(m_params.src.image), // uint32_t arrayLayers;
6346 rasterizationSamples, // VkSampleCountFlagBits samples;
6347 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
6348 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT // VkImageUsageFlags usage;
6349 | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
6350 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
6351 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
6352 0u, // uint32_t queueFamilyIndexCount;
6353 (const uint32_t *)DE_NULL, // const uint32_t* pQueueFamilyIndices;
6354 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
6355 };
6356
6357 m_multisampledImage = createImage(vk, vkDevice, &colorImageParams);
6358 VkMemoryRequirements req = getImageMemoryRequirements(vk, vkDevice, *m_multisampledImage);
6359
6360 // Allocate and bind color image memory.
6361 uint32_t offset = m_params.imageOffset ? static_cast<uint32_t>(req.alignment) : 0u;
6362 m_multisampledImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledImage,
6363 MemoryRequirement::Any, memAlloc, m_params.allocationKind, offset);
6364
6365 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledImage, m_multisampledImageAlloc->getMemory(), offset));
6366
6367 switch (m_options)
6368 {
6369 case COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION:
6370 case COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE:
6371 case COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER:
6372 case COPY_MS_IMAGE_TO_MS_IMAGE:
6373 {
6374 colorImageParams.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
6375 VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
6376 m_multisampledCopyImage = createImage(vk, vkDevice, &colorImageParams);
6377 // Allocate and bind color image memory.
6378 m_multisampledCopyImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage,
6379 MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
6380 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(),
6381 m_multisampledCopyImageAlloc->getOffset()));
6382 break;
6383 }
6384 case COPY_MS_IMAGE_LAYER_TO_MS_IMAGE:
6385 case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
6386 {
6387 colorImageParams.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
6388 VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
6389 colorImageParams.arrayLayers = getArraySize(m_params.dst.image);
6390 m_multisampledCopyImage = createImage(vk, vkDevice, &colorImageParams);
6391 // Allocate and bind color image memory.
6392 m_multisampledCopyImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage,
6393 MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
6394 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(),
6395 m_multisampledCopyImageAlloc->getOffset()));
6396 break;
6397 }
6398 case COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB:
6399 {
6400 colorImageParams.usage =
6401 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
6402 colorImageParams.arrayLayers = getArraySize(m_params.dst.image);
6403 m_multisampledCopyImage = createImage(vk, vkDevice, &colorImageParams);
6404 m_multisampledCopyNoCabImage = createImage(vk, vkDevice, &colorImageParams);
6405 // Allocate and bind color image memory.
6406 m_multisampledCopyImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage,
6407 MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
6408 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(),
6409 m_multisampledCopyImageAlloc->getOffset()));
6410 m_multisampledCopyImageNoCabAlloc =
6411 allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyNoCabImage, MemoryRequirement::Any,
6412 memAlloc, m_params.allocationKind, 0u);
6413 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyNoCabImage,
6414 m_multisampledCopyImageNoCabAlloc->getMemory(),
6415 m_multisampledCopyImageNoCabAlloc->getOffset()));
6416 break;
6417 }
6418
6419 default:
6420 break;
6421 }
6422 }
6423
6424 // Create destination image.
6425 {
6426 VkImageCreateInfo destinationImageParams = {
6427 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
6428 DE_NULL, // const void* pNext;
6429 getCreateFlags(m_params.dst.image), // VkImageCreateFlags flags;
6430 m_params.dst.image.imageType, // VkImageType imageType;
6431 m_params.dst.image.format, // VkFormat format;
6432 getExtent3D(m_params.dst.image), // VkExtent3D extent;
6433 1u, // uint32_t mipLevels;
6434 getArraySize(m_params.dst.image), // uint32_t arraySize;
6435 VK_SAMPLE_COUNT_1_BIT, // uint32_t samples;
6436 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
6437 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
6438 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
6439 0u, // uint32_t queueFamilyIndexCount;
6440 (const uint32_t *)DE_NULL, // const uint32_t* pQueueFamilyIndices;
6441 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
6442 };
6443
6444 #ifndef CTS_USES_VULKANSC
6445 if (!params.useSparseBinding)
6446 {
6447 #endif
6448 m_destination = createImage(vk, m_device, &destinationImageParams);
6449 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, m_device, *m_destination,
6450 MemoryRequirement::Any, *m_allocator, m_params.allocationKind, 0u);
6451 VK_CHECK(vk.bindImageMemory(m_device, *m_destination, m_destinationImageAlloc->getMemory(),
6452 m_destinationImageAlloc->getOffset()));
6453 #ifndef CTS_USES_VULKANSC
6454 }
6455 else
6456 {
6457 destinationImageParams.flags |=
6458 (vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT | vk::VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT);
6459 vk::VkImageFormatProperties imageFormatProperties;
6460 if (vki.getPhysicalDeviceImageFormatProperties(
6461 vkPhysDevice, destinationImageParams.format, destinationImageParams.imageType,
6462 destinationImageParams.tiling, destinationImageParams.usage, destinationImageParams.flags,
6463 &imageFormatProperties) == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
6464 {
6465 TCU_THROW(NotSupportedError, "Image format not supported");
6466 }
6467 m_destination = createImage(vk, m_device, &destinationImageParams);
6468 m_sparseSemaphore = createSemaphore(vk, m_device);
6469 allocateAndBindSparseImage(vk, m_device, vkPhysDevice, vki, destinationImageParams, m_sparseSemaphore.get(),
6470 context.getSparseQueue(), *m_allocator, m_sparseAllocations,
6471 mapVkFormat(destinationImageParams.format), m_destination.get());
6472 }
6473 #endif
6474 }
6475
6476 // Barriers for image clearing.
6477 std::vector<VkImageMemoryBarrier> srcImageBarriers;
6478
6479 const VkImageMemoryBarrier m_multisampledImageBarrier = {
6480 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
6481 DE_NULL, // const void* pNext;
6482 0u, // VkAccessFlags srcAccessMask;
6483 VK_ACCESS_MEMORY_WRITE_BIT, // VkAccessFlags dstAccessMask;
6484 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
6485 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
6486 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
6487 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
6488 m_multisampledImage.get(), // VkImage image;
6489 {
6490 // VkImageSubresourceRange subresourceRange;
6491 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
6492 0u, // uint32_t baseMipLevel;
6493 1u, // uint32_t mipLevels;
6494 0u, // uint32_t baseArraySlice;
6495 getArraySize(m_params.src.image) // uint32_t arraySize;
6496 }};
6497 const VkImageMemoryBarrier m_multisampledCopyImageBarrier = {
6498 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
6499 DE_NULL, // const void* pNext;
6500 0u, // VkAccessFlags srcAccessMask;
6501 VK_ACCESS_MEMORY_WRITE_BIT, // VkAccessFlags dstAccessMask;
6502 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
6503 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
6504 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
6505 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
6506 m_multisampledCopyImage.get(), // VkImage image;
6507 {
6508 // VkImageSubresourceRange subresourceRange;
6509 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
6510 0u, // uint32_t baseMipLevel;
6511 1u, // uint32_t mipLevels;
6512 0u, // uint32_t baseArraySlice;
6513 getArraySize(m_params.dst.image) // uint32_t arraySize;
6514 }};
6515 const VkImageMemoryBarrier m_multisampledCopyImageNoCabBarrier = {
6516 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
6517 DE_NULL, // const void* pNext;
6518 0u, // VkAccessFlags srcAccessMask;
6519 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
6520 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
6521 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
6522 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
6523 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
6524 m_multisampledCopyNoCabImage.get(), // VkImage image;
6525 {
6526 // VkImageSubresourceRange subresourceRange;
6527 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
6528 0u, // uint32_t baseMipLevel;
6529 1u, // uint32_t mipLevels;
6530 0u, // uint32_t baseArraySlice;
6531 getArraySize(m_params.dst.image) // uint32_t arraySize;
6532 }};
6533
6534 // Only use one barrier if no options have been given.
6535 if (m_options != DE_NULL)
6536 {
6537 srcImageBarriers.push_back(m_multisampledImageBarrier);
6538 srcImageBarriers.push_back(m_multisampledCopyImageBarrier);
6539 // Add the third barrier if option is as below.
6540 if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB)
6541 srcImageBarriers.push_back(m_multisampledCopyImageNoCabBarrier);
6542 }
6543 else
6544 {
6545 srcImageBarriers.push_back(m_multisampledImageBarrier);
6546 }
6547
6548 // Create render pass.
6549 {
6550 const VkAttachmentDescription attachmentDescription = {
6551 0u, // VkAttachmentDescriptionFlags flags;
6552 m_params.src.image.format, // VkFormat format;
6553 rasterizationSamples, // VkSampleCountFlagBits samples;
6554 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
6555 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
6556 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
6557 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
6558 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout initialLayout;
6559 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL // VkImageLayout finalLayout;
6560 };
6561
6562 const VkAttachmentReference colorAttachmentReference = {
6563 0u, // uint32_t attachment;
6564 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
6565 };
6566
6567 const VkSubpassDescription subpassDescription = {
6568 0u, // VkSubpassDescriptionFlags flags;
6569 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
6570 0u, // uint32_t inputAttachmentCount;
6571 DE_NULL, // const VkAttachmentReference* pInputAttachments;
6572 1u, // uint32_t colorAttachmentCount;
6573 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments;
6574 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
6575 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
6576 0u, // uint32_t preserveAttachmentCount;
6577 DE_NULL // const VkAttachmentReference* pPreserveAttachments;
6578 };
6579
6580 // Subpass dependency is used to synchronize the memory access of the image clear and color attachment write in some test cases.
6581 const VkSubpassDependency subpassDependency = {
6582 VK_SUBPASS_EXTERNAL, //uint32_t srcSubpass;
6583 0u, //uint32_t dstSubpass;
6584 VK_PIPELINE_STAGE_TRANSFER_BIT, //VkPipelineStageFlags srcStageMask;
6585 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, //VkPipelineStageFlags dstStageMask;
6586 VK_ACCESS_TRANSFER_WRITE_BIT, //VkAccessFlags srcAccessMask;
6587 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, //VkAccessFlags dstAccessMask;
6588 0u //VkDependencyFlags dependencyFlags;
6589 };
6590
6591 const bool useSubpassDependency =
6592 m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION;
6593 const VkRenderPassCreateInfo renderPassParams = {
6594 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
6595 DE_NULL, // const void* pNext;
6596 0u, // VkRenderPassCreateFlags flags;
6597 1u, // uint32_t attachmentCount;
6598 &attachmentDescription, // const VkAttachmentDescription* pAttachments;
6599 1u, // uint32_t subpassCount;
6600 &subpassDescription, // const VkSubpassDescription* pSubpasses;
6601 useSubpassDependency ? 1u : 0u, // uint32_t dependencyCount;
6602 &subpassDependency // const VkSubpassDependency* pDependencies;
6603 };
6604
6605 renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
6606 }
6607
6608 // Create pipeline layout
6609 {
6610 const VkPipelineLayoutCreateInfo pipelineLayoutParams = {
6611 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
6612 DE_NULL, // const void* pNext;
6613 0u, // VkPipelineLayoutCreateFlags flags;
6614 0u, // uint32_t setLayoutCount;
6615 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
6616 0u, // uint32_t pushConstantRangeCount;
6617 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
6618 };
6619
6620 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
6621 }
6622
6623 // Create upper half triangle.
6624 {
6625 const tcu::Vec4 a(-1.0, -1.0, 0.0, 1.0);
6626 const tcu::Vec4 b(1.0, -1.0, 0.0, 1.0);
6627 const tcu::Vec4 c(1.0, 1.0, 0.0, 1.0);
6628 // Add triangle.
6629 vertices.push_back(a);
6630 vertices.push_back(c);
6631 vertices.push_back(b);
6632 }
6633
6634 // Create vertex buffer.
6635 {
6636 const VkDeviceSize vertexDataSize = vertices.size() * sizeof(tcu::Vec4);
6637 const VkBufferCreateInfo vertexBufferParams = {
6638 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
6639 DE_NULL, // const void* pNext;
6640 0u, // VkBufferCreateFlags flags;
6641 vertexDataSize, // VkDeviceSize size;
6642 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
6643 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
6644 0u, // uint32_t queueFamilyIndexCount;
6645 (const uint32_t *)DE_NULL, // const uint32_t* pQueueFamilyIndices;
6646 };
6647
6648 vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
6649 vertexBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *vertexBuffer,
6650 MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
6651 VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferAlloc->getMemory(),
6652 vertexBufferAlloc->getOffset()));
6653
6654 // Load vertices into vertex buffer.
6655 deMemcpy(vertexBufferAlloc->getHostPtr(), vertices.data(), (size_t)vertexDataSize);
6656 flushAlloc(vk, vkDevice, *vertexBufferAlloc);
6657 }
6658
6659 {
6660 Move<VkFramebuffer> framebuffer;
6661 Move<VkImageView> sourceAttachmentView;
6662
6663 uint32_t baseArrayLayer = m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE ? 2u : 0u;
6664
6665 // Create color attachment view.
6666 {
6667 const VkImageViewCreateInfo colorAttachmentViewParams = {
6668 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
6669 DE_NULL, // const void* pNext;
6670 0u, // VkImageViewCreateFlags flags;
6671 *m_multisampledImage, // VkImage image;
6672 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
6673 m_params.src.image.format, // VkFormat format;
6674 componentMappingRGBA, // VkComponentMapping components;
6675 {VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, baseArrayLayer, 1u} // VkImageSubresourceRange subresourceRange;
6676 };
6677 sourceAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
6678 }
6679
6680 // Create framebuffer
6681 {
6682 const VkFramebufferCreateInfo framebufferParams = {
6683 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
6684 DE_NULL, // const void* pNext;
6685 0u, // VkFramebufferCreateFlags flags;
6686 *renderPass, // VkRenderPass renderPass;
6687 1u, // uint32_t attachmentCount;
6688 &sourceAttachmentView.get(), // const VkImageView* pAttachments;
6689 m_params.src.image.extent.width, // uint32_t width;
6690 m_params.src.image.extent.height, // uint32_t height;
6691 1u // uint32_t layers;
6692 };
6693
6694 framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
6695 }
6696
6697 // Create pipeline
6698 {
6699 const std::vector<VkViewport> viewports(1, makeViewport(m_params.src.image.extent));
6700 const std::vector<VkRect2D> scissors(1, makeRect2D(m_params.src.image.extent));
6701
6702 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = {
6703 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
6704 DE_NULL, // const void* pNext;
6705 0u, // VkPipelineMultisampleStateCreateFlags flags;
6706 rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples;
6707 VK_FALSE, // VkBool32 sampleShadingEnable;
6708 0.0f, // float minSampleShading;
6709 DE_NULL, // const VkSampleMask* pSampleMask;
6710 VK_FALSE, // VkBool32 alphaToCoverageEnable;
6711 VK_FALSE // VkBool32 alphaToOneEnable;
6712 };
6713
6714 graphicsPipeline = makeGraphicsPipeline(
6715 vk, // const DeviceInterface& vk
6716 vkDevice, // const VkDevice device
6717 *pipelineLayout, // const VkPipelineLayout pipelineLayout
6718 *vertexShaderModule, // const VkShaderModule vertexShaderModule
6719 DE_NULL, // const VkShaderModule tessellationControlModule
6720 DE_NULL, // const VkShaderModule tessellationEvalModule
6721 DE_NULL, // const VkShaderModule geometryShaderModule
6722 *fragmentShaderModule, // const VkShaderModule fragmentShaderModule
6723 *renderPass, // const VkRenderPass renderPass
6724 viewports, // const std::vector<VkViewport>& viewports
6725 scissors, // const std::vector<VkRect2D>& scissors
6726 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
6727 0u, // const uint32_t subpass
6728 0u, // const uint32_t patchControlPoints
6729 DE_NULL, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
6730 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
6731 &multisampleStateParams); // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
6732 }
6733
6734 // Create command buffer
6735 {
6736 beginCommandBuffer(vk, *m_universalCmdBuffer, 0u);
6737
6738 if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION)
6739 {
6740 // Change the image layouts.
6741 vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
6742 VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0,
6743 (const VkMemoryBarrier *)DE_NULL, 0, (const VkBufferMemoryBarrier *)DE_NULL,
6744 (uint32_t)srcImageBarriers.size(), srcImageBarriers.data());
6745
6746 // Clear the 'm_multisampledImage'.
6747 {
6748 const VkClearColorValue clearValue = {{0.0f, 0.0f, 0.0f, 1.0f}};
6749 const auto clearRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u,
6750 m_params.src.image.extent.depth);
6751 vk.cmdClearColorImage(*m_universalCmdBuffer, m_multisampledImage.get(),
6752 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue, 1u, &clearRange);
6753 }
6754
6755 // Clear the 'm_multisampledCopyImage' with different color.
6756 {
6757 const VkClearColorValue clearValue = {{1.0f, 1.0f, 1.0f, 1.0f}};
6758 const auto clearRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u,
6759 m_params.src.image.extent.depth);
6760 vk.cmdClearColorImage(*m_universalCmdBuffer, m_multisampledCopyImage.get(),
6761 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue, 1u, &clearRange);
6762 }
6763 }
6764 else
6765 {
6766 // Change the image layouts.
6767 vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
6768 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0, 0,
6769 (const VkMemoryBarrier *)DE_NULL, 0, (const VkBufferMemoryBarrier *)DE_NULL,
6770 (uint32_t)srcImageBarriers.size(), srcImageBarriers.data());
6771 }
6772
6773 beginRenderPass(vk, *m_universalCmdBuffer, *renderPass, *framebuffer,
6774 makeRect2D(0, 0, m_params.src.image.extent.width, m_params.src.image.extent.height),
6775 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
6776
6777 const VkDeviceSize vertexBufferOffset = 0u;
6778
6779 vk.cmdBindPipeline(*m_universalCmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
6780 vk.cmdBindVertexBuffers(*m_universalCmdBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
6781 vk.cmdDraw(*m_universalCmdBuffer, (uint32_t)vertices.size(), 1, 0, 0);
6782
6783 endRenderPass(vk, *m_universalCmdBuffer);
6784 endCommandBuffer(vk, *m_universalCmdBuffer);
6785 }
6786
6787 // Queue submit.
6788 {
6789 submitCommandsAndWait(vk, vkDevice, m_universalQueue, *m_universalCmdBuffer);
6790 m_context.resetCommandPoolForVKSC(vkDevice, *m_universalCmdPool);
6791 }
6792 }
6793 }
6794
iterate(void)6795 tcu::TestStatus ResolveImageToImage::iterate(void)
6796 {
6797 const tcu::TextureFormat srcTcuFormat = mapVkFormat(m_params.src.image.format);
6798 const tcu::TextureFormat dstTcuFormat = mapVkFormat(m_params.dst.image.format);
6799
6800 // upload the destination image
6801 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(
6802 new tcu::TextureLevel(dstTcuFormat, (int)m_params.dst.image.extent.width, (int)m_params.dst.image.extent.height,
6803 (int)m_params.dst.image.extent.depth));
6804 generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width,
6805 m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
6806 uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
6807
6808 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(
6809 new tcu::TextureLevel(srcTcuFormat, (int)m_params.src.image.extent.width, (int)m_params.src.image.extent.height,
6810 (int)m_params.dst.image.extent.depth));
6811
6812 generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height,
6813 m_params.dst.image.extent.depth, FILL_MODE_MULTISAMPLE);
6814 generateExpectedResult();
6815
6816 VkImage sourceImage = m_multisampledImage.get();
6817 uint32_t sourceArraySize = getArraySize(m_params.src.image);
6818
6819 switch (m_options)
6820 {
6821 case COPY_MS_IMAGE_LAYER_TO_MS_IMAGE:
6822 case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
6823 // Duplicate the multisampled image to a multisampled image array
6824 sourceArraySize = getArraySize(m_params.dst.image); // fall through
6825 case COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION:
6826 case COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB:
6827 case COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE:
6828 case COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER:
6829 case COPY_MS_IMAGE_TO_MS_IMAGE:
6830 copyMSImageToMSImage(sourceArraySize);
6831 sourceImage = m_multisampledCopyImage.get();
6832 break;
6833 default:
6834 break;
6835 }
6836
6837 const DeviceInterface &vk = m_context.getDeviceInterface();
6838 const VkDevice vkDevice = m_device;
6839
6840 std::vector<VkImageResolve> imageResolves;
6841 std::vector<VkImageResolve2KHR> imageResolves2KHR;
6842 for (CopyRegion region : m_params.regions)
6843 {
6844 // If copying multiple regions, make sure that the same regions are
6845 // used for resolving as the ones used for copying.
6846 if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION)
6847 {
6848 VkExtent3D partialExtent = {getExtent3D(m_params.src.image).width / 2,
6849 getExtent3D(m_params.src.image).height / 2,
6850 getExtent3D(m_params.src.image).depth};
6851
6852 const VkImageResolve imageResolve = {
6853 region.imageResolve.srcSubresource, // VkImageSubresourceLayers srcSubresource;
6854 region.imageResolve.dstOffset, // VkOffset3D srcOffset;
6855 region.imageResolve.dstSubresource, // VkImageSubresourceLayers dstSubresource;
6856 region.imageResolve.dstOffset, // VkOffset3D dstOffset;
6857 partialExtent, // VkExtent3D extent;
6858 };
6859
6860 if (!(m_params.extensionFlags & COPY_COMMANDS_2))
6861 {
6862 imageResolves.push_back(imageResolve);
6863 }
6864 else
6865 {
6866 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
6867 imageResolves2KHR.push_back(convertvkImageResolveTovkImageResolve2KHR(imageResolve));
6868 }
6869 }
6870 else
6871 {
6872 if (!(m_params.extensionFlags & COPY_COMMANDS_2))
6873 {
6874 imageResolves.push_back(region.imageResolve);
6875 }
6876 else
6877 {
6878 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
6879 imageResolves2KHR.push_back(convertvkImageResolveTovkImageResolve2KHR(region.imageResolve));
6880 }
6881 }
6882 }
6883
6884 const VkImageMemoryBarrier imageBarriers[] = {
6885 // source image
6886 {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
6887 DE_NULL, // const void* pNext;
6888 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask;
6889 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
6890 m_options == NO_OPTIONAL_OPERATION ? m_params.dst.image.operationLayout :
6891 m_params.src.image.operationLayout, // VkImageLayout oldLayout;
6892 m_params.src.image.operationLayout, // VkImageLayout newLayout;
6893 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
6894 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
6895 sourceImage, // VkImage image;
6896 {
6897 // VkImageSubresourceRange subresourceRange;
6898 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
6899 0u, // uint32_t baseMipLevel;
6900 1u, // uint32_t mipLevels;
6901 0u, // uint32_t baseArraySlice;
6902 sourceArraySize // uint32_t arraySize;
6903 }},
6904 // destination image
6905 {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
6906 DE_NULL, // const void* pNext;
6907 0u, // VkAccessFlags srcAccessMask;
6908 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
6909 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
6910 m_params.dst.image.operationLayout, // VkImageLayout newLayout;
6911 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
6912 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
6913 m_destination.get(), // VkImage image;
6914 {
6915 // VkImageSubresourceRange subresourceRange;
6916 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
6917 0u, // uint32_t baseMipLevel;
6918 1u, // uint32_t mipLevels;
6919 0u, // uint32_t baseArraySlice;
6920 getArraySize(m_params.dst.image) // uint32_t arraySize;
6921 }},
6922 };
6923
6924 const VkImageMemoryBarrier postImageBarrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
6925 DE_NULL, // const void* pNext;
6926 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
6927 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
6928 m_params.dst.image.operationLayout, // VkImageLayout oldLayout;
6929 m_params.dst.image.operationLayout, // VkImageLayout newLayout;
6930 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
6931 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
6932 m_destination.get(), // VkImage image;
6933 {
6934 // VkImageSubresourceRange subresourceRange;
6935 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
6936 0u, // uint32_t baseMipLevel;
6937 1u, // uint32_t mipLevels;
6938 0u, // uint32_t baseArraySlice;
6939 getArraySize(m_params.dst.image) // uint32_t arraySize;
6940 }};
6941
6942 beginCommandBuffer(vk, *m_universalCmdBuffer);
6943 vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
6944 VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
6945 (const VkBufferMemoryBarrier *)DE_NULL, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers);
6946
6947 if (!(m_params.extensionFlags & COPY_COMMANDS_2))
6948 {
6949 vk.cmdResolveImage(*m_universalCmdBuffer, sourceImage, m_params.src.image.operationLayout, m_destination.get(),
6950 m_params.dst.image.operationLayout, (uint32_t)m_params.regions.size(), imageResolves.data());
6951 }
6952 else
6953 {
6954 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
6955 const VkResolveImageInfo2KHR ResolveImageInfo2KHR = {
6956 VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2_KHR, // VkStructureType sType;
6957 DE_NULL, // const void* pNext;
6958 sourceImage, // VkImage srcImage;
6959 m_params.src.image.operationLayout, // VkImageLayout srcImageLayout;
6960 m_destination.get(), // VkImage dstImage;
6961 m_params.dst.image.operationLayout, // VkImageLayout dstImageLayout;
6962 (uint32_t)m_params.regions.size(), // uint32_t regionCount;
6963 imageResolves2KHR.data() // const VkImageResolve2KHR* pRegions;
6964 };
6965 vk.cmdResolveImage2(*m_universalCmdBuffer, &ResolveImageInfo2KHR);
6966 }
6967
6968 vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
6969 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
6970 (const VkBufferMemoryBarrier *)DE_NULL, 1, &postImageBarrier);
6971 endCommandBuffer(vk, *m_universalCmdBuffer);
6972 submitCommandsAndWait(vk, vkDevice, m_universalQueue, *m_universalCmdBuffer);
6973 m_context.resetCommandPoolForVKSC(vkDevice, *m_universalCmdPool);
6974
6975 de::MovePtr<tcu::TextureLevel> resultTextureLevel = readImage(*m_destination, m_params.dst.image);
6976
6977 if (shouldVerifyIntermediateResults(m_options))
6978 {
6979 // Verify the intermediate multisample copy operation happens properly instead of, for example, shuffling samples around or
6980 // resolving the image and giving every sample the same value.
6981 const auto intermediateResult = checkIntermediateCopy();
6982 if (intermediateResult.getCode() != QP_TEST_RESULT_PASS)
6983 return intermediateResult;
6984 }
6985
6986 return checkTestResult(resultTextureLevel->getAccess());
6987 }
6988
checkTestResult(tcu::ConstPixelBufferAccess result)6989 tcu::TestStatus ResolveImageToImage::checkTestResult(tcu::ConstPixelBufferAccess result)
6990 {
6991 const tcu::ConstPixelBufferAccess expected = m_expectedTextureLevel[0]->getAccess();
6992 const float fuzzyThreshold = 0.01f;
6993
6994 if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
6995 {
6996 // Check that all the layers that have not been written to are solid white.
6997 tcu::Vec4 expectedColor(1.0f, 1.0f, 1.0f, 1.0f);
6998 for (int arrayLayerNdx = 0; arrayLayerNdx < (int)getArraySize(m_params.dst.image) - 1; ++arrayLayerNdx)
6999 {
7000 const tcu::ConstPixelBufferAccess resultSub =
7001 getSubregion(result, 0u, 0u, arrayLayerNdx, result.getWidth(), result.getHeight(), 1u);
7002 if (resultSub.getPixel(0, 0) != expectedColor)
7003 return tcu::TestStatus::fail("CopiesAndBlitting test. Layers image differs from initialized value.");
7004 }
7005
7006 // Check that the layer that has been copied to is the same as the layer that has been copied from.
7007 const tcu::ConstPixelBufferAccess expectedSub =
7008 getSubregion(expected, 0u, 0u, 2u, expected.getWidth(), expected.getHeight(), 1u);
7009 const tcu::ConstPixelBufferAccess resultSub =
7010 getSubregion(result, 0u, 0u, 4u, result.getWidth(), result.getHeight(), 1u);
7011 if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedSub,
7012 resultSub, fuzzyThreshold, tcu::COMPARE_LOG_RESULT))
7013 return tcu::TestStatus::fail("CopiesAndBlitting test");
7014 }
7015 else
7016 {
7017 for (int arrayLayerNdx = 0; arrayLayerNdx < (int)getArraySize(m_params.dst.image); ++arrayLayerNdx)
7018 {
7019 const tcu::ConstPixelBufferAccess expectedSub =
7020 getSubregion(expected, 0u, 0u, arrayLayerNdx, expected.getWidth(), expected.getHeight(), 1u);
7021 const tcu::ConstPixelBufferAccess resultSub =
7022 getSubregion(result, 0u, 0u, arrayLayerNdx, result.getWidth(), result.getHeight(), 1u);
7023 if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedSub,
7024 resultSub, fuzzyThreshold, tcu::COMPARE_LOG_RESULT))
7025 return tcu::TestStatus::fail("CopiesAndBlitting test");
7026 }
7027 }
7028
7029 return tcu::TestStatus::pass("CopiesAndBlitting test");
7030 }
7031
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,uint32_t mipLevel)7032 void ResolveImageToImage::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst,
7033 CopyRegion region, uint32_t mipLevel)
7034 {
7035 DE_UNREF(mipLevel);
7036
7037 VkOffset3D srcOffset = region.imageResolve.srcOffset;
7038 srcOffset.z = region.imageResolve.srcSubresource.baseArrayLayer;
7039 VkOffset3D dstOffset = region.imageResolve.dstOffset;
7040 dstOffset.z = region.imageResolve.dstSubresource.baseArrayLayer;
7041 VkExtent3D extent = region.imageResolve.extent;
7042 extent.depth = (region.imageResolve.srcSubresource.layerCount == VK_REMAINING_ARRAY_LAYERS) ?
7043 (src.getDepth() - region.imageResolve.srcSubresource.baseArrayLayer) :
7044 region.imageResolve.srcSubresource.layerCount;
7045
7046 const tcu::ConstPixelBufferAccess srcSubRegion =
7047 getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
7048 // CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
7049 const tcu::PixelBufferAccess dstWithSrcFormat(srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
7050 const tcu::PixelBufferAccess dstSubRegion = getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z,
7051 extent.width, extent.height, extent.depth);
7052
7053 tcu::copy(dstSubRegion, srcSubRegion);
7054 }
7055
checkIntermediateCopy(void)7056 tcu::TestStatus ResolveImageToImage::checkIntermediateCopy(void)
7057 {
7058 const auto &vkd = m_context.getDeviceInterface();
7059 const auto device = m_device;
7060 const auto queueIndex = m_context.getUniversalQueueFamilyIndex();
7061 auto &alloc = *m_allocator;
7062 const auto currentLayout = m_params.src.image.operationLayout;
7063 const auto numDstLayers = getArraySize(m_params.dst.image);
7064 const auto numInputAttachments =
7065 m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE ? 2u : numDstLayers + 1u; // For the source image.
7066 constexpr auto numSets = 2u; // 1 for the output buffer, 1 for the input attachments.
7067 const auto fbWidth = m_params.src.image.extent.width;
7068 const auto fbHeight = m_params.src.image.extent.height;
7069
7070 // Push constants.
7071 const std::array<int, 3> pushConstantData = {{
7072 static_cast<int>(fbWidth),
7073 static_cast<int>(fbHeight),
7074 static_cast<int>(m_params.samples),
7075 }};
7076 const auto pushConstantSize =
7077 static_cast<uint32_t>(pushConstantData.size() * sizeof(decltype(pushConstantData)::value_type));
7078
7079 // Shader modules.
7080 const auto vertexModule = createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
7081 const auto verificationModule = createShaderModule(vkd, device, m_context.getBinaryCollection().get("verify"), 0u);
7082
7083 // Descriptor sets.
7084 DescriptorPoolBuilder poolBuilder;
7085 poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
7086 poolBuilder.addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, numInputAttachments);
7087 const auto descriptorPool =
7088 poolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, numSets);
7089
7090 DescriptorSetLayoutBuilder layoutBuilderBuffer;
7091 layoutBuilderBuffer.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
7092 const auto outputBufferSetLayout = layoutBuilderBuffer.build(vkd, device);
7093
7094 DescriptorSetLayoutBuilder layoutBuilderAttachments;
7095 for (uint32_t i = 0u; i < numInputAttachments; ++i)
7096 layoutBuilderAttachments.addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT);
7097 const auto inputAttachmentsSetLayout = layoutBuilderAttachments.build(vkd, device);
7098
7099 const auto descriptorSetBuffer = makeDescriptorSet(vkd, device, descriptorPool.get(), outputBufferSetLayout.get());
7100 const auto descriptorSetAttachments =
7101 makeDescriptorSet(vkd, device, descriptorPool.get(), inputAttachmentsSetLayout.get());
7102
7103 // Array with raw descriptor sets.
7104 const std::array<VkDescriptorSet, numSets> descriptorSets = {{
7105 descriptorSetBuffer.get(),
7106 descriptorSetAttachments.get(),
7107 }};
7108
7109 // Pipeline layout.
7110 const std::array<VkDescriptorSetLayout, numSets> setLayouts = {{
7111 outputBufferSetLayout.get(),
7112 inputAttachmentsSetLayout.get(),
7113 }};
7114
7115 const VkPushConstantRange pushConstantRange = {
7116 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
7117 0u, // uint32_t offset;
7118 pushConstantSize, // uint32_t size;
7119 };
7120
7121 const VkPipelineLayoutCreateInfo pipelineLayoutInfo = {
7122 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
7123 nullptr, // const void* pNext;
7124 0u, // VkPipelineLayoutCreateFlags flags;
7125 static_cast<uint32_t>(setLayouts.size()), // uint32_t setLayoutCount;
7126 setLayouts.data(), // const VkDescriptorSetLayout* pSetLayouts;
7127 1u, // uint32_t pushConstantRangeCount;
7128 &pushConstantRange, // const VkPushConstantRange* pPushConstantRanges;
7129 };
7130
7131 const auto pipelineLayout = createPipelineLayout(vkd, device, &pipelineLayoutInfo);
7132
7133 // Render pass.
7134 const VkAttachmentDescription commonAttachmentDescription = {
7135 0u, // VkAttachmentDescriptionFlags flags;
7136 m_params.src.image.format, // VkFormat format;
7137 m_params.samples, // VkSampleCountFlagBits samples;
7138 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
7139 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
7140 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
7141 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
7142 currentLayout, // VkImageLayout initialLayout;
7143 currentLayout, // VkImageLayout finalLayout;
7144 };
7145 const std::vector<VkAttachmentDescription> attachmentDescriptions(numInputAttachments, commonAttachmentDescription);
7146
7147 std::vector<VkAttachmentReference> inputAttachmentReferences;
7148 inputAttachmentReferences.reserve(numInputAttachments);
7149 for (uint32_t i = 0u; i < numInputAttachments; ++i)
7150 {
7151 const VkAttachmentReference reference = {i, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};
7152 inputAttachmentReferences.push_back(reference);
7153 }
7154
7155 const VkSubpassDescription subpassDescription = {
7156 0u, // VkSubpassDescriptionFlags flags;
7157 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
7158 static_cast<uint32_t>(inputAttachmentReferences.size()), // uint32_t inputAttachmentCount;
7159 inputAttachmentReferences.data(), // const VkAttachmentReference* pInputAttachments;
7160 0u, // uint32_t colorAttachmentCount;
7161 nullptr, // const VkAttachmentReference* pColorAttachments;
7162 nullptr, // const VkAttachmentReference* pResolveAttachments;
7163 nullptr, // const VkAttachmentReference* pDepthStencilAttachment;
7164 0u, // uint32_t preserveAttachmentCount;
7165 nullptr, // const uint32_t* pPreserveAttachments;
7166 };
7167
7168 const VkRenderPassCreateInfo renderPassInfo = {
7169 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
7170 nullptr, // const void* pNext;
7171 0u, // VkRenderPassCreateFlags flags;
7172 static_cast<uint32_t>(attachmentDescriptions.size()), // uint32_t attachmentCount;
7173 attachmentDescriptions.data(), // const VkAttachmentDescription* pAttachments;
7174 1u, // uint32_t subpassCount;
7175 &subpassDescription, // const VkSubpassDescription* pSubpasses;
7176 0u, // uint32_t dependencyCount;
7177 nullptr, // const VkSubpassDependency* pDependencies;
7178 };
7179
7180 const auto renderPass = createRenderPass(vkd, device, &renderPassInfo);
7181
7182 // Framebuffer.
7183 std::vector<Move<VkImageView>> imageViews;
7184 std::vector<VkImageView> imageViewsRaw;
7185
7186 if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
7187 {
7188 imageViews.push_back(makeImageView(vkd, device, m_multisampledImage.get(), VK_IMAGE_VIEW_TYPE_2D,
7189 m_params.src.image.format,
7190 makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 2u, 1u)));
7191 imageViews.push_back(makeImageView(vkd, device, m_multisampledCopyImage.get(), VK_IMAGE_VIEW_TYPE_2D,
7192 m_params.src.image.format,
7193 makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 4u, 1u)));
7194 }
7195 else
7196 {
7197 imageViews.push_back(makeImageView(vkd, device, m_multisampledImage.get(), VK_IMAGE_VIEW_TYPE_2D,
7198 m_params.src.image.format,
7199 makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u)));
7200 for (uint32_t i = 0u; i < numDstLayers; ++i)
7201 {
7202 const auto subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, i, 1u);
7203 imageViews.push_back(makeImageView(vkd, device, m_multisampledCopyImage.get(), VK_IMAGE_VIEW_TYPE_2D,
7204 m_params.dst.image.format, subresourceRange));
7205 }
7206 }
7207
7208 imageViewsRaw.reserve(imageViews.size());
7209 std::transform(begin(imageViews), end(imageViews), std::back_inserter(imageViewsRaw),
7210 [](const Move<VkImageView> &ptr) { return ptr.get(); });
7211
7212 const auto framebuffer = makeFramebuffer(vkd, device, renderPass.get(), static_cast<uint32_t>(imageViewsRaw.size()),
7213 imageViewsRaw.data(), fbWidth, fbHeight);
7214
7215 // Storage buffer.
7216 const auto bufferCount = static_cast<size_t>(fbWidth * fbHeight * m_params.samples);
7217 const auto bufferSize = static_cast<VkDeviceSize>(bufferCount * sizeof(int32_t));
7218 BufferWithMemory buffer(vkd, device, alloc, makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
7219 MemoryRequirement::HostVisible);
7220 auto &bufferAlloc = buffer.getAllocation();
7221 void *bufferData = bufferAlloc.getHostPtr();
7222
7223 // Update descriptor sets.
7224 DescriptorSetUpdateBuilder updater;
7225
7226 const auto bufferInfo = makeDescriptorBufferInfo(buffer.get(), 0ull, bufferSize);
7227 updater.writeSingle(descriptorSetBuffer.get(), DescriptorSetUpdateBuilder::Location::binding(0u),
7228 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferInfo);
7229
7230 std::vector<VkDescriptorImageInfo> imageInfos;
7231 imageInfos.reserve(imageViewsRaw.size());
7232 for (size_t i = 0; i < imageViewsRaw.size(); ++i)
7233 imageInfos.push_back(
7234 makeDescriptorImageInfo(DE_NULL, imageViewsRaw[i], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL));
7235
7236 for (size_t i = 0; i < imageInfos.size(); ++i)
7237 updater.writeSingle(descriptorSetAttachments.get(),
7238 DescriptorSetUpdateBuilder::Location::binding(static_cast<uint32_t>(i)),
7239 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &imageInfos[i]);
7240
7241 updater.update(vkd, device);
7242
7243 // Vertex buffer.
7244 std::vector<tcu::Vec4> fullScreenQuad;
7245 {
7246 // Full screen quad so every framebuffer pixel and sample location is verified by the shader.
7247 const tcu::Vec4 topLeft(-1.0f, -1.0f, 0.0f, 1.0f);
7248 const tcu::Vec4 topRight(1.0f, -1.0f, 0.0f, 1.0f);
7249 const tcu::Vec4 bottomLeft(-1.0f, 1.0f, 0.0f, 1.0f);
7250 const tcu::Vec4 bottomRight(1.0f, 1.0f, 0.0f, 1.0f);
7251
7252 fullScreenQuad.reserve(6u);
7253 fullScreenQuad.push_back(topLeft);
7254 fullScreenQuad.push_back(topRight);
7255 fullScreenQuad.push_back(bottomRight);
7256 fullScreenQuad.push_back(topLeft);
7257 fullScreenQuad.push_back(bottomRight);
7258 fullScreenQuad.push_back(bottomLeft);
7259 }
7260
7261 const auto vertexBufferSize =
7262 static_cast<VkDeviceSize>(fullScreenQuad.size() * sizeof(decltype(fullScreenQuad)::value_type));
7263 const auto vertexBufferInfo = makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
7264 const BufferWithMemory vertexBuffer(vkd, device, alloc, vertexBufferInfo, MemoryRequirement::HostVisible);
7265 const auto vertexBufferHandler = vertexBuffer.get();
7266 auto &vertexBufferAlloc = vertexBuffer.getAllocation();
7267 void *vertexBufferData = vertexBufferAlloc.getHostPtr();
7268 const VkDeviceSize vertexBufferOffset = 0ull;
7269
7270 deMemcpy(vertexBufferData, fullScreenQuad.data(), static_cast<size_t>(vertexBufferSize));
7271 flushAlloc(vkd, device, vertexBufferAlloc);
7272
7273 // Graphics pipeline.
7274 const std::vector<VkViewport> viewports(1, makeViewport(m_params.src.image.extent));
7275 const std::vector<VkRect2D> scissors(1, makeRect2D(m_params.src.image.extent));
7276
7277 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = {
7278 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
7279 nullptr, // const void* pNext;
7280 0u, // VkPipelineMultisampleStateCreateFlags flags;
7281 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
7282 VK_FALSE, // VkBool32 sampleShadingEnable;
7283 0.0f, // float minSampleShading;
7284 nullptr, // const VkSampleMask* pSampleMask;
7285 VK_FALSE, // VkBool32 alphaToCoverageEnable;
7286 VK_FALSE // VkBool32 alphaToOneEnable;
7287 };
7288
7289 const auto graphicsPipeline = makeGraphicsPipeline(
7290 vkd, // const DeviceInterface& vk
7291 device, // const VkDevice device
7292 pipelineLayout.get(), // const VkPipelineLayout pipelineLayout
7293 vertexModule.get(), // const VkShaderModule vertexShaderModule
7294 DE_NULL, // const VkShaderModule tessellationControlModule
7295 DE_NULL, // const VkShaderModule tessellationEvalModule
7296 DE_NULL, // const VkShaderModule geometryShaderModule
7297 verificationModule.get(), // const VkShaderModule fragmentShaderModule
7298 renderPass.get(), // const VkRenderPass renderPass
7299 viewports, // const std::vector<VkViewport>& viewports
7300 scissors, // const std::vector<VkRect2D>& scissors
7301 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
7302 0u, // const uint32_t subpass
7303 0u, // const uint32_t patchControlPoints
7304 nullptr, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
7305 nullptr, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
7306 &multisampleStateParams); // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
7307
7308 // Command buffer.
7309 const auto cmdPool = makeCommandPool(vkd, device, queueIndex);
7310 const auto cmdBufferPtr = allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
7311 const auto cmdBuffer = cmdBufferPtr.get();
7312
7313 // Make sure multisample copy data is available to the fragment shader.
7314 const auto imagesBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT);
7315
7316 // Make sure verification buffer data is available on the host.
7317 const auto bufferBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
7318
7319 // Record and submit command buffer.
7320 beginCommandBuffer(vkd, cmdBuffer);
7321 vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 1u,
7322 &imagesBarrier, 0u, nullptr, 0u, nullptr);
7323 beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffer.get(), makeRect2D(m_params.src.image.extent));
7324 vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline.get());
7325 vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBufferHandler, &vertexBufferOffset);
7326 vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), VK_SHADER_STAGE_FRAGMENT_BIT, 0u, pushConstantSize,
7327 pushConstantData.data());
7328 vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u,
7329 static_cast<uint32_t>(descriptorSets.size()), descriptorSets.data(), 0u, nullptr);
7330 vkd.cmdDraw(cmdBuffer, static_cast<uint32_t>(fullScreenQuad.size()), 1u, 0u, 0u);
7331 endRenderPass(vkd, cmdBuffer);
7332 vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u,
7333 &bufferBarrier, 0u, nullptr, 0u, nullptr);
7334 endCommandBuffer(vkd, cmdBuffer);
7335 submitCommandsAndWait(vkd, device, m_universalQueue, cmdBuffer);
7336 m_context.resetCommandPoolForVKSC(device, *cmdPool);
7337
7338 // Verify intermediate results.
7339 invalidateAlloc(vkd, device, bufferAlloc);
7340 std::vector<int32_t> outputFlags(bufferCount, 0);
7341 deMemcpy(outputFlags.data(), bufferData, static_cast<size_t>(bufferSize));
7342
7343 auto &log = m_context.getTestContext().getLog();
7344 log << tcu::TestLog::Message << "Verifying intermediate multisample copy results" << tcu::TestLog::EndMessage;
7345
7346 const auto sampleCount = static_cast<uint32_t>(m_params.samples);
7347
7348 for (uint32_t x = 0u; x < fbWidth; ++x)
7349 for (uint32_t y = 0u; y < fbHeight; ++y)
7350 for (uint32_t s = 0u; s < sampleCount; ++s)
7351 {
7352 const auto index = (y * fbWidth + x) * sampleCount + s;
7353 if (!outputFlags[index])
7354 {
7355 std::ostringstream msg;
7356 msg << "Intermediate verification failed for coordinates (" << x << ", " << y << ") sample " << s;
7357 return tcu::TestStatus::fail(msg.str());
7358 }
7359 }
7360
7361 log << tcu::TestLog::Message << "Intermediate multisample copy verification passed" << tcu::TestLog::EndMessage;
7362 return tcu::TestStatus::pass("Pass");
7363 }
7364
copyMSImageToMSImage(uint32_t copyArraySize)7365 void ResolveImageToImage::copyMSImageToMSImage(uint32_t copyArraySize)
7366 {
7367 const DeviceInterface &vk = m_context.getDeviceInterface();
7368 const VkDevice vkDevice = m_device;
7369 const tcu::TextureFormat srcTcuFormat = mapVkFormat(m_params.src.image.format);
7370 std::vector<VkImageCopy> imageCopies;
7371 std::vector<VkImageCopy2KHR> imageCopies2KHR;
7372
7373 if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
7374 {
7375 const VkImageSubresourceLayers sourceSubresourceLayers = {
7376 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
7377 0u, // uint32_t mipLevel;
7378 2u, // uint32_t baseArrayLayer;
7379 1u // uint32_t layerCount;
7380 };
7381
7382 const VkImageSubresourceLayers destinationSubresourceLayers = {
7383 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;//getAspectFlags(dstTcuFormat)
7384 0u, // uint32_t mipLevel;
7385 4u, // uint32_t baseArrayLayer;
7386 1u // uint32_t layerCount;
7387 };
7388
7389 const VkImageCopy imageCopy = {
7390 sourceSubresourceLayers, // VkImageSubresourceLayers srcSubresource;
7391 {0, 0, 0}, // VkOffset3D srcOffset;
7392 destinationSubresourceLayers, // VkImageSubresourceLayers dstSubresource;
7393 {0, 0, 0}, // VkOffset3D dstOffset;
7394 getExtent3D(m_params.src.image), // VkExtent3D extent;
7395 };
7396
7397 if (!(m_params.extensionFlags & COPY_COMMANDS_2))
7398 {
7399 imageCopies.push_back(imageCopy);
7400 }
7401 else
7402 {
7403 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
7404 imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
7405 }
7406 }
7407 else if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION)
7408 {
7409 VkExtent3D partialExtent = {getExtent3D(m_params.src.image).width / 2,
7410 getExtent3D(m_params.src.image).height / 2, getExtent3D(m_params.src.image).depth};
7411
7412 for (CopyRegion region : m_params.regions)
7413 {
7414 const VkImageCopy imageCopy = {
7415 region.imageResolve.srcSubresource, // VkImageSubresourceLayers srcSubresource;
7416 region.imageResolve.srcOffset, // VkOffset3D srcOffset;
7417 region.imageResolve.dstSubresource, // VkImageSubresourceLayers dstSubresource;
7418 region.imageResolve.dstOffset, // VkOffset3D dstOffset;
7419 partialExtent, // VkExtent3D extent;
7420 };
7421
7422 if (!(m_params.extensionFlags & COPY_COMMANDS_2))
7423 {
7424 imageCopies.push_back(imageCopy);
7425 }
7426 else
7427 {
7428 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
7429 imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
7430 }
7431 }
7432 }
7433 else
7434 {
7435 for (uint32_t layerNdx = 0; layerNdx < copyArraySize; ++layerNdx)
7436 {
7437 const VkImageSubresourceLayers sourceSubresourceLayers = {
7438 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
7439 0u, // uint32_t mipLevel;
7440 0u, // uint32_t baseArrayLayer;
7441 1u // uint32_t layerCount;
7442 };
7443
7444 const VkImageSubresourceLayers destinationSubresourceLayers = {
7445 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;//getAspectFlags(dstTcuFormat)
7446 0u, // uint32_t mipLevel;
7447 layerNdx, // uint32_t baseArrayLayer;
7448 1u // uint32_t layerCount;
7449 };
7450
7451 const VkImageCopy imageCopy = {
7452 sourceSubresourceLayers, // VkImageSubresourceLayers srcSubresource;
7453 {0, 0, 0}, // VkOffset3D srcOffset;
7454 destinationSubresourceLayers, // VkImageSubresourceLayers dstSubresource;
7455 {0, 0, 0}, // VkOffset3D dstOffset;
7456 getExtent3D(m_params.src.image), // VkExtent3D extent;
7457 };
7458
7459 if (!(m_params.extensionFlags & COPY_COMMANDS_2))
7460 {
7461 imageCopies.push_back(imageCopy);
7462 }
7463 else
7464 {
7465 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
7466 imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
7467 }
7468 }
7469 }
7470
7471 VkImageSubresourceRange subresourceRange = {
7472 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask
7473 0u, // uint32_t baseMipLevel
7474 1u, // uint32_t mipLevels
7475 0u, // uint32_t baseArraySlice
7476 copyArraySize // uint32_t arraySize
7477 };
7478
7479 // m_multisampledImage
7480 const VkImageMemoryBarrier m_multisampledImageBarrier = {
7481 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
7482 DE_NULL, // const void* pNext;
7483 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask;
7484 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
7485 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
7486 m_params.src.image.operationLayout, // VkImageLayout newLayout;
7487 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
7488 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
7489 m_multisampledImage.get(), // VkImage image;
7490 {
7491 // VkImageSubresourceRange subresourceRange;
7492 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
7493 0u, // uint32_t baseMipLevel;
7494 1u, // uint32_t mipLevels;
7495 0u, // uint32_t baseArraySlice;
7496 getArraySize(m_params.src.image) // uint32_t arraySize;
7497 }};
7498 // m_multisampledCopyImage
7499 VkImageMemoryBarrier m_multisampledCopyImageBarrier = {
7500 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
7501 DE_NULL, // const void* pNext;
7502 0, // VkAccessFlags srcAccessMask;
7503 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
7504 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
7505 m_params.dst.image.operationLayout, // VkImageLayout newLayout;
7506 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
7507 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
7508 m_multisampledCopyImage.get(), // VkImage image;
7509 subresourceRange // VkImageSubresourceRange subresourceRange;
7510 };
7511
7512 // m_multisampledCopyNoCabImage (no USAGE_COLOR_ATTACHMENT_BIT)
7513 const VkImageMemoryBarrier m_multisampledCopyNoCabImageBarrier = {
7514 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
7515 DE_NULL, // const void* pNext;
7516 0, // VkAccessFlags srcAccessMask;
7517 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
7518 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
7519 m_params.dst.image.operationLayout, // VkImageLayout newLayout;
7520 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
7521 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
7522 m_multisampledCopyNoCabImage.get(), // VkImage image;
7523 subresourceRange // VkImageSubresourceRange subresourceRange;
7524 };
7525
7526 // destination image
7527 const VkImageMemoryBarrier multisampledCopyImagePostBarrier = {
7528 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
7529 DE_NULL, // const void* pNext;
7530 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
7531 VK_ACCESS_MEMORY_READ_BIT, // VkAccessFlags dstAccessMask;
7532 m_params.dst.image.operationLayout, // VkImageLayout oldLayout;
7533 m_params.src.image.operationLayout, // VkImageLayout newLayout;
7534 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
7535 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
7536 m_multisampledCopyImage.get(), // VkImage image;
7537 subresourceRange // VkImageSubresourceRange subresourceRange;
7538 };
7539
7540 // destination image (no USAGE_COLOR_ATTACHMENT_BIT)
7541 const VkImageMemoryBarrier betweenCopyImageBarrier = {
7542 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
7543 DE_NULL, // const void* pNext;
7544 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
7545 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
7546 m_params.dst.image.operationLayout, // VkImageLayout oldLayout;
7547 m_params.src.image.operationLayout, // VkImageLayout newLayout;
7548 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
7549 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
7550 m_multisampledCopyNoCabImage.get(), // VkImage image;
7551 subresourceRange // VkImageSubresourceRange subresourceRange;
7552 };
7553
7554 uint32_t familyIndex = activeQueueFamilyIndex();
7555 VkQueue queue = VK_NULL_HANDLE;
7556 VkCommandBuffer commandBuffer = VK_NULL_HANDLE;
7557 VkCommandPool commandPool = VK_NULL_HANDLE;
7558 std::tie(queue, commandBuffer, commandPool) = activeExecutionCtx();
7559
7560 // Queue family ownership transfer. Move ownership of the m_multisampledImage and m_multisampledImageCopy to the compute/transfer queue.
7561 if (m_params.queueSelection != QueueSelectionOptions::Universal)
7562 {
7563 // Release ownership from graphics queue.
7564 {
7565 std::vector<VkImageMemoryBarrier> barriers;
7566 barriers.reserve(2);
7567
7568 // Barrier for m_multisampledImage
7569 VkImageMemoryBarrier releaseBarrier = m_multisampledImageBarrier;
7570 releaseBarrier.dstAccessMask = 0u; // dstAccessMask is ignored in ownership release operation.
7571 releaseBarrier.srcQueueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
7572 releaseBarrier.dstQueueFamilyIndex = familyIndex;
7573 barriers.push_back(releaseBarrier);
7574
7575 // Barrier for m_multisampledCopyImage
7576 releaseBarrier = m_multisampledCopyImageBarrier;
7577 releaseBarrier.dstAccessMask = 0u; // dstAccessMask is ignored in ownership release operation.
7578 releaseBarrier.srcQueueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
7579 releaseBarrier.dstQueueFamilyIndex = familyIndex;
7580 barriers.push_back(releaseBarrier);
7581
7582 beginCommandBuffer(vk, *m_universalCmdBuffer);
7583 vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
7584 VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, (VkDependencyFlags)0, 0,
7585 (const VkMemoryBarrier *)DE_NULL, 0, (const VkBufferMemoryBarrier *)DE_NULL,
7586 (uint32_t)barriers.size(), barriers.data());
7587 endCommandBuffer(vk, *m_universalCmdBuffer);
7588 submitCommandsAndWait(vk, vkDevice, m_universalQueue, *m_universalCmdBuffer);
7589 m_context.resetCommandPoolForVKSC(vkDevice, *m_universalCmdPool);
7590 }
7591
7592 // Acquire ownership to compute / transfer queue.
7593 {
7594 std::vector<VkImageMemoryBarrier> barriers;
7595 barriers.reserve(2);
7596
7597 // Barrier for m_multisampledImage
7598 VkImageMemoryBarrier acquireBarrier = m_multisampledImageBarrier;
7599 acquireBarrier.srcAccessMask = 0u; // srcAccessMask is ignored in ownership acquire operation.
7600 acquireBarrier.srcQueueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
7601 acquireBarrier.dstQueueFamilyIndex = familyIndex;
7602 barriers.push_back(acquireBarrier);
7603
7604 // Barrier for m_multisampledImage
7605 acquireBarrier = m_multisampledCopyImageBarrier;
7606 acquireBarrier.srcAccessMask = 0u; // srcAccessMask is ignored in ownership acquire operation.
7607 acquireBarrier.srcQueueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
7608 acquireBarrier.dstQueueFamilyIndex = familyIndex;
7609 barriers.push_back(acquireBarrier);
7610
7611 beginCommandBuffer(vk, commandBuffer);
7612 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
7613 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
7614 (const VkBufferMemoryBarrier *)DE_NULL, (uint32_t)barriers.size(), barriers.data());
7615 endCommandBuffer(vk, commandBuffer);
7616 submitCommandsAndWait(vk, vkDevice, queue, commandBuffer);
7617 m_context.resetCommandPoolForVKSC(vkDevice, commandPool);
7618 }
7619
7620 beginCommandBuffer(vk, commandBuffer);
7621 }
7622 else
7623 {
7624 // Universal queue
7625
7626 std::vector<VkImageMemoryBarrier> imageBarriers;
7627
7628 imageBarriers.push_back(m_multisampledImageBarrier);
7629 // Only use one barrier if no options have been given.
7630 if (m_options != NO_OPTIONAL_OPERATION)
7631 {
7632 imageBarriers.push_back(m_multisampledCopyImageBarrier);
7633 // Add the third barrier if option is as below.
7634 if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB)
7635 imageBarriers.push_back(m_multisampledCopyNoCabImageBarrier);
7636 }
7637
7638 beginCommandBuffer(vk, commandBuffer);
7639 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
7640 VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL,
7641 0, (const VkBufferMemoryBarrier *)DE_NULL, (uint32_t)imageBarriers.size(),
7642 imageBarriers.data());
7643 }
7644
7645 if (!(m_params.extensionFlags & COPY_COMMANDS_2))
7646 {
7647 if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB)
7648 {
7649 vk.cmdCopyImage(commandBuffer, m_multisampledImage.get(), m_params.src.image.operationLayout,
7650 m_multisampledCopyNoCabImage.get(), m_params.dst.image.operationLayout,
7651 (uint32_t)imageCopies.size(), imageCopies.data());
7652 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
7653 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
7654 (const VkBufferMemoryBarrier *)DE_NULL, 1u, &betweenCopyImageBarrier);
7655 vk.cmdCopyImage(commandBuffer, m_multisampledCopyNoCabImage.get(), m_params.src.image.operationLayout,
7656 m_multisampledCopyImage.get(), m_params.dst.image.operationLayout,
7657 (uint32_t)imageCopies.size(), imageCopies.data());
7658 }
7659 else
7660 {
7661 vk.cmdCopyImage(commandBuffer, m_multisampledImage.get(), m_params.src.image.operationLayout,
7662 m_multisampledCopyImage.get(), m_params.dst.image.operationLayout,
7663 (uint32_t)imageCopies.size(), imageCopies.data());
7664 }
7665 }
7666 else
7667 {
7668 if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB)
7669 {
7670 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
7671 const VkCopyImageInfo2KHR copyImageInfo2KHR = {
7672 VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR, // VkStructureType sType;
7673 DE_NULL, // const void* pNext;
7674 m_multisampledImage.get(), // VkImage srcImage;
7675 m_params.src.image.operationLayout, // VkImageLayout srcImageLayout;
7676 m_multisampledCopyNoCabImage.get(), // VkImage dstImage;
7677 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout dstImageLayout;
7678 (uint32_t)imageCopies2KHR.size(), // uint32_t regionCount;
7679 imageCopies2KHR.data() // const VkImageCopy2KHR* pRegions;
7680 };
7681 const VkCopyImageInfo2KHR copyImageInfo2KHRCopy = {
7682 VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR, // VkStructureType sType;
7683 DE_NULL, // const void* pNext;
7684 m_multisampledCopyNoCabImage.get(), // VkImage srcImage;
7685 vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout srcImageLayout;
7686 m_multisampledCopyImage.get(), // VkImage dstImage;
7687 m_params.dst.image.operationLayout, // VkImageLayout dstImageLayout;
7688 (uint32_t)imageCopies2KHR.size(), // uint32_t regionCount;
7689 imageCopies2KHR.data() // const VkImageCopy2KHR* pRegions;
7690 };
7691
7692 vk.cmdCopyImage2(commandBuffer, ©ImageInfo2KHR);
7693 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
7694 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
7695 (const VkBufferMemoryBarrier *)DE_NULL, 1u, &betweenCopyImageBarrier);
7696 vk.cmdCopyImage2(commandBuffer, ©ImageInfo2KHRCopy);
7697 }
7698 else
7699 {
7700 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
7701 const VkCopyImageInfo2KHR copyImageInfo2KHR = {
7702 VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR, // VkStructureType sType;
7703 DE_NULL, // const void* pNext;
7704 m_multisampledImage.get(), // VkImage srcImage;
7705 m_params.src.image.operationLayout, // VkImageLayout srcImageLayout;
7706 m_multisampledCopyImage.get(), // VkImage dstImage;
7707 m_params.dst.image.operationLayout, // VkImageLayout dstImageLayout;
7708 (uint32_t)imageCopies2KHR.size(), // uint32_t regionCount;
7709 imageCopies2KHR.data() // const VkImageCopy2KHR* pRegions;
7710 };
7711 vk.cmdCopyImage2(commandBuffer, ©ImageInfo2KHR);
7712 }
7713 }
7714
7715 if (m_params.queueSelection != QueueSelectionOptions::Universal)
7716 {
7717 endCommandBuffer(vk, commandBuffer);
7718 submitCommandsAndWait(vk, vkDevice, queue, commandBuffer);
7719 m_context.resetCommandPoolForVKSC(vkDevice, commandPool);
7720
7721 VkImageMemoryBarrier srcImageBarrier = makeImageMemoryBarrier(
7722 0u, 0u, m_params.src.image.operationLayout, m_params.src.image.operationLayout, m_multisampledImage.get(),
7723 m_multisampledImageBarrier.subresourceRange, familyIndex, m_context.getUniversalQueueFamilyIndex());
7724 // Release ownership from compute / transfer queue.
7725 {
7726 std::vector<VkImageMemoryBarrier> barriers;
7727 barriers.reserve(2);
7728
7729 VkImageMemoryBarrier releaseBarrier = multisampledCopyImagePostBarrier;
7730 releaseBarrier.dstAccessMask = 0u; // dstAccessMask is ignored in ownership release operation.
7731 releaseBarrier.srcQueueFamilyIndex = familyIndex;
7732 releaseBarrier.dstQueueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
7733 barriers.push_back(releaseBarrier);
7734
7735 releaseBarrier = srcImageBarrier;
7736 releaseBarrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
7737 releaseBarrier.dstAccessMask = 0u; // dstAccessMask is ignored in ownership release operation.
7738 barriers.push_back(releaseBarrier);
7739
7740 beginCommandBuffer(vk, commandBuffer);
7741 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
7742 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
7743 (const VkBufferMemoryBarrier *)DE_NULL, (uint32_t)barriers.size(), barriers.data());
7744 endCommandBuffer(vk, commandBuffer);
7745 submitCommandsAndWait(vk, vkDevice, queue, commandBuffer);
7746 m_context.resetCommandPoolForVKSC(vkDevice, commandPool);
7747 }
7748
7749 // Move ownership back to graphics queue.
7750 {
7751 std::vector<VkImageMemoryBarrier> barriers;
7752 barriers.reserve(2);
7753
7754 VkImageMemoryBarrier acquireBarrier = multisampledCopyImagePostBarrier;
7755 acquireBarrier.srcAccessMask = 0u; // srcAccessMask is ignored in ownership acquire operation.
7756 acquireBarrier.srcQueueFamilyIndex = familyIndex;
7757 acquireBarrier.dstQueueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
7758 barriers.push_back(acquireBarrier);
7759
7760 acquireBarrier = srcImageBarrier;
7761 acquireBarrier.srcAccessMask = 0u; // srcAccessMask is ignored in ownership acquire operation.
7762 acquireBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
7763 barriers.push_back(acquireBarrier);
7764
7765 beginCommandBuffer(vk, *m_universalCmdBuffer);
7766 vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
7767 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 0,
7768 (const VkMemoryBarrier *)DE_NULL, 0, (const VkBufferMemoryBarrier *)DE_NULL,
7769 (uint32_t)barriers.size(), barriers.data());
7770 endCommandBuffer(vk, *m_universalCmdBuffer);
7771 submitCommandsAndWait(vk, vkDevice, m_universalQueue, *m_universalCmdBuffer);
7772 m_context.resetCommandPoolForVKSC(vkDevice, *m_universalCmdPool);
7773 }
7774 }
7775 else
7776 {
7777 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7778 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
7779 (const VkBufferMemoryBarrier *)DE_NULL, 1u, &multisampledCopyImagePostBarrier);
7780 endCommandBuffer(vk, commandBuffer);
7781 submitCommandsAndWait(vk, vkDevice, queue, commandBuffer);
7782 m_context.resetCommandPoolForVKSC(vkDevice, commandPool);
7783 }
7784 }
7785
7786 class ResolveImageToImageTestCase : public vkt::TestCase
7787 {
7788 public:
ResolveImageToImageTestCase(tcu::TestContext & testCtx,const std::string & name,const TestParams params,const ResolveImageToImageOptions options=NO_OPTIONAL_OPERATION)7789 ResolveImageToImageTestCase(tcu::TestContext &testCtx, const std::string &name, const TestParams params,
7790 const ResolveImageToImageOptions options = NO_OPTIONAL_OPERATION)
7791 : vkt::TestCase(testCtx, name)
7792 , m_params(params)
7793 , m_options(options)
7794 {
7795 }
7796
7797 virtual void initPrograms(SourceCollections &programCollection) const;
7798
createInstance(Context & context) const7799 virtual TestInstance *createInstance(Context &context) const
7800 {
7801 return new ResolveImageToImage(context, m_params, m_options);
7802 }
7803
checkSupport(Context & context) const7804 virtual void checkSupport(Context &context) const
7805 {
7806 const VkSampleCountFlagBits rasterizationSamples = m_params.samples;
7807
7808 // Intermediate result check uses fragmentStoresAndAtomics.
7809 if (ResolveImageToImage::shouldVerifyIntermediateResults(m_options) &&
7810 !context.getDeviceFeatures().fragmentStoresAndAtomics)
7811 {
7812 TCU_THROW(NotSupportedError, "fragmentStoresAndAtomics not supported");
7813 }
7814
7815 if (!(context.getDeviceProperties().limits.framebufferColorSampleCounts & rasterizationSamples))
7816 throw tcu::NotSupportedError("Unsupported number of rasterization samples");
7817
7818 VkImageFormatProperties properties;
7819 if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
7820 context.getPhysicalDevice(), m_params.src.image.format, m_params.src.image.imageType,
7821 VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
7822 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
7823 (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
7824 context.getPhysicalDevice(), m_params.dst.image.format, m_params.dst.image.imageType,
7825 VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0,
7826 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
7827 {
7828 TCU_THROW(NotSupportedError, "Format not supported");
7829 }
7830
7831 checkExtensionSupport(context, m_params.extensionFlags);
7832
7833 // Find at least one queue family that supports compute queue but does NOT support graphics queue.
7834 if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE)
7835 {
7836 if (context.getComputeQueueFamilyIndex() == -1)
7837 TCU_THROW(NotSupportedError, "No queue family found that only supports compute queue.");
7838 }
7839
7840 // Find at least one queue family that supports transfer queue but does NOT support graphics and compute queue.
7841 if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER)
7842 {
7843 if (context.getTransferQueueFamilyIndex() == -1)
7844 TCU_THROW(NotSupportedError, "No queue family found that only supports transfer queue.");
7845 }
7846 }
7847
7848 private:
7849 TestParams m_params;
7850 const ResolveImageToImageOptions m_options;
7851 };
7852
initPrograms(SourceCollections & programCollection) const7853 void ResolveImageToImageTestCase::initPrograms(SourceCollections &programCollection) const
7854 {
7855 programCollection.glslSources.add("vert") << glu::VertexSource("#version 310 es\n"
7856 "layout (location = 0) in highp vec4 a_position;\n"
7857 "void main()\n"
7858 "{\n"
7859 " gl_Position = a_position;\n"
7860 "}\n");
7861
7862 programCollection.glslSources.add("frag") << glu::FragmentSource("#version 310 es\n"
7863 "layout (location = 0) out highp vec4 o_color;\n"
7864 "void main()\n"
7865 "{\n"
7866 " o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
7867 "}\n");
7868
7869 if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE ||
7870 m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION ||
7871 m_options == COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER)
7872 {
7873 // The shader verifies all layers in the copied image are the same as the source image.
7874 // This needs an image view per layer in the copied image.
7875 // Set 0 contains the output buffer.
7876 // Set 1 contains the input attachments.
7877
7878 std::ostringstream verificationShader;
7879
7880 verificationShader
7881 << "#version 450\n"
7882 << "\n"
7883 << "layout (push_constant, std430) uniform PushConstants {\n"
7884 << " int width;\n"
7885 << " int height;\n"
7886 << " int samples;\n"
7887 << "};\n"
7888 << "layout (set=0, binding=0) buffer VerificationResults {\n"
7889 << " int verificationFlags[];\n"
7890 << "};\n"
7891 << "layout (input_attachment_index=0, set=1, binding=0) uniform subpassInputMS attachment0;\n";
7892
7893 const auto dstLayers = getArraySize(m_params.dst.image);
7894
7895 if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
7896 {
7897 verificationShader
7898 << "layout (input_attachment_index=1, set=1, binding=1) uniform subpassInputMS attachment1;\n";
7899 }
7900 else
7901 {
7902 for (uint32_t layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
7903 {
7904 const auto i = layerNdx + 1u;
7905 verificationShader << "layout (input_attachment_index=" << i << ", set=1, binding=" << i
7906 << ") uniform subpassInputMS attachment" << i << ";\n";
7907 }
7908 }
7909
7910 // Using a loop to iterate over each sample avoids the need for the sampleRateShading feature. The pipeline needs to be
7911 // created with a single sample.
7912 verificationShader << "\n"
7913 << "void main() {\n"
7914 << " for (int sampleID = 0; sampleID < samples; ++sampleID) {\n"
7915 << " vec4 orig = subpassLoad(attachment0, sampleID);\n";
7916
7917 std::ostringstream testCondition;
7918 if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
7919 {
7920 verificationShader << " vec4 copy = subpassLoad(attachment1, sampleID);\n";
7921 testCondition << "orig == copy";
7922 }
7923 else
7924 {
7925 for (uint32_t layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
7926 {
7927 const auto i = layerNdx + 1u;
7928 verificationShader << " vec4 copy" << i << " = subpassLoad(attachment" << i << ", sampleID);\n";
7929 }
7930
7931 for (uint32_t layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
7932 {
7933 const auto i = layerNdx + 1u;
7934 testCondition << (layerNdx == 0u ? "" : " && ") << "orig == copy" << i;
7935 }
7936 }
7937
7938 verificationShader << "\n"
7939 << " ivec3 coords = ivec3(int(gl_FragCoord.x), int(gl_FragCoord.y), sampleID);\n"
7940 << " int bufferPos = (coords.y * width + coords.x) * samples + coords.z;\n"
7941 << "\n"
7942 << " verificationFlags[bufferPos] = ((" << testCondition.str() << ") ? 1 : 0); \n"
7943 << " }\n"
7944 << "}\n";
7945
7946 programCollection.glslSources.add("verify") << glu::FragmentSource(verificationShader.str());
7947 }
7948 }
7949
7950 class DepthStencilMSAA : public vkt::TestInstance
7951 {
7952 public:
7953 enum CopyOptions
7954 {
7955 COPY_WHOLE_IMAGE,
7956 COPY_ARRAY_TO_ARRAY,
7957 COPY_PARTIAL
7958 };
7959
7960 struct TestParameters
7961 {
7962 AllocationKind allocationKind;
7963 uint32_t extensionFlags;
7964 CopyOptions copyOptions;
7965 VkSampleCountFlagBits samples;
7966 VkImageLayout srcImageLayout;
7967 VkImageLayout dstImageLayout;
7968 VkFormat imageFormat;
7969 VkImageAspectFlags copyAspect;
7970 bool imageOffset;
7971 };
7972
7973 DepthStencilMSAA(Context &context, TestParameters testParameters);
7974 tcu::TestStatus iterate(void) override;
7975
7976 protected:
7977 tcu::TestStatus checkCopyResults(VkCommandBuffer cmdBuffer, const VkImageAspectFlagBits &aspectToVerify,
7978 VkImage srcImage, VkImage dstImage);
7979
7980 private:
7981 // Returns image aspects used in the copy regions.
getUsedImageAspects()7982 VkImageAspectFlags getUsedImageAspects()
7983 {
7984 auto aspectFlags = (VkImageAspectFlags)0;
7985 for (const auto ®ion : m_regions)
7986 {
7987 aspectFlags |= region.imageCopy.srcSubresource.aspectMask;
7988 }
7989 return aspectFlags;
7990 }
7991
7992 ImageParms m_srcImage;
7993 ImageParms m_dstImage;
7994 std::vector<CopyRegion> m_regions;
7995 const TestParameters m_params;
7996 const float m_clearValue = 0.0f;
7997 };
7998
DepthStencilMSAA(Context & context,TestParameters testParameters)7999 DepthStencilMSAA::DepthStencilMSAA(Context &context, TestParameters testParameters)
8000 : vkt::TestInstance(context)
8001 , m_params(testParameters)
8002 {
8003 // params.src.image is the parameters used to create the copy source image
8004 m_srcImage.imageType = VK_IMAGE_TYPE_2D;
8005 m_srcImage.format = testParameters.imageFormat;
8006 m_srcImage.extent = defaultExtent;
8007 m_srcImage.tiling = VK_IMAGE_TILING_OPTIMAL;
8008 m_srcImage.operationLayout = testParameters.srcImageLayout;
8009 m_srcImage.createFlags = 0u;
8010
8011 // params.src.image is the parameters used to create the copy destination image
8012 m_dstImage.imageType = VK_IMAGE_TYPE_2D;
8013 m_dstImage.format = testParameters.imageFormat;
8014 m_dstImage.extent = defaultExtent;
8015 m_dstImage.tiling = VK_IMAGE_TILING_OPTIMAL;
8016 m_dstImage.operationLayout = testParameters.dstImageLayout;
8017 m_dstImage.createFlags = 0u;
8018
8019 const VkImageSubresourceLayers depthSubresourceLayers = {
8020 VK_IMAGE_ASPECT_DEPTH_BIT, // VkImageAspectFlags aspectMask;
8021 0u, // uint32_t mipLevel;
8022 0u, // uint32_t baseArrayLayer;
8023 1u // uint32_t layerCount;
8024 };
8025
8026 const VkImageSubresourceLayers stencilSubresourceLayers = {
8027 VK_IMAGE_ASPECT_STENCIL_BIT, // VkImageAspectFlags aspectMask;
8028 0u, // uint32_t mipLevel;
8029 0u, // uint32_t baseArrayLayer;
8030 1u // uint32_t layerCount;
8031 };
8032
8033 VkImageCopy depthCopy = {
8034 depthSubresourceLayers, // VkImageSubresourceLayers srcSubresource;
8035 {0, 0, 0}, // VkOffset3D srcOffset;
8036 depthSubresourceLayers, // VkImageSubresourceLayers dstSubresource;
8037 {0, 0, 0}, // VkOffset3D dstOffset;
8038 defaultExtent, // VkExtent3D extent;
8039 };
8040
8041 VkImageCopy stencilCopy = {
8042 stencilSubresourceLayers, // VkImageSubresourceLayers srcSubresource;
8043 {0, 0, 0}, // VkOffset3D srcOffset;
8044 stencilSubresourceLayers, // VkImageSubresourceLayers dstSubresource;
8045 {0, 0, 0}, // VkOffset3D dstOffset;
8046 defaultExtent, // VkExtent3D extent;
8047 };
8048
8049 if (testParameters.copyOptions == DepthStencilMSAA::COPY_ARRAY_TO_ARRAY)
8050 {
8051 m_srcImage.extent.depth = 5u;
8052 depthCopy.srcSubresource.baseArrayLayer = 2u;
8053 depthCopy.dstSubresource.baseArrayLayer = 3u;
8054 stencilCopy.srcSubresource.baseArrayLayer = 2u;
8055 stencilCopy.dstSubresource.baseArrayLayer = 3u;
8056 }
8057
8058 CopyRegion depthCopyRegion;
8059 CopyRegion stencilCopyRegion;
8060 depthCopyRegion.imageCopy = depthCopy;
8061 stencilCopyRegion.imageCopy = stencilCopy;
8062
8063 std::vector<CopyRegion> depthRegions;
8064 std::vector<CopyRegion> stencilRegions;
8065
8066 if (testParameters.copyOptions == DepthStencilMSAA::COPY_PARTIAL)
8067 {
8068 if (testParameters.copyAspect & VK_IMAGE_ASPECT_DEPTH_BIT)
8069 {
8070 depthCopyRegion.imageCopy.extent = {defaultHalfSize, defaultHalfSize, 1};
8071 // Copy region from bottom right to bottom left
8072 depthCopyRegion.imageCopy.srcOffset = {defaultHalfSize, defaultHalfSize, 0};
8073 depthCopyRegion.imageCopy.dstOffset = {0, defaultHalfSize, 0};
8074 depthRegions.push_back(depthCopyRegion);
8075 // Copy region from top right to bottom right
8076 depthCopyRegion.imageCopy.srcOffset = {defaultHalfSize, 0, 0};
8077 depthCopyRegion.imageCopy.dstOffset = {defaultHalfSize, defaultHalfSize, 0};
8078 depthRegions.push_back(depthCopyRegion);
8079 }
8080 if (testParameters.copyAspect & VK_IMAGE_ASPECT_STENCIL_BIT)
8081 {
8082 stencilCopyRegion.imageCopy.extent = {defaultHalfSize, defaultHalfSize, 1};
8083 // Copy region from bottom right to bottom left
8084 stencilCopyRegion.imageCopy.srcOffset = {defaultHalfSize, defaultHalfSize, 0};
8085 stencilCopyRegion.imageCopy.dstOffset = {0, defaultHalfSize, 0};
8086 stencilRegions.push_back(stencilCopyRegion);
8087 // Copy region from top right to bottom right
8088 stencilCopyRegion.imageCopy.srcOffset = {defaultHalfSize, 0, 0};
8089 stencilCopyRegion.imageCopy.dstOffset = {defaultHalfSize, defaultHalfSize, 0};
8090 stencilRegions.push_back(stencilCopyRegion);
8091 }
8092 }
8093 else
8094 {
8095 // Copy the default region (full image)
8096 if (testParameters.copyAspect & VK_IMAGE_ASPECT_DEPTH_BIT)
8097 {
8098 depthRegions.push_back(depthCopyRegion);
8099 }
8100 if (testParameters.copyAspect & VK_IMAGE_ASPECT_STENCIL_BIT)
8101 {
8102 stencilRegions.push_back(stencilCopyRegion);
8103 }
8104 }
8105
8106 if (testParameters.copyAspect & VK_IMAGE_ASPECT_DEPTH_BIT)
8107 {
8108 m_regions.insert(m_regions.end(), depthRegions.begin(), depthRegions.end());
8109 }
8110
8111 if (testParameters.copyAspect & VK_IMAGE_ASPECT_STENCIL_BIT)
8112 {
8113 m_regions.insert(m_regions.end(), stencilRegions.begin(), stencilRegions.end());
8114 }
8115 }
8116
iterate(void)8117 tcu::TestStatus DepthStencilMSAA::iterate(void)
8118 {
8119 const DeviceInterface &vk = m_context.getDeviceInterface();
8120 const InstanceInterface &vki = m_context.getInstanceInterface();
8121 const VkDevice vkDevice = m_context.getDevice();
8122 const VkPhysicalDevice vkPhysDevice = m_context.getPhysicalDevice();
8123 const VkQueue queue = m_context.getUniversalQueue();
8124 const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
8125 Allocator &memAlloc = m_context.getDefaultAllocator();
8126 Move<VkCommandPool> cmdPool =
8127 createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
8128 Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
8129
8130 const tcu::TextureFormat srcTcuFormat = mapVkFormat(m_srcImage.format);
8131 const tcu::TextureFormat dstTcuFormat = mapVkFormat(m_dstImage.format);
8132 VkImageAspectFlags aspectFlags = getUsedImageAspects();
8133 uint32_t sourceArraySize = getArraySize(m_srcImage);
8134
8135 Move<VkImage> srcImage;
8136 de::MovePtr<Allocation> srcImageAlloc;
8137 Move<VkImage> dstImage;
8138 de::MovePtr<Allocation> dstImageAlloc;
8139
8140 // 1. Create the images and draw a triangle to the source image.
8141 {
8142 const VkComponentMapping componentMappingRGBA = {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
8143 VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
8144 Move<VkShaderModule> vertexShaderModule =
8145 createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
8146 Move<VkShaderModule> fragmentShaderModule =
8147 createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
8148 std::vector<tcu::Vec4> vertices;
8149 Move<VkBuffer> vertexBuffer;
8150 de::MovePtr<Allocation> vertexBufferAlloc;
8151 Move<VkPipelineLayout> pipelineLayout;
8152 Move<VkPipeline> graphicsPipeline;
8153 Move<VkRenderPass> renderPass;
8154
8155 // Create multisampled depth/stencil image (srcImage) and the copy destination image (dstImage).
8156 {
8157 VkImageCreateInfo multiSampledImageParams = {
8158 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
8159 DE_NULL, // const void* pNext;
8160 getCreateFlags(m_srcImage), // VkImageCreateFlags flags;
8161 m_srcImage.imageType, // VkImageType imageType;
8162 m_srcImage.format, // VkFormat format;
8163 getExtent3D(m_srcImage), // VkExtent3D extent;
8164 1u, // uint32_t mipLevels;
8165 getArraySize(m_srcImage), // uint32_t arrayLayers;
8166 m_params.samples, // VkSampleCountFlagBits samples;
8167 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
8168 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT // VkImageUsageFlags usage;
8169 | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL |
8170 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
8171 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
8172 1u, // uint32_t queueFamilyIndexCount;
8173 &queueFamilyIndex, // const uint32_t* pQueueFamilyIndices;
8174 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
8175 };
8176
8177 srcImage = createImage(vk, vkDevice, &multiSampledImageParams);
8178
8179 VkMemoryRequirements req = getImageMemoryRequirements(vk, vkDevice, *srcImage);
8180 uint32_t offset = m_params.imageOffset ? static_cast<uint32_t>(req.alignment) : 0;
8181
8182 srcImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, srcImage.get(), MemoryRequirement::Any,
8183 memAlloc, m_params.allocationKind, offset);
8184 VK_CHECK(vk.bindImageMemory(vkDevice, srcImage.get(), srcImageAlloc->getMemory(),
8185 srcImageAlloc->getOffset() + offset));
8186
8187 dstImage = createImage(vk, vkDevice, &multiSampledImageParams);
8188 dstImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, dstImage.get(), MemoryRequirement::Any,
8189 memAlloc, m_params.allocationKind, 0u);
8190 VK_CHECK(
8191 vk.bindImageMemory(vkDevice, dstImage.get(), dstImageAlloc->getMemory(), dstImageAlloc->getOffset()));
8192 }
8193
8194 // Create render pass.
8195 {
8196 const VkImageLayout initialLayout = m_params.copyOptions == COPY_ARRAY_TO_ARRAY ?
8197 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL :
8198 VK_IMAGE_LAYOUT_UNDEFINED;
8199 const VkAttachmentDescription attachmentDescription = {
8200 0u, // VkAttachmentDescriptionFlags flags
8201 m_srcImage.format, // VkFormat format
8202 m_params.samples, // VkSampleCountFlagBits samples
8203 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp
8204 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp
8205 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp stencilLoadOp
8206 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp
8207 initialLayout, // VkImageLayout initialLayout
8208 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout
8209 };
8210
8211 const VkAttachmentReference attachmentReference = {
8212 0u, // uint32_t attachment
8213 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout layout
8214 };
8215
8216 const VkSubpassDescription subpassDescription = {
8217 0u, // VkSubpassDescriptionFlags flags
8218 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint
8219 0u, // uint32_t inputAttachmentCount
8220 DE_NULL, // const VkAttachmentReference* pInputAttachments
8221 0u, // uint32_t colorAttachmentCount
8222 DE_NULL, // const VkAttachmentReference* pColorAttachments
8223 DE_NULL, // const VkAttachmentReference* pResolveAttachments
8224 &attachmentReference, // const VkAttachmentReference* pDepthStencilAttachment
8225 0u, // uint32_t preserveAttachmentCount
8226 DE_NULL // const VkAttachmentReference* pPreserveAttachments
8227 };
8228
8229 const VkRenderPassCreateInfo renderPassParams = {
8230 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
8231 DE_NULL, // const void* pNext;
8232 0u, // VkRenderPassCreateFlags flags;
8233 1u, // uint32_t attachmentCount;
8234 &attachmentDescription, // const VkAttachmentDescription* pAttachments;
8235 1u, // uint32_t subpassCount;
8236 &subpassDescription, // const VkSubpassDescription* pSubpasses;
8237 0u, // uint32_t dependencyCount;
8238 DE_NULL // const VkSubpassDependency* pDependencies;
8239 };
8240
8241 renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
8242 }
8243
8244 // Create pipeline layout
8245 {
8246 const VkPipelineLayoutCreateInfo pipelineLayoutParams = {
8247 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
8248 DE_NULL, // const void* pNext;
8249 0u, // VkPipelineLayoutCreateFlags flags;
8250 0u, // uint32_t setLayoutCount;
8251 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
8252 0u, // uint32_t pushConstantRangeCount;
8253 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
8254 };
8255
8256 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
8257 }
8258
8259 // Create upper half triangle.
8260 {
8261 // Add triangle.
8262 vertices.emplace_back(-1.0f, -1.0f, 0.0f, 1.0f);
8263 vertices.emplace_back(1.0f, -1.0f, 0.0f, 1.0f);
8264 vertices.emplace_back(1.0f, 1.0f, 0.0f, 1.0f);
8265 }
8266
8267 // Create vertex buffer.
8268 {
8269 const VkDeviceSize vertexDataSize = vertices.size() * sizeof(tcu::Vec4);
8270 const VkBufferCreateInfo vertexBufferParams = {
8271 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
8272 DE_NULL, // const void* pNext;
8273 0u, // VkBufferCreateFlags flags;
8274 vertexDataSize, // VkDeviceSize size;
8275 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
8276 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
8277 1u, // uint32_t queueFamilyIndexCount;
8278 &queueFamilyIndex // const uint32_t* pQueueFamilyIndices;
8279 };
8280
8281 vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
8282 vertexBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *vertexBuffer,
8283 MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
8284 VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferAlloc->getMemory(),
8285 vertexBufferAlloc->getOffset()));
8286
8287 // Load vertices into vertex buffer.
8288 deMemcpy(vertexBufferAlloc->getHostPtr(), vertices.data(), (size_t)vertexDataSize);
8289 flushAlloc(vk, vkDevice, *vertexBufferAlloc);
8290 }
8291
8292 {
8293 Move<VkFramebuffer> framebuffer;
8294 Move<VkImageView> sourceAttachmentView;
8295
8296 // Create depth/stencil attachment view.
8297 {
8298 const uint32_t arrayLayer = m_params.copyOptions == COPY_ARRAY_TO_ARRAY ? 2u : 0u;
8299 const VkImageViewCreateInfo depthStencilAttachmentViewParams = {
8300 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
8301 DE_NULL, // const void* pNext;
8302 0u, // VkImageViewCreateFlags flags;
8303 *srcImage, // VkImage image;
8304 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
8305 m_srcImage.format, // VkFormat format;
8306 componentMappingRGBA, // VkComponentMapping components;
8307 {aspectFlags, 0u, 1u, arrayLayer, 1u} // VkImageSubresourceRange subresourceRange;
8308 };
8309 sourceAttachmentView = createImageView(vk, vkDevice, &depthStencilAttachmentViewParams);
8310 }
8311
8312 // Create framebuffer
8313 {
8314 const VkFramebufferCreateInfo framebufferParams = {
8315 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
8316 DE_NULL, // const void* pNext;
8317 0u, // VkFramebufferCreateFlags flags;
8318 *renderPass, // VkRenderPass renderPass;
8319 1u, // uint32_t attachmentCount;
8320 &sourceAttachmentView.get(), // const VkImageView* pAttachments;
8321 m_srcImage.extent.width, // uint32_t width;
8322 m_srcImage.extent.height, // uint32_t height;
8323 1u // uint32_t layers;
8324 };
8325
8326 framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
8327 }
8328
8329 // Create pipeline
8330 {
8331 const std::vector<VkViewport> viewports(1, makeViewport(m_srcImage.extent));
8332 const std::vector<VkRect2D> scissors(1, makeRect2D(m_srcImage.extent));
8333
8334 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = {
8335 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
8336 DE_NULL, // const void* pNext;
8337 0u, // VkPipelineMultisampleStateCreateFlags flags;
8338 m_params.samples, // VkSampleCountFlagBits rasterizationSamples;
8339 VK_FALSE, // VkBool32 sampleShadingEnable;
8340 0.0f, // float minSampleShading;
8341 DE_NULL, // const VkSampleMask* pSampleMask;
8342 VK_FALSE, // VkBool32 alphaToCoverageEnable;
8343 VK_FALSE // VkBool32 alphaToOneEnable;
8344 };
8345
8346 const VkStencilOpState stencilOpState = {
8347 VK_STENCIL_OP_KEEP, // VkStencilOp failOp
8348 VK_STENCIL_OP_REPLACE, // VkStencilOp passOp
8349 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp
8350 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp
8351 0, // uint32_t compareMask
8352 0xFF, // uint32_t writeMask
8353 0xFF // uint32_t reference
8354 };
8355
8356 const VkPipelineDepthStencilStateCreateInfo depthStencilStateCreateInfoDefault = {
8357 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType
8358 DE_NULL, // const void* pNext
8359 0u, // VkPipelineDepthStencilStateCreateFlags flags
8360 aspectFlags & VK_IMAGE_ASPECT_DEPTH_BIT ?
8361 VK_TRUE :
8362 VK_FALSE, // VkBool32 depthTestEnable
8363 aspectFlags & VK_IMAGE_ASPECT_DEPTH_BIT ?
8364 VK_TRUE :
8365 VK_FALSE, // VkBool32 depthWriteEnable
8366 VK_COMPARE_OP_ALWAYS, // VkCompareOp depthCompareOp
8367 VK_FALSE, // VkBool32 depthBoundsTestEnable
8368 aspectFlags & VK_IMAGE_ASPECT_STENCIL_BIT ?
8369 VK_TRUE :
8370 VK_FALSE, // VkBool32 stencilTestEnable
8371 stencilOpState, // VkStencilOpState front
8372 stencilOpState, // VkStencilOpState back
8373 0.0f, // float minDepthBounds
8374 1.0f, // float maxDepthBounds
8375 };
8376
8377 graphicsPipeline = makeGraphicsPipeline(
8378 vk, // const DeviceInterface& vk
8379 vkDevice, // const VkDevice device
8380 *pipelineLayout, // const VkPipelineLayout pipelineLayout
8381 *vertexShaderModule, // const VkShaderModule vertexShaderModule
8382 DE_NULL, // const VkShaderModule tessellationControlModule
8383 DE_NULL, // const VkShaderModule tessellationEvalModule
8384 DE_NULL, // const VkShaderModule geometryShaderModule
8385 *fragmentShaderModule, // const VkShaderModule fragmentShaderModule
8386 *renderPass, // const VkRenderPass renderPass
8387 viewports, // const std::vector<VkViewport>& viewports
8388 scissors, // const std::vector<VkRect2D>& scissors
8389 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
8390 0u, // const uint32_t subpass
8391 0u, // const uint32_t patchControlPoints
8392 DE_NULL, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
8393 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
8394 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
8395 &depthStencilStateCreateInfoDefault); // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
8396 }
8397
8398 // Create command buffer
8399 {
8400 beginCommandBuffer(vk, *cmdBuffer, 0u);
8401
8402 const VkClearValue srcImageClearValue = makeClearValueDepthStencil(0.1f, 0x10);
8403
8404 // Change the layout of each layer of the depth / stencil image to VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL and clear the images.
8405 const VkClearValue copiedImageClearValue =
8406 makeClearValueDepthStencil(m_clearValue, (uint32_t)m_clearValue);
8407 const auto subResourceRange = makeImageSubresourceRange( // VkImageSubresourceRange subresourceRange
8408 (getAspectFlags(m_srcImage.format)), // VkImageAspectFlags aspectMask
8409 0u, // uint32_t baseMipLevel
8410 1u, // uint32_t levelCount
8411 0u, // uint32_t baseArrayLayer
8412 getArraySize(m_srcImage));
8413
8414 const VkImageMemoryBarrier preClearBarrier =
8415 makeImageMemoryBarrier(0u, // VkAccessFlags srcAccessMask
8416 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask
8417 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
8418 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout
8419 srcImage.get(), // VkImage image
8420 subResourceRange); // VkImageSubresourceRange subresourceRange
8421 std::vector<VkImageMemoryBarrier> preClearBarriers(2u, preClearBarrier);
8422 preClearBarriers[1].image = dstImage.get();
8423 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
8424 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
8425 (const VkBufferMemoryBarrier *)DE_NULL, 2, preClearBarriers.data());
8426
8427 vk.cmdClearDepthStencilImage(
8428 *cmdBuffer, // VkCommandBuffer commandBuffer
8429 srcImage.get(), // VkImage image
8430 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout imageLayout
8431 &srcImageClearValue.depthStencil, // const VkClearDepthStencilValue* pDepthStencil
8432 1u, // uint32_t rangeCount
8433 &subResourceRange); // const VkImageSubresourceRange* pRanges
8434
8435 vk.cmdClearDepthStencilImage(
8436 *cmdBuffer, // VkCommandBuffer commandBuffer
8437 dstImage.get(), // VkImage image
8438 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout imageLayout
8439 &copiedImageClearValue.depthStencil, // const VkClearDepthStencilValue* pDepthStencil
8440 1u, // uint32_t rangeCount
8441 &subResourceRange); // const VkImageSubresourceRange* pRanges
8442
8443 // Post clear barrier
8444 const VkImageMemoryBarrier postClearBarrier = makeImageMemoryBarrier(
8445 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask
8446 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
8447 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout
8448 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout
8449 srcImage.get(), // VkImage image
8450 subResourceRange); // VkImageSubresourceRange subresourceRange
8451
8452 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
8453 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, (VkDependencyFlags)0, 0,
8454 (const VkMemoryBarrier *)DE_NULL, 0, (const VkBufferMemoryBarrier *)DE_NULL, 1,
8455 &postClearBarrier);
8456
8457 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer,
8458 makeRect2D(0, 0, m_srcImage.extent.width, m_srcImage.extent.height), 1u,
8459 &srcImageClearValue);
8460
8461 const VkDeviceSize vertexBufferOffset = 0u;
8462
8463 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
8464 vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
8465 vk.cmdDraw(*cmdBuffer, (uint32_t)vertices.size(), 1, 0, 0);
8466
8467 endRenderPass(vk, *cmdBuffer);
8468 endCommandBuffer(vk, *cmdBuffer);
8469 }
8470
8471 submitCommandsAndWait(vk, vkDevice, queue, *cmdBuffer);
8472 m_context.resetCommandPoolForVKSC(vkDevice, *cmdPool);
8473 }
8474 }
8475
8476 // 2. Record a command buffer that contains the copy operation(s).
8477 beginCommandBuffer(vk, *cmdBuffer);
8478 {
8479 // Change the image layouts and synchronize the memory access before copying
8480 {
8481 const VkImageMemoryBarrier imageBarriers[] = {
8482 // srcImage
8483 makeImageMemoryBarrier(
8484 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
8485 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask
8486 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout
8487 m_srcImage.operationLayout, // VkImageLayout newLayout
8488 srcImage.get(), // VkImage image
8489 makeImageSubresourceRange( // VkImageSubresourceRange subresourceRange
8490 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask
8491 0u, // uint32_t baseMipLevel
8492 1u, // uint32_t levelCount
8493 0u, // uint32_t baseArrayLayer
8494 sourceArraySize // uint32_t layerCount
8495 )),
8496 // dstImage
8497 makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask
8498 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask
8499 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout
8500 m_dstImage.operationLayout, // VkImageLayout newLayout
8501 dstImage.get(), // VkImage image
8502 makeImageSubresourceRange( // VkImageSubresourceRange subresourceRange
8503 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask
8504 0u, // uint32_t baseMipLevel
8505 1u, // uint32_t levelCount
8506 0u, // uint32_t baseArrayLayer
8507 sourceArraySize // uint32_t layerCount
8508 )),
8509 };
8510 vk.cmdPipelineBarrier(
8511 *cmdBuffer, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT,
8512 VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
8513 (const VkBufferMemoryBarrier *)DE_NULL, 2u, imageBarriers);
8514 }
8515
8516 std::vector<VkImageCopy> imageCopies;
8517 std::vector<VkImageCopy2KHR> imageCopies2KHR;
8518 for (const auto ®ion : m_regions)
8519 {
8520 if (!(m_params.extensionFlags & COPY_COMMANDS_2))
8521 {
8522 imageCopies.push_back(region.imageCopy);
8523 }
8524 else
8525 {
8526 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
8527 imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(region.imageCopy));
8528 }
8529 }
8530
8531 if (!(m_params.extensionFlags & COPY_COMMANDS_2))
8532 {
8533 vk.cmdCopyImage(*cmdBuffer, srcImage.get(), m_srcImage.operationLayout, dstImage.get(),
8534 m_dstImage.operationLayout, (uint32_t)imageCopies.size(), imageCopies.data());
8535 }
8536 else
8537 {
8538 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
8539 const VkCopyImageInfo2KHR copyImageInfo2KHR = {
8540 VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR, // VkStructureType sType;
8541 DE_NULL, // const void* pNext;
8542 srcImage.get(), // VkImage srcImage;
8543 m_srcImage.operationLayout, // VkImageLayout srcImageLayout;
8544 dstImage.get(), // VkImage dstImage;
8545 m_dstImage.operationLayout, // VkImageLayout dstImageLayout;
8546 (uint32_t)imageCopies2KHR.size(), // uint32_t regionCount;
8547 imageCopies2KHR.data() // const VkImageCopy2KHR* pRegions;
8548 };
8549
8550 vk.cmdCopyImage2(*cmdBuffer, ©ImageInfo2KHR);
8551 }
8552 }
8553 endCommandBuffer(vk, *cmdBuffer);
8554 submitCommandsAndWait(vk, vkDevice, queue, *cmdBuffer);
8555 m_context.resetCommandPoolForVKSC(vkDevice, *cmdPool);
8556
8557 // Verify that all samples have been copied properly from all aspects.
8558 const auto usedImageAspects = getUsedImageAspects();
8559 if (usedImageAspects & VK_IMAGE_ASPECT_DEPTH_BIT)
8560 {
8561 auto copyResult = checkCopyResults(cmdBuffer.get(), VK_IMAGE_ASPECT_DEPTH_BIT, srcImage.get(), dstImage.get());
8562 if (copyResult.getCode() != QP_TEST_RESULT_PASS)
8563 return copyResult;
8564 }
8565 if (usedImageAspects & VK_IMAGE_ASPECT_STENCIL_BIT)
8566 {
8567 auto copyResult =
8568 checkCopyResults(cmdBuffer.get(), VK_IMAGE_ASPECT_STENCIL_BIT, srcImage.get(), dstImage.get());
8569 if (copyResult.getCode() != QP_TEST_RESULT_PASS)
8570 return copyResult;
8571 }
8572 return tcu::TestStatus::pass("pass");
8573 }
8574
checkCopyResults(VkCommandBuffer cmdBuffer,const VkImageAspectFlagBits & aspectToVerify,VkImage srcImage,VkImage dstImage)8575 tcu::TestStatus DepthStencilMSAA::checkCopyResults(VkCommandBuffer cmdBuffer,
8576 const VkImageAspectFlagBits &aspectToVerify, VkImage srcImage,
8577 VkImage dstImage)
8578 {
8579 DE_ASSERT((aspectToVerify & VK_IMAGE_ASPECT_DEPTH_BIT) || (aspectToVerify & VK_IMAGE_ASPECT_STENCIL_BIT));
8580
8581 const auto &vkd = m_context.getDeviceInterface();
8582 const auto device = m_context.getDevice();
8583 const auto queue = m_context.getUniversalQueue();
8584 auto &alloc = m_context.getDefaultAllocator();
8585 const auto layerCount = getArraySize(m_srcImage);
8586 const auto numInputAttachments = layerCount + 1u; // +1 for the source image.
8587 const auto numOutputBuffers = 2u; // 1 for the reference and 1 for the copied values.
8588 const auto numSets = 2u; // 1 for the output buffers, 1 for the input attachments.
8589 const auto fbWidth = m_srcImage.extent.width;
8590 const auto fbHeight = m_srcImage.extent.height;
8591 const auto aspectFlags = getUsedImageAspects();
8592
8593 // Shader modules.
8594 const auto vertexModule = createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
8595 const auto verificationModule =
8596 createShaderModule(vkd, device,
8597 m_context.getBinaryCollection().get(
8598 aspectToVerify & VK_IMAGE_ASPECT_DEPTH_BIT ? "verify_depth" : "verify_stencil"),
8599 0u);
8600
8601 // Descriptor sets.
8602 DescriptorPoolBuilder poolBuilder;
8603 poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, numOutputBuffers);
8604 poolBuilder.addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, numInputAttachments);
8605 const auto descriptorPool =
8606 poolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, numSets);
8607
8608 DescriptorSetLayoutBuilder layoutBuilderBuffer;
8609 layoutBuilderBuffer.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
8610 layoutBuilderBuffer.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
8611 const auto outputBufferSetLayout = layoutBuilderBuffer.build(vkd, device);
8612
8613 DescriptorSetLayoutBuilder layoutBuilderAttachments;
8614 for (uint32_t i = 0u; i < numInputAttachments; ++i)
8615 layoutBuilderAttachments.addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT);
8616 const auto inputAttachmentsSetLayout = layoutBuilderAttachments.build(vkd, device);
8617
8618 const auto descriptorSetBuffer = makeDescriptorSet(vkd, device, descriptorPool.get(), outputBufferSetLayout.get());
8619 const auto descriptorSetAttachments =
8620 makeDescriptorSet(vkd, device, descriptorPool.get(), inputAttachmentsSetLayout.get());
8621
8622 // Array with raw descriptor sets.
8623 const std::array<VkDescriptorSet, numSets> descriptorSets = {{
8624 descriptorSetBuffer.get(),
8625 descriptorSetAttachments.get(),
8626 }};
8627
8628 // Pipeline layout.
8629 const std::array<VkDescriptorSetLayout, numSets> setLayouts = {{
8630 outputBufferSetLayout.get(),
8631 inputAttachmentsSetLayout.get(),
8632 }};
8633
8634 // Push constants.
8635 std::array<int, 3> pushConstantData = {{
8636 static_cast<int>(fbWidth),
8637 static_cast<int>(fbHeight),
8638 static_cast<int>(m_params.samples),
8639 }};
8640
8641 const auto pushConstantSize =
8642 static_cast<uint32_t>(pushConstantData.size() * sizeof(decltype(pushConstantData)::value_type));
8643
8644 const VkPushConstantRange pushConstantRange = {
8645 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
8646 0u, // uint32_t offset;
8647 pushConstantSize, // uint32_t size;
8648 };
8649
8650 const VkPipelineLayoutCreateInfo pipelineLayoutInfo = {
8651 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
8652 nullptr, // const void* pNext;
8653 0u, // VkPipelineLayoutCreateFlags flags;
8654 static_cast<uint32_t>(setLayouts.size()), // uint32_t setLayoutCount;
8655 setLayouts.data(), // const VkDescriptorSetLayout* pSetLayouts;
8656 1u, // uint32_t pushConstantRangeCount;
8657 &pushConstantRange, // const VkPushConstantRange* pPushConstantRanges;
8658 };
8659
8660 const auto pipelineLayout = createPipelineLayout(vkd, device, &pipelineLayoutInfo);
8661
8662 // Render pass.
8663 const VkAttachmentDescription commonAttachmentDescription = {
8664 0u, // VkAttachmentDescriptionFlags flags;
8665 m_srcImage.format, // VkFormat format;
8666 m_params.samples, // VkSampleCountFlagBits samples;
8667 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
8668 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
8669 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
8670 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
8671 m_dstImage.operationLayout, // VkImageLayout initialLayout;
8672 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout finalLayout;
8673 };
8674
8675 std::vector<VkAttachmentDescription> attachmentDescriptions(numInputAttachments, commonAttachmentDescription);
8676 // Set the first attachment's (m_srcImage) initial layout to match the layout it was left after copying.
8677 attachmentDescriptions[0].initialLayout = m_srcImage.operationLayout;
8678
8679 std::vector<VkAttachmentReference> inputAttachmentReferences;
8680 inputAttachmentReferences.reserve(numInputAttachments);
8681 for (uint32_t i = 0u; i < numInputAttachments; ++i)
8682 {
8683 const VkAttachmentReference reference = {i, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};
8684 inputAttachmentReferences.push_back(reference);
8685 }
8686
8687 const VkSubpassDescription subpassDescription = {
8688 0u, // VkSubpassDescriptionFlags flags;
8689 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
8690 static_cast<uint32_t>(inputAttachmentReferences.size()), // uint32_t inputAttachmentCount;
8691 inputAttachmentReferences.data(), // const VkAttachmentReference* pInputAttachments;
8692 0u, // uint32_t colorAttachmentCount;
8693 nullptr, // const VkAttachmentReference* pColorAttachments;
8694 nullptr, // const VkAttachmentReference* pResolveAttachments;
8695 nullptr, // const VkAttachmentReference* pDepthStencilAttachment;
8696 0u, // uint32_t preserveAttachmentCount;
8697 nullptr, // const uint32_t* pPreserveAttachments;
8698 };
8699
8700 const VkRenderPassCreateInfo renderPassInfo = {
8701 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
8702 nullptr, // const void* pNext;
8703 0u, // VkRenderPassCreateFlags flags;
8704 static_cast<uint32_t>(attachmentDescriptions.size()), // uint32_t attachmentCount;
8705 attachmentDescriptions.data(), // const VkAttachmentDescription* pAttachments;
8706 1u, // uint32_t subpassCount;
8707 &subpassDescription, // const VkSubpassDescription* pSubpasses;
8708 0u, // uint32_t dependencyCount;
8709 nullptr, // const VkSubpassDependency* pDependencies;
8710 };
8711
8712 const auto renderPass = createRenderPass(vkd, device, &renderPassInfo);
8713
8714 // Framebuffer.
8715 std::vector<Move<VkImageView>> imageViews;
8716 std::vector<VkImageView> imageViewsRaw;
8717
8718 const uint32_t srcArrayLayer = m_params.copyOptions == COPY_ARRAY_TO_ARRAY ? 2u : 0u;
8719 imageViews.push_back(makeImageView(vkd, device, srcImage, VK_IMAGE_VIEW_TYPE_2D, m_srcImage.format,
8720 makeImageSubresourceRange(aspectFlags, 0u, 1u, srcArrayLayer, 1u)));
8721 for (uint32_t i = 0u; i < layerCount; ++i)
8722 {
8723 const auto subresourceRange = makeImageSubresourceRange(aspectFlags, 0u, 1u, i, 1u);
8724 imageViews.push_back(
8725 makeImageView(vkd, device, dstImage, VK_IMAGE_VIEW_TYPE_2D, m_srcImage.format, subresourceRange));
8726 }
8727
8728 imageViewsRaw.reserve(imageViews.size());
8729 std::transform(begin(imageViews), end(imageViews), std::back_inserter(imageViewsRaw),
8730 [](const Move<VkImageView> &ptr) { return ptr.get(); });
8731
8732 const auto framebuffer = makeFramebuffer(vkd, device, renderPass.get(), static_cast<uint32_t>(imageViewsRaw.size()),
8733 imageViewsRaw.data(), fbWidth, fbHeight);
8734
8735 // Create storage buffers for both original and copied multisampled depth/stencil images.
8736 const auto bufferCount = static_cast<size_t>(fbWidth * fbHeight * m_params.samples);
8737 const auto bufferSize = static_cast<VkDeviceSize>(bufferCount * sizeof(float));
8738 BufferWithMemory bufferOriginal(vkd, device, alloc,
8739 makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
8740 MemoryRequirement::HostVisible);
8741 BufferWithMemory bufferCopied(vkd, device, alloc,
8742 makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
8743 MemoryRequirement::HostVisible);
8744 auto &bufferOriginalAlloc = bufferOriginal.getAllocation();
8745 auto &bufferCopiedAlloc = bufferCopied.getAllocation();
8746
8747 // Update descriptor sets.
8748 DescriptorSetUpdateBuilder updater;
8749
8750 const auto bufferOriginalInfo = makeDescriptorBufferInfo(bufferOriginal.get(), 0ull, bufferSize);
8751 const auto bufferCopiedInfo = makeDescriptorBufferInfo(bufferCopied.get(), 0ull, bufferSize);
8752 updater.writeSingle(descriptorSetBuffer.get(), DescriptorSetUpdateBuilder::Location::binding(0u),
8753 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferOriginalInfo);
8754 updater.writeSingle(descriptorSetBuffer.get(), DescriptorSetUpdateBuilder::Location::binding(1u),
8755 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferCopiedInfo);
8756
8757 std::vector<VkDescriptorImageInfo> imageInfos;
8758 imageInfos.reserve(imageViewsRaw.size());
8759 for (size_t i = 0; i < imageViewsRaw.size(); ++i)
8760 {
8761 imageInfos.push_back(
8762 makeDescriptorImageInfo(DE_NULL, imageViewsRaw[i], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL));
8763 updater.writeSingle(descriptorSetAttachments.get(),
8764 DescriptorSetUpdateBuilder::Location::binding(static_cast<uint32_t>(i)),
8765 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &imageInfos[i]);
8766 }
8767
8768 updater.update(vkd, device);
8769
8770 // Vertex buffer.
8771 std::vector<tcu::Vec4> fullScreenQuad;
8772 {
8773 // Full screen quad so every framebuffer pixel and sample location is verified by the shader.
8774 const tcu::Vec4 topLeft(-1.0f, -1.0f, 0.0f, 1.0f);
8775 const tcu::Vec4 topRight(1.0f, -1.0f, 0.0f, 1.0f);
8776 const tcu::Vec4 bottomLeft(-1.0f, 1.0f, 0.0f, 1.0f);
8777 const tcu::Vec4 bottomRight(1.0f, 1.0f, 0.0f, 1.0f);
8778
8779 fullScreenQuad.reserve(6u);
8780 fullScreenQuad.push_back(topLeft);
8781 fullScreenQuad.push_back(topRight);
8782 fullScreenQuad.push_back(bottomRight);
8783 fullScreenQuad.push_back(topLeft);
8784 fullScreenQuad.push_back(bottomRight);
8785 fullScreenQuad.push_back(bottomLeft);
8786 }
8787
8788 const auto vertexBufferSize =
8789 static_cast<VkDeviceSize>(fullScreenQuad.size() * sizeof(decltype(fullScreenQuad)::value_type));
8790 const auto vertexBufferInfo = makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
8791 const BufferWithMemory vertexBuffer(vkd, device, alloc, vertexBufferInfo, MemoryRequirement::HostVisible);
8792 const VkDeviceSize vertexBufferOffset = 0ull;
8793
8794 deMemcpy(vertexBuffer.getAllocation().getHostPtr(), fullScreenQuad.data(), static_cast<size_t>(vertexBufferSize));
8795 flushAlloc(vkd, device, vertexBuffer.getAllocation());
8796
8797 // Graphics pipeline.
8798 const std::vector<VkViewport> viewports(1, makeViewport(m_srcImage.extent));
8799 const std::vector<VkRect2D> scissors(1, makeRect2D(m_srcImage.extent));
8800
8801 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = {
8802 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
8803 nullptr, // const void* pNext;
8804 0u, // VkPipelineMultisampleStateCreateFlags flags;
8805 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
8806 VK_FALSE, // VkBool32 sampleShadingEnable;
8807 0.0f, // float minSampleShading;
8808 nullptr, // const VkSampleMask* pSampleMask;
8809 VK_FALSE, // VkBool32 alphaToCoverageEnable;
8810 VK_FALSE // VkBool32 alphaToOneEnable;
8811 };
8812
8813 const auto graphicsPipeline = makeGraphicsPipeline(
8814 vkd, // const DeviceInterface& vk
8815 device, // const VkDevice device
8816 pipelineLayout.get(), // const VkPipelineLayout pipelineLayout
8817 vertexModule.get(), // const VkShaderModule vertexShaderModule
8818 DE_NULL, // const VkShaderModule tessellationControlModule
8819 DE_NULL, // const VkShaderModule tessellationEvalModule
8820 DE_NULL, // const VkShaderModule geometryShaderModule
8821 verificationModule.get(), // const VkShaderModule fragmentShaderModule
8822 renderPass.get(), // const VkRenderPass renderPass
8823 viewports, // const std::vector<VkViewport>& viewports
8824 scissors, // const std::vector<VkRect2D>& scissors
8825 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
8826 0u, // const uint32_t subpass
8827 0u, // const uint32_t patchControlPoints
8828 nullptr, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
8829 nullptr, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
8830 &multisampleStateParams); // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
8831
8832 // Make sure multisample copy data is available to the fragment shader.
8833 const auto imagesBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT);
8834
8835 // Record and submit command buffer.
8836 beginCommandBuffer(vkd, cmdBuffer);
8837 vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 1u,
8838 &imagesBarrier, 0u, nullptr, 0u, nullptr);
8839 beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffer.get(), makeRect2D(m_srcImage.extent));
8840 vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline.get());
8841 vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
8842
8843 vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), VK_SHADER_STAGE_FRAGMENT_BIT, 0u, pushConstantSize,
8844 pushConstantData.data());
8845 vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u,
8846 static_cast<uint32_t>(descriptorSets.size()), descriptorSets.data(), 0u, nullptr);
8847 vkd.cmdDraw(cmdBuffer, static_cast<uint32_t>(fullScreenQuad.size()), 1u, 0u, 0u);
8848
8849 endRenderPass(vkd, cmdBuffer);
8850
8851 // Make sure verification buffer data is available on the host.
8852 const auto bufferBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
8853 vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u,
8854 &bufferBarrier, 0u, nullptr, 0u, nullptr);
8855 endCommandBuffer(vkd, cmdBuffer);
8856 submitCommandsAndWait(vkd, device, queue, cmdBuffer);
8857
8858 // Verify intermediate results.
8859 invalidateAlloc(vkd, device, bufferOriginalAlloc);
8860 invalidateAlloc(vkd, device, bufferCopiedAlloc);
8861 std::vector<float> outputOriginal(bufferCount, 0);
8862 std::vector<float> outputCopied(bufferCount, 0);
8863 deMemcpy(outputOriginal.data(), bufferOriginalAlloc.getHostPtr(), static_cast<size_t>(bufferSize));
8864 deMemcpy(outputCopied.data(), bufferCopiedAlloc.getHostPtr(), static_cast<size_t>(bufferSize));
8865
8866 auto &log = m_context.getTestContext().getLog();
8867 log << tcu::TestLog::Message << "Verifying intermediate multisample copy results" << tcu::TestLog::EndMessage;
8868
8869 const auto sampleCount = static_cast<uint32_t>(m_params.samples);
8870
8871 // Verify copied region(s)
8872 for (const auto ®ion : m_regions)
8873 {
8874 for (uint32_t x = 0u; x < region.imageCopy.extent.width; ++x)
8875 for (uint32_t y = 0u; y < region.imageCopy.extent.height; ++y)
8876 for (uint32_t s = 0u; s < sampleCount; ++s)
8877 {
8878 tcu::UVec2 srcCoord(x + region.imageCopy.srcOffset.x, y + region.imageCopy.srcOffset.y);
8879 tcu::UVec2 dstCoord(x + region.imageCopy.dstOffset.x, y + region.imageCopy.dstOffset.y);
8880 const auto srcIndex = (srcCoord.y() * fbWidth + srcCoord.x()) * sampleCount + s;
8881 const auto dstIndex = (dstCoord.y() * fbWidth + dstCoord.x()) * sampleCount + s;
8882 if (outputOriginal[srcIndex] != outputCopied[dstIndex])
8883 {
8884 std::ostringstream msg;
8885 msg << "Intermediate verification failed for coordinates (" << x << ", " << y << ") sample "
8886 << s << ". "
8887 << "result: " << outputCopied[dstIndex] << " expected: " << outputOriginal[srcIndex];
8888 return tcu::TestStatus::fail(msg.str());
8889 }
8890 }
8891 }
8892
8893 if (m_params.copyOptions == COPY_PARTIAL)
8894 {
8895 // In the partial copy tests the destination image contains copied data only in the bottom half of the image.
8896 // Verify that the upper half of the image is left at it's clear value (0).
8897 for (uint32_t x = 0u; x < m_srcImage.extent.width; x++)
8898 for (uint32_t y = 0u; y < m_srcImage.extent.height / 2; y++)
8899 for (uint32_t s = 0u; s < sampleCount; ++s)
8900 {
8901 const auto bufferIndex = (y * fbWidth + x) * sampleCount + s;
8902 if (outputCopied[bufferIndex] != m_clearValue)
8903 {
8904 std::ostringstream msg;
8905 msg << "Intermediate verification failed for coordinates (" << x << ", " << y << ") sample "
8906 << s << ". "
8907 << "result: " << outputCopied[bufferIndex] << " expected: 0.0";
8908 return tcu::TestStatus::fail(msg.str());
8909 }
8910 }
8911 }
8912
8913 log << tcu::TestLog::Message << "Intermediate multisample copy verification passed" << tcu::TestLog::EndMessage;
8914 return tcu::TestStatus::pass("Pass");
8915 }
8916
8917 class DepthStencilMSAATestCase : public vkt::TestCase
8918 {
8919 public:
DepthStencilMSAATestCase(tcu::TestContext & testCtx,const std::string & name,const DepthStencilMSAA::TestParameters testParams)8920 DepthStencilMSAATestCase(tcu::TestContext &testCtx, const std::string &name,
8921 const DepthStencilMSAA::TestParameters testParams)
8922 : vkt::TestCase(testCtx, name)
8923 , m_params(testParams)
8924 {
8925 }
8926
8927 virtual void initPrograms(SourceCollections &programCollection) const;
8928
createInstance(Context & context) const8929 virtual TestInstance *createInstance(Context &context) const
8930 {
8931 return new DepthStencilMSAA(context, m_params);
8932 }
8933
checkSupport(Context & context) const8934 virtual void checkSupport(Context &context) const
8935 {
8936 checkExtensionSupport(context, m_params.extensionFlags);
8937
8938 const VkSampleCountFlagBits rasterizationSamples = m_params.samples;
8939
8940 if (!context.getDeviceFeatures().fragmentStoresAndAtomics)
8941 TCU_THROW(NotSupportedError, "fragmentStoresAndAtomics not supported");
8942
8943 if ((m_params.copyAspect & VK_IMAGE_ASPECT_DEPTH_BIT) &&
8944 !(context.getDeviceProperties().limits.framebufferDepthSampleCounts & rasterizationSamples))
8945 TCU_THROW(NotSupportedError, "Unsupported number of depth samples");
8946
8947 if ((m_params.copyAspect & VK_IMAGE_ASPECT_STENCIL_BIT) &&
8948 !(context.getDeviceProperties().limits.framebufferDepthSampleCounts & rasterizationSamples))
8949 TCU_THROW(NotSupportedError, "Unsupported number of stencil samples");
8950
8951 VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
8952 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
8953
8954 VkImageFormatProperties properties;
8955 if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
8956 context.getPhysicalDevice(), m_params.imageFormat, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
8957 usageFlags, 0, &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
8958 {
8959 TCU_THROW(NotSupportedError, "Format not supported");
8960 }
8961 }
8962
8963 private:
getArrayLayerCount() const8964 uint32_t getArrayLayerCount() const
8965 {
8966 return (m_params.copyOptions == DepthStencilMSAA::COPY_ARRAY_TO_ARRAY) ? 5u : 1u;
8967 }
8968
createVerificationShader(std::ostringstream & shaderCode,const VkImageAspectFlagBits attachmentAspect) const8969 void createVerificationShader(std::ostringstream &shaderCode, const VkImageAspectFlagBits attachmentAspect) const
8970 {
8971 DE_ASSERT(attachmentAspect & (VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT));
8972 // The shader copies the sample values from the source and destination image to output buffers OriginalValue and
8973 // CopiedValues, respectively. If the dst image contains multiple array layers, only one layer has the copied data
8974 // and the rest should be filled with the clear value (0). This is also verified in this shader.
8975 // Array layer cases need an image view per layer in the copied image.
8976 // Set 0 contains the output buffers.
8977 // Set 1 contains the input attachments.
8978
8979 std::string inputAttachmentPrefix = attachmentAspect == VK_IMAGE_ASPECT_STENCIL_BIT ? "u" : "";
8980
8981 shaderCode << "#version 450\n"
8982 << "\n"
8983 << "layout (push_constant, std430) uniform PushConstants {\n"
8984 << " int width;\n"
8985 << " int height;\n"
8986 << " int samples;\n"
8987 << "};\n"
8988 << "layout (set=0, binding=0) buffer OriginalValues {\n"
8989 << " float outputOriginal[];\n"
8990 << "};\n"
8991 << "layout (set=0, binding=1) buffer CopiedValues {\n"
8992 << " float outputCopied[];\n"
8993 << "};\n"
8994 << "layout (input_attachment_index=0, set=1, binding=0) uniform " << inputAttachmentPrefix
8995 << "subpassInputMS attachment0;\n";
8996
8997 const auto layerCount = getArrayLayerCount();
8998 for (uint32_t layerNdx = 0u; layerNdx < layerCount; ++layerNdx)
8999 {
9000 const auto i = layerNdx + 1u;
9001 shaderCode << "layout (input_attachment_index=" << i << ", set=1, binding=" << i << ") uniform "
9002 << inputAttachmentPrefix << "subpassInputMS attachment" << i << ";\n";
9003 }
9004
9005 // Using a loop to iterate over each sample avoids the need for the sampleRateShading feature. The pipeline needs to be
9006 // created with a single sample.
9007 shaderCode << "\n"
9008 << "void main() {\n"
9009 << " for (int sampleID = 0; sampleID < samples; ++sampleID) {\n"
9010 << " ivec3 coords = ivec3(int(gl_FragCoord.x), int(gl_FragCoord.y), sampleID);\n"
9011 << " int bufferPos = (coords.y * width + coords.x) * samples + coords.z;\n"
9012 << " " << inputAttachmentPrefix << "vec4 orig = subpassLoad(attachment0, sampleID);\n"
9013 << " outputOriginal[bufferPos] = orig.r;\n";
9014
9015 for (uint32_t layerNdx = 0u; layerNdx < layerCount; ++layerNdx)
9016 {
9017 const auto i = layerNdx + 1u;
9018 shaderCode << " " << inputAttachmentPrefix << "vec4 copy" << i << " = subpassLoad(attachment" << i
9019 << ", sampleID);\n";
9020 }
9021
9022 std::ostringstream testCondition;
9023 std::string layerToVerify = m_params.copyOptions == DepthStencilMSAA::COPY_ARRAY_TO_ARRAY ? "copy4" : "copy1";
9024 shaderCode << "\n"
9025 << " outputCopied[bufferPos] = " << layerToVerify << ".r; \n";
9026
9027 if (m_params.copyOptions == DepthStencilMSAA::COPY_ARRAY_TO_ARRAY)
9028 {
9029 // In array layer copy tests the copied image should be in the layer 3 and other layers should be value of 0 or 0.0 depending on the format.
9030 // This verifies that all the samples in the other layers have proper values.
9031 shaderCode << " bool equalEmptyLayers = ";
9032 for (uint32_t layerNdx = 0u; layerNdx < layerCount; ++layerNdx)
9033 {
9034 if (layerNdx == 3)
9035 continue;
9036 const auto i = layerNdx + 1u;
9037 shaderCode << "copy" << i << ".r == " << (attachmentAspect == VK_IMAGE_ASPECT_STENCIL_BIT ? "0" : "0.0")
9038 << (layerNdx < 4u ? " && " : ";\n");
9039 }
9040 shaderCode << " if (!equalEmptyLayers)\n"
9041 << " outputCopied[bufferPos]--; \n";
9042 }
9043
9044 shaderCode << " }\n"
9045 << "}\n";
9046 }
9047
9048 DepthStencilMSAA::TestParameters m_params;
9049 };
9050
initPrograms(SourceCollections & programCollection) const9051 void DepthStencilMSAATestCase::initPrograms(SourceCollections &programCollection) const
9052 {
9053 programCollection.glslSources.add("vert") << glu::VertexSource("#version 310 es\n"
9054 "layout (location = 0) in highp vec4 a_position;\n"
9055 "void main()\n"
9056 "{\n"
9057 " gl_Position = vec4(a_position.xy, 1.0, 1.0);\n"
9058 "}\n");
9059
9060 programCollection.glslSources.add("frag") << glu::FragmentSource("#version 310 es\n"
9061 "void main()\n"
9062 "{}\n");
9063
9064 // Create the verifying shader for the depth aspect if the depth is used.
9065 if (m_params.copyAspect & VK_IMAGE_ASPECT_DEPTH_BIT)
9066 {
9067 std::ostringstream verificationShader;
9068 // All the depth formats are float types, so the input attachment prefix is not used.
9069 createVerificationShader(verificationShader, VK_IMAGE_ASPECT_DEPTH_BIT);
9070 programCollection.glslSources.add("verify_depth") << glu::FragmentSource(verificationShader.str());
9071 }
9072
9073 // Create the verifying shader for the stencil aspect if the stencil is used.
9074 if (m_params.copyAspect & VK_IMAGE_ASPECT_STENCIL_BIT)
9075 {
9076 std::ostringstream verificationShader;
9077 // All the stencil formats are uint types, so the input attachment prefix is "u".
9078 createVerificationShader(verificationShader, VK_IMAGE_ASPECT_STENCIL_BIT);
9079 programCollection.glslSources.add("verify_stencil") << glu::FragmentSource(verificationShader.str());
9080 }
9081 }
9082
9083 struct BufferOffsetParams
9084 {
9085 static constexpr uint32_t kMaxOffset = 8u;
9086
9087 uint32_t srcOffset;
9088 uint32_t dstOffset;
9089 };
9090
checkZerosAt(const std::vector<uint8_t> & bufferData,uint32_t from,uint32_t count)9091 void checkZerosAt(const std::vector<uint8_t> &bufferData, uint32_t from, uint32_t count)
9092 {
9093 constexpr uint8_t zero{0};
9094 for (uint32_t i = 0; i < count; ++i)
9095 {
9096 const auto &val = bufferData[from + i];
9097 if (val != zero)
9098 {
9099 std::ostringstream msg;
9100 msg << "Unexpected non-zero byte found at position " << (from + i) << ": " << static_cast<int>(val);
9101 TCU_FAIL(msg.str());
9102 }
9103 }
9104 }
9105
bufferOffsetTest(Context & ctx,BufferOffsetParams params)9106 tcu::TestStatus bufferOffsetTest(Context &ctx, BufferOffsetParams params)
9107 {
9108 // 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.
9109 constexpr auto kMaxOffset = BufferOffsetParams::kMaxOffset;
9110 constexpr auto kBlockSize = kMaxOffset * 2u;
9111 constexpr auto kBufferSize = kMaxOffset * kBlockSize;
9112
9113 DE_ASSERT(params.srcOffset < kMaxOffset);
9114 DE_ASSERT(params.dstOffset < kMaxOffset);
9115
9116 const auto &vkd = ctx.getDeviceInterface();
9117 const auto device = ctx.getDevice();
9118 auto &alloc = ctx.getDefaultAllocator();
9119 const auto qIndex = ctx.getUniversalQueueFamilyIndex();
9120 const auto queue = ctx.getUniversalQueue();
9121
9122 const auto srcBufferInfo = makeBufferCreateInfo(kBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
9123 const auto dstBufferInfo = makeBufferCreateInfo(kBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
9124
9125 BufferWithMemory srcBuffer(vkd, device, alloc, srcBufferInfo, MemoryRequirement::HostVisible);
9126 BufferWithMemory dstBuffer(vkd, device, alloc, dstBufferInfo, MemoryRequirement::HostVisible);
9127 auto &srcAlloc = srcBuffer.getAllocation();
9128 auto &dstAlloc = dstBuffer.getAllocation();
9129
9130 // Zero-out destination buffer.
9131 deMemset(dstAlloc.getHostPtr(), 0, kBufferSize);
9132 flushAlloc(vkd, device, dstAlloc);
9133
9134 // Fill source buffer with nonzero bytes.
9135 std::vector<uint8_t> srcData;
9136 srcData.reserve(kBufferSize);
9137 for (uint32_t i = 0; i < kBufferSize; ++i)
9138 srcData.push_back(static_cast<uint8_t>(100u + i));
9139 deMemcpy(srcAlloc.getHostPtr(), srcData.data(), de::dataSize(srcData));
9140 flushAlloc(vkd, device, srcAlloc);
9141
9142 // Copy regions.
9143 std::vector<VkBufferCopy> copies;
9144 copies.reserve(kMaxOffset);
9145 for (uint32_t i = 0; i < kMaxOffset; ++i)
9146 {
9147 const auto blockStart = kBlockSize * i;
9148 const auto copySize = i + 1u;
9149 const auto bufferCopy = makeBufferCopy(params.srcOffset + blockStart, params.dstOffset + blockStart, copySize);
9150 copies.push_back(bufferCopy);
9151 }
9152
9153 const auto cmdPool = makeCommandPool(vkd, device, qIndex);
9154 const auto cmdBufferPtr = allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
9155 const auto cmdBuffer = cmdBufferPtr.get();
9156
9157 beginCommandBuffer(vkd, cmdBuffer);
9158 vkd.cmdCopyBuffer(cmdBuffer, srcBuffer.get(), dstBuffer.get(), static_cast<uint32_t>(copies.size()), copies.data());
9159 const auto barrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
9160 vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &barrier, 0u,
9161 nullptr, 0u, nullptr);
9162 endCommandBuffer(vkd, cmdBuffer);
9163 submitCommandsAndWait(vkd, device, queue, cmdBuffer);
9164 invalidateAlloc(vkd, device, dstAlloc);
9165
9166 // Verify destination buffer data.
9167 std::vector<uint8_t> dstData(kBufferSize);
9168 deMemcpy(dstData.data(), dstAlloc.getHostPtr(), de::dataSize(dstData));
9169
9170 for (uint32_t blockIdx = 0; blockIdx < kMaxOffset; ++blockIdx)
9171 {
9172 const auto blockStart = kBlockSize * blockIdx;
9173 const auto copySize = blockIdx + 1u;
9174
9175 // Verify no data has been written before dstOffset.
9176 checkZerosAt(dstData, blockStart, params.dstOffset);
9177
9178 // Verify copied block.
9179 for (uint32_t i = 0; i < copySize; ++i)
9180 {
9181 const auto &dstVal = dstData[blockStart + params.dstOffset + i];
9182 const auto &srcVal = srcData[blockStart + params.srcOffset + i];
9183 if (dstVal != srcVal)
9184 {
9185 std::ostringstream msg;
9186 msg << "Unexpected value found at position " << (blockStart + params.dstOffset + i) << ": expected "
9187 << static_cast<int>(srcVal) << " but found " << static_cast<int>(dstVal);
9188 TCU_FAIL(msg.str());
9189 }
9190 }
9191
9192 // Verify no data has been written after copy block.
9193 checkZerosAt(dstData, blockStart + params.dstOffset + copySize, kBlockSize - (params.dstOffset + copySize));
9194 }
9195
9196 return tcu::TestStatus::pass("Pass");
9197 }
9198
getSampleCountCaseName(VkSampleCountFlagBits sampleFlag)9199 std::string getSampleCountCaseName(VkSampleCountFlagBits sampleFlag)
9200 {
9201 return de::toLower(de::toString(getSampleCountFlagsStr(sampleFlag)).substr(16));
9202 }
9203
getFormatCaseName(VkFormat format)9204 std::string getFormatCaseName(VkFormat format)
9205 {
9206 return de::toLower(de::toString(getFormatStr(format)).substr(10));
9207 }
9208
getImageLayoutCaseName(VkImageLayout layout)9209 std::string getImageLayoutCaseName(VkImageLayout layout)
9210 {
9211 switch (layout)
9212 {
9213 case VK_IMAGE_LAYOUT_GENERAL:
9214 return "general";
9215 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
9216 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
9217 return "optimal";
9218 default:
9219 DE_ASSERT(false);
9220 return "";
9221 }
9222 }
9223
9224 struct TestGroupParams
9225 {
9226 AllocationKind allocationKind;
9227 uint32_t extensionFlags;
9228 QueueSelectionOptions queueSelection;
9229 bool useSecondaryCmdBuffer;
9230 bool useSparseBinding;
9231 };
9232
9233 using TestGroupParamsPtr = de::SharedPtr<TestGroupParams>;
9234
addImageToImageSimpleTests(tcu::TestCaseGroup * group,TestGroupParamsPtr testGroupParams)9235 void addImageToImageSimpleTests(tcu::TestCaseGroup *group, TestGroupParamsPtr testGroupParams)
9236 {
9237 tcu::TestContext &testCtx = group->getTestContext();
9238
9239 {
9240 TestParams params;
9241 params.src.image.imageType = VK_IMAGE_TYPE_2D;
9242 params.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
9243 params.src.image.extent = defaultExtent;
9244 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9245 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9246 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
9247 params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
9248 params.dst.image.extent = defaultExtent;
9249 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9250 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9251 params.allocationKind = testGroupParams->allocationKind;
9252 params.extensionFlags = testGroupParams->extensionFlags;
9253 params.queueSelection = testGroupParams->queueSelection;
9254 params.useSecondaryCmdBuffer = testGroupParams->useSecondaryCmdBuffer;
9255 params.useSparseBinding = testGroupParams->useSparseBinding;
9256
9257 {
9258 const VkImageCopy testCopy = {
9259 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
9260 {0, 0, 0}, // VkOffset3D srcOffset;
9261 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
9262 {0, 0, 0}, // VkOffset3D dstOffset;
9263 defaultExtent, // VkExtent3D extent;
9264 };
9265
9266 CopyRegion imageCopy;
9267 imageCopy.imageCopy = testCopy;
9268 params.regions.push_back(imageCopy);
9269 }
9270
9271 group->addChild(new CopyImageToImageTestCase(testCtx, "whole_image", params));
9272 }
9273
9274 {
9275 TestParams params;
9276 params.src.image.imageType = VK_IMAGE_TYPE_2D;
9277 params.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
9278 params.src.image.extent = defaultExtent;
9279 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9280 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9281 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
9282 params.dst.image.format = VK_FORMAT_R32_UINT;
9283 params.dst.image.extent = defaultExtent;
9284 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9285 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9286 params.allocationKind = testGroupParams->allocationKind;
9287 params.extensionFlags = testGroupParams->extensionFlags;
9288 params.queueSelection = testGroupParams->queueSelection;
9289 params.useSecondaryCmdBuffer = testGroupParams->useSecondaryCmdBuffer;
9290 params.useSparseBinding = testGroupParams->useSparseBinding;
9291
9292 {
9293 const VkImageCopy testCopy = {
9294 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
9295 {0, 0, 0}, // VkOffset3D srcOffset;
9296 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
9297 {0, 0, 0}, // VkOffset3D dstOffset;
9298 defaultExtent, // VkExtent3D extent;
9299 };
9300
9301 CopyRegion imageCopy;
9302 imageCopy.imageCopy = testCopy;
9303 params.regions.push_back(imageCopy);
9304 }
9305
9306 group->addChild(new CopyImageToImageTestCase(testCtx, "whole_image_diff_format", params));
9307 }
9308
9309 {
9310 TestParams params;
9311 params.src.image.imageType = VK_IMAGE_TYPE_2D;
9312 params.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
9313 params.src.image.extent = defaultExtent;
9314 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9315 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9316 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
9317 params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
9318 params.dst.image.extent = defaultExtent;
9319 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9320 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9321 params.allocationKind = testGroupParams->allocationKind;
9322 params.extensionFlags = testGroupParams->extensionFlags;
9323 params.queueSelection = testGroupParams->queueSelection;
9324 params.useSecondaryCmdBuffer = testGroupParams->useSecondaryCmdBuffer;
9325 params.useSparseBinding = testGroupParams->useSparseBinding;
9326
9327 {
9328 const VkImageCopy testCopy = {
9329 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
9330 {0, 0, 0}, // VkOffset3D srcOffset;
9331 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
9332 {defaultQuarterSize, defaultQuarterSize / 2, 0}, // VkOffset3D dstOffset;
9333 {defaultQuarterSize / 2, defaultQuarterSize / 2, 1}, // VkExtent3D extent;
9334 };
9335
9336 CopyRegion imageCopy;
9337 imageCopy.imageCopy = testCopy;
9338 params.regions.push_back(imageCopy);
9339 }
9340
9341 group->addChild(new CopyImageToImageTestCase(testCtx, "partial_image", params));
9342 }
9343
9344 static const struct
9345 {
9346 std::string name;
9347 vk::VkFormat format1;
9348 vk::VkFormat format2;
9349 } formats[] = {{"diff_format", vk::VK_FORMAT_R32_UINT, vk::VK_FORMAT_R8G8B8A8_UNORM},
9350 {"same_format", vk::VK_FORMAT_R8G8B8A8_UNORM, vk::VK_FORMAT_R8G8B8A8_UNORM}};
9351 static const struct
9352 {
9353 std::string name;
9354 vk::VkBool32 clear;
9355 } clears[] = {{"clear", VK_TRUE}, {"noclear", VK_FALSE}};
9356 static const struct
9357 {
9358 std::string name;
9359 VkExtent3D extent;
9360 } extents[] = {{"npot", {65u, 63u, 1u}}, {"pot", {64u, 64u, 1u}}};
9361
9362 for (const auto &format : formats)
9363 {
9364 for (const auto &clear : clears)
9365 {
9366 if (testGroupParams->queueSelection == QueueSelectionOptions::TransferOnly)
9367 continue;
9368
9369 for (const auto &extent : extents)
9370 {
9371 TestParams params;
9372 params.src.image.imageType = VK_IMAGE_TYPE_2D;
9373 params.src.image.format = format.format1;
9374 params.src.image.extent = extent.extent;
9375 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9376 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9377 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
9378 params.dst.image.format = format.format2;
9379 params.dst.image.extent = extent.extent;
9380 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9381 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9382 params.allocationKind = testGroupParams->allocationKind;
9383 params.extensionFlags = testGroupParams->extensionFlags;
9384 params.queueSelection = testGroupParams->queueSelection;
9385 params.useSecondaryCmdBuffer = testGroupParams->useSecondaryCmdBuffer;
9386 params.useSparseBinding = testGroupParams->useSparseBinding;
9387 params.clearDestinationWithRed = clear.clear;
9388
9389 {
9390 VkImageCopy testCopy = {
9391 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
9392 {34, 34, 0}, // VkOffset3D srcOffset;
9393 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
9394 {0, 0, 0}, // VkOffset3D dstOffset;
9395 {31, 29, 1} // VkExtent3D extent;
9396 };
9397
9398 if (extent.name == "pot")
9399 {
9400 testCopy.srcOffset = {16, 16, 0};
9401 testCopy.extent = {32, 32, 1};
9402 }
9403
9404 CopyRegion imageCopy;
9405 imageCopy.imageCopy = testCopy;
9406 params.regions.push_back(imageCopy);
9407 }
9408
9409 // Example test case name: "partial_image_npot_diff_format_clear"
9410 const std::string testCaseName = "partial_image_" + extent.name + "_" + format.name + "_" + clear.name;
9411
9412 group->addChild(new CopyImageToImageTestCase(testCtx, testCaseName, params));
9413 }
9414 }
9415 }
9416
9417 {
9418 TestParams params;
9419 params.src.image.imageType = VK_IMAGE_TYPE_2D;
9420 params.src.image.format = VK_FORMAT_D32_SFLOAT;
9421 params.src.image.extent = defaultExtent;
9422 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9423 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9424 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
9425 params.dst.image.format = VK_FORMAT_D32_SFLOAT;
9426 params.dst.image.extent = defaultExtent;
9427 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9428 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9429 params.allocationKind = testGroupParams->allocationKind;
9430 params.extensionFlags = testGroupParams->extensionFlags;
9431 params.queueSelection = testGroupParams->queueSelection;
9432 params.useSecondaryCmdBuffer = testGroupParams->useSecondaryCmdBuffer;
9433 params.useSparseBinding = testGroupParams->useSparseBinding;
9434
9435 {
9436 const VkImageSubresourceLayers sourceLayer = {
9437 VK_IMAGE_ASPECT_DEPTH_BIT, // VkImageAspectFlags aspectMask;
9438 0u, // uint32_t mipLevel;
9439 0u, // uint32_t baseArrayLayer;
9440 1u // uint32_t layerCount;
9441 };
9442 const VkImageCopy testCopy = {
9443 sourceLayer, // VkImageSubresourceLayers srcSubresource;
9444 {0, 0, 0}, // VkOffset3D srcOffset;
9445 sourceLayer, // VkImageSubresourceLayers dstSubresource;
9446 {defaultQuarterSize, defaultQuarterSize / 2, 0}, // VkOffset3D dstOffset;
9447 {defaultQuarterSize / 2, defaultQuarterSize / 2, 1}, // VkExtent3D extent;
9448 };
9449
9450 CopyRegion imageCopy;
9451 imageCopy.imageCopy = testCopy;
9452 params.regions.push_back(imageCopy);
9453 }
9454
9455 group->addChild(new CopyImageToImageTestCase(testCtx, "depth", params));
9456 }
9457
9458 {
9459 TestParams params;
9460 params.src.image.imageType = VK_IMAGE_TYPE_2D;
9461 params.src.image.format = VK_FORMAT_S8_UINT;
9462 params.src.image.extent = defaultExtent;
9463 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9464 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9465 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
9466 params.dst.image.format = VK_FORMAT_S8_UINT;
9467 params.dst.image.extent = defaultExtent;
9468 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9469 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9470 params.allocationKind = testGroupParams->allocationKind;
9471 params.extensionFlags = testGroupParams->extensionFlags;
9472 params.queueSelection = testGroupParams->queueSelection;
9473 params.useSecondaryCmdBuffer = testGroupParams->useSecondaryCmdBuffer;
9474 params.useSparseBinding = testGroupParams->useSparseBinding;
9475
9476 {
9477 const VkImageSubresourceLayers sourceLayer = {
9478 VK_IMAGE_ASPECT_STENCIL_BIT, // VkImageAspectFlags aspectMask;
9479 0u, // uint32_t mipLevel;
9480 0u, // uint32_t baseArrayLayer;
9481 1u // uint32_t layerCount;
9482 };
9483 const VkImageCopy testCopy = {
9484 sourceLayer, // VkImageSubresourceLayers srcSubresource;
9485 {0, 0, 0}, // VkOffset3D srcOffset;
9486 sourceLayer, // VkImageSubresourceLayers dstSubresource;
9487 {defaultQuarterSize, defaultQuarterSize / 2, 0}, // VkOffset3D dstOffset;
9488 {defaultQuarterSize / 2, defaultQuarterSize / 2, 1}, // VkExtent3D extent;
9489 };
9490
9491 CopyRegion imageCopy;
9492 imageCopy.imageCopy = testCopy;
9493 params.regions.push_back(imageCopy);
9494 }
9495
9496 group->addChild(new CopyImageToImageTestCase(testCtx, "stencil", params));
9497 }
9498 }
9499
9500 struct CopyColorTestParams
9501 {
9502 TestParams params;
9503 const VkFormat *compatibleFormats;
9504 };
9505
addImageToImageAllFormatsColorSrcFormatDstFormatTests(tcu::TestCaseGroup * group,TestParams params)9506 void addImageToImageAllFormatsColorSrcFormatDstFormatTests(tcu::TestCaseGroup *group, TestParams params)
9507 {
9508 const VkImageLayout copySrcLayouts[] = {VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL};
9509 const VkImageLayout copyDstLayouts[] = {VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL};
9510
9511 for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx)
9512 {
9513 params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
9514
9515 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx)
9516 {
9517 params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
9518
9519 const std::string testName = getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
9520 getImageLayoutCaseName(params.dst.image.operationLayout);
9521 const std::string description = "From layout " + getImageLayoutCaseName(params.src.image.operationLayout) +
9522 " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
9523 group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, params));
9524 }
9525 }
9526 }
9527
isAllowedImageToImageAllFormatsColorSrcFormatTests(const CopyColorTestParams & testParams)9528 bool isAllowedImageToImageAllFormatsColorSrcFormatTests(const CopyColorTestParams &testParams)
9529 {
9530 bool result = true;
9531
9532 if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED)
9533 {
9534 DE_ASSERT(!dedicatedAllocationImageToImageFormatsToTestSet.empty());
9535
9536 result = de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.dst.image.format) ||
9537 de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.src.image.format);
9538 }
9539
9540 return result;
9541 }
9542
addImageToImageAllFormatsColorSrcFormatTests(tcu::TestCaseGroup * group,CopyColorTestParams testParams)9543 void addImageToImageAllFormatsColorSrcFormatTests(tcu::TestCaseGroup *group, CopyColorTestParams testParams)
9544 {
9545 // If testParams.compatibleFormats is nullptr, the destination format will be copied from the source format.
9546 const VkFormat srcFormatOnly[2] = {testParams.params.src.image.format, VK_FORMAT_UNDEFINED};
9547 const VkFormat *formatList = (testParams.compatibleFormats ? testParams.compatibleFormats : srcFormatOnly);
9548
9549 for (int dstFormatIndex = 0; formatList[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex)
9550 {
9551 testParams.params.dst.image.format = formatList[dstFormatIndex];
9552
9553 const VkFormat srcFormat = testParams.params.src.image.format;
9554 const VkFormat dstFormat = testParams.params.dst.image.format;
9555
9556 if (!isSupportedByFramework(dstFormat) && !isCompressedFormat(dstFormat))
9557 continue;
9558
9559 if (!isAllowedImageToImageAllFormatsColorSrcFormatTests(testParams))
9560 continue;
9561
9562 if (isCompressedFormat(srcFormat) && isCompressedFormat(dstFormat))
9563 if ((getBlockWidth(srcFormat) != getBlockWidth(dstFormat)) ||
9564 (getBlockHeight(srcFormat) != getBlockHeight(dstFormat)))
9565 continue;
9566
9567 const std::string description = "Copy to destination format " + getFormatCaseName(dstFormat);
9568 addTestGroup(group, getFormatCaseName(dstFormat), addImageToImageAllFormatsColorSrcFormatDstFormatTests,
9569 testParams.params);
9570 }
9571 }
9572
9573 const VkFormat compatibleFormats8Bit[] = {VK_FORMAT_R4G4_UNORM_PACK8, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_SNORM,
9574 VK_FORMAT_R8_USCALED, VK_FORMAT_R8_SSCALED, VK_FORMAT_R8_UINT,
9575 VK_FORMAT_R8_SINT, VK_FORMAT_R8_SRGB,
9576
9577 VK_FORMAT_UNDEFINED};
9578
9579 const VkFormat compatibleFormats8BitA[] = {
9580 #ifndef CTS_USES_VULKANSC
9581 VK_FORMAT_A8_UNORM_KHR,
9582 #endif // CTS_USES_VULKANSC
9583 VK_FORMAT_UNDEFINED};
9584
9585 const VkFormat compatibleFormats16Bit[] = {VK_FORMAT_R4G4B4A4_UNORM_PACK16,
9586 VK_FORMAT_B4G4R4A4_UNORM_PACK16,
9587 VK_FORMAT_R5G6B5_UNORM_PACK16,
9588 VK_FORMAT_B5G6R5_UNORM_PACK16,
9589 VK_FORMAT_R5G5B5A1_UNORM_PACK16,
9590 VK_FORMAT_B5G5R5A1_UNORM_PACK16,
9591 VK_FORMAT_A1R5G5B5_UNORM_PACK16,
9592 #ifndef CTS_USES_VULKANSC
9593 VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR,
9594 #endif // CTS_USES_VULKANSC
9595 VK_FORMAT_R8G8_UNORM,
9596 VK_FORMAT_R8G8_SNORM,
9597 VK_FORMAT_R8G8_USCALED,
9598 VK_FORMAT_R8G8_SSCALED,
9599 VK_FORMAT_R8G8_UINT,
9600 VK_FORMAT_R8G8_SINT,
9601 VK_FORMAT_R8G8_SRGB,
9602 VK_FORMAT_R16_UNORM,
9603 VK_FORMAT_R16_SNORM,
9604 VK_FORMAT_R16_USCALED,
9605 VK_FORMAT_R16_SSCALED,
9606 VK_FORMAT_R16_UINT,
9607 VK_FORMAT_R16_SINT,
9608 VK_FORMAT_R16_SFLOAT,
9609 VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
9610 VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
9611
9612 VK_FORMAT_UNDEFINED};
9613 const VkFormat compatibleFormats24Bit[] = {VK_FORMAT_R8G8B8_UNORM, VK_FORMAT_R8G8B8_SNORM, VK_FORMAT_R8G8B8_USCALED,
9614 VK_FORMAT_R8G8B8_SSCALED, VK_FORMAT_R8G8B8_UINT, VK_FORMAT_R8G8B8_SINT,
9615 VK_FORMAT_R8G8B8_SRGB, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_B8G8R8_SNORM,
9616 VK_FORMAT_B8G8R8_USCALED, VK_FORMAT_B8G8R8_SSCALED, VK_FORMAT_B8G8R8_UINT,
9617 VK_FORMAT_B8G8R8_SINT, VK_FORMAT_B8G8R8_SRGB,
9618
9619 VK_FORMAT_UNDEFINED};
9620 const VkFormat compatibleFormats32Bit[] = {VK_FORMAT_R8G8B8A8_UNORM,
9621 VK_FORMAT_R8G8B8A8_SNORM,
9622 VK_FORMAT_R8G8B8A8_USCALED,
9623 VK_FORMAT_R8G8B8A8_SSCALED,
9624 VK_FORMAT_R8G8B8A8_UINT,
9625 VK_FORMAT_R8G8B8A8_SINT,
9626 VK_FORMAT_R8G8B8A8_SRGB,
9627 VK_FORMAT_B8G8R8A8_UNORM,
9628 VK_FORMAT_B8G8R8A8_SNORM,
9629 VK_FORMAT_B8G8R8A8_USCALED,
9630 VK_FORMAT_B8G8R8A8_SSCALED,
9631 VK_FORMAT_B8G8R8A8_UINT,
9632 VK_FORMAT_B8G8R8A8_SINT,
9633 VK_FORMAT_B8G8R8A8_SRGB,
9634 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
9635 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
9636 VK_FORMAT_A8B8G8R8_USCALED_PACK32,
9637 VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
9638 VK_FORMAT_A8B8G8R8_UINT_PACK32,
9639 VK_FORMAT_A8B8G8R8_SINT_PACK32,
9640 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
9641 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
9642 VK_FORMAT_A2R10G10B10_SNORM_PACK32,
9643 VK_FORMAT_A2R10G10B10_USCALED_PACK32,
9644 VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
9645 VK_FORMAT_A2R10G10B10_UINT_PACK32,
9646 VK_FORMAT_A2R10G10B10_SINT_PACK32,
9647 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
9648 VK_FORMAT_A2B10G10R10_SNORM_PACK32,
9649 VK_FORMAT_A2B10G10R10_USCALED_PACK32,
9650 VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
9651 VK_FORMAT_A2B10G10R10_UINT_PACK32,
9652 VK_FORMAT_A2B10G10R10_SINT_PACK32,
9653 VK_FORMAT_R16G16_UNORM,
9654 VK_FORMAT_R16G16_SNORM,
9655 VK_FORMAT_R16G16_USCALED,
9656 VK_FORMAT_R16G16_SSCALED,
9657 VK_FORMAT_R16G16_UINT,
9658 VK_FORMAT_R16G16_SINT,
9659 VK_FORMAT_R16G16_SFLOAT,
9660 VK_FORMAT_R32_UINT,
9661 VK_FORMAT_R32_SINT,
9662 VK_FORMAT_R32_SFLOAT,
9663
9664 VK_FORMAT_UNDEFINED};
9665 const VkFormat compatibleFormats48Bit[] = {
9666 VK_FORMAT_R16G16B16_UNORM, VK_FORMAT_R16G16B16_SNORM, VK_FORMAT_R16G16B16_USCALED, VK_FORMAT_R16G16B16_SSCALED,
9667 VK_FORMAT_R16G16B16_UINT, VK_FORMAT_R16G16B16_SINT, VK_FORMAT_R16G16B16_SFLOAT,
9668
9669 VK_FORMAT_UNDEFINED};
9670 const VkFormat compatibleFormats64Bit[] = {VK_FORMAT_R16G16B16A16_UNORM,
9671 VK_FORMAT_R16G16B16A16_SNORM,
9672 VK_FORMAT_R16G16B16A16_USCALED,
9673 VK_FORMAT_R16G16B16A16_SSCALED,
9674 VK_FORMAT_R16G16B16A16_UINT,
9675 VK_FORMAT_R16G16B16A16_SINT,
9676 VK_FORMAT_R16G16B16A16_SFLOAT,
9677 VK_FORMAT_R32G32_UINT,
9678 VK_FORMAT_R32G32_SINT,
9679 VK_FORMAT_R32G32_SFLOAT,
9680 VK_FORMAT_R64_UINT,
9681 VK_FORMAT_R64_SINT,
9682 VK_FORMAT_R64_SFLOAT,
9683
9684 VK_FORMAT_BC1_RGB_UNORM_BLOCK,
9685 VK_FORMAT_BC1_RGB_SRGB_BLOCK,
9686 VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
9687 VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
9688 VK_FORMAT_BC4_UNORM_BLOCK,
9689 VK_FORMAT_BC4_SNORM_BLOCK,
9690
9691 VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
9692 VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
9693 VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
9694 VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
9695
9696 VK_FORMAT_EAC_R11_UNORM_BLOCK,
9697 VK_FORMAT_EAC_R11_SNORM_BLOCK,
9698
9699 VK_FORMAT_UNDEFINED};
9700 const VkFormat compatibleFormats96Bit[] = {VK_FORMAT_R32G32B32_UINT, VK_FORMAT_R32G32B32_SINT,
9701 VK_FORMAT_R32G32B32_SFLOAT,
9702
9703 VK_FORMAT_UNDEFINED};
9704 const VkFormat compatibleFormats128Bit[] = {VK_FORMAT_R32G32B32A32_UINT,
9705 VK_FORMAT_R32G32B32A32_SINT,
9706 VK_FORMAT_R32G32B32A32_SFLOAT,
9707 VK_FORMAT_R64G64_UINT,
9708 VK_FORMAT_R64G64_SINT,
9709 VK_FORMAT_R64G64_SFLOAT,
9710
9711 VK_FORMAT_BC2_UNORM_BLOCK,
9712 VK_FORMAT_BC2_SRGB_BLOCK,
9713 VK_FORMAT_BC3_UNORM_BLOCK,
9714 VK_FORMAT_BC3_SRGB_BLOCK,
9715 VK_FORMAT_BC5_UNORM_BLOCK,
9716 VK_FORMAT_BC5_SNORM_BLOCK,
9717 VK_FORMAT_BC6H_UFLOAT_BLOCK,
9718 VK_FORMAT_BC6H_SFLOAT_BLOCK,
9719 VK_FORMAT_BC7_UNORM_BLOCK,
9720 VK_FORMAT_BC7_SRGB_BLOCK,
9721
9722 VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
9723 VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
9724
9725 VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
9726 VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
9727
9728 VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
9729 VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
9730 VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
9731 VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
9732 VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
9733 VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
9734 VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
9735 VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
9736 VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
9737 VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
9738 VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
9739 VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
9740 VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
9741 VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
9742 VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
9743 VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
9744 VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
9745 VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
9746 VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
9747 VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
9748 VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
9749 VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
9750 VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
9751 VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
9752 VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
9753 VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
9754 VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
9755 VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
9756
9757 VK_FORMAT_UNDEFINED};
9758 const VkFormat compatibleFormats192Bit[] = {VK_FORMAT_R64G64B64_UINT, VK_FORMAT_R64G64B64_SINT,
9759 VK_FORMAT_R64G64B64_SFLOAT,
9760
9761 VK_FORMAT_UNDEFINED};
9762 const VkFormat compatibleFormats256Bit[] = {VK_FORMAT_R64G64B64A64_UINT, VK_FORMAT_R64G64B64A64_SINT,
9763 VK_FORMAT_R64G64B64A64_SFLOAT,
9764
9765 VK_FORMAT_UNDEFINED};
9766
9767 const VkFormat *colorImageFormatsToTest[] = {compatibleFormats8Bit, compatibleFormats8BitA, compatibleFormats16Bit,
9768 compatibleFormats24Bit, compatibleFormats32Bit, compatibleFormats48Bit,
9769 compatibleFormats64Bit, compatibleFormats96Bit, compatibleFormats128Bit,
9770 compatibleFormats192Bit, compatibleFormats256Bit};
9771
9772 const VkFormat compatibleFormatsUInts[] = {VK_FORMAT_R8_UINT,
9773 VK_FORMAT_R8G8_UINT,
9774 VK_FORMAT_R8G8B8_UINT,
9775 VK_FORMAT_B8G8R8_UINT,
9776 VK_FORMAT_R8G8B8A8_UINT,
9777 VK_FORMAT_B8G8R8A8_UINT,
9778 VK_FORMAT_A8B8G8R8_UINT_PACK32,
9779 VK_FORMAT_A2R10G10B10_UINT_PACK32,
9780 VK_FORMAT_A2B10G10R10_UINT_PACK32,
9781 VK_FORMAT_R16_UINT,
9782 VK_FORMAT_R16G16_UINT,
9783 VK_FORMAT_R16G16B16_UINT,
9784 VK_FORMAT_R16G16B16A16_UINT,
9785 VK_FORMAT_R32_UINT,
9786 VK_FORMAT_R32G32_UINT,
9787 VK_FORMAT_R32G32B32_UINT,
9788 VK_FORMAT_R32G32B32A32_UINT,
9789 VK_FORMAT_R64_UINT,
9790 VK_FORMAT_R64G64_UINT,
9791 VK_FORMAT_R64G64B64_UINT,
9792 VK_FORMAT_R64G64B64A64_UINT,
9793
9794 VK_FORMAT_UNDEFINED};
9795 const VkFormat compatibleFormatsSInts[] = {VK_FORMAT_R8_SINT,
9796 VK_FORMAT_R8G8_SINT,
9797 VK_FORMAT_R8G8B8_SINT,
9798 VK_FORMAT_B8G8R8_SINT,
9799 VK_FORMAT_R8G8B8A8_SINT,
9800 VK_FORMAT_B8G8R8A8_SINT,
9801 VK_FORMAT_A8B8G8R8_SINT_PACK32,
9802 VK_FORMAT_A2R10G10B10_SINT_PACK32,
9803 VK_FORMAT_A2B10G10R10_SINT_PACK32,
9804 VK_FORMAT_R16_SINT,
9805 VK_FORMAT_R16G16_SINT,
9806 VK_FORMAT_R16G16B16_SINT,
9807 VK_FORMAT_R16G16B16A16_SINT,
9808 VK_FORMAT_R32_SINT,
9809 VK_FORMAT_R32G32_SINT,
9810 VK_FORMAT_R32G32B32_SINT,
9811 VK_FORMAT_R32G32B32A32_SINT,
9812 VK_FORMAT_R64_SINT,
9813 VK_FORMAT_R64G64_SINT,
9814 VK_FORMAT_R64G64B64_SINT,
9815 VK_FORMAT_R64G64B64A64_SINT,
9816
9817 VK_FORMAT_UNDEFINED};
9818 const VkFormat compatibleFormatsFloats[] = {VK_FORMAT_R4G4_UNORM_PACK8,
9819 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
9820 VK_FORMAT_B4G4R4A4_UNORM_PACK16,
9821 VK_FORMAT_R5G6B5_UNORM_PACK16,
9822 VK_FORMAT_B5G6R5_UNORM_PACK16,
9823 VK_FORMAT_R5G5B5A1_UNORM_PACK16,
9824 VK_FORMAT_B5G5R5A1_UNORM_PACK16,
9825 VK_FORMAT_A1R5G5B5_UNORM_PACK16,
9826 #ifndef CTS_USES_VULKANSC
9827 VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR,
9828 #endif // CTS_USES_VULKANSC
9829 VK_FORMAT_R8_UNORM,
9830 VK_FORMAT_R8_SNORM,
9831 VK_FORMAT_R8_USCALED,
9832 VK_FORMAT_R8_SSCALED,
9833 #ifndef CTS_USES_VULKANSC
9834 VK_FORMAT_A8_UNORM_KHR,
9835 #endif // CTS_USES_VULKANSC
9836 VK_FORMAT_R8G8_UNORM,
9837 VK_FORMAT_R8G8_SNORM,
9838 VK_FORMAT_R8G8_USCALED,
9839 VK_FORMAT_R8G8_SSCALED,
9840 VK_FORMAT_R8G8B8_UNORM,
9841 VK_FORMAT_R8G8B8_SNORM,
9842 VK_FORMAT_R8G8B8_USCALED,
9843 VK_FORMAT_R8G8B8_SSCALED,
9844 VK_FORMAT_B8G8R8_UNORM,
9845 VK_FORMAT_B8G8R8_SNORM,
9846 VK_FORMAT_B8G8R8_USCALED,
9847 VK_FORMAT_B8G8R8_SSCALED,
9848 VK_FORMAT_R8G8B8A8_UNORM,
9849 VK_FORMAT_R8G8B8A8_SNORM,
9850 VK_FORMAT_R8G8B8A8_USCALED,
9851 VK_FORMAT_R8G8B8A8_SSCALED,
9852 VK_FORMAT_B8G8R8A8_UNORM,
9853 VK_FORMAT_B8G8R8A8_SNORM,
9854 VK_FORMAT_B8G8R8A8_USCALED,
9855 VK_FORMAT_B8G8R8A8_SSCALED,
9856 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
9857 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
9858 VK_FORMAT_A8B8G8R8_USCALED_PACK32,
9859 VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
9860 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
9861 VK_FORMAT_A2R10G10B10_SNORM_PACK32,
9862 VK_FORMAT_A2R10G10B10_USCALED_PACK32,
9863 VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
9864 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
9865 VK_FORMAT_A2B10G10R10_SNORM_PACK32,
9866 VK_FORMAT_A2B10G10R10_USCALED_PACK32,
9867 VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
9868 VK_FORMAT_R16_UNORM,
9869 VK_FORMAT_R16_SNORM,
9870 VK_FORMAT_R16_USCALED,
9871 VK_FORMAT_R16_SSCALED,
9872 VK_FORMAT_R16_SFLOAT,
9873 VK_FORMAT_R16G16_UNORM,
9874 VK_FORMAT_R16G16_SNORM,
9875 VK_FORMAT_R16G16_USCALED,
9876 VK_FORMAT_R16G16_SSCALED,
9877 VK_FORMAT_R16G16_SFLOAT,
9878 VK_FORMAT_R16G16B16_UNORM,
9879 VK_FORMAT_R16G16B16_SNORM,
9880 VK_FORMAT_R16G16B16_USCALED,
9881 VK_FORMAT_R16G16B16_SSCALED,
9882 VK_FORMAT_R16G16B16_SFLOAT,
9883 VK_FORMAT_R16G16B16A16_UNORM,
9884 VK_FORMAT_R16G16B16A16_SNORM,
9885 VK_FORMAT_R16G16B16A16_USCALED,
9886 VK_FORMAT_R16G16B16A16_SSCALED,
9887 VK_FORMAT_R16G16B16A16_SFLOAT,
9888 VK_FORMAT_R32_SFLOAT,
9889 VK_FORMAT_R32G32_SFLOAT,
9890 VK_FORMAT_R32G32B32_SFLOAT,
9891 VK_FORMAT_R32G32B32A32_SFLOAT,
9892 VK_FORMAT_R64_SFLOAT,
9893 VK_FORMAT_R64G64_SFLOAT,
9894 VK_FORMAT_R64G64B64_SFLOAT,
9895 VK_FORMAT_R64G64B64A64_SFLOAT,
9896 VK_FORMAT_B10G11R11_UFLOAT_PACK32,
9897 VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
9898
9899 VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
9900 VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
9901
9902 VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
9903
9904 VK_FORMAT_UNDEFINED};
9905
9906 const VkFormat compressedFormatsFloats[] = {VK_FORMAT_BC1_RGB_UNORM_BLOCK,
9907 VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
9908 VK_FORMAT_BC2_UNORM_BLOCK,
9909 VK_FORMAT_BC3_UNORM_BLOCK,
9910 VK_FORMAT_BC4_UNORM_BLOCK,
9911 VK_FORMAT_BC4_SNORM_BLOCK,
9912 VK_FORMAT_BC5_UNORM_BLOCK,
9913 VK_FORMAT_BC5_SNORM_BLOCK,
9914 VK_FORMAT_BC6H_UFLOAT_BLOCK,
9915 VK_FORMAT_BC6H_SFLOAT_BLOCK,
9916 VK_FORMAT_BC7_UNORM_BLOCK,
9917 VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
9918 VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
9919 VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
9920 VK_FORMAT_EAC_R11_UNORM_BLOCK,
9921 VK_FORMAT_EAC_R11_SNORM_BLOCK,
9922 VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
9923 VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
9924 VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
9925 VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
9926 VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
9927 VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
9928 VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
9929 VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
9930 VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
9931 VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
9932 VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
9933 VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
9934 VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
9935 VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
9936 VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
9937 VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
9938
9939 VK_FORMAT_UNDEFINED};
9940
9941 const VkFormat compatibleFormatsSrgb[] = {
9942 VK_FORMAT_R8_SRGB, VK_FORMAT_R8G8_SRGB, VK_FORMAT_R8G8B8_SRGB, VK_FORMAT_B8G8R8_SRGB,
9943 VK_FORMAT_R8G8B8A8_SRGB, VK_FORMAT_B8G8R8A8_SRGB, VK_FORMAT_A8B8G8R8_SRGB_PACK32,
9944
9945 VK_FORMAT_UNDEFINED};
9946
9947 const VkFormat compressedFormatsSrgb[] = {VK_FORMAT_BC1_RGB_SRGB_BLOCK,
9948 VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
9949 VK_FORMAT_BC2_SRGB_BLOCK,
9950 VK_FORMAT_BC3_SRGB_BLOCK,
9951 VK_FORMAT_BC7_SRGB_BLOCK,
9952 VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
9953 VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
9954 VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
9955 VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
9956 VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
9957 VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
9958 VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
9959 VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
9960 VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
9961 VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
9962 VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
9963 VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
9964 VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
9965 VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
9966 VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
9967 VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
9968 VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
9969
9970 VK_FORMAT_UNDEFINED};
9971
9972 const VkFormat dedicatedAllocationImageToImageFormatsToTest[] = {
9973 // From compatibleFormats8Bit
9974 VK_FORMAT_R4G4_UNORM_PACK8,
9975 VK_FORMAT_R8_SRGB,
9976
9977 // From compatibleFormats16Bit
9978 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
9979 VK_FORMAT_R16_SFLOAT,
9980
9981 // From compatibleFormats24Bit
9982 VK_FORMAT_R8G8B8_UNORM,
9983 VK_FORMAT_B8G8R8_SRGB,
9984
9985 // From compatibleFormats32Bit
9986 VK_FORMAT_R8G8B8A8_UNORM,
9987 VK_FORMAT_R32_SFLOAT,
9988
9989 // From compatibleFormats48Bit
9990 VK_FORMAT_R16G16B16_UNORM,
9991 VK_FORMAT_R16G16B16_SFLOAT,
9992
9993 // From compatibleFormats64Bit
9994 VK_FORMAT_R16G16B16A16_UNORM,
9995 VK_FORMAT_R64_SFLOAT,
9996
9997 // From compatibleFormats96Bit
9998 VK_FORMAT_R32G32B32_UINT,
9999 VK_FORMAT_R32G32B32_SFLOAT,
10000
10001 // From compatibleFormats128Bit
10002 VK_FORMAT_R32G32B32A32_UINT,
10003 VK_FORMAT_R64G64_SFLOAT,
10004
10005 // From compatibleFormats192Bit
10006 VK_FORMAT_R64G64B64_UINT,
10007 VK_FORMAT_R64G64B64_SFLOAT,
10008
10009 // From compatibleFormats256Bit
10010 VK_FORMAT_R64G64B64A64_UINT,
10011 VK_FORMAT_R64G64B64A64_SFLOAT,
10012 };
10013
addImageToImageAllFormatsColorTests(tcu::TestCaseGroup * group,TestGroupParamsPtr testGroupParams)10014 void addImageToImageAllFormatsColorTests(tcu::TestCaseGroup *group, TestGroupParamsPtr testGroupParams)
10015 {
10016 if (testGroupParams->allocationKind == ALLOCATION_KIND_DEDICATED)
10017 {
10018 const int numOfDedicatedAllocationImageToImageFormatsToTest =
10019 DE_LENGTH_OF_ARRAY(dedicatedAllocationImageToImageFormatsToTest);
10020 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfDedicatedAllocationImageToImageFormatsToTest;
10021 ++compatibleFormatsIndex)
10022 dedicatedAllocationImageToImageFormatsToTestSet.insert(
10023 dedicatedAllocationImageToImageFormatsToTest[compatibleFormatsIndex]);
10024 }
10025
10026 // 1D to 1D tests.
10027 {
10028 // 1D to 1D copies
10029 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d_to_1d"));
10030
10031 TestParams params;
10032 params.src.image.imageType = VK_IMAGE_TYPE_1D;
10033 params.dst.image.imageType = VK_IMAGE_TYPE_1D;
10034 params.src.image.extent = default1dExtent;
10035 params.dst.image.extent = default1dExtent;
10036 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10037 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10038 params.src.image.fillMode = FILL_MODE_WHITE;
10039 params.dst.image.fillMode = FILL_MODE_GRADIENT;
10040 params.allocationKind = testGroupParams->allocationKind;
10041 params.extensionFlags = testGroupParams->extensionFlags;
10042 params.queueSelection = testGroupParams->queueSelection;
10043
10044 for (int32_t i = defaultQuarterSize; i < defaultSize; i += defaultSize / 2)
10045 {
10046 const VkImageCopy testCopy = {
10047 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
10048 {0, 0, 0}, // VkOffset3D srcOffset;
10049 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
10050 {i, 0, 0}, // VkOffset3D dstOffset;
10051 {defaultQuarterSize, 1, 1}, // VkExtent3D extent;
10052 };
10053
10054 CopyRegion imageCopy;
10055 imageCopy.imageCopy = testCopy;
10056
10057 params.regions.push_back(imageCopy);
10058 }
10059
10060 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
10061 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest;
10062 ++compatibleFormatsIndex)
10063 {
10064 const VkFormat *compatibleFormats = colorImageFormatsToTest[compatibleFormatsIndex];
10065 for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
10066 {
10067 params.src.image.format = compatibleFormats[srcFormatIndex];
10068 if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
10069 continue;
10070
10071 CopyColorTestParams testParams;
10072 testParams.params = params;
10073 testParams.compatibleFormats = nullptr;
10074
10075 const std::string testName = getFormatCaseName(params.src.image.format);
10076 addTestGroup(subGroup.get(), testName, addImageToImageAllFormatsColorSrcFormatTests, testParams);
10077 }
10078 }
10079
10080 group->addChild(subGroup.release());
10081 }
10082
10083 // 1D to 2D tests.
10084 {
10085 // 1D to 2D copies
10086 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d_to_2d"));
10087
10088 TestParams params;
10089 params.src.image.imageType = VK_IMAGE_TYPE_1D;
10090 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
10091 params.src.image.extent = default1dExtent;
10092 params.dst.image.extent = defaultRootExtent;
10093 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10094 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10095 params.src.image.fillMode = FILL_MODE_WHITE;
10096 params.dst.image.fillMode = FILL_MODE_GRADIENT;
10097 params.allocationKind = testGroupParams->allocationKind;
10098 params.extensionFlags = testGroupParams->extensionFlags;
10099 params.queueSelection = testGroupParams->queueSelection;
10100 params.extensionFlags |= MAINTENANCE_5;
10101
10102 for (uint32_t i = 0; i < defaultRootSize; ++i)
10103 {
10104 const VkImageCopy testCopy = {
10105 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
10106 {static_cast<int32_t>(defaultRootSize * i), 0, 0}, // VkOffset3D srcOffset;
10107 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
10108 {0, static_cast<int32_t>(i), 0}, // VkOffset3D dstOffset;
10109 {defaultRootSize, 1, 1}, // VkExtent3D extent;
10110 };
10111
10112 CopyRegion imageCopy;
10113 imageCopy.imageCopy = testCopy;
10114
10115 params.regions.push_back(imageCopy);
10116 }
10117
10118 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
10119 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest;
10120 ++compatibleFormatsIndex)
10121 {
10122 const VkFormat *compatibleFormats = colorImageFormatsToTest[compatibleFormatsIndex];
10123 for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
10124 {
10125 params.src.image.format = compatibleFormats[srcFormatIndex];
10126 if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
10127 continue;
10128
10129 CopyColorTestParams testParams;
10130 testParams.params = params;
10131 testParams.compatibleFormats = nullptr;
10132
10133 const std::string testName = getFormatCaseName(params.src.image.format);
10134 addTestGroup(subGroup.get(), testName, addImageToImageAllFormatsColorSrcFormatTests, testParams);
10135 }
10136 }
10137
10138 group->addChild(subGroup.release());
10139 }
10140
10141 // 1D to 3D tests.
10142 {
10143 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d_to_3d"));
10144
10145 TestParams params;
10146 params.src.image.imageType = VK_IMAGE_TYPE_1D;
10147 params.dst.image.imageType = VK_IMAGE_TYPE_3D;
10148 params.src.image.extent = default1dExtent;
10149 params.dst.image.extent = default3dSmallExtent;
10150 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10151 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10152 params.src.image.fillMode = FILL_MODE_WHITE;
10153 params.dst.image.fillMode = FILL_MODE_GRADIENT;
10154 params.allocationKind = testGroupParams->allocationKind;
10155 params.extensionFlags = testGroupParams->extensionFlags;
10156 params.queueSelection = testGroupParams->queueSelection;
10157 params.extensionFlags |= MAINTENANCE_5;
10158
10159 for (int32_t i = 0; i < defaultSixteenthSize; ++i)
10160 {
10161 for (int32_t j = 0; j < defaultSixteenthSize; ++j)
10162 {
10163 const VkImageCopy testCopy = {
10164 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
10165 {i * defaultQuarterSize + j * defaultSixteenthSize, 0, 0}, // VkOffset3D srcOffset;
10166 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
10167 {0, j, i % defaultSixteenthSize}, // VkOffset3D dstOffset;
10168 {defaultSixteenthSize, 1, 1}, // VkExtent3D extent;
10169 };
10170
10171 CopyRegion imageCopy;
10172 imageCopy.imageCopy = testCopy;
10173
10174 params.regions.push_back(imageCopy);
10175 }
10176 }
10177
10178 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
10179 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest;
10180 ++compatibleFormatsIndex)
10181 {
10182 const VkFormat *compatibleFormats = colorImageFormatsToTest[compatibleFormatsIndex];
10183 for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
10184 {
10185 params.src.image.format = compatibleFormats[srcFormatIndex];
10186 if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
10187 continue;
10188
10189 CopyColorTestParams testParams;
10190 testParams.params = params;
10191 testParams.compatibleFormats = nullptr;
10192
10193 const std::string testName = getFormatCaseName(params.src.image.format);
10194 addTestGroup(subGroup.get(), testName, addImageToImageAllFormatsColorSrcFormatTests, testParams);
10195 }
10196 }
10197
10198 group->addChild(subGroup.release());
10199 }
10200
10201 // 2D to 1D tests.
10202 {
10203 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d_to_1d"));
10204
10205 TestParams params;
10206 params.src.image.imageType = VK_IMAGE_TYPE_2D;
10207 params.dst.image.imageType = VK_IMAGE_TYPE_1D;
10208 params.src.image.extent = defaultQuarterExtent;
10209 params.dst.image.extent = default1dQuarterSquaredExtent;
10210 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10211 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10212 params.src.image.fillMode = FILL_MODE_WHITE;
10213 params.dst.image.fillMode = FILL_MODE_GRADIENT;
10214 params.allocationKind = testGroupParams->allocationKind;
10215 params.extensionFlags = testGroupParams->extensionFlags;
10216 params.queueSelection = testGroupParams->queueSelection;
10217 params.extensionFlags |= MAINTENANCE_5;
10218
10219 for (int32_t i = 0; i < defaultQuarterSize; ++i)
10220 {
10221 const VkImageCopy testCopy = {
10222 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
10223 {0, i, 0}, // VkOffset3D srcOffset;
10224 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
10225 {i * defaultQuarterSize, 0, 0}, // VkOffset3D dstOffset;
10226 {defaultQuarterSize, 1, 1}, // VkExtent3D extent;
10227 };
10228
10229 CopyRegion imageCopy;
10230 imageCopy.imageCopy = testCopy;
10231
10232 params.regions.push_back(imageCopy);
10233 }
10234
10235 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
10236 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest;
10237 ++compatibleFormatsIndex)
10238 {
10239 const VkFormat *compatibleFormats = colorImageFormatsToTest[compatibleFormatsIndex];
10240 for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
10241 {
10242 params.src.image.format = compatibleFormats[srcFormatIndex];
10243 if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
10244 continue;
10245
10246 CopyColorTestParams testParams;
10247 testParams.params = params;
10248 testParams.compatibleFormats = compatibleFormats;
10249
10250 const std::string testName = getFormatCaseName(params.src.image.format);
10251 addTestGroup(subGroup.get(), testName, addImageToImageAllFormatsColorSrcFormatTests, testParams);
10252 }
10253 }
10254
10255 group->addChild(subGroup.release());
10256 }
10257
10258 // 2D to 2D tests.
10259 {
10260 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d_to_2d"));
10261
10262 TestParams params;
10263 params.src.image.imageType = VK_IMAGE_TYPE_2D;
10264 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
10265 params.src.image.extent = defaultExtent;
10266 params.dst.image.extent = defaultExtent;
10267 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10268 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10269 params.src.image.fillMode = FILL_MODE_WHITE;
10270 params.dst.image.fillMode = FILL_MODE_GRADIENT;
10271 params.allocationKind = testGroupParams->allocationKind;
10272 params.extensionFlags = testGroupParams->extensionFlags;
10273 params.queueSelection = testGroupParams->queueSelection;
10274
10275 for (int32_t i = 0; i < defaultSize; i += defaultQuarterSize)
10276 {
10277 const VkImageCopy testCopy = {
10278 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
10279 {0, 0, 0}, // VkOffset3D srcOffset;
10280 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
10281 {i, defaultSize - i - defaultQuarterSize, 0}, // VkOffset3D dstOffset;
10282 {defaultQuarterSize, defaultQuarterSize, 1}, // VkExtent3D extent;
10283 };
10284
10285 CopyRegion imageCopy;
10286 imageCopy.imageCopy = testCopy;
10287
10288 params.regions.push_back(imageCopy);
10289 }
10290
10291 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
10292 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest;
10293 ++compatibleFormatsIndex)
10294 {
10295 const VkFormat *compatibleFormats = colorImageFormatsToTest[compatibleFormatsIndex];
10296 for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
10297 {
10298 params.src.image.format = compatibleFormats[srcFormatIndex];
10299 if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
10300 continue;
10301
10302 CopyColorTestParams testParams;
10303 testParams.params = params;
10304 testParams.compatibleFormats = compatibleFormats;
10305
10306 const std::string testName = getFormatCaseName(params.src.image.format);
10307 addTestGroup(subGroup.get(), testName, addImageToImageAllFormatsColorSrcFormatTests, testParams);
10308 }
10309 }
10310
10311 group->addChild(subGroup.release());
10312 }
10313
10314 // 2D to 3D tests.
10315 {
10316 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d_to_3d"));
10317
10318 TestParams params;
10319 params.src.image.imageType = VK_IMAGE_TYPE_2D;
10320 params.dst.image.imageType = VK_IMAGE_TYPE_3D;
10321 params.src.image.extent = defaultExtent;
10322 params.dst.image.extent = default3dSmallExtent;
10323 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10324 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10325 params.src.image.fillMode = FILL_MODE_WHITE;
10326 params.dst.image.fillMode = FILL_MODE_GRADIENT;
10327 params.allocationKind = testGroupParams->allocationKind;
10328 params.extensionFlags = testGroupParams->extensionFlags;
10329 params.queueSelection = testGroupParams->queueSelection;
10330 params.extensionFlags |= MAINTENANCE_1;
10331
10332 for (int32_t i = 0; i < defaultSixteenthSize; ++i)
10333 {
10334 const VkImageCopy testCopy = {
10335 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
10336 {i * defaultSixteenthSize, i % defaultSixteenthSize, 0}, // VkOffset3D srcOffset;
10337 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
10338 {0, 0, i}, // VkOffset3D dstOffset;
10339 {defaultSixteenthSize, defaultSixteenthSize, 1}, // VkExtent3D extent;
10340 };
10341
10342 CopyRegion imageCopy;
10343 imageCopy.imageCopy = testCopy;
10344
10345 params.regions.push_back(imageCopy);
10346 }
10347
10348 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
10349 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest;
10350 ++compatibleFormatsIndex)
10351 {
10352 const VkFormat *compatibleFormats = colorImageFormatsToTest[compatibleFormatsIndex];
10353 for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
10354 {
10355 params.src.image.format = compatibleFormats[srcFormatIndex];
10356 if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
10357 continue;
10358
10359 CopyColorTestParams testParams;
10360 testParams.params = params;
10361 testParams.compatibleFormats = compatibleFormats;
10362
10363 const std::string testName = getFormatCaseName(params.src.image.format);
10364 addTestGroup(subGroup.get(), testName, addImageToImageAllFormatsColorSrcFormatTests, testParams);
10365 }
10366 }
10367
10368 group->addChild(subGroup.release());
10369 }
10370
10371 // 3D to 1D tests.
10372 {
10373 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d_to_1d"));
10374
10375 TestParams params;
10376 params.src.image.imageType = VK_IMAGE_TYPE_3D;
10377 params.dst.image.imageType = VK_IMAGE_TYPE_1D;
10378 params.src.image.extent = default3dSmallExtent;
10379 params.dst.image.extent = default1dExtent;
10380 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10381 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10382 params.src.image.fillMode = FILL_MODE_WHITE;
10383 params.dst.image.fillMode = FILL_MODE_GRADIENT;
10384 params.allocationKind = testGroupParams->allocationKind;
10385 params.extensionFlags = testGroupParams->extensionFlags;
10386 params.queueSelection = testGroupParams->queueSelection;
10387 params.extensionFlags |= MAINTENANCE_5;
10388
10389 for (int32_t i = 0; i < defaultSixteenthSize; ++i)
10390 {
10391 for (int32_t j = 0; j < defaultSixteenthSize; ++j)
10392 {
10393 const VkImageCopy testCopy = {
10394 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
10395 {0, j % defaultSixteenthSize, i % defaultSixteenthSize}, // VkOffset3D srcOffset;
10396 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
10397 {j * defaultSixteenthSize + i * defaultQuarterSize, 0, 0}, // VkOffset3D dstOffset;
10398 {defaultSixteenthSize, 1, 1}, // VkExtent3D extent;
10399 };
10400
10401 CopyRegion imageCopy;
10402 imageCopy.imageCopy = testCopy;
10403
10404 params.regions.push_back(imageCopy);
10405 }
10406 }
10407
10408 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
10409 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest;
10410 ++compatibleFormatsIndex)
10411 {
10412 const VkFormat *compatibleFormats = colorImageFormatsToTest[compatibleFormatsIndex];
10413 for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
10414 {
10415 params.src.image.format = compatibleFormats[srcFormatIndex];
10416 if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
10417 continue;
10418
10419 CopyColorTestParams testParams;
10420 testParams.params = params;
10421 testParams.compatibleFormats = nullptr;
10422
10423 const std::string testName = getFormatCaseName(params.src.image.format);
10424 addTestGroup(subGroup.get(), testName, addImageToImageAllFormatsColorSrcFormatTests, testParams);
10425 }
10426 }
10427
10428 group->addChild(subGroup.release());
10429 }
10430
10431 // 3D to 2D tests.
10432 {
10433 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d_to_2d"));
10434
10435 TestParams params;
10436 params.src.image.imageType = VK_IMAGE_TYPE_3D;
10437 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
10438 params.src.image.extent = default3dExtent;
10439 params.dst.image.extent = defaultExtent;
10440 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10441 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10442 params.src.image.fillMode = FILL_MODE_WHITE;
10443 params.dst.image.fillMode = FILL_MODE_GRADIENT;
10444 params.allocationKind = testGroupParams->allocationKind;
10445 params.extensionFlags = testGroupParams->extensionFlags;
10446 params.queueSelection = testGroupParams->queueSelection;
10447 params.extensionFlags |= MAINTENANCE_1;
10448
10449 for (int32_t i = 0; i < defaultSixteenthSize; ++i)
10450 {
10451 for (int32_t j = 0; j < defaultSixteenthSize; ++j)
10452 {
10453 const VkImageCopy testCopy = {
10454 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
10455 {0, 0, i * defaultSixteenthSize + j}, // VkOffset3D srcOffset;
10456 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
10457 {j * defaultQuarterSize, i * defaultQuarterSize, 0}, // VkOffset3D dstOffset;
10458 {defaultQuarterSize, defaultQuarterSize, 1}, // VkExtent3D extent;
10459 };
10460
10461 CopyRegion imageCopy;
10462 imageCopy.imageCopy = testCopy;
10463
10464 params.regions.push_back(imageCopy);
10465 }
10466 }
10467
10468 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
10469 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest;
10470 ++compatibleFormatsIndex)
10471 {
10472 const VkFormat *compatibleFormats = colorImageFormatsToTest[compatibleFormatsIndex];
10473 for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
10474 {
10475 params.src.image.format = compatibleFormats[srcFormatIndex];
10476 if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
10477 continue;
10478
10479 CopyColorTestParams testParams;
10480 testParams.params = params;
10481 testParams.compatibleFormats = nullptr;
10482
10483 const std::string testName = getFormatCaseName(params.src.image.format);
10484 addTestGroup(subGroup.get(), testName, addImageToImageAllFormatsColorSrcFormatTests, testParams);
10485 }
10486 }
10487
10488 group->addChild(subGroup.release());
10489 }
10490
10491 // 3D to 3D tests. Note we use smaller dimensions here for performance reasons.
10492 {
10493 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d_to_3d"));
10494
10495 TestParams params;
10496 params.src.image.imageType = VK_IMAGE_TYPE_3D;
10497 params.dst.image.imageType = VK_IMAGE_TYPE_3D;
10498 params.src.image.extent = default3dExtent;
10499 params.dst.image.extent = default3dExtent;
10500 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10501 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10502 params.src.image.fillMode = FILL_MODE_WHITE;
10503 params.dst.image.fillMode = FILL_MODE_GRADIENT;
10504 params.allocationKind = testGroupParams->allocationKind;
10505 params.extensionFlags = testGroupParams->extensionFlags;
10506 params.queueSelection = testGroupParams->queueSelection;
10507
10508 for (int32_t i = 0; i < defaultQuarterSize; i += defaultSixteenthSize)
10509 {
10510 const VkImageCopy testCopy = {
10511 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
10512 {0, 0, 0}, // VkOffset3D srcOffset;
10513 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
10514 {i, defaultQuarterSize - i - defaultSixteenthSize, i}, // VkOffset3D dstOffset;
10515 {defaultSixteenthSize, defaultSixteenthSize, defaultSixteenthSize}, // VkExtent3D extent;
10516 };
10517
10518 CopyRegion imageCopy;
10519 imageCopy.imageCopy = testCopy;
10520
10521 params.regions.push_back(imageCopy);
10522 }
10523
10524 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
10525 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest;
10526 ++compatibleFormatsIndex)
10527 {
10528 const VkFormat *compatibleFormats = colorImageFormatsToTest[compatibleFormatsIndex];
10529 for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
10530 {
10531 params.src.image.format = compatibleFormats[srcFormatIndex];
10532 if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
10533 continue;
10534
10535 CopyColorTestParams testParams;
10536 testParams.params = params;
10537 testParams.compatibleFormats = nullptr;
10538
10539 const std::string testName = getFormatCaseName(params.src.image.format);
10540 addTestGroup(subGroup.get(), testName, addImageToImageAllFormatsColorSrcFormatTests, testParams);
10541 }
10542 }
10543
10544 group->addChild(subGroup.release());
10545 }
10546 }
10547
addImageToImageDimensionsTests(tcu::TestCaseGroup * group,TestGroupParamsPtr testGroupParams)10548 void addImageToImageDimensionsTests(tcu::TestCaseGroup *group, TestGroupParamsPtr testGroupParams)
10549 {
10550 tcu::TestContext &testCtx = group->getTestContext();
10551
10552 const VkFormat testFormats[][2] = {// From compatibleFormats8Bit
10553 {VK_FORMAT_R4G4_UNORM_PACK8, VK_FORMAT_R8_SRGB},
10554 // From compatibleFormats16Bit
10555 {
10556 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
10557 VK_FORMAT_R16_SFLOAT,
10558 },
10559 // From compatibleFormats24Bit
10560 {VK_FORMAT_R8G8B8_UNORM, VK_FORMAT_B8G8R8_SRGB},
10561 // From compatibleFormats32Bit
10562 {VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_R32_SFLOAT},
10563 // From compatibleFormats48Bit
10564 {VK_FORMAT_R16G16B16_UNORM, VK_FORMAT_R16G16B16_SFLOAT},
10565 // From compatibleFormats64Bit
10566 {VK_FORMAT_R16G16B16A16_UNORM, VK_FORMAT_R64_SFLOAT},
10567 // From compatibleFormats96Bit
10568 {VK_FORMAT_R32G32B32_UINT, VK_FORMAT_R32G32B32_SFLOAT},
10569 // From compatibleFormats128Bit
10570 {VK_FORMAT_R32G32B32A32_UINT, VK_FORMAT_R64G64_SFLOAT},
10571 // From compatibleFormats192Bit
10572 {
10573 VK_FORMAT_R64G64B64_UINT,
10574 VK_FORMAT_R64G64B64_SFLOAT,
10575 },
10576 // From compatibleFormats256Bit
10577 {VK_FORMAT_R64G64B64A64_UINT, VK_FORMAT_R64G64B64A64_SFLOAT}};
10578
10579 const tcu::UVec2 imageDimensions[] = {
10580 // large pot x small pot
10581 tcu::UVec2(4096, 4u), tcu::UVec2(8192, 4u), tcu::UVec2(16384, 4u), tcu::UVec2(32768, 4u),
10582
10583 // large pot x small npot
10584 tcu::UVec2(4096, 6u), tcu::UVec2(8192, 6u), tcu::UVec2(16384, 6u), tcu::UVec2(32768, 6u),
10585
10586 // small pot x large pot
10587 tcu::UVec2(4u, 4096), tcu::UVec2(4u, 8192), tcu::UVec2(4u, 16384), tcu::UVec2(4u, 32768),
10588
10589 // small npot x large pot
10590 tcu::UVec2(6u, 4096), tcu::UVec2(6u, 8192), tcu::UVec2(6u, 16384), tcu::UVec2(6u, 32768)};
10591
10592 const VkImageLayout copySrcLayouts[] = {VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL};
10593
10594 const VkImageLayout copyDstLayouts[] = {VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL};
10595
10596 if (testGroupParams->allocationKind == ALLOCATION_KIND_DEDICATED)
10597 {
10598 for (int compatibleFormatsIndex = 0;
10599 compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(dedicatedAllocationImageToImageFormatsToTest);
10600 compatibleFormatsIndex++)
10601 dedicatedAllocationImageToImageFormatsToTestSet.insert(
10602 dedicatedAllocationImageToImageFormatsToTest[compatibleFormatsIndex]);
10603 }
10604
10605 // Image dimensions
10606 for (size_t dimensionNdx = 0; dimensionNdx < DE_LENGTH_OF_ARRAY(imageDimensions); dimensionNdx++)
10607 {
10608 CopyRegion copyRegion;
10609 CopyColorTestParams testParams;
10610
10611 const VkExtent3D extent = {imageDimensions[dimensionNdx].x(), imageDimensions[dimensionNdx].y(), 1};
10612
10613 const VkImageCopy testCopy = {
10614 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
10615 {0, 0, 0}, // VkOffset3D srcOffset;
10616 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
10617 {0, 0, 0}, // VkOffset3D dstOffset;
10618 extent, // VkExtent3D extent;
10619 };
10620
10621 testParams.params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10622 testParams.params.src.image.imageType = VK_IMAGE_TYPE_2D;
10623 testParams.params.src.image.extent = extent;
10624
10625 testParams.params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10626 testParams.params.dst.image.imageType = VK_IMAGE_TYPE_2D;
10627 testParams.params.dst.image.extent = extent;
10628
10629 copyRegion.imageCopy = testCopy;
10630 testParams.params.allocationKind = testGroupParams->allocationKind;
10631 testParams.params.extensionFlags = testGroupParams->extensionFlags;
10632 testParams.params.queueSelection = testGroupParams->queueSelection;
10633 testParams.params.useSparseBinding = testGroupParams->useSparseBinding;
10634
10635 testParams.params.regions.push_back(copyRegion);
10636
10637 const std::string dimensionStr = "src" + de::toString(testParams.params.src.image.extent.width) + "x" +
10638 de::toString(testParams.params.src.image.extent.height) + "_dst" +
10639 de::toString(testParams.params.dst.image.extent.width) + "x" +
10640 de::toString(testParams.params.dst.image.extent.height);
10641 tcu::TestCaseGroup *imageSizeGroup = new tcu::TestCaseGroup(testCtx, dimensionStr.c_str());
10642
10643 // Compatible formats for copying
10644 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(testFormats);
10645 compatibleFormatsIndex++)
10646 {
10647 const VkFormat *compatibleFormats = testFormats[compatibleFormatsIndex];
10648
10649 testParams.compatibleFormats = compatibleFormats;
10650
10651 // Source image format
10652 for (int srcFormatIndex = 0; srcFormatIndex < DE_LENGTH_OF_ARRAY(testFormats[compatibleFormatsIndex]);
10653 srcFormatIndex++)
10654 {
10655 testParams.params.src.image.format = testParams.compatibleFormats[srcFormatIndex];
10656
10657 if (!isSupportedByFramework(testParams.params.src.image.format) &&
10658 !isCompressedFormat(testParams.params.src.image.format))
10659 continue;
10660
10661 tcu::TestCaseGroup *srcFormatGroup =
10662 new tcu::TestCaseGroup(testCtx, getFormatCaseName(testParams.params.src.image.format).c_str());
10663
10664 // Destination image format
10665 for (int dstFormatIndex = 0; dstFormatIndex < DE_LENGTH_OF_ARRAY(testFormats[compatibleFormatsIndex]);
10666 dstFormatIndex++)
10667 {
10668 testParams.params.dst.image.format = testParams.compatibleFormats[dstFormatIndex];
10669
10670 if (!isSupportedByFramework(testParams.params.dst.image.format) &&
10671 !isCompressedFormat(testParams.params.dst.image.format))
10672 continue;
10673
10674 if (!isAllowedImageToImageAllFormatsColorSrcFormatTests(testParams))
10675 continue;
10676
10677 if (isCompressedFormat(testParams.params.src.image.format) &&
10678 isCompressedFormat(testParams.params.dst.image.format))
10679 {
10680 if ((getBlockWidth(testParams.params.src.image.format) !=
10681 getBlockWidth(testParams.params.dst.image.format)) ||
10682 (getBlockHeight(testParams.params.src.image.format) !=
10683 getBlockHeight(testParams.params.dst.image.format)))
10684 continue;
10685 }
10686
10687 tcu::TestCaseGroup *dstFormatGroup =
10688 new tcu::TestCaseGroup(testCtx, getFormatCaseName(testParams.params.dst.image.format).c_str());
10689
10690 // Source/destionation image layouts
10691 for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); srcLayoutNdx++)
10692 {
10693 testParams.params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
10694
10695 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); dstLayoutNdx++)
10696 {
10697 testParams.params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
10698
10699 const std::string testName =
10700 getImageLayoutCaseName(testParams.params.src.image.operationLayout) + "_" +
10701 getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
10702 const TestParams params = testParams.params;
10703
10704 dstFormatGroup->addChild(new CopyImageToImageTestCase(testCtx, testName, params));
10705 }
10706 }
10707
10708 srcFormatGroup->addChild(dstFormatGroup);
10709 }
10710
10711 imageSizeGroup->addChild(srcFormatGroup);
10712 }
10713 }
10714
10715 group->addChild(imageSizeGroup);
10716 }
10717 }
10718
addImageToImageAllFormatsDepthStencilFormatsTests(tcu::TestCaseGroup * group,TestParams params)10719 void addImageToImageAllFormatsDepthStencilFormatsTests(tcu::TestCaseGroup *group, TestParams params)
10720 {
10721 const VkImageLayout copySrcLayouts[] = {VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL};
10722 const VkImageLayout copyDstLayouts[] = {VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL};
10723
10724 for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx)
10725 {
10726 params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
10727 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx)
10728 {
10729 params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
10730
10731 const std::string testName = getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
10732 getImageLayoutCaseName(params.dst.image.operationLayout);
10733 group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, params));
10734 }
10735 }
10736 }
10737
addImageToImageAllFormatsDepthStencilTests(tcu::TestCaseGroup * group,TestGroupParamsPtr testGroupParams)10738 void addImageToImageAllFormatsDepthStencilTests(tcu::TestCaseGroup *group, TestGroupParamsPtr testGroupParams)
10739 {
10740 const VkFormat depthAndStencilFormats[] = {
10741 VK_FORMAT_D16_UNORM, VK_FORMAT_X8_D24_UNORM_PACK32, VK_FORMAT_D32_SFLOAT, VK_FORMAT_S8_UINT,
10742 VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT,
10743 };
10744
10745 // 1D to 1D tests.
10746 {
10747 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d_to_1d"));
10748
10749 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats);
10750 ++compatibleFormatsIndex)
10751 {
10752 TestParams params;
10753 params.src.image.imageType = VK_IMAGE_TYPE_1D;
10754 params.dst.image.imageType = VK_IMAGE_TYPE_1D;
10755 params.src.image.extent = default1dExtent;
10756 params.dst.image.extent = default1dExtent;
10757 params.src.image.format = depthAndStencilFormats[compatibleFormatsIndex];
10758 params.dst.image.format = params.src.image.format;
10759 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10760 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10761 params.allocationKind = testGroupParams->allocationKind;
10762 params.extensionFlags = testGroupParams->extensionFlags;
10763 params.queueSelection = testGroupParams->queueSelection;
10764 params.useSparseBinding = testGroupParams->useSparseBinding;
10765
10766 bool hasDepth = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
10767 bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
10768
10769 const VkImageSubresourceLayers defaultDepthSourceLayer = {VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u};
10770 const VkImageSubresourceLayers defaultStencilSourceLayer = {VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u};
10771
10772 for (int32_t i = defaultQuarterSize; i < defaultSize; i += defaultSize / 2)
10773 {
10774 CopyRegion copyRegion;
10775 const VkOffset3D srcOffset = {0, 0, 0};
10776 const VkOffset3D dstOffset = {i, 0, 0};
10777 const VkExtent3D extent = {defaultQuarterSize, 1, 1};
10778
10779 if (hasDepth)
10780 {
10781 const VkImageCopy testCopy = {
10782 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
10783 srcOffset, // VkOffset3D srcOffset;
10784 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
10785 dstOffset, // VkOffset3D dstOffset;
10786 extent, // VkExtent3D extent;
10787 };
10788
10789 copyRegion.imageCopy = testCopy;
10790 params.regions.push_back(copyRegion);
10791 }
10792 if (hasStencil)
10793 {
10794 const VkImageCopy testCopy = {
10795 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
10796 srcOffset, // VkOffset3D srcOffset;
10797 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
10798 dstOffset, // VkOffset3D dstOffset;
10799 extent, // VkExtent3D extent;
10800 };
10801
10802 copyRegion.imageCopy = testCopy;
10803 params.regions.push_back(copyRegion);
10804 }
10805 }
10806
10807 const std::string testName =
10808 getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
10809 addTestGroup(subGroup.get(), testName, addImageToImageAllFormatsDepthStencilFormatsTests, params);
10810
10811 if (hasDepth && hasStencil)
10812 {
10813 params.extensionFlags |= SEPARATE_DEPTH_STENCIL_LAYOUT;
10814 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" +
10815 getFormatCaseName(params.dst.image.format) + "_separate_layouts";
10816 addTestGroup(subGroup.get(), testName2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
10817 }
10818 }
10819
10820 group->addChild(subGroup.release());
10821 }
10822
10823 // 1D to 2D tests.
10824 {
10825 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d_to_2d"));
10826
10827 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats);
10828 ++compatibleFormatsIndex)
10829 {
10830 TestParams params;
10831 params.src.image.imageType = VK_IMAGE_TYPE_1D;
10832 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
10833 params.src.image.extent = default1dExtent;
10834 params.dst.image.extent = defaultRootExtent;
10835 params.src.image.format = depthAndStencilFormats[compatibleFormatsIndex];
10836 params.dst.image.format = params.src.image.format;
10837 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10838 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10839 params.allocationKind = testGroupParams->allocationKind;
10840 params.extensionFlags = testGroupParams->extensionFlags;
10841 params.queueSelection = testGroupParams->queueSelection;
10842 params.useSparseBinding = testGroupParams->useSparseBinding;
10843 params.extensionFlags |= MAINTENANCE_5;
10844
10845 bool hasDepth = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
10846 bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
10847
10848 const VkImageSubresourceLayers defaultDepthSourceLayer = {VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u};
10849 const VkImageSubresourceLayers defaultStencilSourceLayer = {VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u};
10850
10851 for (uint32_t i = 0; i < defaultRootSize; ++i)
10852 {
10853 CopyRegion copyRegion;
10854 const VkOffset3D srcOffset = {static_cast<int32_t>(i * defaultRootSize), 0, 0};
10855 const VkOffset3D dstOffset = {0, static_cast<int32_t>(i), 0};
10856 const VkExtent3D extent = {defaultRootSize, 1, 1};
10857
10858 if (hasDepth)
10859 {
10860 const VkImageCopy testCopy = {
10861 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
10862 srcOffset, // VkOffset3D srcOffset;
10863 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
10864 dstOffset, // VkOffset3D dstOffset;
10865 extent, // VkExtent3D extent;
10866 };
10867
10868 copyRegion.imageCopy = testCopy;
10869 params.regions.push_back(copyRegion);
10870 }
10871 if (hasStencil)
10872 {
10873 const VkImageCopy testCopy = {
10874 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
10875 srcOffset, // VkOffset3D srcOffset;
10876 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
10877 dstOffset, // VkOffset3D dstOffset;
10878 extent, // VkExtent3D extent;
10879 };
10880
10881 copyRegion.imageCopy = testCopy;
10882 params.regions.push_back(copyRegion);
10883 }
10884 }
10885
10886 const std::string testName =
10887 getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
10888 addTestGroup(subGroup.get(), testName, addImageToImageAllFormatsDepthStencilFormatsTests, params);
10889
10890 if (hasDepth && hasStencil)
10891 {
10892 params.extensionFlags |= SEPARATE_DEPTH_STENCIL_LAYOUT;
10893 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" +
10894 getFormatCaseName(params.dst.image.format) + "_separate_layouts";
10895 addTestGroup(subGroup.get(), testName2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
10896 }
10897 }
10898
10899 group->addChild(subGroup.release());
10900 }
10901
10902 // 1D to 3D tests.
10903 {
10904 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d_to_3d"));
10905
10906 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats);
10907 ++compatibleFormatsIndex)
10908 {
10909 TestParams params;
10910 params.src.image.imageType = VK_IMAGE_TYPE_1D;
10911 params.dst.image.imageType = VK_IMAGE_TYPE_3D;
10912 params.src.image.extent = default1dExtent;
10913 params.dst.image.extent = default3dSmallExtent;
10914 params.src.image.format = depthAndStencilFormats[compatibleFormatsIndex];
10915 params.dst.image.format = params.src.image.format;
10916 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10917 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10918 params.allocationKind = testGroupParams->allocationKind;
10919 params.extensionFlags = testGroupParams->extensionFlags;
10920 params.queueSelection = testGroupParams->queueSelection;
10921 params.useSparseBinding = testGroupParams->useSparseBinding;
10922 params.extensionFlags |= MAINTENANCE_5;
10923
10924 bool hasDepth = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
10925 bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
10926
10927 const VkImageSubresourceLayers defaultDepthSourceLayer = {VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u};
10928 const VkImageSubresourceLayers defaultStencilSourceLayer = {VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u};
10929
10930 for (int32_t i = 0; i < defaultSixteenthSize; ++i)
10931 {
10932 for (int32_t j = 0; j < defaultSixteenthSize; ++j)
10933 {
10934 CopyRegion copyRegion;
10935 const VkOffset3D srcOffset = {i * defaultQuarterSize + j * defaultSixteenthSize, 0, 0};
10936 const VkOffset3D dstOffset = {0, j, i};
10937 const VkExtent3D extent = {defaultSixteenthSize, 1, 1};
10938
10939 if (hasDepth)
10940 {
10941 const VkImageCopy testCopy = {
10942 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
10943 srcOffset, // VkOffset3D srcOffset;
10944 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
10945 dstOffset, // VkOffset3D dstOffset;
10946 extent, // VkExtent3D extent;
10947 };
10948
10949 copyRegion.imageCopy = testCopy;
10950 params.regions.push_back(copyRegion);
10951 }
10952 if (hasStencil)
10953 {
10954 const VkImageCopy testCopy = {
10955 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
10956 srcOffset, // VkOffset3D srcOffset;
10957 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
10958 dstOffset, // VkOffset3D dstOffset;
10959 extent, // VkExtent3D extent;
10960 };
10961
10962 copyRegion.imageCopy = testCopy;
10963 params.regions.push_back(copyRegion);
10964 }
10965 }
10966 }
10967
10968 const std::string testName =
10969 getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
10970 addTestGroup(subGroup.get(), testName, addImageToImageAllFormatsDepthStencilFormatsTests, params);
10971
10972 if (hasDepth && hasStencil)
10973 {
10974 params.extensionFlags |= SEPARATE_DEPTH_STENCIL_LAYOUT;
10975 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" +
10976 getFormatCaseName(params.dst.image.format) + "_separate_layouts";
10977 addTestGroup(subGroup.get(), testName2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
10978 }
10979 }
10980
10981 group->addChild(subGroup.release());
10982 }
10983
10984 // 2D to 1D tests.
10985 {
10986 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d_to_1d"));
10987
10988 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats);
10989 ++compatibleFormatsIndex)
10990 {
10991 TestParams params;
10992 params.src.image.imageType = VK_IMAGE_TYPE_2D;
10993 params.dst.image.imageType = VK_IMAGE_TYPE_1D;
10994 params.src.image.extent = defaultQuarterExtent;
10995 params.dst.image.extent = default1dQuarterSquaredExtent;
10996 params.src.image.format = depthAndStencilFormats[compatibleFormatsIndex];
10997 params.dst.image.format = params.src.image.format;
10998 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10999 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11000 params.allocationKind = testGroupParams->allocationKind;
11001 params.extensionFlags = testGroupParams->extensionFlags;
11002 params.queueSelection = testGroupParams->queueSelection;
11003 params.useSparseBinding = testGroupParams->useSparseBinding;
11004 params.extensionFlags |= MAINTENANCE_5;
11005
11006 bool hasDepth = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
11007 bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
11008
11009 const VkImageSubresourceLayers defaultDepthSourceLayer = {VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u};
11010 const VkImageSubresourceLayers defaultStencilSourceLayer = {VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u};
11011 const VkImageSubresourceLayers defaultDSSourceLayer = {
11012 VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u};
11013
11014 for (int32_t i = 0; i < defaultQuarterSize; ++i)
11015 {
11016 CopyRegion copyRegion;
11017 const VkOffset3D srcOffset = {0, i, 0};
11018 const VkOffset3D dstOffset = {i * defaultQuarterSize, 0, 0};
11019 const VkExtent3D extent = {defaultQuarterSize, 1, 1};
11020
11021 if (hasDepth)
11022 {
11023 const VkImageCopy testCopy = {
11024 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
11025 srcOffset, // VkOffset3D srcOffset;
11026 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
11027 dstOffset, // VkOffset3D dstOffset;
11028 extent, // VkExtent3D extent;
11029 };
11030
11031 copyRegion.imageCopy = testCopy;
11032 params.regions.push_back(copyRegion);
11033 }
11034 if (hasStencil)
11035 {
11036 const VkImageCopy testCopy = {
11037 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
11038 srcOffset, // VkOffset3D srcOffset;
11039 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
11040 dstOffset, // VkOffset3D dstOffset;
11041 extent, // VkExtent3D extent;
11042 };
11043
11044 copyRegion.imageCopy = testCopy;
11045 params.regions.push_back(copyRegion);
11046 }
11047 }
11048
11049 const std::string testName =
11050 getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
11051 addTestGroup(subGroup.get(), testName, addImageToImageAllFormatsDepthStencilFormatsTests, params);
11052
11053 if (hasDepth && hasStencil)
11054 {
11055 params.extensionFlags |= SEPARATE_DEPTH_STENCIL_LAYOUT;
11056 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" +
11057 getFormatCaseName(params.dst.image.format) + "_separate_layouts";
11058 addTestGroup(subGroup.get(), testName2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
11059
11060 // DS Image copy
11061 {
11062 params.extensionFlags &= ~SEPARATE_DEPTH_STENCIL_LAYOUT;
11063 // Clear previous vkImageCopy elements
11064 params.regions.clear();
11065
11066 for (int32_t i = 0; i < defaultQuarterSize; ++i)
11067 {
11068 CopyRegion copyRegion;
11069 const VkOffset3D srcOffset = {0, i, 0};
11070 const VkOffset3D dstOffset = {i * defaultQuarterSize, 0, 0};
11071 const VkExtent3D extent = {defaultQuarterSize, 1, 1};
11072
11073 const VkImageCopy testCopy = {
11074 defaultDSSourceLayer, // VkImageSubresourceLayers srcSubresource;
11075 srcOffset, // VkOffset3D srcOffset;
11076 defaultDSSourceLayer, // VkImageSubresourceLayers dstSubresource;
11077 dstOffset, // VkOffset3D dstOffset;
11078 extent, // VkExtent3D extent;
11079 };
11080
11081 copyRegion.imageCopy = testCopy;
11082 params.regions.push_back(copyRegion);
11083 }
11084
11085 const std::string testName3 = getFormatCaseName(params.src.image.format) + "_" +
11086 getFormatCaseName(params.dst.image.format) + "_depth_stencil_aspects";
11087 addTestGroup(subGroup.get(), testName3, addImageToImageAllFormatsDepthStencilFormatsTests, params);
11088 }
11089 }
11090 }
11091
11092 group->addChild(subGroup.release());
11093 }
11094
11095 // 2D to 2D tests.
11096 {
11097 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d_to_2d"));
11098
11099 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats);
11100 ++compatibleFormatsIndex)
11101 {
11102 TestParams params;
11103 params.src.image.imageType = VK_IMAGE_TYPE_2D;
11104 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
11105 params.src.image.extent = defaultExtent;
11106 params.dst.image.extent = defaultExtent;
11107 params.src.image.format = depthAndStencilFormats[compatibleFormatsIndex];
11108 params.dst.image.format = params.src.image.format;
11109 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11110 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11111 params.allocationKind = testGroupParams->allocationKind;
11112 params.extensionFlags = testGroupParams->extensionFlags;
11113 params.queueSelection = testGroupParams->queueSelection;
11114 params.useSparseBinding = testGroupParams->useSparseBinding;
11115
11116 bool hasDepth = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
11117 bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
11118
11119 const VkImageSubresourceLayers defaultDepthSourceLayer = {VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u};
11120 const VkImageSubresourceLayers defaultStencilSourceLayer = {VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u};
11121 const VkImageSubresourceLayers defaultDSSourceLayer = {
11122 VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u};
11123
11124 for (int32_t i = 0; i < defaultSize; i += defaultQuarterSize)
11125 {
11126 CopyRegion copyRegion;
11127 const VkOffset3D srcOffset = {0, 0, 0};
11128 const VkOffset3D dstOffset = {i, defaultSize - i - defaultQuarterSize, 0};
11129 const VkExtent3D extent = {defaultQuarterSize, defaultQuarterSize, 1};
11130
11131 if (hasDepth)
11132 {
11133 const VkImageCopy testCopy = {
11134 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
11135 srcOffset, // VkOffset3D srcOffset;
11136 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
11137 dstOffset, // VkOffset3D dstOffset;
11138 extent, // VkExtent3D extent;
11139 };
11140
11141 copyRegion.imageCopy = testCopy;
11142 params.regions.push_back(copyRegion);
11143 }
11144 if (hasStencil)
11145 {
11146 const VkImageCopy testCopy = {
11147 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
11148 srcOffset, // VkOffset3D srcOffset;
11149 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
11150 dstOffset, // VkOffset3D dstOffset;
11151 extent, // VkExtent3D extent;
11152 };
11153
11154 copyRegion.imageCopy = testCopy;
11155 params.regions.push_back(copyRegion);
11156 }
11157 }
11158
11159 const std::string testName =
11160 getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
11161 addTestGroup(subGroup.get(), testName, addImageToImageAllFormatsDepthStencilFormatsTests, params);
11162
11163 if (hasDepth && hasStencil)
11164 {
11165 params.extensionFlags |= SEPARATE_DEPTH_STENCIL_LAYOUT;
11166 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" +
11167 getFormatCaseName(params.dst.image.format) + "_separate_layouts";
11168 addTestGroup(subGroup.get(), testName2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
11169
11170 // DS Image copy
11171 {
11172 params.extensionFlags &= ~SEPARATE_DEPTH_STENCIL_LAYOUT;
11173 // Clear previous vkImageCopy elements
11174 params.regions.clear();
11175
11176 for (int32_t i = 0; i < defaultSize; i += defaultQuarterSize)
11177 {
11178 CopyRegion copyRegion;
11179 const VkOffset3D srcOffset = {0, 0, 0};
11180 const VkOffset3D dstOffset = {i, defaultSize - i - defaultQuarterSize, 0};
11181 const VkExtent3D extent = {defaultQuarterSize, defaultQuarterSize, 1};
11182
11183 const VkImageCopy testCopy = {
11184 defaultDSSourceLayer, // VkImageSubresourceLayers srcSubresource;
11185 srcOffset, // VkOffset3D srcOffset;
11186 defaultDSSourceLayer, // VkImageSubresourceLayers dstSubresource;
11187 dstOffset, // VkOffset3D dstOffset;
11188 extent, // VkExtent3D extent;
11189 };
11190
11191 copyRegion.imageCopy = testCopy;
11192 params.regions.push_back(copyRegion);
11193 }
11194
11195 const std::string testName3 = getFormatCaseName(params.src.image.format) + "_" +
11196 getFormatCaseName(params.dst.image.format) + "_depth_stencil_aspects";
11197 addTestGroup(subGroup.get(), testName3, addImageToImageAllFormatsDepthStencilFormatsTests, params);
11198 }
11199 }
11200 }
11201
11202 group->addChild(subGroup.release());
11203 }
11204
11205 // 2D to 3D tests.
11206 {
11207 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d_to_3d"));
11208
11209 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats);
11210 ++compatibleFormatsIndex)
11211 {
11212 TestParams params;
11213 params.src.image.imageType = VK_IMAGE_TYPE_2D;
11214 params.dst.image.imageType = VK_IMAGE_TYPE_3D;
11215 params.src.image.extent = defaultExtent;
11216 params.dst.image.extent = default3dSmallExtent;
11217 params.src.image.format = depthAndStencilFormats[compatibleFormatsIndex];
11218 params.dst.image.format = params.src.image.format;
11219 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11220 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11221 params.allocationKind = testGroupParams->allocationKind;
11222 params.extensionFlags = testGroupParams->extensionFlags;
11223 params.queueSelection = testGroupParams->queueSelection;
11224 params.useSparseBinding = testGroupParams->useSparseBinding;
11225 params.extensionFlags |= MAINTENANCE_1;
11226
11227 bool hasDepth = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
11228 bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
11229
11230 const VkImageSubresourceLayers defaultDepthSourceLayer = {VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u};
11231 const VkImageSubresourceLayers defaultStencilSourceLayer = {VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u};
11232 const VkImageSubresourceLayers defaultDSSourceLayer = {
11233 VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u};
11234
11235 for (int32_t i = 0; i < defaultSixteenthSize; ++i)
11236 {
11237 CopyRegion copyRegion;
11238 const VkOffset3D srcOffset = {i * defaultSixteenthSize, i % defaultSixteenthSize, 0};
11239 const VkOffset3D dstOffset = {0, 0, i};
11240 const VkExtent3D extent = {defaultSixteenthSize, defaultSixteenthSize, 1};
11241
11242 if (hasDepth)
11243 {
11244 const VkImageCopy testCopy = {
11245 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
11246 srcOffset, // VkOffset3D srcOffset;
11247 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
11248 dstOffset, // VkOffset3D dstOffset;
11249 extent, // VkExtent3D extent;
11250 };
11251
11252 copyRegion.imageCopy = testCopy;
11253 params.regions.push_back(copyRegion);
11254 }
11255 if (hasStencil)
11256 {
11257 const VkImageCopy testCopy = {
11258 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
11259 srcOffset, // VkOffset3D srcOffset;
11260 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
11261 dstOffset, // VkOffset3D dstOffset;
11262 extent, // VkExtent3D extent;
11263 };
11264
11265 copyRegion.imageCopy = testCopy;
11266 params.regions.push_back(copyRegion);
11267 }
11268 }
11269
11270 const std::string testName =
11271 getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
11272 addTestGroup(subGroup.get(), testName, addImageToImageAllFormatsDepthStencilFormatsTests, params);
11273
11274 if (hasDepth && hasStencil)
11275 {
11276 params.extensionFlags |= SEPARATE_DEPTH_STENCIL_LAYOUT;
11277 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" +
11278 getFormatCaseName(params.dst.image.format) + "_separate_layouts";
11279 addTestGroup(subGroup.get(), testName2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
11280
11281 // DS Image copy
11282 {
11283 params.extensionFlags &= ~SEPARATE_DEPTH_STENCIL_LAYOUT;
11284 // Clear previous vkImageCopy elements
11285 params.regions.clear();
11286
11287 for (int32_t i = 0; i < defaultSixteenthSize; ++i)
11288 {
11289 CopyRegion copyRegion;
11290 const VkOffset3D srcOffset = {i * defaultSixteenthSize, i % defaultSixteenthSize, 0};
11291 const VkOffset3D dstOffset = {0, 0, i};
11292 const VkExtent3D extent = {defaultSixteenthSize, defaultSixteenthSize, 1};
11293
11294 const VkImageCopy testCopy = {
11295 defaultDSSourceLayer, // VkImageSubresourceLayers srcSubresource;
11296 srcOffset, // VkOffset3D srcOffset;
11297 defaultDSSourceLayer, // VkImageSubresourceLayers dstSubresource;
11298 dstOffset, // VkOffset3D dstOffset;
11299 extent, // VkExtent3D extent;
11300 };
11301
11302 copyRegion.imageCopy = testCopy;
11303 params.regions.push_back(copyRegion);
11304 }
11305
11306 const std::string testName3 = getFormatCaseName(params.src.image.format) + "_" +
11307 getFormatCaseName(params.dst.image.format) + "_depth_stencil_aspects";
11308 addTestGroup(subGroup.get(), testName3, addImageToImageAllFormatsDepthStencilFormatsTests, params);
11309 }
11310 }
11311 }
11312
11313 group->addChild(subGroup.release());
11314 }
11315
11316 // 3D to 1D tests.
11317 {
11318 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d_to_1d"));
11319
11320 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats);
11321 ++compatibleFormatsIndex)
11322 {
11323 TestParams params;
11324 params.src.image.imageType = VK_IMAGE_TYPE_3D;
11325 params.dst.image.imageType = VK_IMAGE_TYPE_1D;
11326 params.src.image.extent = default3dSmallExtent;
11327 params.dst.image.extent = default1dExtent;
11328 params.src.image.format = depthAndStencilFormats[compatibleFormatsIndex];
11329 params.dst.image.format = params.src.image.format;
11330 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11331 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11332 params.allocationKind = testGroupParams->allocationKind;
11333 params.extensionFlags = testGroupParams->extensionFlags;
11334 params.queueSelection = testGroupParams->queueSelection;
11335 params.useSparseBinding = testGroupParams->useSparseBinding;
11336 params.extensionFlags |= MAINTENANCE_5;
11337
11338 bool hasDepth = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
11339 bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
11340
11341 const VkImageSubresourceLayers defaultDepthSourceLayer = {VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u};
11342 const VkImageSubresourceLayers defaultStencilSourceLayer = {VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u};
11343
11344 for (int32_t i = 0; i < defaultSixteenthSize; ++i)
11345 {
11346 for (int32_t j = 0; j < defaultSixteenthSize; ++j)
11347 {
11348 CopyRegion copyRegion;
11349 const VkOffset3D srcOffset = {0, j % defaultSixteenthSize, i % defaultSixteenthSize};
11350 const VkOffset3D dstOffset = {j * defaultSixteenthSize + i * defaultQuarterSize, 0, 0};
11351 const VkExtent3D extent = {defaultSixteenthSize, 1, 1};
11352
11353 if (hasDepth)
11354 {
11355 const VkImageCopy testCopy = {
11356 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
11357 srcOffset, // VkOffset3D srcOffset;
11358 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
11359 dstOffset, // VkOffset3D dstOffset;
11360 extent, // VkExtent3D extent;
11361 };
11362
11363 copyRegion.imageCopy = testCopy;
11364 params.regions.push_back(copyRegion);
11365 }
11366 if (hasStencil)
11367 {
11368 const VkImageCopy testCopy = {
11369 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
11370 srcOffset, // VkOffset3D srcOffset;
11371 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
11372 dstOffset, // VkOffset3D dstOffset;
11373 extent, // VkExtent3D extent;
11374 };
11375
11376 copyRegion.imageCopy = testCopy;
11377 params.regions.push_back(copyRegion);
11378 }
11379 }
11380 }
11381
11382 const std::string testName =
11383 getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
11384 addTestGroup(subGroup.get(), testName, addImageToImageAllFormatsDepthStencilFormatsTests, params);
11385
11386 if (hasDepth && hasStencil)
11387 {
11388 params.extensionFlags |= SEPARATE_DEPTH_STENCIL_LAYOUT;
11389 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" +
11390 getFormatCaseName(params.dst.image.format) + "_separate_layouts";
11391 addTestGroup(subGroup.get(), testName2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
11392 }
11393 }
11394
11395 group->addChild(subGroup.release());
11396 }
11397
11398 // 3D to 2D tests.
11399 {
11400 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d_to_2d"));
11401
11402 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats);
11403 ++compatibleFormatsIndex)
11404 {
11405 TestParams params;
11406 params.src.image.imageType = VK_IMAGE_TYPE_3D;
11407 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
11408 params.src.image.extent = default3dExtent;
11409 params.dst.image.extent = defaultExtent;
11410 params.src.image.format = depthAndStencilFormats[compatibleFormatsIndex];
11411 params.dst.image.format = params.src.image.format;
11412 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11413 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11414 params.allocationKind = testGroupParams->allocationKind;
11415 params.extensionFlags = testGroupParams->extensionFlags;
11416 params.queueSelection = testGroupParams->queueSelection;
11417 params.useSparseBinding = testGroupParams->useSparseBinding;
11418 params.extensionFlags |= MAINTENANCE_1;
11419
11420 bool hasDepth = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
11421 bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
11422
11423 const VkImageSubresourceLayers defaultDepthSourceLayer = {VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u};
11424 const VkImageSubresourceLayers defaultStencilSourceLayer = {VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u};
11425
11426 for (int32_t i = 0; i < defaultSixteenthSize; ++i)
11427 {
11428 for (int32_t j = 0; j < defaultSixteenthSize; ++j)
11429 {
11430 CopyRegion copyRegion;
11431 const VkOffset3D srcOffset = {0, 0, i % defaultSixteenthSize + j};
11432 const VkOffset3D dstOffset = {j * defaultQuarterSize, i * defaultQuarterSize, 0};
11433 const VkExtent3D extent = {defaultQuarterSize, defaultQuarterSize, 1};
11434
11435 if (hasDepth)
11436 {
11437 const VkImageCopy testCopy = {
11438 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
11439 srcOffset, // VkOffset3D srcOffset;
11440 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
11441 dstOffset, // VkOffset3D dstOffset;
11442 extent, // VkExtent3D extent;
11443 };
11444
11445 copyRegion.imageCopy = testCopy;
11446 params.regions.push_back(copyRegion);
11447 }
11448 if (hasStencil)
11449 {
11450 const VkImageCopy testCopy = {
11451 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
11452 srcOffset, // VkOffset3D srcOffset;
11453 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
11454 dstOffset, // VkOffset3D dstOffset;
11455 extent, // VkExtent3D extent;
11456 };
11457
11458 copyRegion.imageCopy = testCopy;
11459 params.regions.push_back(copyRegion);
11460 }
11461 }
11462 }
11463
11464 const std::string testName =
11465 getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
11466 addTestGroup(subGroup.get(), testName, addImageToImageAllFormatsDepthStencilFormatsTests, params);
11467
11468 if (hasDepth && hasStencil)
11469 {
11470 params.extensionFlags |= SEPARATE_DEPTH_STENCIL_LAYOUT;
11471 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" +
11472 getFormatCaseName(params.dst.image.format) + "_separate_layouts";
11473 addTestGroup(subGroup.get(), testName2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
11474 }
11475 }
11476
11477 group->addChild(subGroup.release());
11478 }
11479
11480 // 3D tests. Note we use smaller dimensions here for performance reasons.
11481 {
11482 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d_to_3d"));
11483
11484 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats);
11485 ++compatibleFormatsIndex)
11486 {
11487 TestParams params;
11488 params.src.image.imageType = VK_IMAGE_TYPE_3D;
11489 params.dst.image.imageType = VK_IMAGE_TYPE_3D;
11490 params.src.image.extent = default3dExtent;
11491 params.dst.image.extent = default3dExtent;
11492 params.src.image.format = depthAndStencilFormats[compatibleFormatsIndex];
11493 params.dst.image.format = params.src.image.format;
11494 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11495 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11496 params.allocationKind = testGroupParams->allocationKind;
11497 params.extensionFlags = testGroupParams->extensionFlags;
11498 params.queueSelection = testGroupParams->queueSelection;
11499 params.useSparseBinding = testGroupParams->useSparseBinding;
11500
11501 bool hasDepth = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
11502 bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
11503
11504 const VkImageSubresourceLayers defaultDepthSourceLayer = {VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u};
11505 const VkImageSubresourceLayers defaultStencilSourceLayer = {VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u};
11506
11507 for (int32_t i = 0; i < defaultQuarterSize; i += defaultSixteenthSize)
11508 {
11509 CopyRegion copyRegion;
11510 const VkOffset3D srcOffset = {0, 0, 0};
11511 const VkOffset3D dstOffset = {i, defaultQuarterSize - i - defaultSixteenthSize, i};
11512 const VkExtent3D extent = {defaultSixteenthSize, defaultSixteenthSize, defaultSixteenthSize};
11513
11514 if (hasDepth)
11515 {
11516 const VkImageCopy testCopy = {
11517 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
11518 srcOffset, // VkOffset3D srcOffset;
11519 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
11520 dstOffset, // VkOffset3D dstOffset;
11521 extent, // VkExtent3D extent;
11522 };
11523
11524 copyRegion.imageCopy = testCopy;
11525 params.regions.push_back(copyRegion);
11526 }
11527 if (hasStencil)
11528 {
11529 const VkImageCopy testCopy = {
11530 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
11531 srcOffset, // VkOffset3D srcOffset;
11532 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
11533 dstOffset, // VkOffset3D dstOffset;
11534 extent, // VkExtent3D extent;
11535 };
11536
11537 copyRegion.imageCopy = testCopy;
11538 params.regions.push_back(copyRegion);
11539 }
11540 }
11541
11542 const std::string testName =
11543 getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
11544 addTestGroup(subGroup.get(), testName, addImageToImageAllFormatsDepthStencilFormatsTests, params);
11545
11546 if (hasDepth && hasStencil)
11547 {
11548 params.extensionFlags |= SEPARATE_DEPTH_STENCIL_LAYOUT;
11549 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" +
11550 getFormatCaseName(params.dst.image.format) + "_separate_layouts";
11551 addTestGroup(subGroup.get(), testName2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
11552 }
11553 }
11554
11555 group->addChild(subGroup.release());
11556 }
11557 }
11558
addImageToImageAllFormatsTests(tcu::TestCaseGroup * group,TestGroupParamsPtr testGroupParams)11559 void addImageToImageAllFormatsTests(tcu::TestCaseGroup *group, TestGroupParamsPtr testGroupParams)
11560 {
11561 addTestGroup(group, "color", addImageToImageAllFormatsColorTests, testGroupParams);
11562 if (testGroupParams->queueSelection == QueueSelectionOptions::Universal)
11563 addTestGroup(group, "depth_stencil", addImageToImageAllFormatsDepthStencilTests, testGroupParams);
11564 }
11565
addImageToImage3dImagesTests(tcu::TestCaseGroup * group,TestGroupParamsPtr testGroupParams)11566 void addImageToImage3dImagesTests(tcu::TestCaseGroup *group, TestGroupParamsPtr testGroupParams)
11567 {
11568 tcu::TestContext &testCtx = group->getTestContext();
11569
11570 {
11571 TestParams params3DTo2D;
11572 const uint32_t slicesLayers = 16u;
11573 params3DTo2D.src.image.imageType = VK_IMAGE_TYPE_3D;
11574 params3DTo2D.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
11575 params3DTo2D.src.image.extent = defaultHalfExtent;
11576 params3DTo2D.src.image.extent.depth = slicesLayers;
11577 params3DTo2D.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11578 params3DTo2D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11579 params3DTo2D.dst.image.imageType = VK_IMAGE_TYPE_2D;
11580 params3DTo2D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
11581 params3DTo2D.dst.image.extent = defaultHalfExtent;
11582 params3DTo2D.dst.image.extent.depth = slicesLayers;
11583 params3DTo2D.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11584 params3DTo2D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11585 params3DTo2D.allocationKind = testGroupParams->allocationKind;
11586 params3DTo2D.extensionFlags = testGroupParams->extensionFlags;
11587 params3DTo2D.queueSelection = testGroupParams->queueSelection;
11588
11589 for (uint32_t slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
11590 {
11591 const VkImageSubresourceLayers sourceLayer = {
11592 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11593 0u, // uint32_t mipLevel;
11594 0u, // uint32_t baseArrayLayer;
11595 1u // uint32_t layerCount;
11596 };
11597
11598 const VkImageSubresourceLayers destinationLayer = {
11599 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11600 0u, // uint32_t mipLevel;
11601 slicesLayersNdx, // uint32_t baseArrayLayer;
11602 1u // uint32_t layerCount;
11603 };
11604
11605 const VkImageCopy testCopy = {
11606 sourceLayer, // VkImageSubresourceLayers srcSubresource;
11607 {0, 0, (int32_t)slicesLayersNdx}, // VkOffset3D srcOffset;
11608 destinationLayer, // VkImageSubresourceLayers dstSubresource;
11609 {0, 0, 0}, // VkOffset3D dstOffset;
11610 defaultHalfExtent, // VkExtent3D extent;
11611 };
11612
11613 CopyRegion imageCopy;
11614 imageCopy.imageCopy = testCopy;
11615
11616 params3DTo2D.regions.push_back(imageCopy);
11617 }
11618 group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_by_slices", params3DTo2D));
11619 }
11620
11621 {
11622 TestParams params2DTo3D;
11623 const uint32_t slicesLayers = 16u;
11624 params2DTo3D.src.image.imageType = VK_IMAGE_TYPE_2D;
11625 params2DTo3D.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
11626 params2DTo3D.src.image.extent = defaultHalfExtent;
11627 params2DTo3D.src.image.extent.depth = slicesLayers;
11628 params2DTo3D.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11629 params2DTo3D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11630 params2DTo3D.dst.image.imageType = VK_IMAGE_TYPE_3D;
11631 params2DTo3D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
11632 params2DTo3D.dst.image.extent = defaultHalfExtent;
11633 params2DTo3D.dst.image.extent.depth = slicesLayers;
11634 params2DTo3D.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11635 params2DTo3D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11636 params2DTo3D.allocationKind = testGroupParams->allocationKind;
11637 params2DTo3D.extensionFlags = testGroupParams->extensionFlags;
11638 params2DTo3D.queueSelection = testGroupParams->queueSelection;
11639
11640 for (uint32_t slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
11641 {
11642 const VkImageSubresourceLayers sourceLayer = {
11643 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11644 0u, // uint32_t mipLevel;
11645 slicesLayersNdx, // uint32_t baseArrayLayer;
11646 1u // uint32_t layerCount;
11647 };
11648
11649 const VkImageSubresourceLayers destinationLayer = {
11650 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11651 0u, // uint32_t mipLevel;
11652 0u, // uint32_t baseArrayLayer;
11653 1u // uint32_t layerCount;
11654 };
11655
11656 const VkImageCopy testCopy = {
11657 sourceLayer, // VkImageSubresourceLayers srcSubresource;
11658 {0, 0, 0}, // VkOffset3D srcOffset;
11659 destinationLayer, // VkImageSubresourceLayers dstSubresource;
11660 {0, 0, (int32_t)slicesLayersNdx}, // VkOffset3D dstOffset;
11661 defaultHalfExtent, // VkExtent3D extent;
11662 };
11663
11664 CopyRegion imageCopy;
11665 imageCopy.imageCopy = testCopy;
11666
11667 params2DTo3D.regions.push_back(imageCopy);
11668 }
11669
11670 group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_by_layers", params2DTo3D));
11671 }
11672
11673 {
11674 TestParams params3DTo2D;
11675 const uint32_t slicesLayers = 16u;
11676 params3DTo2D.src.image.imageType = VK_IMAGE_TYPE_3D;
11677 params3DTo2D.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
11678 params3DTo2D.src.image.extent = defaultHalfExtent;
11679 params3DTo2D.src.image.extent.depth = slicesLayers;
11680 params3DTo2D.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11681 params3DTo2D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11682 params3DTo2D.dst.image.imageType = VK_IMAGE_TYPE_2D;
11683 params3DTo2D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
11684 params3DTo2D.dst.image.extent = defaultHalfExtent;
11685 params3DTo2D.dst.image.extent.depth = slicesLayers;
11686 params3DTo2D.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11687 params3DTo2D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11688 params3DTo2D.allocationKind = testGroupParams->allocationKind;
11689 params3DTo2D.extensionFlags = testGroupParams->extensionFlags;
11690 params3DTo2D.queueSelection = testGroupParams->queueSelection;
11691
11692 {
11693 const VkImageSubresourceLayers sourceLayer = {
11694 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11695 0u, // uint32_t mipLevel;
11696 0u, // uint32_t baseArrayLayer;
11697 1u // uint32_t layerCount;
11698 };
11699
11700 const VkImageSubresourceLayers destinationLayer = {
11701 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11702 0u, // uint32_t mipLevel;
11703 0, // uint32_t baseArrayLayer;
11704 slicesLayers // uint32_t layerCount;
11705 };
11706
11707 const VkImageCopy testCopy = {
11708 sourceLayer, // VkImageSubresourceLayers srcSubresource;
11709 {0, 0, 0}, // VkOffset3D srcOffset;
11710 destinationLayer, // VkImageSubresourceLayers dstSubresource;
11711 {0, 0, 0}, // VkOffset3D dstOffset;
11712 params3DTo2D.src.image.extent // VkExtent3D extent;
11713 };
11714
11715 CopyRegion imageCopy;
11716 imageCopy.imageCopy = testCopy;
11717
11718 params3DTo2D.regions.push_back(imageCopy);
11719 }
11720 group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_whole", params3DTo2D));
11721 }
11722
11723 {
11724 TestParams params2DTo3D;
11725 const uint32_t slicesLayers = 16u;
11726 params2DTo3D.src.image.imageType = VK_IMAGE_TYPE_2D;
11727 params2DTo3D.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
11728 params2DTo3D.src.image.extent = defaultHalfExtent;
11729 params2DTo3D.src.image.extent.depth = slicesLayers;
11730 params2DTo3D.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11731 params2DTo3D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11732 params2DTo3D.dst.image.imageType = VK_IMAGE_TYPE_3D;
11733 params2DTo3D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
11734 params2DTo3D.dst.image.extent = defaultHalfExtent;
11735 params2DTo3D.dst.image.extent.depth = slicesLayers;
11736 params2DTo3D.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11737 params2DTo3D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11738 params2DTo3D.allocationKind = testGroupParams->allocationKind;
11739 params2DTo3D.extensionFlags = testGroupParams->extensionFlags;
11740 params2DTo3D.queueSelection = testGroupParams->queueSelection;
11741
11742 {
11743 const VkImageSubresourceLayers sourceLayer = {
11744 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11745 0u, // uint32_t mipLevel;
11746 0u, // uint32_t baseArrayLayer;
11747 slicesLayers // uint32_t layerCount;
11748 };
11749
11750 const VkImageSubresourceLayers destinationLayer = {
11751 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11752 0u, // uint32_t mipLevel;
11753 0u, // uint32_t baseArrayLayer;
11754 1u // uint32_t layerCount;
11755 };
11756
11757 const VkImageCopy testCopy = {
11758 sourceLayer, // VkImageSubresourceLayers srcSubresource;
11759 {0, 0, 0}, // VkOffset3D srcOffset;
11760 destinationLayer, // VkImageSubresourceLayers dstSubresource;
11761 {0, 0, 0}, // VkOffset3D dstOffset;
11762 params2DTo3D.src.image.extent, // VkExtent3D extent;
11763 };
11764
11765 CopyRegion imageCopy;
11766 imageCopy.imageCopy = testCopy;
11767
11768 params2DTo3D.regions.push_back(imageCopy);
11769 }
11770
11771 group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_whole", params2DTo3D));
11772 }
11773
11774 {
11775 TestParams params3DTo2D;
11776 const uint32_t slicesLayers = 16u;
11777 params3DTo2D.src.image.imageType = VK_IMAGE_TYPE_3D;
11778 params3DTo2D.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
11779 params3DTo2D.src.image.extent = defaultHalfExtent;
11780 params3DTo2D.src.image.extent.depth = slicesLayers;
11781 params3DTo2D.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11782 params3DTo2D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11783 params3DTo2D.dst.image.imageType = VK_IMAGE_TYPE_2D;
11784 params3DTo2D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
11785 params3DTo2D.dst.image.extent = defaultHalfExtent;
11786 params3DTo2D.dst.image.extent.depth = slicesLayers;
11787 params3DTo2D.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11788 params3DTo2D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11789 params3DTo2D.allocationKind = testGroupParams->allocationKind;
11790 params3DTo2D.extensionFlags = testGroupParams->extensionFlags;
11791 params3DTo2D.queueSelection = testGroupParams->queueSelection;
11792
11793 const uint32_t regionWidth = defaultHalfExtent.width / slicesLayers - 1;
11794 const uint32_t regionHeight = defaultHalfExtent.height / slicesLayers - 1;
11795
11796 for (uint32_t slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
11797 {
11798 const VkImageSubresourceLayers sourceLayer = {
11799 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11800 0u, // uint32_t mipLevel;
11801 0u, // uint32_t baseArrayLayer;
11802 1u // uint32_t layerCount;
11803 };
11804
11805 const VkImageSubresourceLayers destinationLayer = {
11806 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11807 0u, // uint32_t mipLevel;
11808 slicesLayersNdx, // uint32_t baseArrayLayer;
11809 1u // uint32_t layerCount;
11810 };
11811
11812 const VkImageCopy testCopy = {
11813 sourceLayer, // VkImageSubresourceLayers srcSubresource;
11814 {0, (int32_t)(regionHeight * slicesLayersNdx), (int32_t)slicesLayersNdx}, // VkOffset3D srcOffset;
11815 destinationLayer, // VkImageSubresourceLayers dstSubresource;
11816 {(int32_t)(regionWidth * slicesLayersNdx), 0, 0}, // VkOffset3D dstOffset;
11817 {(defaultHalfExtent.width - regionWidth * slicesLayersNdx),
11818 (defaultHalfExtent.height - regionHeight * slicesLayersNdx), 1} // VkExtent3D extent;
11819 };
11820
11821 CopyRegion imageCopy;
11822 imageCopy.imageCopy = testCopy;
11823 params3DTo2D.regions.push_back(imageCopy);
11824 }
11825 group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_regions", params3DTo2D));
11826 }
11827
11828 {
11829 TestParams params2DTo3D;
11830 const uint32_t slicesLayers = 16u;
11831 params2DTo3D.src.image.imageType = VK_IMAGE_TYPE_2D;
11832 params2DTo3D.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
11833 params2DTo3D.src.image.extent = defaultHalfExtent;
11834 params2DTo3D.src.image.extent.depth = slicesLayers;
11835 params2DTo3D.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11836 params2DTo3D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11837 params2DTo3D.dst.image.imageType = VK_IMAGE_TYPE_3D;
11838 params2DTo3D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
11839 params2DTo3D.dst.image.extent = defaultHalfExtent;
11840 params2DTo3D.dst.image.extent.depth = slicesLayers;
11841 params2DTo3D.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11842 params2DTo3D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11843 params2DTo3D.allocationKind = testGroupParams->allocationKind;
11844 params2DTo3D.extensionFlags = testGroupParams->extensionFlags;
11845 params2DTo3D.queueSelection = testGroupParams->queueSelection;
11846
11847 const uint32_t regionWidth = defaultHalfExtent.width / slicesLayers - 1;
11848 const uint32_t regionHeight = defaultHalfExtent.height / slicesLayers - 1;
11849
11850 for (uint32_t slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
11851 {
11852 const VkImageSubresourceLayers sourceLayer = {
11853 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11854 0u, // uint32_t mipLevel;
11855 slicesLayersNdx, // uint32_t baseArrayLayer;
11856 1u // uint32_t layerCount;
11857 };
11858
11859 const VkImageSubresourceLayers destinationLayer = {
11860 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11861 0u, // uint32_t mipLevel;
11862 0u, // uint32_t baseArrayLayer;
11863 1u // uint32_t layerCount;
11864 };
11865
11866 const VkImageCopy testCopy = {
11867 sourceLayer, // VkImageSubresourceLayers srcSubresource;
11868 {(int32_t)(regionWidth * slicesLayersNdx), 0, 0}, // VkOffset3D srcOffset;
11869 destinationLayer, // VkImageSubresourceLayers dstSubresource;
11870 {0, (int32_t)(regionHeight * slicesLayersNdx), (int32_t)(slicesLayersNdx)}, // VkOffset3D dstOffset;
11871 {defaultHalfExtent.width - regionWidth * slicesLayersNdx,
11872 defaultHalfExtent.height - regionHeight * slicesLayersNdx, 1} // VkExtent3D extent;
11873 };
11874
11875 CopyRegion imageCopy;
11876 imageCopy.imageCopy = testCopy;
11877
11878 params2DTo3D.regions.push_back(imageCopy);
11879 }
11880
11881 group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_regions", params2DTo3D));
11882 }
11883 }
11884
addImageToImageCubeTests(tcu::TestCaseGroup * group,TestGroupParamsPtr testGroupParams)11885 void addImageToImageCubeTests(tcu::TestCaseGroup *group, TestGroupParamsPtr testGroupParams)
11886 {
11887 tcu::TestContext &testCtx = group->getTestContext();
11888
11889 {
11890 TestParams paramsCubeToArray;
11891 const uint32_t arrayLayers = 6u;
11892 paramsCubeToArray.src.image.createFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
11893 paramsCubeToArray.src.image.imageType = VK_IMAGE_TYPE_2D;
11894 paramsCubeToArray.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
11895 paramsCubeToArray.src.image.extent = defaultHalfExtent;
11896 paramsCubeToArray.src.image.extent.depth = arrayLayers;
11897 paramsCubeToArray.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11898 paramsCubeToArray.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11899 paramsCubeToArray.dst.image.createFlags = 0;
11900 paramsCubeToArray.dst.image.imageType = VK_IMAGE_TYPE_2D;
11901 paramsCubeToArray.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
11902 paramsCubeToArray.dst.image.extent = defaultHalfExtent;
11903 paramsCubeToArray.dst.image.extent.depth = arrayLayers;
11904 paramsCubeToArray.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11905 paramsCubeToArray.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11906 paramsCubeToArray.dst.image.fillMode = FILL_MODE_GRADIENT;
11907 paramsCubeToArray.allocationKind = testGroupParams->allocationKind;
11908 paramsCubeToArray.extensionFlags = testGroupParams->extensionFlags;
11909 paramsCubeToArray.queueSelection = testGroupParams->queueSelection;
11910
11911 for (uint32_t arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
11912 {
11913 const VkImageSubresourceLayers sourceLayer = {
11914 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11915 0u, // uint32_t mipLevel;
11916 arrayLayersNdx, // uint32_t baseArrayLayer;
11917 1u // uint32_t layerCount;
11918 };
11919
11920 const VkImageSubresourceLayers destinationLayer = {
11921 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11922 0u, // uint32_t mipLevel;
11923 arrayLayersNdx, // uint32_t baseArrayLayer;
11924 1u // uint32_t layerCount;
11925 };
11926
11927 const VkImageCopy testCopy = {
11928 sourceLayer, // VkImageSubresourceLayers srcSubresource;
11929 {0, 0, 0}, // VkOffset3D srcOffset;
11930 destinationLayer, // VkImageSubresourceLayers dstSubresource;
11931 {0, 0, 0}, // VkOffset3D dstOffset;
11932 defaultHalfExtent // VkExtent3D extent;
11933 };
11934
11935 CopyRegion imageCopy;
11936 imageCopy.imageCopy = testCopy;
11937
11938 paramsCubeToArray.regions.push_back(imageCopy);
11939 }
11940
11941 group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_array_layers", paramsCubeToArray));
11942 }
11943
11944 {
11945 TestParams paramsCubeToArray;
11946 const uint32_t arrayLayers = 6u;
11947 paramsCubeToArray.src.image.createFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
11948 paramsCubeToArray.src.image.imageType = VK_IMAGE_TYPE_2D;
11949 paramsCubeToArray.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
11950 paramsCubeToArray.src.image.extent = defaultHalfExtent;
11951 paramsCubeToArray.src.image.extent.depth = arrayLayers;
11952 paramsCubeToArray.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11953 paramsCubeToArray.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11954 paramsCubeToArray.dst.image.createFlags = 0;
11955 paramsCubeToArray.dst.image.imageType = VK_IMAGE_TYPE_2D;
11956 paramsCubeToArray.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
11957 paramsCubeToArray.dst.image.extent = defaultHalfExtent;
11958 paramsCubeToArray.dst.image.extent.depth = arrayLayers;
11959 paramsCubeToArray.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11960 paramsCubeToArray.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11961 paramsCubeToArray.dst.image.fillMode = FILL_MODE_GRADIENT;
11962 paramsCubeToArray.allocationKind = testGroupParams->allocationKind;
11963 paramsCubeToArray.extensionFlags = testGroupParams->extensionFlags;
11964 paramsCubeToArray.queueSelection = testGroupParams->queueSelection;
11965
11966 {
11967 const VkImageSubresourceLayers sourceLayer = {
11968 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11969 0u, // uint32_t mipLevel;
11970 0u, // uint32_t baseArrayLayer;
11971 arrayLayers // uint32_t layerCount;
11972 };
11973
11974 const VkImageSubresourceLayers destinationLayer = {
11975 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11976 0u, // uint32_t mipLevel;
11977 0u, // uint32_t baseArrayLayer;
11978 arrayLayers // uint32_t layerCount;
11979 };
11980
11981 const VkImageCopy testCopy = {
11982 sourceLayer, // VkImageSubresourceLayers srcSubresource;
11983 {0, 0, 0}, // VkOffset3D srcOffset;
11984 destinationLayer, // VkImageSubresourceLayers dstSubresource;
11985 {0, 0, 0}, // VkOffset3D dstOffset;
11986 defaultHalfExtent // VkExtent3D extent;
11987 };
11988
11989 CopyRegion imageCopy;
11990 imageCopy.imageCopy = testCopy;
11991
11992 paramsCubeToArray.regions.push_back(imageCopy);
11993 }
11994
11995 group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_array_whole", paramsCubeToArray));
11996 }
11997
11998 {
11999 TestParams paramsArrayToCube;
12000 const uint32_t arrayLayers = 6u;
12001 paramsArrayToCube.src.image.createFlags = 0;
12002 paramsArrayToCube.src.image.imageType = VK_IMAGE_TYPE_2D;
12003 paramsArrayToCube.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
12004 paramsArrayToCube.src.image.extent = defaultHalfExtent;
12005 paramsArrayToCube.src.image.extent.depth = arrayLayers;
12006 paramsArrayToCube.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12007 paramsArrayToCube.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12008 paramsArrayToCube.dst.image.createFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
12009 paramsArrayToCube.dst.image.imageType = VK_IMAGE_TYPE_2D;
12010 paramsArrayToCube.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
12011 paramsArrayToCube.dst.image.extent = defaultHalfExtent;
12012 paramsArrayToCube.dst.image.extent.depth = arrayLayers;
12013 paramsArrayToCube.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12014 paramsArrayToCube.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12015 paramsArrayToCube.dst.image.fillMode = FILL_MODE_GRADIENT;
12016 paramsArrayToCube.allocationKind = testGroupParams->allocationKind;
12017 paramsArrayToCube.extensionFlags = testGroupParams->extensionFlags;
12018 paramsArrayToCube.queueSelection = testGroupParams->queueSelection;
12019
12020 for (uint32_t arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
12021 {
12022 const VkImageSubresourceLayers sourceLayer = {
12023 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12024 0u, // uint32_t mipLevel;
12025 arrayLayersNdx, // uint32_t baseArrayLayer;
12026 1u // uint32_t layerCount;
12027 };
12028
12029 const VkImageSubresourceLayers destinationLayer = {
12030 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12031 0u, // uint32_t mipLevel;
12032 arrayLayersNdx, // uint32_t baseArrayLayer;
12033 1u // uint32_t layerCount;
12034 };
12035
12036 const VkImageCopy testCopy = {
12037 sourceLayer, // VkImageSubresourceLayers srcSubresource;
12038 {0, 0, 0}, // VkOffset3D srcOffset;
12039 destinationLayer, // VkImageSubresourceLayers dstSubresource;
12040 {0, 0, 0}, // VkOffset3D dstOffset;
12041 defaultHalfExtent // VkExtent3D extent;
12042 };
12043
12044 CopyRegion imageCopy;
12045 imageCopy.imageCopy = testCopy;
12046
12047 paramsArrayToCube.regions.push_back(imageCopy);
12048 }
12049
12050 group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_cube_layers", paramsArrayToCube));
12051 }
12052
12053 {
12054 TestParams paramsArrayToCube;
12055 const uint32_t arrayLayers = 6u;
12056 paramsArrayToCube.src.image.createFlags = 0;
12057 paramsArrayToCube.src.image.imageType = VK_IMAGE_TYPE_2D;
12058 paramsArrayToCube.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
12059 paramsArrayToCube.src.image.extent = defaultHalfExtent;
12060 paramsArrayToCube.src.image.extent.depth = arrayLayers;
12061 paramsArrayToCube.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12062 paramsArrayToCube.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12063 paramsArrayToCube.dst.image.createFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
12064 paramsArrayToCube.dst.image.imageType = VK_IMAGE_TYPE_2D;
12065 paramsArrayToCube.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
12066 paramsArrayToCube.dst.image.extent = defaultHalfExtent;
12067 paramsArrayToCube.dst.image.extent.depth = arrayLayers;
12068 paramsArrayToCube.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12069 paramsArrayToCube.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12070 paramsArrayToCube.dst.image.fillMode = FILL_MODE_GRADIENT;
12071 paramsArrayToCube.allocationKind = testGroupParams->allocationKind;
12072 paramsArrayToCube.extensionFlags = testGroupParams->extensionFlags;
12073 paramsArrayToCube.queueSelection = testGroupParams->queueSelection;
12074
12075 {
12076 const VkImageSubresourceLayers sourceLayer = {
12077 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12078 0u, // uint32_t mipLevel;
12079 0u, // uint32_t baseArrayLayer;
12080 arrayLayers // uint32_t layerCount;
12081 };
12082
12083 const VkImageSubresourceLayers destinationLayer = {
12084 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12085 0u, // uint32_t mipLevel;
12086 0u, // uint32_t baseArrayLayer;
12087 arrayLayers // uint32_t layerCount;
12088 };
12089
12090 const VkImageCopy testCopy = {
12091 sourceLayer, // VkImageSubresourceLayers srcSubresource;
12092 {0, 0, 0}, // VkOffset3D srcOffset;
12093 destinationLayer, // VkImageSubresourceLayers dstSubresource;
12094 {0, 0, 0}, // VkOffset3D dstOffset;
12095 defaultHalfExtent // VkExtent3D extent;
12096 };
12097
12098 CopyRegion imageCopy;
12099 imageCopy.imageCopy = testCopy;
12100
12101 paramsArrayToCube.regions.push_back(imageCopy);
12102 }
12103
12104 group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_cube_whole", paramsArrayToCube));
12105 }
12106
12107 {
12108 TestParams paramsCubeToArray;
12109 const uint32_t arrayLayers = 6u;
12110 paramsCubeToArray.src.image.createFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
12111 paramsCubeToArray.src.image.imageType = VK_IMAGE_TYPE_2D;
12112 paramsCubeToArray.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
12113 paramsCubeToArray.src.image.extent = defaultHalfExtent;
12114 paramsCubeToArray.src.image.extent.depth = arrayLayers;
12115 paramsCubeToArray.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12116 paramsCubeToArray.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12117 paramsCubeToArray.dst.image.createFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
12118 paramsCubeToArray.dst.image.imageType = VK_IMAGE_TYPE_2D;
12119 paramsCubeToArray.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
12120 paramsCubeToArray.dst.image.extent = defaultHalfExtent;
12121 paramsCubeToArray.dst.image.extent.depth = arrayLayers;
12122 paramsCubeToArray.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12123 paramsCubeToArray.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12124 paramsCubeToArray.dst.image.fillMode = FILL_MODE_GRADIENT;
12125 paramsCubeToArray.allocationKind = testGroupParams->allocationKind;
12126 paramsCubeToArray.extensionFlags = testGroupParams->extensionFlags;
12127 paramsCubeToArray.queueSelection = testGroupParams->queueSelection;
12128
12129 for (uint32_t arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
12130 {
12131 const VkImageSubresourceLayers sourceLayer = {
12132 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12133 0u, // uint32_t mipLevel;
12134 arrayLayersNdx, // uint32_t baseArrayLayer;
12135 1u // uint32_t layerCount;
12136 };
12137
12138 const VkImageSubresourceLayers destinationLayer = {
12139 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12140 0u, // uint32_t mipLevel;
12141 arrayLayersNdx, // uint32_t baseArrayLayer;
12142 1u // uint32_t layerCount;
12143 };
12144
12145 const VkImageCopy testCopy = {
12146 sourceLayer, // VkImageSubresourceLayers srcSubresource;
12147 {0, 0, 0}, // VkOffset3D srcOffset;
12148 destinationLayer, // VkImageSubresourceLayers dstSubresource;
12149 {0, 0, 0}, // VkOffset3D dstOffset;
12150 defaultHalfExtent // VkExtent3D extent;
12151 };
12152
12153 CopyRegion imageCopy;
12154 imageCopy.imageCopy = testCopy;
12155
12156 paramsCubeToArray.regions.push_back(imageCopy);
12157 }
12158
12159 group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_cube_layers", paramsCubeToArray));
12160 }
12161
12162 {
12163 TestParams paramsCubeToCube;
12164 const uint32_t arrayLayers = 6u;
12165 paramsCubeToCube.src.image.createFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
12166 paramsCubeToCube.src.image.imageType = VK_IMAGE_TYPE_2D;
12167 paramsCubeToCube.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
12168 paramsCubeToCube.src.image.extent = defaultHalfExtent;
12169 paramsCubeToCube.src.image.extent.depth = arrayLayers;
12170 paramsCubeToCube.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12171 paramsCubeToCube.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12172 paramsCubeToCube.dst.image.createFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
12173 paramsCubeToCube.dst.image.imageType = VK_IMAGE_TYPE_2D;
12174 paramsCubeToCube.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
12175 paramsCubeToCube.dst.image.extent = defaultHalfExtent;
12176 paramsCubeToCube.dst.image.extent.depth = arrayLayers;
12177 paramsCubeToCube.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12178 paramsCubeToCube.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12179 paramsCubeToCube.dst.image.fillMode = FILL_MODE_GRADIENT;
12180 paramsCubeToCube.allocationKind = testGroupParams->allocationKind;
12181 paramsCubeToCube.extensionFlags = testGroupParams->extensionFlags;
12182 paramsCubeToCube.queueSelection = testGroupParams->queueSelection;
12183
12184 {
12185 const VkImageSubresourceLayers sourceLayer = {
12186 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12187 0u, // uint32_t mipLevel;
12188 0u, // uint32_t baseArrayLayer;
12189 arrayLayers // uint32_t layerCount;
12190 };
12191
12192 const VkImageSubresourceLayers destinationLayer = {
12193 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12194 0u, // uint32_t mipLevel;
12195 0u, // uint32_t baseArrayLayer;
12196 arrayLayers // uint32_t layerCount;
12197 };
12198
12199 const VkImageCopy testCopy = {
12200 sourceLayer, // VkImageSubresourceLayers srcSubresource;
12201 {0, 0, 0}, // VkOffset3D srcOffset;
12202 destinationLayer, // VkImageSubresourceLayers dstSubresource;
12203 {0, 0, 0}, // VkOffset3D dstOffset;
12204 defaultHalfExtent // VkExtent3D extent;
12205 };
12206
12207 CopyRegion imageCopy;
12208 imageCopy.imageCopy = testCopy;
12209
12210 paramsCubeToCube.regions.push_back(imageCopy);
12211 }
12212
12213 group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_cube_whole", paramsCubeToCube));
12214 }
12215 }
12216
addImageToImageArrayTests(tcu::TestCaseGroup * group,TestGroupParamsPtr testGroupParams)12217 void addImageToImageArrayTests(tcu::TestCaseGroup *group, TestGroupParamsPtr testGroupParams)
12218 {
12219 tcu::TestContext &testCtx = group->getTestContext();
12220
12221 {
12222 TestParams paramsArrayToArray;
12223 const uint32_t arrayLayers = 16u;
12224 paramsArrayToArray.src.image.imageType = VK_IMAGE_TYPE_2D;
12225 paramsArrayToArray.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
12226 paramsArrayToArray.src.image.extent = defaultHalfExtent;
12227 paramsArrayToArray.src.image.extent.depth = arrayLayers;
12228 paramsArrayToArray.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12229 paramsArrayToArray.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12230 paramsArrayToArray.dst.image.imageType = VK_IMAGE_TYPE_2D;
12231 paramsArrayToArray.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
12232 paramsArrayToArray.dst.image.extent = defaultHalfExtent;
12233 paramsArrayToArray.dst.image.extent.depth = arrayLayers;
12234 paramsArrayToArray.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12235 paramsArrayToArray.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12236 paramsArrayToArray.dst.image.fillMode = FILL_MODE_GRADIENT;
12237 paramsArrayToArray.allocationKind = testGroupParams->allocationKind;
12238 paramsArrayToArray.extensionFlags = testGroupParams->extensionFlags;
12239 paramsArrayToArray.queueSelection = testGroupParams->queueSelection;
12240 paramsArrayToArray.useSparseBinding = testGroupParams->useSparseBinding;
12241
12242 for (uint32_t arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
12243 {
12244 const VkImageSubresourceLayers sourceLayer = {
12245 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12246 0u, // uint32_t mipLevel;
12247 arrayLayersNdx, // uint32_t baseArrayLayer;
12248 1u // uint32_t layerCount;
12249 };
12250
12251 const VkImageSubresourceLayers destinationLayer = {
12252 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12253 0u, // uint32_t mipLevel;
12254 arrayLayersNdx, // uint32_t baseArrayLayer;
12255 1u // uint32_t layerCount;
12256 };
12257
12258 const VkImageCopy testCopy = {
12259 sourceLayer, // VkImageSubresourceLayers srcSubresource;
12260 {0, 0, 0}, // VkOffset3D srcOffset;
12261 destinationLayer, // VkImageSubresourceLayers dstSubresource;
12262 {0, 0, 0}, // VkOffset3D dstOffset;
12263 defaultHalfExtent // VkExtent3D extent;
12264 };
12265
12266 CopyRegion imageCopy;
12267 imageCopy.imageCopy = testCopy;
12268
12269 paramsArrayToArray.regions.push_back(imageCopy);
12270 }
12271
12272 group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_array_layers", paramsArrayToArray));
12273 }
12274
12275 {
12276 TestParams paramsArrayToArray;
12277 const uint32_t arrayLayers = 16u;
12278 paramsArrayToArray.src.image.imageType = VK_IMAGE_TYPE_2D;
12279 paramsArrayToArray.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
12280 paramsArrayToArray.src.image.extent = defaultHalfExtent;
12281 paramsArrayToArray.src.image.extent.depth = arrayLayers;
12282 paramsArrayToArray.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12283 paramsArrayToArray.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12284 paramsArrayToArray.dst.image.imageType = VK_IMAGE_TYPE_2D;
12285 paramsArrayToArray.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
12286 paramsArrayToArray.dst.image.extent = defaultHalfExtent;
12287 paramsArrayToArray.dst.image.extent.depth = arrayLayers;
12288 paramsArrayToArray.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12289 paramsArrayToArray.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12290 paramsArrayToArray.dst.image.fillMode = FILL_MODE_GRADIENT;
12291 paramsArrayToArray.allocationKind = testGroupParams->allocationKind;
12292 paramsArrayToArray.extensionFlags = testGroupParams->extensionFlags;
12293 paramsArrayToArray.queueSelection = testGroupParams->queueSelection;
12294
12295 {
12296 const VkImageSubresourceLayers sourceLayer = {
12297 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12298 0u, // uint32_t mipLevel;
12299 0u, // uint32_t baseArrayLayer;
12300 arrayLayers // uint32_t layerCount;
12301 };
12302
12303 const VkImageSubresourceLayers destinationLayer = {
12304 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12305 0u, // uint32_t mipLevel;
12306 0u, // uint32_t baseArrayLayer;
12307 arrayLayers // uint32_t layerCount;
12308 };
12309
12310 const VkImageCopy testCopy = {
12311 sourceLayer, // VkImageSubresourceLayers srcSubresource;
12312 {0, 0, 0}, // VkOffset3D srcOffset;
12313 destinationLayer, // VkImageSubresourceLayers dstSubresource;
12314 {0, 0, 0}, // VkOffset3D dstOffset;
12315 defaultHalfExtent // VkExtent3D extent;
12316 };
12317
12318 CopyRegion imageCopy;
12319 imageCopy.imageCopy = testCopy;
12320
12321 paramsArrayToArray.regions.push_back(imageCopy);
12322 }
12323
12324 group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_array_whole", paramsArrayToArray));
12325 }
12326
12327 if (testGroupParams->queueSelection == QueueSelectionOptions::Universal)
12328 {
12329 TestParams paramsArrayToArray;
12330 const uint32_t arrayLayers = 16u;
12331 paramsArrayToArray.src.image.imageType = VK_IMAGE_TYPE_2D;
12332 paramsArrayToArray.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
12333 paramsArrayToArray.src.image.extent = defaultHalfExtent;
12334 paramsArrayToArray.src.image.extent.depth = arrayLayers;
12335 paramsArrayToArray.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12336 paramsArrayToArray.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12337 paramsArrayToArray.dst.image.imageType = VK_IMAGE_TYPE_2D;
12338 paramsArrayToArray.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
12339 paramsArrayToArray.dst.image.extent = defaultHalfExtent;
12340 paramsArrayToArray.dst.image.extent.depth = arrayLayers;
12341 paramsArrayToArray.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12342 paramsArrayToArray.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12343 paramsArrayToArray.dst.image.fillMode = FILL_MODE_GRADIENT;
12344 paramsArrayToArray.allocationKind = testGroupParams->allocationKind;
12345 paramsArrayToArray.extensionFlags = testGroupParams->extensionFlags;
12346 paramsArrayToArray.queueSelection = testGroupParams->queueSelection;
12347 paramsArrayToArray.extensionFlags |= MAINTENANCE_5;
12348
12349 {
12350 const VkImageSubresourceLayers sourceLayer = {
12351 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12352 0u, // uint32_t mipLevel;
12353 0u, // uint32_t baseArrayLayer;
12354 VK_REMAINING_ARRAY_LAYERS // uint32_t layerCount;
12355 };
12356
12357 const VkImageSubresourceLayers destinationLayer = {
12358 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12359 0u, // uint32_t mipLevel;
12360 0u, // uint32_t baseArrayLayer;
12361 VK_REMAINING_ARRAY_LAYERS // uint32_t layerCount;
12362 };
12363
12364 const VkImageCopy testCopy = {
12365 sourceLayer, // VkImageSubresourceLayers srcSubresource;
12366 {0, 0, 0}, // VkOffset3D srcOffset;
12367 destinationLayer, // VkImageSubresourceLayers dstSubresource;
12368 {0, 0, 0}, // VkOffset3D dstOffset;
12369 defaultHalfExtent // VkExtent3D extent;
12370 };
12371
12372 CopyRegion imageCopy;
12373 imageCopy.imageCopy = testCopy;
12374
12375 paramsArrayToArray.regions.push_back(imageCopy);
12376 }
12377
12378 group->addChild(
12379 new CopyImageToImageTestCase(testCtx, "array_to_array_whole_remaining_layers", paramsArrayToArray));
12380 }
12381
12382 {
12383 TestParams paramsArrayToArray;
12384 const uint32_t arrayLayers = 16u;
12385 paramsArrayToArray.src.image.imageType = VK_IMAGE_TYPE_2D;
12386 paramsArrayToArray.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
12387 paramsArrayToArray.src.image.extent = defaultHalfExtent;
12388 paramsArrayToArray.src.image.extent.depth = arrayLayers;
12389 paramsArrayToArray.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12390 paramsArrayToArray.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12391 paramsArrayToArray.dst.image.imageType = VK_IMAGE_TYPE_2D;
12392 paramsArrayToArray.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
12393 paramsArrayToArray.dst.image.extent = defaultHalfExtent;
12394 paramsArrayToArray.dst.image.extent.depth = arrayLayers;
12395 paramsArrayToArray.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12396 paramsArrayToArray.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12397 paramsArrayToArray.dst.image.fillMode = FILL_MODE_GRADIENT;
12398 paramsArrayToArray.allocationKind = testGroupParams->allocationKind;
12399 paramsArrayToArray.extensionFlags = testGroupParams->extensionFlags;
12400 paramsArrayToArray.queueSelection = testGroupParams->queueSelection;
12401 paramsArrayToArray.extensionFlags |= MAINTENANCE_5;
12402
12403 {
12404 const VkImageSubresourceLayers sourceLayer = {
12405 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12406 0u, // uint32_t mipLevel;
12407 3u, // uint32_t baseArrayLayer;
12408 VK_REMAINING_ARRAY_LAYERS // uint32_t layerCount;
12409 };
12410
12411 const VkImageSubresourceLayers destinationLayer = {
12412 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12413 0u, // uint32_t mipLevel;
12414 3u, // uint32_t baseArrayLayer;
12415 VK_REMAINING_ARRAY_LAYERS // uint32_t layerCount;
12416 };
12417
12418 const VkImageCopy testCopy = {
12419 sourceLayer, // VkImageSubresourceLayers srcSubresource;
12420 {0, 0, 0}, // VkOffset3D srcOffset;
12421 destinationLayer, // VkImageSubresourceLayers dstSubresource;
12422 {0, 0, 0}, // VkOffset3D dstOffset;
12423 defaultHalfExtent // VkExtent3D extent;
12424 };
12425
12426 CopyRegion imageCopy;
12427 imageCopy.imageCopy = testCopy;
12428
12429 paramsArrayToArray.regions.push_back(imageCopy);
12430 }
12431
12432 group->addChild(
12433 new CopyImageToImageTestCase(testCtx, "array_to_array_partial_remaining_layers", paramsArrayToArray));
12434 }
12435
12436 {
12437 TestParams paramsArrayToArray;
12438 const uint32_t arrayLayers = 16u;
12439 paramsArrayToArray.src.image.imageType = VK_IMAGE_TYPE_2D;
12440 paramsArrayToArray.src.image.extent = defaultHalfExtent;
12441 paramsArrayToArray.src.image.extent.depth = arrayLayers;
12442 paramsArrayToArray.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12443 paramsArrayToArray.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12444 paramsArrayToArray.dst.image.imageType = VK_IMAGE_TYPE_2D;
12445 paramsArrayToArray.dst.image.extent = defaultHalfExtent;
12446 paramsArrayToArray.dst.image.extent.depth = arrayLayers;
12447 paramsArrayToArray.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12448 paramsArrayToArray.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12449 paramsArrayToArray.dst.image.fillMode = FILL_MODE_GRADIENT;
12450 paramsArrayToArray.allocationKind = testGroupParams->allocationKind;
12451 paramsArrayToArray.extensionFlags = testGroupParams->extensionFlags;
12452 paramsArrayToArray.queueSelection = testGroupParams->queueSelection;
12453 paramsArrayToArray.useSparseBinding = testGroupParams->useSparseBinding;
12454 paramsArrayToArray.mipLevels = deLog2Floor32(deMaxu32(defaultHalfExtent.width, defaultHalfExtent.height)) + 1u;
12455
12456 for (uint32_t mipLevelNdx = 0u; mipLevelNdx < paramsArrayToArray.mipLevels; mipLevelNdx++)
12457 {
12458 const VkImageSubresourceLayers sourceLayer = {
12459 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12460 mipLevelNdx, // uint32_t mipLevel;
12461 0u, // uint32_t baseArrayLayer;
12462 arrayLayers // uint32_t layerCount;
12463 };
12464
12465 const VkImageSubresourceLayers destinationLayer = {
12466 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12467 mipLevelNdx, // uint32_t mipLevel;
12468 0u, // uint32_t baseArrayLayer;
12469 arrayLayers // uint32_t layerCount;
12470 };
12471
12472 const VkExtent3D extent = {
12473 (uint32_t)deMax(defaultHalfExtent.width >> mipLevelNdx, 1), // uint32_t width;
12474 (uint32_t)deMax(defaultHalfExtent.height >> mipLevelNdx, 1), // uint32_t height;
12475 1u, // uint32_t depth;
12476 };
12477
12478 const VkImageCopy testCopy = {
12479 sourceLayer, // VkImageSubresourceLayers srcSubresource;
12480 {0, 0, 0}, // VkOffset3D srcOffset;
12481 destinationLayer, // VkImageSubresourceLayers dstSubresource;
12482 {0, 0, 0}, // VkOffset3D dstOffset;
12483 extent // VkExtent3D extent;
12484 };
12485
12486 CopyRegion imageCopy;
12487 imageCopy.imageCopy = testCopy;
12488
12489 paramsArrayToArray.regions.push_back(imageCopy);
12490 }
12491
12492 VkFormat imageFormats[] = {VK_FORMAT_R8G8B8A8_UINT, VK_FORMAT_D32_SFLOAT, VK_FORMAT_D16_UNORM,
12493 VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_S8_UINT};
12494
12495 for (uint32_t imageFormatsNdx = 0; imageFormatsNdx < DE_LENGTH_OF_ARRAY(imageFormats); imageFormatsNdx++)
12496 {
12497 paramsArrayToArray.src.image.format = imageFormats[imageFormatsNdx];
12498 paramsArrayToArray.dst.image.format = imageFormats[imageFormatsNdx];
12499 for (uint32_t regionNdx = 0u; regionNdx < paramsArrayToArray.regions.size(); regionNdx++)
12500 {
12501 paramsArrayToArray.regions[regionNdx].imageCopy.srcSubresource.aspectMask =
12502 getImageAspectFlags(mapVkFormat(imageFormats[imageFormatsNdx]));
12503 paramsArrayToArray.regions[regionNdx].imageCopy.dstSubresource.aspectMask =
12504 getImageAspectFlags(mapVkFormat(imageFormats[imageFormatsNdx]));
12505 }
12506 std::ostringstream testName;
12507 const std::string formatName = getFormatName(imageFormats[imageFormatsNdx]);
12508 testName << "array_to_array_whole_mipmap_" << de::toLower(formatName.substr(10));
12509 group->addChild(new CopyImageToImageMipmapTestCase(testCtx, testName.str(), paramsArrayToArray));
12510 }
12511 }
12512 }
12513
addImageToImageTestsSimpleOnly(tcu::TestCaseGroup * group,TestGroupParamsPtr testGroupParams)12514 void addImageToImageTestsSimpleOnly(tcu::TestCaseGroup *group, TestGroupParamsPtr testGroupParams)
12515 {
12516 addTestGroup(group, "simple_tests", addImageToImageSimpleTests, testGroupParams);
12517 }
12518
addImageToImageTests(tcu::TestCaseGroup * group,TestGroupParamsPtr testGroupParams)12519 void addImageToImageTests(tcu::TestCaseGroup *group, TestGroupParamsPtr testGroupParams)
12520 {
12521 addTestGroup(group, "simple_tests", addImageToImageSimpleTests, testGroupParams);
12522 if (!testGroupParams->useSparseBinding)
12523 addTestGroup(group, "all_formats", addImageToImageAllFormatsTests, testGroupParams);
12524 addTestGroup(group, "3d_images", addImageToImage3dImagesTests, testGroupParams);
12525 if (!testGroupParams->useSparseBinding)
12526 addTestGroup(group, "dimensions", addImageToImageDimensionsTests, testGroupParams);
12527 addTestGroup(group, "cube", addImageToImageCubeTests, testGroupParams);
12528 addTestGroup(group, "array", addImageToImageArrayTests, testGroupParams);
12529 }
12530
add1dImageToBufferTests(tcu::TestCaseGroup * group,TestGroupParamsPtr testGroupParams)12531 void add1dImageToBufferTests(tcu::TestCaseGroup *group, TestGroupParamsPtr testGroupParams)
12532 {
12533 tcu::TestContext &testCtx = group->getTestContext();
12534
12535 {
12536 TestParams params;
12537 params.src.image.imageType = VK_IMAGE_TYPE_1D;
12538 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12539 params.src.image.extent = default1dExtent;
12540 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12541 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12542 params.dst.buffer.size = defaultSize;
12543 params.allocationKind = testGroupParams->allocationKind;
12544 params.extensionFlags = testGroupParams->extensionFlags;
12545 params.queueSelection = testGroupParams->queueSelection;
12546 params.useSparseBinding = testGroupParams->useSparseBinding;
12547
12548 const VkBufferImageCopy bufferImageCopy = {
12549 0u, // VkDeviceSize bufferOffset;
12550 0u, // uint32_t bufferRowLength;
12551 0u, // uint32_t bufferImageHeight;
12552 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
12553 {0, 0, 0}, // VkOffset3D imageOffset;
12554 default1dExtent // VkExtent3D imageExtent;
12555 };
12556 CopyRegion copyRegion;
12557 copyRegion.bufferImageCopy = bufferImageCopy;
12558
12559 params.regions.push_back(copyRegion);
12560
12561 group->addChild(new CopyImageToBufferTestCase(testCtx, "tightly_sized_buffer", params));
12562 }
12563
12564 {
12565 TestParams params;
12566 uint32_t bufferImageHeight = defaultSize + 1u;
12567 params.src.image.imageType = VK_IMAGE_TYPE_1D;
12568 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12569 params.src.image.extent = default1dExtent;
12570 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12571 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12572 params.dst.buffer.size = bufferImageHeight;
12573 params.allocationKind = testGroupParams->allocationKind;
12574 params.extensionFlags = testGroupParams->extensionFlags;
12575 params.queueSelection = testGroupParams->queueSelection;
12576 params.useSparseBinding = testGroupParams->useSparseBinding;
12577
12578 const VkBufferImageCopy bufferImageCopy = {
12579 0u, // VkDeviceSize bufferOffset;
12580 0u, // uint32_t bufferRowLength;
12581 bufferImageHeight, // uint32_t bufferImageHeight;
12582 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
12583 {0, 0, 0}, // VkOffset3D imageOffset;
12584 default1dExtent // VkExtent3D imageExtent;
12585 };
12586 CopyRegion copyRegion;
12587 copyRegion.bufferImageCopy = bufferImageCopy;
12588
12589 params.regions.push_back(copyRegion);
12590
12591 group->addChild(new CopyImageToBufferTestCase(testCtx, "larger_buffer", params));
12592 }
12593
12594 {
12595 TestParams params;
12596 uint32_t arrayLayers = 16u;
12597 params.src.image.imageType = VK_IMAGE_TYPE_1D;
12598 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12599 params.src.image.extent = default1dExtent;
12600 params.src.image.extent.depth = arrayLayers;
12601 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12602 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12603 params.dst.buffer.size = defaultSize * arrayLayers;
12604 params.allocationKind = testGroupParams->allocationKind;
12605 params.extensionFlags = testGroupParams->extensionFlags;
12606 params.queueSelection = testGroupParams->queueSelection;
12607 params.useSparseBinding = testGroupParams->useSparseBinding;
12608
12609 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.src.image.format));
12610 for (uint32_t arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
12611 {
12612 const VkDeviceSize offset = defaultSize * pixelSize * arrayLayerNdx;
12613 const VkBufferImageCopy bufferImageCopy = {
12614 offset, // VkDeviceSize bufferOffset;
12615 0u, // uint32_t bufferRowLength;
12616 defaultSize, // uint32_t bufferImageHeight;
12617 {
12618 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12619 0u, // uint32_t mipLevel;
12620 arrayLayerNdx, // uint32_t baseArrayLayer;
12621 1u, // uint32_t layerCount;
12622 }, // VkImageSubresourceLayers imageSubresource;
12623 {0, 0, 0}, // VkOffset3D imageOffset;
12624 default1dExtent // VkExtent3D imageExtent;
12625 };
12626 CopyRegion copyRegion;
12627 copyRegion.bufferImageCopy = bufferImageCopy;
12628
12629 params.regions.push_back(copyRegion);
12630 }
12631
12632 group->addChild(new CopyImageToBufferTestCase(testCtx, "array_tightly_sized_buffer", params));
12633 }
12634
12635 {
12636 TestParams params;
12637 uint32_t arrayLayers = 16u;
12638 uint32_t bufferImageHeight = defaultSize + 1u;
12639 params.src.image.imageType = VK_IMAGE_TYPE_1D;
12640 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12641 params.src.image.extent = default1dExtent;
12642 params.src.image.extent.depth = arrayLayers;
12643 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12644 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12645 params.dst.buffer.size = bufferImageHeight * arrayLayers;
12646 params.allocationKind = testGroupParams->allocationKind;
12647 params.extensionFlags = testGroupParams->extensionFlags;
12648 params.queueSelection = testGroupParams->queueSelection;
12649 params.useSparseBinding = testGroupParams->useSparseBinding;
12650
12651 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.src.image.format));
12652 for (uint32_t arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
12653 {
12654 const VkDeviceSize offset = bufferImageHeight * pixelSize * arrayLayerNdx;
12655 const VkBufferImageCopy bufferImageCopy = {
12656 offset, // VkDeviceSize bufferOffset;
12657 0u, // uint32_t bufferRowLength;
12658 bufferImageHeight, // uint32_t bufferImageHeight;
12659 {
12660 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12661 0u, // uint32_t mipLevel;
12662 arrayLayerNdx, // uint32_t baseArrayLayer;
12663 1u, // uint32_t layerCount;
12664 }, // VkImageSubresourceLayers imageSubresource;
12665 {0, 0, 0}, // VkOffset3D imageOffset;
12666 default1dExtent // VkExtent3D imageExtent;
12667 };
12668 CopyRegion copyRegion;
12669 copyRegion.bufferImageCopy = bufferImageCopy;
12670
12671 params.regions.push_back(copyRegion);
12672 }
12673
12674 group->addChild(new CopyImageToBufferTestCase(testCtx, "array_larger_buffer", params));
12675 }
12676
12677 {
12678 TestParams params;
12679 const uint32_t baseLayer = 0u;
12680 const uint32_t layerCount = 16u;
12681 params.src.image.imageType = VK_IMAGE_TYPE_1D;
12682 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12683 params.src.image.extent = default1dExtent;
12684 params.src.image.extent.depth = layerCount;
12685 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12686 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12687 params.src.image.fillMode = FILL_MODE_RED;
12688 params.dst.buffer.size = defaultSize * layerCount;
12689 params.dst.buffer.fillMode = FILL_MODE_RED;
12690 params.allocationKind = testGroupParams->allocationKind;
12691 params.extensionFlags = testGroupParams->extensionFlags;
12692 params.queueSelection = testGroupParams->queueSelection;
12693 params.useSparseBinding = testGroupParams->useSparseBinding;
12694 params.extensionFlags |= MAINTENANCE_5;
12695
12696 const VkImageSubresourceLayers defaultLayer = {
12697 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12698 0u, // uint32_t mipLevel;
12699 baseLayer, // uint32_t baseArrayLayer;
12700 VK_REMAINING_ARRAY_LAYERS // uint32_t layerCount;
12701 };
12702
12703 const VkBufferImageCopy bufferImageCopy = {
12704 0u, // VkDeviceSize bufferOffset;
12705 0u, // uint32_t bufferRowLength;
12706 0u, // uint32_t bufferImageHeight;
12707 defaultLayer, // VkImageSubresourceLayers imageSubresource;
12708 {0, 0, 0}, // VkOffset3D imageOffset;
12709 default1dExtent // VkExtent3D imageExtent;
12710 };
12711
12712 CopyRegion copyRegion;
12713 copyRegion.bufferImageCopy = bufferImageCopy;
12714
12715 params.regions.push_back(copyRegion);
12716
12717 group->addChild(new CopyImageToBufferTestCase(testCtx, "array_all_remaining_layers", params));
12718 }
12719
12720 {
12721 TestParams params;
12722 const uint32_t baseLayer = 2u;
12723 const uint32_t layerCount = 16u;
12724 params.src.image.imageType = VK_IMAGE_TYPE_1D;
12725 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12726 params.src.image.extent = default1dExtent;
12727 params.src.image.extent.depth = layerCount;
12728 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12729 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12730 params.src.image.fillMode = FILL_MODE_RED;
12731 params.dst.buffer.size = defaultSize * layerCount;
12732 params.dst.buffer.fillMode = FILL_MODE_RED;
12733 params.allocationKind = testGroupParams->allocationKind;
12734 params.extensionFlags = testGroupParams->extensionFlags;
12735 params.queueSelection = testGroupParams->queueSelection;
12736 params.useSparseBinding = testGroupParams->useSparseBinding;
12737 params.extensionFlags |= MAINTENANCE_5;
12738
12739 const VkImageSubresourceLayers defaultLayer = {
12740 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12741 0u, // uint32_t mipLevel;
12742 baseLayer, // uint32_t baseArrayLayer;
12743 VK_REMAINING_ARRAY_LAYERS // uint32_t layerCount;
12744 };
12745
12746 const VkBufferImageCopy bufferImageCopy = {
12747 0u, // VkDeviceSize bufferOffset;
12748 0u, // uint32_t bufferRowLength;
12749 0u, // uint32_t bufferImageHeight;
12750 defaultLayer, // VkImageSubresourceLayers imageSubresource;
12751 {0, 0, 0}, // VkOffset3D imageOffset;
12752 default1dExtent // VkExtent3D imageExtent;
12753 };
12754
12755 CopyRegion copyRegion;
12756 copyRegion.bufferImageCopy = bufferImageCopy;
12757
12758 params.regions.push_back(copyRegion);
12759
12760 group->addChild(new CopyImageToBufferTestCase(testCtx, "array_not_all_remaining_layers", params));
12761 }
12762 }
12763
add2dImageToBufferTests(tcu::TestCaseGroup * group,TestGroupParamsPtr testGroupParams)12764 void add2dImageToBufferTests(tcu::TestCaseGroup *group, TestGroupParamsPtr testGroupParams)
12765 {
12766 tcu::TestContext &testCtx = group->getTestContext();
12767
12768 {
12769 TestParams params;
12770 params.src.image.imageType = VK_IMAGE_TYPE_2D;
12771 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12772 params.src.image.extent = defaultExtent;
12773 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12774 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12775 params.dst.buffer.size = defaultSize * defaultSize;
12776 params.allocationKind = testGroupParams->allocationKind;
12777 params.extensionFlags = testGroupParams->extensionFlags;
12778 params.queueSelection = testGroupParams->queueSelection;
12779 params.useSparseBinding = testGroupParams->useSparseBinding;
12780
12781 const VkBufferImageCopy bufferImageCopy = {
12782 0u, // VkDeviceSize bufferOffset;
12783 0u, // uint32_t bufferRowLength;
12784 0u, // uint32_t bufferImageHeight;
12785 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
12786 {0, 0, 0}, // VkOffset3D imageOffset;
12787 defaultExtent // VkExtent3D imageExtent;
12788 };
12789 CopyRegion copyRegion;
12790 copyRegion.bufferImageCopy = bufferImageCopy;
12791
12792 params.regions.push_back(copyRegion);
12793
12794 group->addChild(new CopyImageToBufferTestCase(testCtx, "whole", params));
12795 }
12796
12797 {
12798 TestParams params;
12799 params.src.image.imageType = VK_IMAGE_TYPE_2D;
12800 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12801 params.src.image.extent = defaultExtent;
12802 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12803 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12804 params.dst.buffer.size = defaultSize * defaultSize;
12805 params.allocationKind = testGroupParams->allocationKind;
12806 params.extensionFlags = testGroupParams->extensionFlags;
12807 params.queueSelection = testGroupParams->queueSelection;
12808 params.useSparseBinding = testGroupParams->useSparseBinding;
12809
12810 const VkBufferImageCopy bufferImageCopy = {
12811 defaultSize * defaultHalfSize, // VkDeviceSize bufferOffset;
12812 0u, // uint32_t bufferRowLength;
12813 0u, // uint32_t bufferImageHeight;
12814 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
12815 {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
12816 defaultHalfExtent // VkExtent3D imageExtent;
12817 };
12818 CopyRegion copyRegion;
12819 copyRegion.bufferImageCopy = bufferImageCopy;
12820
12821 params.regions.push_back(copyRegion);
12822
12823 group->addChild(new CopyImageToBufferTestCase(testCtx, "buffer_offset", params));
12824 }
12825
12826 if (testGroupParams->queueSelection == QueueSelectionOptions::Universal)
12827 {
12828 TestParams params;
12829 params.src.image.imageType = VK_IMAGE_TYPE_2D;
12830 params.src.image.format = VK_FORMAT_R8_UNORM;
12831 params.src.image.extent = defaultExtent;
12832 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12833 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12834 params.dst.buffer.size = defaultSize * defaultSize;
12835 params.allocationKind = testGroupParams->allocationKind;
12836 params.extensionFlags = testGroupParams->extensionFlags;
12837 params.queueSelection = testGroupParams->queueSelection;
12838 params.useSparseBinding = testGroupParams->useSparseBinding;
12839
12840 const VkBufferImageCopy bufferImageCopy = {
12841 defaultSize * defaultHalfSize + 1u, // VkDeviceSize bufferOffset;
12842 0u, // uint32_t bufferRowLength;
12843 0u, // uint32_t bufferImageHeight;
12844 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
12845 {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
12846 defaultHalfExtent // VkExtent3D imageExtent;
12847 };
12848 CopyRegion copyRegion;
12849 copyRegion.bufferImageCopy = bufferImageCopy;
12850
12851 params.regions.push_back(copyRegion);
12852
12853 group->addChild(new CopyImageToBufferTestCase(testCtx, "buffer_offset_relaxed", params));
12854 }
12855
12856 {
12857 TestParams params;
12858 params.src.image.imageType = VK_IMAGE_TYPE_2D;
12859 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12860 params.src.image.extent = defaultExtent;
12861 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12862 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12863 params.dst.buffer.size = defaultSize * defaultSize;
12864 params.allocationKind = testGroupParams->allocationKind;
12865 params.extensionFlags = testGroupParams->extensionFlags;
12866 params.queueSelection = testGroupParams->queueSelection;
12867 params.useSparseBinding = testGroupParams->useSparseBinding;
12868
12869 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.src.image.format));
12870 const VkDeviceSize bufferSize = pixelSize * params.dst.buffer.size;
12871 const VkDeviceSize offsetSize = pixelSize * defaultQuarterSize * defaultQuarterSize;
12872 uint32_t divisor = 1;
12873 for (VkDeviceSize offset = 0; offset < bufferSize - offsetSize; offset += offsetSize, ++divisor)
12874 {
12875 const uint32_t bufferRowLength = defaultQuarterSize;
12876 const uint32_t bufferImageHeight = defaultQuarterSize;
12877 const VkExtent3D imageExtent = {defaultQuarterSize / divisor, defaultQuarterSize, 1};
12878 DE_ASSERT(!bufferRowLength || bufferRowLength >= imageExtent.width);
12879 DE_ASSERT(!bufferImageHeight || bufferImageHeight >= imageExtent.height);
12880 DE_ASSERT(imageExtent.width * imageExtent.height * imageExtent.depth <= offsetSize);
12881
12882 CopyRegion region;
12883 const VkBufferImageCopy bufferImageCopy = {
12884 offset, // VkDeviceSize bufferOffset;
12885 bufferRowLength, // uint32_t bufferRowLength;
12886 bufferImageHeight, // uint32_t bufferImageHeight;
12887 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
12888 {0, 0, 0}, // VkOffset3D imageOffset;
12889 imageExtent // VkExtent3D imageExtent;
12890 };
12891 region.bufferImageCopy = bufferImageCopy;
12892 params.regions.push_back(region);
12893 }
12894
12895 group->addChild(new CopyImageToBufferTestCase(testCtx, "regions", params));
12896 }
12897
12898 {
12899 TestParams params;
12900 params.src.image.imageType = VK_IMAGE_TYPE_2D;
12901 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12902 params.src.image.extent = defaultExtent;
12903 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12904 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12905 params.dst.buffer.size = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize;
12906 params.allocationKind = testGroupParams->allocationKind;
12907 params.extensionFlags = testGroupParams->extensionFlags;
12908 params.queueSelection = testGroupParams->queueSelection;
12909 params.useSparseBinding = testGroupParams->useSparseBinding;
12910
12911 const VkBufferImageCopy bufferImageCopy = {
12912 0u, // VkDeviceSize bufferOffset;
12913 defaultSize, // uint32_t bufferRowLength;
12914 defaultSize, // uint32_t bufferImageHeight;
12915 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
12916 {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
12917 defaultHalfExtent // VkExtent3D imageExtent;
12918 };
12919 CopyRegion copyRegion;
12920 copyRegion.bufferImageCopy = bufferImageCopy;
12921
12922 params.regions.push_back(copyRegion);
12923
12924 group->addChild(new CopyImageToBufferTestCase(testCtx, "tightly_sized_buffer", params));
12925 }
12926
12927 {
12928 TestParams params;
12929 uint32_t bufferImageHeight = defaultSize + 1u;
12930 params.src.image.imageType = VK_IMAGE_TYPE_2D;
12931 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12932 params.src.image.extent = defaultExtent;
12933 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12934 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12935 params.dst.buffer.size = bufferImageHeight * defaultSize;
12936 params.allocationKind = testGroupParams->allocationKind;
12937 params.extensionFlags = testGroupParams->extensionFlags;
12938 params.queueSelection = testGroupParams->queueSelection;
12939 params.useSparseBinding = testGroupParams->useSparseBinding;
12940
12941 const VkBufferImageCopy bufferImageCopy = {
12942 0u, // VkDeviceSize bufferOffset;
12943 defaultSize, // uint32_t bufferRowLength;
12944 bufferImageHeight, // uint32_t bufferImageHeight;
12945 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
12946 {0, 0, 0}, // VkOffset3D imageOffset;
12947 defaultExtent // VkExtent3D imageExtent;
12948 };
12949 CopyRegion copyRegion;
12950 copyRegion.bufferImageCopy = bufferImageCopy;
12951
12952 params.regions.push_back(copyRegion);
12953
12954 group->addChild(new CopyImageToBufferTestCase(testCtx, "larger_buffer", params));
12955 }
12956
12957 {
12958 TestParams params;
12959 params.src.image.imageType = VK_IMAGE_TYPE_2D;
12960 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12961 params.src.image.extent = defaultExtent;
12962 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12963 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12964 params.dst.buffer.size = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultQuarterSize;
12965 params.allocationKind = testGroupParams->allocationKind;
12966 params.extensionFlags = testGroupParams->extensionFlags;
12967 params.queueSelection = testGroupParams->queueSelection;
12968 params.useSparseBinding = testGroupParams->useSparseBinding;
12969
12970 const VkBufferImageCopy bufferImageCopy = {
12971 defaultQuarterSize, // VkDeviceSize bufferOffset;
12972 defaultSize, // uint32_t bufferRowLength;
12973 defaultSize, // uint32_t bufferImageHeight;
12974 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
12975 {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
12976 defaultHalfExtent // VkExtent3D imageExtent;
12977 };
12978 CopyRegion copyRegion;
12979 copyRegion.bufferImageCopy = bufferImageCopy;
12980
12981 params.regions.push_back(copyRegion);
12982
12983 group->addChild(new CopyImageToBufferTestCase(testCtx, "tightly_sized_buffer_offset", params));
12984 }
12985
12986 {
12987 TestParams params;
12988 uint32_t arrayLayers = 16u;
12989 params.src.image.imageType = VK_IMAGE_TYPE_2D;
12990 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12991 params.src.image.extent = defaultHalfExtent;
12992 params.src.image.extent.depth = arrayLayers;
12993 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12994 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12995 params.dst.buffer.size = defaultHalfSize * defaultHalfSize * arrayLayers;
12996 params.allocationKind = testGroupParams->allocationKind;
12997 params.extensionFlags = testGroupParams->extensionFlags;
12998 params.queueSelection = testGroupParams->queueSelection;
12999 params.useSparseBinding = testGroupParams->useSparseBinding;
13000
13001 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.src.image.format));
13002 for (uint32_t arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
13003 {
13004 const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
13005 const VkBufferImageCopy bufferImageCopy = {
13006 offset, // VkDeviceSize bufferOffset;
13007 0u, // uint32_t bufferRowLength;
13008 0u, // uint32_t bufferImageHeight;
13009 {
13010 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
13011 0u, // uint32_t mipLevel;
13012 arrayLayerNdx, // uint32_t baseArrayLayer;
13013 1u, // uint32_t layerCount;
13014 }, // VkImageSubresourceLayers imageSubresource;
13015 {0, 0, 0}, // VkOffset3D imageOffset;
13016 defaultHalfExtent // VkExtent3D imageExtent;
13017 };
13018 CopyRegion copyRegion;
13019 copyRegion.bufferImageCopy = bufferImageCopy;
13020
13021 params.regions.push_back(copyRegion);
13022 }
13023 group->addChild(new CopyImageToBufferTestCase(testCtx, "array", params));
13024 }
13025
13026 {
13027 TestParams params;
13028 uint32_t arrayLayers = 16u;
13029 uint32_t imageBufferHeight = defaultHalfSize + 1u;
13030 params.src.image.imageType = VK_IMAGE_TYPE_2D;
13031 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
13032 params.src.image.extent = defaultHalfExtent;
13033 params.src.image.extent.depth = arrayLayers;
13034 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13035 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13036 params.dst.buffer.size = defaultHalfSize * imageBufferHeight * arrayLayers;
13037 params.allocationKind = testGroupParams->allocationKind;
13038 params.extensionFlags = testGroupParams->extensionFlags;
13039 params.queueSelection = testGroupParams->queueSelection;
13040 params.useSparseBinding = testGroupParams->useSparseBinding;
13041
13042 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.src.image.format));
13043 for (uint32_t arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
13044 {
13045 const VkDeviceSize offset = defaultHalfSize * imageBufferHeight * pixelSize * arrayLayerNdx;
13046 const VkBufferImageCopy bufferImageCopy = {
13047 offset, // VkDeviceSize bufferOffset;
13048 0u, // uint32_t bufferRowLength;
13049 imageBufferHeight, // uint32_t bufferImageHeight;
13050 {
13051 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
13052 0u, // uint32_t mipLevel;
13053 arrayLayerNdx, // uint32_t baseArrayLayer;
13054 1u, // uint32_t layerCount;
13055 }, // VkImageSubresourceLayers imageSubresource;
13056 {0, 0, 0}, // VkOffset3D imageOffset;
13057 defaultHalfExtent // VkExtent3D imageExtent;
13058 };
13059 CopyRegion copyRegion;
13060 copyRegion.bufferImageCopy = bufferImageCopy;
13061
13062 params.regions.push_back(copyRegion);
13063 }
13064 group->addChild(new CopyImageToBufferTestCase(testCtx, "array_larger_buffer", params));
13065 }
13066
13067 {
13068 TestParams params;
13069 uint32_t arrayLayers = 16u;
13070 params.src.image.imageType = VK_IMAGE_TYPE_2D;
13071 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
13072 params.src.image.extent = defaultHalfExtent;
13073 params.src.image.extent.depth = arrayLayers;
13074 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13075 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13076 params.dst.buffer.size = defaultHalfSize * defaultHalfSize * arrayLayers;
13077 params.allocationKind = testGroupParams->allocationKind;
13078 params.extensionFlags = testGroupParams->extensionFlags;
13079 params.queueSelection = testGroupParams->queueSelection;
13080 params.useSparseBinding = testGroupParams->useSparseBinding;
13081
13082 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.src.image.format));
13083 for (uint32_t arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
13084 {
13085 const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
13086 const VkBufferImageCopy bufferImageCopy = {
13087 offset, // VkDeviceSize bufferOffset;
13088 defaultHalfSize, // uint32_t bufferRowLength;
13089 defaultHalfSize, // uint32_t bufferImageHeight;
13090 {
13091 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
13092 0u, // uint32_t mipLevel;
13093 arrayLayerNdx, // uint32_t baseArrayLayer;
13094 1u, // uint32_t layerCount;
13095 }, // VkImageSubresourceLayers imageSubresource;
13096 {0, 0, 0}, // VkOffset3D imageOffset;
13097 defaultHalfExtent // VkExtent3D imageExtent;
13098 };
13099 CopyRegion copyRegion;
13100 copyRegion.bufferImageCopy = bufferImageCopy;
13101
13102 params.regions.push_back(copyRegion);
13103 }
13104 group->addChild(new CopyImageToBufferTestCase(testCtx, "array_tightly_sized_buffer", params));
13105 }
13106
13107 {
13108 TestParams params;
13109 const uint32_t baseLayer = 0u;
13110 const uint32_t layerCount = 16u;
13111 params.src.image.imageType = VK_IMAGE_TYPE_2D;
13112 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
13113 params.src.image.extent = defaultHalfExtent;
13114 params.src.image.extent.depth = layerCount;
13115 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13116 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13117 params.src.image.fillMode = FILL_MODE_RED;
13118 params.dst.buffer.size = defaultHalfSize * defaultHalfSize * layerCount;
13119 params.dst.buffer.fillMode = FILL_MODE_RED;
13120 params.allocationKind = testGroupParams->allocationKind;
13121 params.extensionFlags = testGroupParams->extensionFlags;
13122 params.queueSelection = testGroupParams->queueSelection;
13123 params.useSparseBinding = testGroupParams->useSparseBinding;
13124 params.extensionFlags |= MAINTENANCE_5;
13125
13126 const VkImageSubresourceLayers defaultLayer = {
13127 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
13128 0u, // uint32_t mipLevel;
13129 baseLayer, // uint32_t baseArrayLayer;
13130 VK_REMAINING_ARRAY_LAYERS // uint32_t layerCount;
13131 };
13132
13133 const VkBufferImageCopy bufferImageCopy = {
13134 0, // VkDeviceSize bufferOffset;
13135 0, // uint32_t bufferRowLength;
13136 0, // uint32_t bufferImageHeight;
13137 defaultLayer, // VkImageSubresourceLayers imageSubresource;
13138 {0, 0, 0}, // VkOffset3D imageOffset;
13139 defaultHalfExtent // VkExtent3D imageExtent;
13140 };
13141
13142 CopyRegion copyRegion;
13143 copyRegion.bufferImageCopy = bufferImageCopy;
13144
13145 params.regions.push_back(copyRegion);
13146
13147 group->addChild(new CopyImageToBufferTestCase(testCtx, "array_all_remaining_layers", params));
13148 }
13149
13150 {
13151 TestParams params;
13152 const uint32_t baseLayer = 2u;
13153 const uint32_t layerCount = 16u;
13154 params.src.image.imageType = VK_IMAGE_TYPE_2D;
13155 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
13156 params.src.image.extent = defaultHalfExtent;
13157 params.src.image.extent.depth = layerCount;
13158 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13159 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13160 params.src.image.fillMode = FILL_MODE_RED;
13161 params.dst.buffer.size = defaultHalfSize * defaultHalfSize * layerCount;
13162 params.dst.buffer.fillMode = FILL_MODE_RED;
13163 params.allocationKind = testGroupParams->allocationKind;
13164 params.extensionFlags = testGroupParams->extensionFlags;
13165 params.queueSelection = testGroupParams->queueSelection;
13166 params.useSparseBinding = testGroupParams->useSparseBinding;
13167 params.extensionFlags |= MAINTENANCE_5;
13168
13169 const VkImageSubresourceLayers defaultLayer = {
13170 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
13171 0u, // uint32_t mipLevel;
13172 baseLayer, // uint32_t baseArrayLayer;
13173 VK_REMAINING_ARRAY_LAYERS // uint32_t layerCount;
13174 };
13175
13176 const VkBufferImageCopy bufferImageCopy = {
13177 0, // VkDeviceSize bufferOffset;
13178 0, // uint32_t bufferRowLength;
13179 0, // uint32_t bufferImageHeight;
13180 defaultLayer, // VkImageSubresourceLayers imageSubresource;
13181 {0, 0, 0}, // VkOffset3D imageOffset;
13182 defaultHalfExtent // VkExtent3D imageExtent;
13183 };
13184
13185 CopyRegion copyRegion;
13186 copyRegion.bufferImageCopy = bufferImageCopy;
13187
13188 params.regions.push_back(copyRegion);
13189
13190 group->addChild(new CopyImageToBufferTestCase(testCtx, "array_not_all_remaining_layers", params));
13191 }
13192
13193 // those tests are performed for all queues, no need to repeat them
13194 // when testGroupParams->queueSelection is set to TransferOnly
13195 if (testGroupParams->queueSelection == QueueSelectionOptions::Universal)
13196 {
13197 VkExtent3D extents[] = {
13198 // Most miplevels will be multiples of four. All power-of-2 edge sizes. Never a weird mip level with extents smaller than the blockwidth.
13199 {64, 64, 1},
13200 // Odd mip edge multiples, two lowest miplevels on the y-axis will have widths of 3 and 1 respectively, less than the compression blocksize, and potentially tricky.
13201 {64, 192, 1},
13202 };
13203
13204 uint32_t arrayLayers[] = {1, 2, 5};
13205
13206 auto getCaseName = [](VkFormat format, VkExtent3D extent, uint32_t numLayers, std::string queueName)
13207 {
13208 std::string caseName = "mip_copies_" + getFormatCaseName(format) + "_" + std::to_string(extent.width) +
13209 "x" + std::to_string(extent.height);
13210 if (numLayers > 1)
13211 caseName.append("_" + std::to_string(numLayers) + "_layers");
13212 caseName.append("_" + queueName);
13213 return caseName;
13214 };
13215
13216 for (const auto &extent : extents)
13217 for (const auto numLayers : arrayLayers)
13218 {
13219 TestParams params;
13220 params.src.image.imageType = VK_IMAGE_TYPE_2D;
13221 params.src.image.extent = extent;
13222 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13223 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
13224 params.allocationKind = testGroupParams->allocationKind;
13225 params.extensionFlags = testGroupParams->extensionFlags;
13226 params.queueSelection = testGroupParams->queueSelection;
13227 params.useSparseBinding = testGroupParams->useSparseBinding;
13228 params.arrayLayers = numLayers;
13229
13230 for (const VkFormat *format = compressedFormatsFloats; *format != VK_FORMAT_UNDEFINED; format++)
13231 {
13232 params.src.image.format = *format;
13233 {
13234 params.queueSelection = QueueSelectionOptions::Universal;
13235 group->addChild(new CopyCompressedImageToBufferTestCase(
13236 testCtx, getCaseName(*format, params.src.image.extent, numLayers, "universal"), params));
13237 params.queueSelection = QueueSelectionOptions::ComputeOnly;
13238 group->addChild(new CopyCompressedImageToBufferTestCase(
13239 testCtx, getCaseName(*format, params.src.image.extent, numLayers, "compute"), params));
13240 params.queueSelection = QueueSelectionOptions::TransferOnly;
13241 group->addChild(new CopyCompressedImageToBufferTestCase(
13242 testCtx, getCaseName(*format, params.src.image.extent, numLayers, "transfer"), params));
13243 }
13244 }
13245 }
13246 }
13247 }
13248
addBufferToDepthStencilTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)13249 void addBufferToDepthStencilTests(tcu::TestCaseGroup *group, AllocationKind allocationKind, uint32_t extensionFlags)
13250 {
13251 tcu::TestContext &testCtx = group->getTestContext();
13252
13253 const struct
13254 {
13255 const char *name;
13256 const VkFormat format;
13257 } depthAndStencilFormats[] = {{"d16_unorm", VK_FORMAT_D16_UNORM},
13258 {"x8_d24_unorm_pack32", VK_FORMAT_X8_D24_UNORM_PACK32},
13259 {"d32_sfloat", VK_FORMAT_D32_SFLOAT},
13260 {"d16_unorm_s8_uint", VK_FORMAT_D16_UNORM_S8_UINT},
13261 {"d24_unorm_s8_uint", VK_FORMAT_D24_UNORM_S8_UINT},
13262 {"d32_sfloat_s8_uint", VK_FORMAT_D32_SFLOAT_S8_UINT}};
13263
13264 const VkImageSubresourceLayers depthSourceLayer = {
13265 VK_IMAGE_ASPECT_DEPTH_BIT, // VkImageAspectFlags aspectMask;
13266 0u, // uint32_t mipLevel;
13267 0u, // uint32_t baseArrayLayer;
13268 1u, // uint32_t layerCount;
13269 };
13270
13271 const VkBufferImageCopy bufferDepthCopy = {
13272 0u, // VkDeviceSize bufferOffset;
13273 0u, // uint32_t bufferRowLength;
13274 0u, // uint32_t bufferImageHeight;
13275 depthSourceLayer, // VkImageSubresourceLayers imageSubresource;
13276 {0, 0, 0}, // VkOffset3D imageOffset;
13277 defaultExtent // VkExtent3D imageExtent;
13278 };
13279
13280 const VkBufferImageCopy bufferDepthCopyOffset = {
13281 32, // VkDeviceSize bufferOffset;
13282 defaultHalfSize + defaultQuarterSize, // uint32_t bufferRowLength;
13283 defaultHalfSize + defaultQuarterSize, // uint32_t bufferImageHeight;
13284 depthSourceLayer, // VkImageSubresourceLayers imageSubresource;
13285 {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
13286 defaultHalfExtent // VkExtent3D imageExtent;
13287 };
13288
13289 const VkImageSubresourceLayers stencilSourceLayer = {
13290 VK_IMAGE_ASPECT_STENCIL_BIT, // VkImageAspectFlags aspectMask;
13291 0u, // uint32_t mipLevel;
13292 0u, // uint32_t baseArrayLayer;
13293 1u, // uint32_t layerCount;
13294 };
13295
13296 const VkBufferImageCopy bufferStencilCopy = {
13297 0u, // VkDeviceSize bufferOffset;
13298 0u, // uint32_t bufferRowLength;
13299 0u, // uint32_t bufferImageHeight;
13300 stencilSourceLayer, // VkImageSubresourceLayers imageSubresource;
13301 {0, 0, 0}, // VkOffset3D imageOffset;
13302 defaultExtent // VkExtent3D imageExtent;
13303 };
13304
13305 const VkBufferImageCopy bufferStencilCopyOffset = {
13306 32, // VkDeviceSize bufferOffset;
13307 defaultHalfSize + defaultQuarterSize, // uint32_t bufferRowLength;
13308 defaultHalfSize + defaultQuarterSize, // uint32_t bufferImageHeight;
13309 stencilSourceLayer, // VkImageSubresourceLayers imageSubresource;
13310 {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
13311 defaultHalfExtent // VkExtent3D imageExtent;
13312 };
13313
13314 const bool useOffset[] = {false, true};
13315
13316 // Note: Depth stencil tests I want to do
13317 // Formats: D16, D24S8, D32FS8
13318 // Test writing each component with separate CopyBufferToImage commands
13319 // Test writing both components in one CopyBufferToImage command
13320 // Swap order of writes of Depth & Stencil
13321 // whole surface, subimages?
13322 // Similar tests as BufferToImage?
13323 for (const auto config : depthAndStencilFormats)
13324 for (const auto offset : useOffset)
13325 {
13326 // TODO: Check that this format is supported before creating tests?
13327 //if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D24_UNORM_S8_UINT))
13328
13329 CopyRegion copyDepthRegion;
13330 CopyRegion copyStencilRegion;
13331 TestParams params;
13332 const tcu::TextureFormat format = mapVkFormat(config.format);
13333 const bool hasDepth = tcu::hasDepthComponent(format.order);
13334 const bool hasStencil = tcu::hasStencilComponent(format.order);
13335 std::string testName = config.name;
13336
13337 if (offset)
13338 {
13339 copyDepthRegion.bufferImageCopy = bufferDepthCopyOffset;
13340 copyStencilRegion.bufferImageCopy = bufferStencilCopyOffset;
13341 testName = "buffer_offset_" + testName;
13342 params.src.buffer.size = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultQuarterSize;
13343 }
13344 else
13345 {
13346 copyDepthRegion.bufferImageCopy = bufferDepthCopy;
13347 copyStencilRegion.bufferImageCopy = bufferStencilCopy;
13348 params.src.buffer.size = defaultSize * defaultSize;
13349 }
13350
13351 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
13352 params.dst.image.format = config.format;
13353 params.dst.image.extent = defaultExtent;
13354 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13355 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13356 params.allocationKind = allocationKind;
13357 params.extensionFlags = extensionFlags;
13358
13359 if (hasDepth && hasStencil)
13360 {
13361 params.singleCommand = true;
13362
13363 params.regions.push_back(copyDepthRegion);
13364 params.regions.push_back(copyStencilRegion);
13365
13366 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, testName + "_DS", params));
13367
13368 params.singleCommand = false;
13369
13370 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, testName + "_D_S", params));
13371
13372 params.regions.clear();
13373 params.regions.push_back(copyStencilRegion);
13374 params.regions.push_back(copyDepthRegion);
13375
13376 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, testName + "_S_D", params));
13377
13378 params.singleCommand = true;
13379 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, testName + "_SD", params));
13380 }
13381
13382 if (hasStencil)
13383 {
13384 params.regions.clear();
13385 params.regions.push_back(copyStencilRegion);
13386
13387 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, testName + "_S", params));
13388 }
13389
13390 if (hasDepth)
13391 {
13392 params.regions.clear();
13393 params.regions.push_back(copyDepthRegion);
13394
13395 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, testName + "_D", params));
13396 }
13397 }
13398 }
13399
add1dBufferToImageTests(tcu::TestCaseGroup * group,TestGroupParamsPtr testGroupParams)13400 void add1dBufferToImageTests(tcu::TestCaseGroup *group, TestGroupParamsPtr testGroupParams)
13401 {
13402 tcu::TestContext &testCtx = group->getTestContext();
13403
13404 {
13405 TestParams params;
13406 params.src.buffer.size = defaultSize;
13407 params.dst.image.imageType = VK_IMAGE_TYPE_1D;
13408 params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
13409 params.dst.image.extent = default1dExtent;
13410 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13411 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13412 params.allocationKind = testGroupParams->allocationKind;
13413 params.extensionFlags = testGroupParams->extensionFlags;
13414 params.queueSelection = testGroupParams->queueSelection;
13415 params.useSparseBinding = testGroupParams->useSparseBinding;
13416
13417 const VkBufferImageCopy bufferImageCopy = {
13418 0u, // VkDeviceSize bufferOffset;
13419 0u, // uint32_t bufferRowLength;
13420 0u, // uint32_t bufferImageHeight;
13421 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
13422 {0, 0, 0}, // VkOffset3D imageOffset;
13423 default1dExtent // VkExtent3D imageExtent;
13424 };
13425 CopyRegion copyRegion;
13426 copyRegion.bufferImageCopy = bufferImageCopy;
13427
13428 params.regions.push_back(copyRegion);
13429
13430 group->addChild(new CopyBufferToImageTestCase(testCtx, "tightly_sized_buffer", params));
13431 }
13432
13433 {
13434 TestParams params;
13435 uint32_t bufferImageHeight = defaultSize + 1u;
13436 params.src.buffer.size = bufferImageHeight;
13437 params.dst.image.imageType = VK_IMAGE_TYPE_1D;
13438 params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
13439 params.dst.image.extent = default1dExtent;
13440 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13441 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13442 params.allocationKind = testGroupParams->allocationKind;
13443 params.extensionFlags = testGroupParams->extensionFlags;
13444 params.queueSelection = testGroupParams->queueSelection;
13445 params.useSparseBinding = testGroupParams->useSparseBinding;
13446
13447 const VkBufferImageCopy bufferImageCopy = {
13448 0u, // VkDeviceSize bufferOffset;
13449 0u, // uint32_t bufferRowLength;
13450 bufferImageHeight, // uint32_t bufferImageHeight;
13451 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
13452 {0, 0, 0}, // VkOffset3D imageOffset;
13453 default1dExtent // VkExtent3D imageExtent;
13454 };
13455 CopyRegion copyRegion;
13456 copyRegion.bufferImageCopy = bufferImageCopy;
13457
13458 params.regions.push_back(copyRegion);
13459
13460 group->addChild(new CopyBufferToImageTestCase(testCtx, "larger_buffer", params));
13461 }
13462
13463 {
13464 TestParams params;
13465 uint32_t arrayLayers = 16u;
13466 params.src.buffer.size = defaultSize * arrayLayers;
13467 params.dst.image.imageType = VK_IMAGE_TYPE_1D;
13468 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
13469 params.dst.image.extent = default1dExtent;
13470 params.dst.image.extent.depth = arrayLayers;
13471 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13472 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13473 params.allocationKind = testGroupParams->allocationKind;
13474 params.extensionFlags = testGroupParams->extensionFlags;
13475 params.queueSelection = testGroupParams->queueSelection;
13476 params.useSparseBinding = testGroupParams->useSparseBinding;
13477
13478 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.dst.image.format));
13479 for (uint32_t arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
13480 {
13481 const VkDeviceSize offset = defaultSize * pixelSize * arrayLayerNdx;
13482 const VkBufferImageCopy bufferImageCopy = {
13483 offset, // VkDeviceSize bufferOffset;
13484 0u, // uint32_t bufferRowLength;
13485 0u, // uint32_t bufferImageHeight;
13486 {
13487 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
13488 0u, // uint32_t mipLevel;
13489 arrayLayerNdx, // uint32_t baseArrayLayer;
13490 1u, // uint32_t layerCount;
13491 }, // VkImageSubresourceLayers imageSubresource;
13492 {0, 0, 0}, // VkOffset3D imageOffset;
13493 default1dExtent // VkExtent3D imageExtent;
13494 };
13495 CopyRegion copyRegion;
13496 copyRegion.bufferImageCopy = bufferImageCopy;
13497
13498 params.regions.push_back(copyRegion);
13499 }
13500
13501 group->addChild(new CopyBufferToImageTestCase(testCtx, "array_tightly_sized_buffer", params));
13502 }
13503
13504 {
13505 TestParams params;
13506 const uint32_t baseLayer = 0u;
13507 const uint32_t layerCount = 16u;
13508 params.src.buffer.size = defaultSize * layerCount;
13509 params.src.buffer.fillMode = FILL_MODE_RED;
13510 params.dst.image.imageType = VK_IMAGE_TYPE_1D;
13511 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
13512 params.dst.image.extent = default1dExtent;
13513 params.dst.image.extent.depth = layerCount;
13514 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13515 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13516 params.dst.image.fillMode = FILL_MODE_RED;
13517 params.allocationKind = testGroupParams->allocationKind;
13518 params.extensionFlags = testGroupParams->extensionFlags;
13519 params.queueSelection = testGroupParams->queueSelection;
13520 params.useSparseBinding = testGroupParams->useSparseBinding;
13521 params.extensionFlags |= MAINTENANCE_5;
13522
13523 const VkImageSubresourceLayers defaultLayer = {
13524 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
13525 0u, // uint32_t mipLevel;
13526 baseLayer, // uint32_t baseArrayLayer;
13527 VK_REMAINING_ARRAY_LAYERS // uint32_t layerCount;
13528 };
13529
13530 const VkBufferImageCopy bufferImageCopy = {
13531 0u, // VkDeviceSize bufferOffset;
13532 0u, // uint32_t bufferRowLength;
13533 0u, // uint32_t bufferImageHeight;
13534 defaultLayer, // VkImageSubresourceLayers imageSubresource;
13535 {0, 0, 0}, // VkOffset3D imageOffset;
13536 default1dExtent // VkExtent3D imageExtent;
13537 };
13538
13539 CopyRegion copyRegion;
13540 copyRegion.bufferImageCopy = bufferImageCopy;
13541
13542 params.regions.push_back(copyRegion);
13543
13544 group->addChild(new CopyBufferToImageTestCase(testCtx, "array_all_remaining_layers", params));
13545 }
13546
13547 {
13548 TestParams params;
13549 const uint32_t baseLayer = 2u;
13550 const uint32_t layerCount = 16u;
13551 params.src.buffer.size = defaultSize * layerCount;
13552 params.src.buffer.fillMode = FILL_MODE_RED;
13553 params.dst.image.imageType = VK_IMAGE_TYPE_1D;
13554 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
13555 params.dst.image.extent = default1dExtent;
13556 params.dst.image.extent.depth = layerCount;
13557 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13558 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13559 params.dst.image.fillMode = FILL_MODE_RED;
13560 params.allocationKind = testGroupParams->allocationKind;
13561 params.extensionFlags = testGroupParams->extensionFlags;
13562 params.queueSelection = testGroupParams->queueSelection;
13563 params.useSparseBinding = testGroupParams->useSparseBinding;
13564 params.extensionFlags |= MAINTENANCE_5;
13565
13566 const VkImageSubresourceLayers defaultLayer = {
13567 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
13568 0u, // uint32_t mipLevel;
13569 baseLayer, // uint32_t baseArrayLayer;
13570 VK_REMAINING_ARRAY_LAYERS // uint32_t layerCount;
13571 };
13572
13573 const VkBufferImageCopy bufferImageCopy = {
13574 0u, // VkDeviceSize bufferOffset;
13575 0u, // uint32_t bufferRowLength;
13576 0u, // uint32_t bufferImageHeight;
13577 defaultLayer, // VkImageSubresourceLayers imageSubresource;
13578 {0, 0, 0}, // VkOffset3D imageOffset;
13579 default1dExtent // VkExtent3D imageExtent;
13580 };
13581
13582 CopyRegion copyRegion;
13583 copyRegion.bufferImageCopy = bufferImageCopy;
13584
13585 params.regions.push_back(copyRegion);
13586
13587 group->addChild(new CopyBufferToImageTestCase(testCtx, "array_not_all_remaining_layers", params));
13588 }
13589
13590 {
13591 TestParams params;
13592 uint32_t arrayLayers = 16u;
13593 uint32_t bufferImageHeight = defaultSize + 1u;
13594 params.src.buffer.size = defaultSize * arrayLayers;
13595 params.dst.image.imageType = VK_IMAGE_TYPE_1D;
13596 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
13597 params.dst.image.extent = default1dExtent;
13598 params.dst.image.extent.depth = arrayLayers;
13599 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13600 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13601 params.allocationKind = testGroupParams->allocationKind;
13602 params.extensionFlags = testGroupParams->extensionFlags;
13603 params.queueSelection = testGroupParams->queueSelection;
13604 params.useSparseBinding = testGroupParams->useSparseBinding;
13605
13606 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.dst.image.format));
13607 for (uint32_t arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
13608 {
13609 const VkDeviceSize offset = defaultSize * pixelSize * arrayLayerNdx;
13610 const VkBufferImageCopy bufferImageCopy = {
13611 offset, // VkDeviceSize bufferOffset;
13612 0u, // uint32_t bufferRowLength;
13613 bufferImageHeight, // uint32_t bufferImageHeight;
13614 {
13615 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
13616 0u, // uint32_t mipLevel;
13617 arrayLayerNdx, // uint32_t baseArrayLayer;
13618 1u, // uint32_t layerCount;
13619 }, // VkImageSubresourceLayers imageSubresource;
13620 {0, 0, 0}, // VkOffset3D imageOffset;
13621 default1dExtent // VkExtent3D imageExtent;
13622 };
13623 CopyRegion copyRegion;
13624 copyRegion.bufferImageCopy = bufferImageCopy;
13625
13626 params.regions.push_back(copyRegion);
13627 }
13628
13629 group->addChild(new CopyBufferToImageTestCase(testCtx, "array_larger_buffer", params));
13630 }
13631 }
13632
add2dBufferToImageTests(tcu::TestCaseGroup * group,TestGroupParamsPtr testGroupParams)13633 void add2dBufferToImageTests(tcu::TestCaseGroup *group, TestGroupParamsPtr testGroupParams)
13634 {
13635 tcu::TestContext &testCtx = group->getTestContext();
13636
13637 {
13638 TestParams params;
13639 params.src.buffer.size = defaultSize * defaultSize;
13640 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
13641 params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
13642 params.dst.image.extent = defaultExtent;
13643 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13644 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13645 params.allocationKind = testGroupParams->allocationKind;
13646 params.extensionFlags = testGroupParams->extensionFlags;
13647 params.queueSelection = testGroupParams->queueSelection;
13648 params.useSparseBinding = testGroupParams->useSparseBinding;
13649
13650 const VkBufferImageCopy bufferImageCopy = {
13651 0u, // VkDeviceSize bufferOffset;
13652 0u, // uint32_t bufferRowLength;
13653 0u, // uint32_t bufferImageHeight;
13654 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
13655 {0, 0, 0}, // VkOffset3D imageOffset;
13656 defaultExtent // VkExtent3D imageExtent;
13657 };
13658 CopyRegion copyRegion;
13659 copyRegion.bufferImageCopy = bufferImageCopy;
13660
13661 params.regions.push_back(copyRegion);
13662
13663 group->addChild(new CopyBufferToImageTestCase(testCtx, "whole", params));
13664 }
13665
13666 {
13667 TestParams params;
13668 params.src.buffer.size = defaultSize * defaultSize;
13669 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
13670 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
13671 params.dst.image.extent = defaultExtent;
13672 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13673 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13674 params.allocationKind = testGroupParams->allocationKind;
13675 params.extensionFlags = testGroupParams->extensionFlags;
13676 params.queueSelection = testGroupParams->queueSelection;
13677 params.useSparseBinding = testGroupParams->useSparseBinding;
13678
13679 CopyRegion region;
13680 uint32_t divisor = 1;
13681 for (int offset = 0; (offset + defaultQuarterSize / divisor < defaultSize) && (defaultQuarterSize > divisor);
13682 offset += defaultQuarterSize / divisor++)
13683 {
13684 const VkBufferImageCopy bufferImageCopy = {
13685 0u, // VkDeviceSize bufferOffset;
13686 0u, // uint32_t bufferRowLength;
13687 0u, // uint32_t bufferImageHeight;
13688 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
13689 {offset, defaultHalfSize, 0}, // VkOffset3D imageOffset;
13690 {defaultQuarterSize / divisor, defaultQuarterSize / divisor, 1} // VkExtent3D imageExtent;
13691 };
13692 region.bufferImageCopy = bufferImageCopy;
13693 params.regions.push_back(region);
13694 }
13695
13696 group->addChild(new CopyBufferToImageTestCase(testCtx, "regions", params));
13697 }
13698
13699 {
13700 TestParams params;
13701 params.src.buffer.size = defaultSize * defaultSize;
13702 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
13703 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
13704 params.dst.image.extent = defaultExtent;
13705 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13706 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13707 params.allocationKind = testGroupParams->allocationKind;
13708 params.extensionFlags = testGroupParams->extensionFlags;
13709 params.queueSelection = testGroupParams->queueSelection;
13710 params.useSparseBinding = testGroupParams->useSparseBinding;
13711
13712 const VkBufferImageCopy bufferImageCopy = {
13713 defaultQuarterSize, // VkDeviceSize bufferOffset;
13714 defaultHalfSize + defaultQuarterSize, // uint32_t bufferRowLength;
13715 defaultHalfSize + defaultQuarterSize, // uint32_t bufferImageHeight;
13716 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
13717 {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
13718 defaultHalfExtent // VkExtent3D imageExtent;
13719 };
13720 CopyRegion copyRegion;
13721 copyRegion.bufferImageCopy = bufferImageCopy;
13722
13723 params.regions.push_back(copyRegion);
13724
13725 group->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_offset", params));
13726 }
13727
13728 if (testGroupParams->queueSelection == QueueSelectionOptions::Universal)
13729 {
13730 TestParams params;
13731 params.src.buffer.size = defaultSize * defaultSize;
13732 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
13733 params.dst.image.format = VK_FORMAT_R8_UNORM;
13734 params.dst.image.extent = defaultExtent;
13735 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13736 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13737 params.allocationKind = testGroupParams->allocationKind;
13738 params.extensionFlags = testGroupParams->extensionFlags;
13739 params.queueSelection = testGroupParams->queueSelection;
13740 params.useSparseBinding = testGroupParams->useSparseBinding;
13741
13742 const VkBufferImageCopy bufferImageCopy = {
13743 defaultQuarterSize + 1u, // VkDeviceSize bufferOffset;
13744 defaultHalfSize + defaultQuarterSize, // uint32_t bufferRowLength;
13745 defaultHalfSize + defaultQuarterSize, // uint32_t bufferImageHeight;
13746 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
13747 {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
13748 defaultHalfExtent // VkExtent3D imageExtent;
13749 };
13750 CopyRegion copyRegion;
13751 copyRegion.bufferImageCopy = bufferImageCopy;
13752
13753 params.regions.push_back(copyRegion);
13754
13755 group->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_offset_relaxed", params));
13756 }
13757
13758 {
13759 TestParams params;
13760 params.src.buffer.size = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize;
13761 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
13762 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
13763 params.dst.image.extent = defaultExtent;
13764 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13765 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13766 params.allocationKind = testGroupParams->allocationKind;
13767 params.extensionFlags = testGroupParams->extensionFlags;
13768 params.queueSelection = testGroupParams->queueSelection;
13769 params.useSparseBinding = testGroupParams->useSparseBinding;
13770
13771 const VkBufferImageCopy bufferImageCopy = {
13772 0u, // VkDeviceSize bufferOffset;
13773 defaultSize, // uint32_t bufferRowLength;
13774 defaultSize, // uint32_t bufferImageHeight;
13775 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
13776 {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
13777 defaultHalfExtent // VkExtent3D imageExtent;
13778 };
13779 CopyRegion copyRegion;
13780 copyRegion.bufferImageCopy = bufferImageCopy;
13781
13782 params.regions.push_back(copyRegion);
13783
13784 group->addChild(new CopyBufferToImageTestCase(testCtx, "tightly_sized_buffer", params));
13785 }
13786
13787 {
13788 TestParams params;
13789 uint32_t bufferImageHeight = defaultSize + 1u;
13790 params.src.buffer.size = defaultSize * bufferImageHeight;
13791 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
13792 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
13793 params.dst.image.extent = defaultExtent;
13794 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13795 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13796 params.allocationKind = testGroupParams->allocationKind;
13797 params.extensionFlags = testGroupParams->extensionFlags;
13798 params.queueSelection = testGroupParams->queueSelection;
13799 params.useSparseBinding = testGroupParams->useSparseBinding;
13800
13801 const VkBufferImageCopy bufferImageCopy = {
13802 0u, // VkDeviceSize bufferOffset;
13803 defaultSize, // uint32_t bufferRowLength;
13804 bufferImageHeight, // uint32_t bufferImageHeight;
13805 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
13806 {0, 0, 0}, // VkOffset3D imageOffset;
13807 defaultHalfExtent // VkExtent3D imageExtent;
13808 };
13809 CopyRegion copyRegion;
13810 copyRegion.bufferImageCopy = bufferImageCopy;
13811
13812 params.regions.push_back(copyRegion);
13813
13814 group->addChild(new CopyBufferToImageTestCase(testCtx, "larger_buffer", params));
13815 }
13816
13817 {
13818 TestParams params;
13819 params.src.buffer.size = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultQuarterSize;
13820 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
13821 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
13822 params.dst.image.extent = defaultExtent;
13823 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13824 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13825 params.allocationKind = testGroupParams->allocationKind;
13826 params.extensionFlags = testGroupParams->extensionFlags;
13827 params.queueSelection = testGroupParams->queueSelection;
13828 params.useSparseBinding = testGroupParams->useSparseBinding;
13829
13830 const VkBufferImageCopy bufferImageCopy = {
13831 defaultQuarterSize, // VkDeviceSize bufferOffset;
13832 defaultSize, // uint32_t bufferRowLength;
13833 defaultSize, // uint32_t bufferImageHeight;
13834 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
13835 {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
13836 defaultHalfExtent // VkExtent3D imageExtent;
13837 };
13838 CopyRegion copyRegion;
13839 copyRegion.bufferImageCopy = bufferImageCopy;
13840
13841 params.regions.push_back(copyRegion);
13842
13843 group->addChild(new CopyBufferToImageTestCase(testCtx, "tightly_sized_buffer_offset", params));
13844 }
13845
13846 {
13847 TestParams params;
13848 uint32_t arrayLayers = 16u;
13849 params.src.buffer.size = defaultHalfSize * defaultHalfSize * arrayLayers;
13850 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
13851 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
13852 params.dst.image.extent = defaultHalfExtent;
13853 params.dst.image.extent.depth = arrayLayers;
13854 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13855 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13856 params.allocationKind = testGroupParams->allocationKind;
13857 params.extensionFlags = testGroupParams->extensionFlags;
13858 params.queueSelection = testGroupParams->queueSelection;
13859 params.useSparseBinding = testGroupParams->useSparseBinding;
13860
13861 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.dst.image.format));
13862 for (uint32_t arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
13863 {
13864 const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
13865 const VkBufferImageCopy bufferImageCopy = {
13866 offset, // VkDeviceSize bufferOffset;
13867 0u, // uint32_t bufferRowLength;
13868 0u, // uint32_t bufferImageHeight;
13869 {
13870 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
13871 0u, // uint32_t mipLevel;
13872 arrayLayerNdx, // uint32_t baseArrayLayer;
13873 1u, // uint32_t layerCount;
13874 }, // VkImageSubresourceLayers imageSubresource;
13875 {0, 0, 0}, // VkOffset3D imageOffset;
13876 defaultHalfExtent // VkExtent3D imageExtent;
13877 };
13878 CopyRegion copyRegion;
13879 copyRegion.bufferImageCopy = bufferImageCopy;
13880
13881 params.regions.push_back(copyRegion);
13882 }
13883 group->addChild(new CopyBufferToImageTestCase(testCtx, "array", params));
13884 }
13885
13886 {
13887 TestParams params;
13888 uint32_t arrayLayers = 16u;
13889 uint32_t bufferImageHeight = defaultHalfSize + 1u;
13890 params.src.buffer.size = defaultHalfSize * bufferImageHeight * arrayLayers;
13891 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
13892 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
13893 params.dst.image.extent = defaultHalfExtent;
13894 params.dst.image.extent.depth = arrayLayers;
13895 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13896 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13897 params.allocationKind = testGroupParams->allocationKind;
13898 params.extensionFlags = testGroupParams->extensionFlags;
13899 params.queueSelection = testGroupParams->queueSelection;
13900 params.useSparseBinding = testGroupParams->useSparseBinding;
13901
13902 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.dst.image.format));
13903 for (uint32_t arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
13904 {
13905 const VkDeviceSize offset = defaultHalfSize * bufferImageHeight * pixelSize * arrayLayerNdx;
13906 const VkBufferImageCopy bufferImageCopy = {
13907 offset, // VkDeviceSize bufferOffset;
13908 defaultHalfSize, // uint32_t bufferRowLength;
13909 bufferImageHeight, // uint32_t bufferImageHeight;
13910 {
13911 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
13912 0u, // uint32_t mipLevel;
13913 arrayLayerNdx, // uint32_t baseArrayLayer;
13914 1u, // uint32_t layerCount;
13915 }, // VkImageSubresourceLayers imageSubresource;
13916 {0, 0, 0}, // VkOffset3D imageOffset;
13917 defaultHalfExtent // VkExtent3D imageExtent;
13918 };
13919 CopyRegion copyRegion;
13920 copyRegion.bufferImageCopy = bufferImageCopy;
13921
13922 params.regions.push_back(copyRegion);
13923 }
13924 group->addChild(new CopyBufferToImageTestCase(testCtx, "array_larger_buffer", params));
13925 }
13926
13927 {
13928 TestParams params;
13929 uint32_t arrayLayers = 16u;
13930 params.src.buffer.size = defaultHalfSize * defaultHalfSize * arrayLayers;
13931 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
13932 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
13933 params.dst.image.extent = defaultHalfExtent;
13934 params.dst.image.extent.depth = arrayLayers;
13935 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13936 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13937 params.allocationKind = testGroupParams->allocationKind;
13938 params.extensionFlags = testGroupParams->extensionFlags;
13939 params.queueSelection = testGroupParams->queueSelection;
13940 params.useSparseBinding = testGroupParams->useSparseBinding;
13941
13942 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.dst.image.format));
13943 for (uint32_t arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
13944 {
13945 const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
13946 const VkBufferImageCopy bufferImageCopy = {
13947 offset, // VkDeviceSize bufferOffset;
13948 defaultHalfSize, // uint32_t bufferRowLength;
13949 defaultHalfSize, // uint32_t bufferImageHeight;
13950 {
13951 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
13952 0u, // uint32_t mipLevel;
13953 arrayLayerNdx, // uint32_t baseArrayLayer;
13954 1u, // uint32_t layerCount;
13955 }, // VkImageSubresourceLayers imageSubresource;
13956 {0, 0, 0}, // VkOffset3D imageOffset;
13957 defaultHalfExtent // VkExtent3D imageExtent;
13958 };
13959 CopyRegion copyRegion;
13960 copyRegion.bufferImageCopy = bufferImageCopy;
13961
13962 params.regions.push_back(copyRegion);
13963 }
13964 group->addChild(new CopyBufferToImageTestCase(testCtx, "array_tightly_sized_buffer", params));
13965 }
13966
13967 {
13968 TestParams params;
13969 const uint32_t baseLayer = 0u;
13970 const uint32_t layerCount = 16u;
13971 params.src.buffer.size = defaultHalfSize * defaultHalfSize * layerCount;
13972 params.src.buffer.fillMode = FILL_MODE_RED;
13973 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
13974 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
13975 params.dst.image.extent = defaultHalfExtent;
13976 params.dst.image.extent.depth = layerCount;
13977 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13978 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13979 params.dst.image.fillMode = FILL_MODE_RED;
13980 params.allocationKind = testGroupParams->allocationKind;
13981 params.extensionFlags = testGroupParams->extensionFlags;
13982 params.queueSelection = testGroupParams->queueSelection;
13983 params.useSparseBinding = testGroupParams->useSparseBinding;
13984 params.extensionFlags |= MAINTENANCE_5;
13985
13986 const VkImageSubresourceLayers defaultLayer = {
13987 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
13988 0u, // uint32_t mipLevel;
13989 baseLayer, // uint32_t baseArrayLayer;
13990 VK_REMAINING_ARRAY_LAYERS // uint32_t layerCount;
13991 };
13992
13993 const VkBufferImageCopy bufferImageCopy = {
13994 0, // VkDeviceSize bufferOffset;
13995 0, // uint32_t bufferRowLength;
13996 0, // uint32_t bufferImageHeight;
13997 defaultLayer, // VkImageSubresourceLayers imageSubresource;
13998 {0, 0, 0}, // VkOffset3D imageOffset;
13999 defaultHalfExtent // VkExtent3D imageExtent;
14000 };
14001
14002 CopyRegion copyRegion;
14003 copyRegion.bufferImageCopy = bufferImageCopy;
14004
14005 params.regions.push_back(copyRegion);
14006
14007 group->addChild(new CopyBufferToImageTestCase(testCtx, "array_all_remaining_layers", params));
14008 }
14009
14010 {
14011 TestParams params;
14012 const uint32_t baseLayer = 2u;
14013 const uint32_t layerCount = 16u;
14014 params.src.buffer.size = defaultHalfSize * defaultHalfSize * layerCount;
14015 params.src.buffer.fillMode = FILL_MODE_RED;
14016 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
14017 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14018 params.dst.image.extent = defaultHalfExtent;
14019 params.dst.image.extent.depth = layerCount;
14020 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14021 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14022 params.dst.image.fillMode = FILL_MODE_RED;
14023 params.allocationKind = testGroupParams->allocationKind;
14024 params.extensionFlags = testGroupParams->extensionFlags;
14025 params.queueSelection = testGroupParams->queueSelection;
14026 params.useSparseBinding = testGroupParams->useSparseBinding;
14027 params.extensionFlags |= MAINTENANCE_5;
14028
14029 const VkImageSubresourceLayers defaultLayer = {
14030 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
14031 0u, // uint32_t mipLevel;
14032 baseLayer, // uint32_t baseArrayLayer;
14033 VK_REMAINING_ARRAY_LAYERS // uint32_t layerCount;
14034 };
14035
14036 const VkBufferImageCopy bufferImageCopy = {
14037 0, // VkDeviceSize bufferOffset;
14038 0, // uint32_t bufferRowLength;
14039 0, // uint32_t bufferImageHeight;
14040 defaultLayer, // VkImageSubresourceLayers imageSubresource;
14041 {0, 0, 0}, // VkOffset3D imageOffset;
14042 defaultHalfExtent // VkExtent3D imageExtent;
14043 };
14044
14045 CopyRegion copyRegion;
14046 copyRegion.bufferImageCopy = bufferImageCopy;
14047
14048 params.regions.push_back(copyRegion);
14049
14050 group->addChild(new CopyBufferToImageTestCase(testCtx, "array_not_all_remaining_layers", params));
14051 }
14052 }
14053
addBufferToBufferTests(tcu::TestCaseGroup * group,TestGroupParamsPtr testGroupParams)14054 void addBufferToBufferTests(tcu::TestCaseGroup *group, TestGroupParamsPtr testGroupParams)
14055 {
14056 tcu::TestContext &testCtx = group->getTestContext();
14057
14058 {
14059 TestParams params;
14060 params.src.buffer.size = defaultSize;
14061 params.dst.buffer.size = defaultSize;
14062 params.allocationKind = testGroupParams->allocationKind;
14063 params.extensionFlags = testGroupParams->extensionFlags;
14064 params.queueSelection = testGroupParams->queueSelection;
14065 params.useSparseBinding = testGroupParams->useSparseBinding;
14066
14067 const VkBufferCopy bufferCopy = {
14068 0u, // VkDeviceSize srcOffset;
14069 0u, // VkDeviceSize dstOffset;
14070 defaultSize, // VkDeviceSize size;
14071 };
14072
14073 CopyRegion copyRegion;
14074 copyRegion.bufferCopy = bufferCopy;
14075 params.regions.push_back(copyRegion);
14076
14077 group->addChild(new BufferToBufferTestCase(testCtx, "whole", params));
14078 }
14079
14080 // Filter is VK_FILTER_NEAREST.
14081 {
14082 TestParams params;
14083 params.src.buffer.size = defaultQuarterSize;
14084 params.dst.buffer.size = defaultQuarterSize;
14085 params.allocationKind = testGroupParams->allocationKind;
14086 params.extensionFlags = testGroupParams->extensionFlags;
14087 params.queueSelection = testGroupParams->queueSelection;
14088 params.useSparseBinding = testGroupParams->useSparseBinding;
14089
14090 const VkBufferCopy bufferCopy = {
14091 12u, // VkDeviceSize srcOffset;
14092 4u, // VkDeviceSize dstOffset;
14093 1u, // VkDeviceSize size;
14094 };
14095
14096 CopyRegion copyRegion;
14097 copyRegion.bufferCopy = bufferCopy;
14098 params.regions.push_back(copyRegion);
14099
14100 group->addChild(new BufferToBufferTestCase(testCtx, "partial", params));
14101 }
14102
14103 {
14104 const uint32_t size = 16;
14105 TestParams params;
14106 params.src.buffer.size = size;
14107 params.dst.buffer.size = size * (size + 1);
14108 params.allocationKind = testGroupParams->allocationKind;
14109 params.extensionFlags = testGroupParams->extensionFlags;
14110 params.queueSelection = testGroupParams->queueSelection;
14111 params.useSparseBinding = testGroupParams->useSparseBinding;
14112
14113 // Copy region with size 1..size
14114 for (unsigned int i = 1; i <= size; i++)
14115 {
14116 const VkBufferCopy bufferCopy = {
14117 0, // VkDeviceSize srcOffset;
14118 i * size, // VkDeviceSize dstOffset;
14119 i, // VkDeviceSize size;
14120 };
14121
14122 CopyRegion copyRegion;
14123 copyRegion.bufferCopy = bufferCopy;
14124 params.regions.push_back(copyRegion);
14125 }
14126
14127 group->addChild(new BufferToBufferTestCase(testCtx, "regions", params));
14128 }
14129
14130 {
14131 TestParams params;
14132 params.src.buffer.size = 32;
14133 params.dst.buffer.size = 32;
14134 params.allocationKind = testGroupParams->allocationKind;
14135 params.extensionFlags = testGroupParams->extensionFlags;
14136 params.queueSelection = testGroupParams->queueSelection;
14137 params.useSparseBinding = testGroupParams->useSparseBinding;
14138
14139 // Copy four unaligned regions
14140 for (unsigned int i = 0; i < 4; i++)
14141 {
14142 const VkBufferCopy bufferCopy{
14143 3 + i * 3, // VkDeviceSize srcOffset; 3 6 9 12
14144 1 + i * 5, // VkDeviceSize dstOffset; 1 6 11 16
14145 2 + i, // VkDeviceSize size; 2 3 4 5
14146 };
14147
14148 CopyRegion copyRegion;
14149 copyRegion.bufferCopy = bufferCopy;
14150 params.regions.push_back(copyRegion);
14151 }
14152
14153 group->addChild(new BufferToBufferTestCase(testCtx, "unaligned_regions", params));
14154 }
14155 }
14156
addBlittingImageSimpleTests(tcu::TestCaseGroup * group,TestParams & params)14157 void addBlittingImageSimpleTests(tcu::TestCaseGroup *group, TestParams ¶ms)
14158 {
14159 tcu::TestContext &testCtx = group->getTestContext();
14160
14161 // Filter is VK_FILTER_NEAREST.
14162 {
14163 params.filter = VK_FILTER_NEAREST;
14164
14165 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14166 group->addChild(new BlitImageTestCase(testCtx, "nearest", params));
14167
14168 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
14169 group->addChild(
14170 new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", params));
14171
14172 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
14173 group->addChild(
14174 new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", params));
14175 }
14176
14177 // Filter is VK_FILTER_LINEAR.
14178 {
14179 params.filter = VK_FILTER_LINEAR;
14180
14181 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14182 group->addChild(new BlitImageTestCase(testCtx, "linear", params));
14183
14184 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
14185 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", params));
14186
14187 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
14188 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", params));
14189 }
14190
14191 // Filter is VK_FILTER_CUBIC_EXT.
14192 // Cubic filtering can only be used with 2D images.
14193 if (params.dst.image.imageType == VK_IMAGE_TYPE_2D)
14194 {
14195 params.filter = VK_FILTER_CUBIC_EXT;
14196
14197 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14198 group->addChild(new BlitImageTestCase(testCtx, "cubic", params));
14199
14200 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
14201 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_cubic", params));
14202
14203 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
14204 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_cubic", params));
14205 }
14206 }
14207
addBlittingImageSimpleWholeTests(tcu::TestCaseGroup * group,TestParams params)14208 void addBlittingImageSimpleWholeTests(tcu::TestCaseGroup *group, TestParams params)
14209 {
14210 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
14211 const int32_t imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
14212 params.src.image.extent = defaultExtent;
14213 params.dst.image.extent = defaultExtent;
14214 params.src.image.extent.depth = imageDepth;
14215 params.dst.image.extent.depth = imageDepth;
14216
14217 {
14218 const VkImageBlit imageBlit = {
14219 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
14220 {{0, 0, 0}, {defaultSize, defaultSize, imageDepth}}, // VkOffset3D srcOffsets[2];
14221
14222 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
14223 {{0, 0, 0}, {defaultSize, defaultSize, imageDepth}} // VkOffset3D dstOffset[2];
14224 };
14225
14226 CopyRegion region;
14227 region.imageBlit = imageBlit;
14228 params.regions.push_back(region);
14229 }
14230
14231 addBlittingImageSimpleTests(group, params);
14232 }
14233
addBlittingImageArrayTests(tcu::TestCaseGroup * group,TestParams params)14234 void addBlittingImageArrayTests(tcu::TestCaseGroup *group, TestParams params)
14235 {
14236 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
14237
14238 tcu::TestContext &testCtx = group->getTestContext();
14239
14240 {
14241 const uint32_t baseLayer = 0u;
14242 const uint32_t layerCount = 16u;
14243 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14244 params.src.image.extent = defaultExtent;
14245 params.dst.image.extent = defaultExtent;
14246 params.src.image.extent.depth = layerCount;
14247 params.dst.image.extent.depth = layerCount;
14248 params.filter = VK_FILTER_NEAREST;
14249 params.extensionFlags |= MAINTENANCE_5;
14250
14251 const VkImageSubresourceLayers defaultLayer = {
14252 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
14253 0u, // uint32_t mipLevel;
14254 baseLayer, // uint32_t baseArrayLayer;
14255 VK_REMAINING_ARRAY_LAYERS // uint32_t layerCount;
14256 };
14257
14258 const VkImageBlit imageBlit = {
14259 defaultLayer, // VkImageSubresourceLayers srcSubresource;
14260 {{0, 0, 0}, {defaultSize, defaultSize, 1}}, // VkOffset3D srcOffsets[2];
14261
14262 defaultLayer, // VkImageSubresourceLayers dstSubresource;
14263 {{0, 0, 0}, {defaultSize, defaultSize, 1}} // VkOffset3D dstOffset[2];
14264 };
14265
14266 CopyRegion region;
14267 region.imageBlit = imageBlit;
14268
14269 params.regions.push_back(region);
14270
14271 group->addChild(new BlitImageTestCase(testCtx, "all_remaining_layers", params));
14272 }
14273
14274 params.regions.clear();
14275
14276 {
14277 const uint32_t baseLayer = 2u;
14278 const uint32_t layerCount = 16u;
14279 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14280 params.src.image.extent = defaultExtent;
14281 params.dst.image.extent = defaultExtent;
14282 params.src.image.extent.depth = layerCount;
14283 params.dst.image.extent.depth = layerCount;
14284 params.filter = VK_FILTER_NEAREST;
14285 params.extensionFlags |= MAINTENANCE_5;
14286
14287 const VkImageSubresourceLayers defaultLayer = {
14288 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
14289 0u, // uint32_t mipLevel;
14290 baseLayer, // uint32_t baseArrayLayer;
14291 VK_REMAINING_ARRAY_LAYERS // uint32_t layerCount;
14292 };
14293
14294 const VkImageBlit imageBlit = {
14295 defaultLayer, // VkImageSubresourceLayers srcSubresource;
14296 {{0, 0, 0}, {defaultSize, defaultSize, 1}}, // VkOffset3D srcOffsets[2];
14297
14298 defaultLayer, // VkImageSubresourceLayers dstSubresource;
14299 {{0, 0, 0}, {defaultSize, defaultSize, 1}} // VkOffset3D dstOffset[2];
14300 };
14301
14302 CopyRegion region;
14303 region.imageBlit = imageBlit;
14304
14305 params.regions.push_back(region);
14306
14307 group->addChild(new BlitImageTestCase(testCtx, "not_all_remaining_layers", params));
14308 }
14309 }
14310
addBlittingImageSimpleMirrorXYTests(tcu::TestCaseGroup * group,TestParams params)14311 void addBlittingImageSimpleMirrorXYTests(tcu::TestCaseGroup *group, TestParams params)
14312 {
14313 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
14314 const int32_t imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
14315 params.src.image.extent = defaultExtent;
14316 params.dst.image.extent = defaultExtent;
14317 params.src.image.extent.depth = imageDepth;
14318 params.dst.image.extent.depth = imageDepth;
14319
14320 {
14321 const VkImageBlit imageBlit = {
14322 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
14323 {{0, 0, 0}, {defaultSize, defaultSize, imageDepth}}, // VkOffset3D srcOffsets[2];
14324
14325 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
14326 {{defaultSize, defaultSize, 0}, {0, 0, imageDepth}} // VkOffset3D dstOffset[2];
14327 };
14328
14329 CopyRegion region;
14330 region.imageBlit = imageBlit;
14331 params.regions.push_back(region);
14332 }
14333
14334 addBlittingImageSimpleTests(group, params);
14335 }
14336
addBlittingImageSimpleMirrorXTests(tcu::TestCaseGroup * group,TestParams params)14337 void addBlittingImageSimpleMirrorXTests(tcu::TestCaseGroup *group, TestParams params)
14338 {
14339 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
14340 const int32_t imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
14341 params.src.image.extent = defaultExtent;
14342 params.dst.image.extent = defaultExtent;
14343 params.src.image.extent.depth = imageDepth;
14344 params.dst.image.extent.depth = imageDepth;
14345
14346 {
14347 const VkImageBlit imageBlit = {
14348 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
14349 {{0, 0, 0}, {defaultSize, defaultSize, imageDepth}}, // VkOffset3D srcOffsets[2];
14350
14351 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
14352 {{defaultSize, 0, 0}, {0, defaultSize, imageDepth}} // VkOffset3D dstOffset[2];
14353 };
14354
14355 CopyRegion region;
14356 region.imageBlit = imageBlit;
14357 params.regions.push_back(region);
14358 }
14359
14360 addBlittingImageSimpleTests(group, params);
14361 }
14362
addBlittingImageSimpleMirrorYTests(tcu::TestCaseGroup * group,TestParams params)14363 void addBlittingImageSimpleMirrorYTests(tcu::TestCaseGroup *group, TestParams params)
14364 {
14365 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
14366 const int32_t imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
14367 params.src.image.extent = defaultExtent;
14368 params.dst.image.extent = defaultExtent;
14369 params.src.image.extent.depth = imageDepth;
14370 params.dst.image.extent.depth = imageDepth;
14371
14372 {
14373 const VkImageBlit imageBlit = {
14374 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
14375 {{0, 0, 0}, {defaultSize, defaultSize, imageDepth}}, // VkOffset3D srcOffsets[2];
14376
14377 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
14378 {{0, defaultSize, 0}, {defaultSize, 0, imageDepth}} // VkOffset3D dstOffset[2];
14379 };
14380
14381 CopyRegion region;
14382 region.imageBlit = imageBlit;
14383 params.regions.push_back(region);
14384 }
14385
14386 addBlittingImageSimpleTests(group, params);
14387 }
14388
addBlittingImageSimpleMirrorZTests(tcu::TestCaseGroup * group,TestParams params)14389 void addBlittingImageSimpleMirrorZTests(tcu::TestCaseGroup *group, TestParams params)
14390 {
14391 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
14392 DE_ASSERT(params.src.image.imageType == VK_IMAGE_TYPE_3D);
14393 params.src.image.extent = defaultExtent;
14394 params.dst.image.extent = defaultExtent;
14395 params.src.image.extent.depth = defaultSize;
14396 params.dst.image.extent.depth = defaultSize;
14397
14398 {
14399 const VkImageBlit imageBlit = {
14400 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
14401 {{0, 0, 0}, {defaultSize, defaultSize, defaultSize}}, // VkOffset3D srcOffsets[2];
14402
14403 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
14404 {{0, 0, defaultSize}, {defaultSize, defaultSize, 0}} // VkOffset3D dstOffset[2];
14405 };
14406
14407 CopyRegion region;
14408 region.imageBlit = imageBlit;
14409 params.regions.push_back(region);
14410 }
14411
14412 addBlittingImageSimpleTests(group, params);
14413 }
14414
addBlittingImageSimpleMirrorSubregionsTests(tcu::TestCaseGroup * group,TestParams params)14415 void addBlittingImageSimpleMirrorSubregionsTests(tcu::TestCaseGroup *group, TestParams params)
14416 {
14417 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
14418 const int32_t imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
14419 params.src.image.extent = defaultExtent;
14420 params.dst.image.extent = defaultExtent;
14421 params.src.image.extent.depth = imageDepth;
14422 params.dst.image.extent.depth = imageDepth;
14423
14424 // No mirroring.
14425 {
14426 const VkImageBlit imageBlit = {
14427 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
14428 {{0, 0, 0}, {defaultHalfSize, defaultHalfSize, imageDepth}}, // VkOffset3D srcOffsets[2];
14429
14430 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
14431 {{0, 0, 0}, {defaultHalfSize, defaultHalfSize, imageDepth}} // VkOffset3D dstOffset[2];
14432 };
14433
14434 CopyRegion region;
14435 region.imageBlit = imageBlit;
14436 params.regions.push_back(region);
14437 }
14438
14439 // Flipping y coordinates.
14440 {
14441 const VkImageBlit imageBlit = {
14442 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
14443 {{defaultHalfSize, 0, 0}, {defaultSize, defaultHalfSize, imageDepth}}, // VkOffset3D srcOffsets[2];
14444
14445 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
14446 {{defaultHalfSize, defaultHalfSize, 0}, {defaultSize, 0, imageDepth}} // VkOffset3D dstOffset[2];
14447 };
14448 CopyRegion region;
14449 region.imageBlit = imageBlit;
14450 params.regions.push_back(region);
14451 }
14452
14453 // Flipping x coordinates.
14454 {
14455 const VkImageBlit imageBlit = {
14456 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
14457 {{0, defaultHalfSize, 0}, {defaultHalfSize, defaultSize, imageDepth}}, // VkOffset3D srcOffsets[2];
14458
14459 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
14460 {{defaultHalfSize, defaultHalfSize, 0}, {0, defaultSize, imageDepth}} // VkOffset3D dstOffset[2];
14461 };
14462
14463 CopyRegion region;
14464 region.imageBlit = imageBlit;
14465 params.regions.push_back(region);
14466 }
14467
14468 // Flipping x and y coordinates.
14469 {
14470 const VkImageBlit imageBlit = {
14471 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
14472 {{defaultHalfSize, defaultHalfSize, 0},
14473 {defaultSize, defaultSize, imageDepth}}, // VkOffset3D srcOffsets[2];
14474
14475 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
14476 {{defaultSize, defaultSize, 0}, {defaultHalfSize, defaultHalfSize, imageDepth}} // VkOffset3D dstOffset[2];
14477 };
14478
14479 CopyRegion region;
14480 region.imageBlit = imageBlit;
14481 params.regions.push_back(region);
14482 }
14483
14484 addBlittingImageSimpleTests(group, params);
14485 }
14486
addBlittingImageSimpleScalingWhole1Tests(tcu::TestCaseGroup * group,TestParams params)14487 void addBlittingImageSimpleScalingWhole1Tests(tcu::TestCaseGroup *group, TestParams params)
14488 {
14489 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
14490 const int32_t imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
14491 const int32_t halfImageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultHalfSize : 1;
14492 params.src.image.extent = defaultExtent;
14493 params.dst.image.extent = defaultHalfExtent;
14494 params.src.image.extent.depth = imageDepth;
14495 params.dst.image.extent.depth = halfImageDepth;
14496
14497 {
14498 const VkImageBlit imageBlit = {
14499 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
14500 {{0, 0, 0}, {defaultSize, defaultSize, imageDepth}}, // VkOffset3D srcOffsets[2];
14501
14502 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
14503 {{0, 0, 0}, {defaultHalfSize, defaultHalfSize, halfImageDepth}} // VkOffset3D dstOffset[2];
14504 };
14505
14506 CopyRegion region;
14507 region.imageBlit = imageBlit;
14508 params.regions.push_back(region);
14509 }
14510
14511 addBlittingImageSimpleTests(group, params);
14512 }
14513
addBlittingImageSimpleScalingWhole2Tests(tcu::TestCaseGroup * group,TestParams params)14514 void addBlittingImageSimpleScalingWhole2Tests(tcu::TestCaseGroup *group, TestParams params)
14515 {
14516 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
14517 const int32_t imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
14518 const int32_t halfImageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultHalfSize : 1;
14519 params.src.image.extent = defaultHalfExtent;
14520 params.dst.image.extent = defaultExtent;
14521 params.src.image.extent.depth = halfImageDepth;
14522 params.dst.image.extent.depth = imageDepth;
14523
14524 {
14525 const VkImageBlit imageBlit = {
14526 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
14527 {{0, 0, 0}, {defaultHalfSize, defaultHalfSize, halfImageDepth}}, // VkOffset3D srcOffsets[2];
14528
14529 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
14530 {{0, 0, 0}, {defaultSize, defaultSize, imageDepth}} // VkOffset3D dstOffset[2];
14531 };
14532
14533 CopyRegion region;
14534 region.imageBlit = imageBlit;
14535 params.regions.push_back(region);
14536 }
14537
14538 addBlittingImageSimpleTests(group, params);
14539 }
14540
addBlittingImageSimpleScalingAndOffsetTests(tcu::TestCaseGroup * group,TestParams params)14541 void addBlittingImageSimpleScalingAndOffsetTests(tcu::TestCaseGroup *group, TestParams params)
14542 {
14543 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
14544 const int32_t imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
14545 const int32_t srcDepthOffset = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultQuarterSize : 0;
14546 const int32_t srcDepthSize = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultQuarterSize * 3 : 1;
14547 params.src.image.extent = defaultExtent;
14548 params.dst.image.extent = defaultExtent;
14549 params.src.image.extent.depth = imageDepth;
14550 params.dst.image.extent.depth = imageDepth;
14551
14552 {
14553 const VkImageBlit imageBlit = {
14554 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
14555 {{defaultQuarterSize, defaultQuarterSize, srcDepthOffset},
14556 {defaultQuarterSize * 3, defaultQuarterSize * 3, srcDepthSize}}, // VkOffset3D srcOffsets[2];
14557
14558 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
14559 {{0, 0, 0}, {defaultSize, defaultSize, imageDepth}} // VkOffset3D dstOffset[2];
14560 };
14561
14562 CopyRegion region;
14563 region.imageBlit = imageBlit;
14564 params.regions.push_back(region);
14565 }
14566
14567 addBlittingImageSimpleTests(group, params);
14568 }
14569
addBlittingImageSimpleWithoutScalingPartialTests(tcu::TestCaseGroup * group,TestParams params)14570 void addBlittingImageSimpleWithoutScalingPartialTests(tcu::TestCaseGroup *group, TestParams params)
14571 {
14572 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
14573 const bool is3dBlit = params.src.image.imageType == VK_IMAGE_TYPE_3D;
14574 params.src.image.extent = defaultExtent;
14575 params.dst.image.extent = defaultExtent;
14576
14577 if (is3dBlit)
14578 {
14579 params.src.image.extent.depth = defaultSize;
14580 params.dst.image.extent.depth = defaultSize;
14581 }
14582
14583 {
14584 CopyRegion region;
14585 for (int i = 0; i < defaultSize; i += defaultQuarterSize)
14586 {
14587 const VkImageBlit imageBlit = {
14588 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
14589 {{defaultSize - defaultQuarterSize - i, defaultSize - defaultQuarterSize - i,
14590 is3dBlit ? defaultSize - defaultQuarterSize - i : 0},
14591 {defaultSize - i, defaultSize - i, is3dBlit ? defaultSize - i : 1}}, // VkOffset3D srcOffsets[2];
14592
14593 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
14594 {{i, i, is3dBlit ? i : 0},
14595 {i + defaultQuarterSize, i + defaultQuarterSize,
14596 is3dBlit ? i + defaultQuarterSize : 1}} // VkOffset3D dstOffset[2];
14597 };
14598 region.imageBlit = imageBlit;
14599 params.regions.push_back(region);
14600 }
14601 }
14602
14603 addBlittingImageSimpleTests(group, params);
14604 }
14605
addBlittingImageSimpleTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)14606 void addBlittingImageSimpleTests(tcu::TestCaseGroup *group, AllocationKind allocationKind, uint32_t extensionFlags)
14607 {
14608 TestParams params;
14609 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14610 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14611 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14612 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14613 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14614 params.allocationKind = allocationKind;
14615 params.extensionFlags = extensionFlags;
14616 params.src.image.imageType = VK_IMAGE_TYPE_2D;
14617 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
14618 addTestGroup(group, "whole", addBlittingImageSimpleWholeTests, params);
14619 addTestGroup(group, "array", addBlittingImageArrayTests, params);
14620 addTestGroup(group, "mirror_xy", addBlittingImageSimpleMirrorXYTests, params);
14621 addTestGroup(group, "mirror_x", addBlittingImageSimpleMirrorXTests, params);
14622 addTestGroup(group, "mirror_y", addBlittingImageSimpleMirrorYTests, params);
14623 addTestGroup(group, "mirror_subregions", addBlittingImageSimpleMirrorSubregionsTests, params);
14624 addTestGroup(group, "scaling_whole1", addBlittingImageSimpleScalingWhole1Tests, params);
14625 addTestGroup(group, "scaling_whole2", addBlittingImageSimpleScalingWhole2Tests, params);
14626 addTestGroup(group, "scaling_and_offset", addBlittingImageSimpleScalingAndOffsetTests, params);
14627 addTestGroup(group, "without_scaling_partial", addBlittingImageSimpleWithoutScalingPartialTests, params);
14628
14629 params.src.image.imageType = VK_IMAGE_TYPE_3D;
14630 params.dst.image.imageType = VK_IMAGE_TYPE_3D;
14631 addTestGroup(group, "whole_3d", addBlittingImageSimpleWholeTests, params);
14632 addTestGroup(group, "mirror_xy_3d", addBlittingImageSimpleMirrorXYTests, params);
14633 addTestGroup(group, "mirror_x_3d", addBlittingImageSimpleMirrorXTests, params);
14634 addTestGroup(group, "mirror_y_3d", addBlittingImageSimpleMirrorYTests, params);
14635 addTestGroup(group, "mirror_z_3d", addBlittingImageSimpleMirrorZTests, params);
14636 addTestGroup(group, "mirror_subregions_3d", addBlittingImageSimpleMirrorSubregionsTests, params);
14637 addTestGroup(group, "scaling_whole1_3d", addBlittingImageSimpleScalingWhole1Tests, params);
14638 addTestGroup(group, "scaling_whole2_3d", addBlittingImageSimpleScalingWhole2Tests, params);
14639 addTestGroup(group, "scaling_and_offset_3d", addBlittingImageSimpleScalingAndOffsetTests, params);
14640 addTestGroup(group, "without_scaling_partial_3d", addBlittingImageSimpleWithoutScalingPartialTests, params);
14641 }
14642
14643 enum FilterMaskBits
14644 {
14645 FILTER_MASK_NEAREST = 0, // Always tested.
14646 FILTER_MASK_LINEAR = (1u << 0),
14647 FILTER_MASK_CUBIC = (1u << 1),
14648 };
14649
14650 using FilterMask = uint32_t;
14651
makeFilterMask(bool onlyNearest,bool discardCubicFilter)14652 FilterMask makeFilterMask(bool onlyNearest, bool discardCubicFilter)
14653 {
14654 FilterMask mask = FILTER_MASK_NEAREST;
14655
14656 if (!onlyNearest)
14657 {
14658 mask |= FILTER_MASK_LINEAR;
14659 if (!discardCubicFilter)
14660 mask |= FILTER_MASK_CUBIC;
14661 }
14662
14663 return mask;
14664 }
14665
14666 struct BlitColorTestParams
14667 {
14668 TestParams params;
14669 const VkFormat *compatibleFormats;
14670 FilterMask testFilters;
14671 };
14672
isAllowedBlittingAllFormatsColorSrcFormatTests(const BlitColorTestParams & testParams)14673 bool isAllowedBlittingAllFormatsColorSrcFormatTests(const BlitColorTestParams &testParams)
14674 {
14675 bool result = true;
14676
14677 if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED)
14678 {
14679 DE_ASSERT(!dedicatedAllocationBlittingFormatsToTestSet.empty());
14680
14681 result = de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.dst.image.format) ||
14682 de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.src.image.format);
14683 }
14684
14685 return result;
14686 }
14687
14688 const VkFormat linearOtherImageFormatsToTest[] = {
14689 // From compatibleFormats8Bit
14690 VK_FORMAT_R4G4_UNORM_PACK8,
14691 VK_FORMAT_R8_SRGB,
14692
14693 // From compatibleFormats16Bit
14694 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
14695 VK_FORMAT_R16_SFLOAT,
14696
14697 // From compatibleFormats24Bit
14698 VK_FORMAT_R8G8B8_UNORM,
14699 VK_FORMAT_B8G8R8_SRGB,
14700
14701 // From compatibleFormats32Bit
14702 VK_FORMAT_R8G8B8A8_UNORM,
14703 VK_FORMAT_R32_SFLOAT,
14704
14705 // From compatibleFormats48Bit
14706 VK_FORMAT_R16G16B16_UNORM,
14707 VK_FORMAT_R16G16B16_SFLOAT,
14708
14709 // From compatibleFormats64Bit
14710 VK_FORMAT_R16G16B16A16_UNORM,
14711 VK_FORMAT_R64_SFLOAT,
14712
14713 // From compatibleFormats96Bit
14714 VK_FORMAT_R32G32B32_UINT,
14715 VK_FORMAT_R32G32B32_SFLOAT,
14716
14717 // From compatibleFormats128Bit
14718 VK_FORMAT_R32G32B32A32_UINT,
14719 VK_FORMAT_R64G64_SFLOAT,
14720
14721 // From compatibleFormats192Bit
14722 VK_FORMAT_R64G64B64_UINT,
14723 VK_FORMAT_R64G64B64_SFLOAT,
14724
14725 // From compatibleFormats256Bit
14726 VK_FORMAT_R64G64B64A64_UINT,
14727 VK_FORMAT_R64G64B64A64_SFLOAT,
14728 };
14729
getBlitImageTilingLayoutCaseName(VkImageTiling tiling,VkImageLayout layout)14730 std::string getBlitImageTilingLayoutCaseName(VkImageTiling tiling, VkImageLayout layout)
14731 {
14732 switch (tiling)
14733 {
14734 case VK_IMAGE_TILING_OPTIMAL:
14735 return getImageLayoutCaseName(layout);
14736 case VK_IMAGE_TILING_LINEAR:
14737 return "linear";
14738 default:
14739 DE_ASSERT(false);
14740 return "";
14741 }
14742 }
14743
addBlittingImageAllFormatsColorSrcFormatDstFormatTests(tcu::TestCaseGroup * group,BlitColorTestParams testParams)14744 void addBlittingImageAllFormatsColorSrcFormatDstFormatTests(tcu::TestCaseGroup *group, BlitColorTestParams testParams)
14745 {
14746 tcu::TestContext &testCtx = group->getTestContext();
14747
14748 FormatSet linearOtherImageFormatsToTestSet;
14749 const int numOfOtherImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(linearOtherImageFormatsToTest);
14750 for (int otherImageFormatsIndex = 0; otherImageFormatsIndex < numOfOtherImageFormatsToTestFilter;
14751 ++otherImageFormatsIndex)
14752 linearOtherImageFormatsToTestSet.insert(linearOtherImageFormatsToTest[otherImageFormatsIndex]);
14753
14754 const VkImageTiling blitSrcTilings[] = {
14755 VK_IMAGE_TILING_OPTIMAL,
14756 VK_IMAGE_TILING_LINEAR,
14757 };
14758 const VkImageLayout blitSrcLayouts[] = {VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL};
14759 const VkImageTiling blitDstTilings[] = {
14760 VK_IMAGE_TILING_OPTIMAL,
14761 VK_IMAGE_TILING_LINEAR,
14762 };
14763 const VkImageLayout blitDstLayouts[] = {VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL};
14764
14765 for (int srcTilingNdx = 0u; srcTilingNdx < DE_LENGTH_OF_ARRAY(blitSrcTilings); ++srcTilingNdx)
14766 {
14767 testParams.params.src.image.tiling = blitSrcTilings[srcTilingNdx];
14768
14769 for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
14770 {
14771 testParams.params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx];
14772
14773 // 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
14774 if (testParams.params.src.image.tiling == VK_IMAGE_TILING_LINEAR &&
14775 testParams.params.src.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)
14776 continue;
14777
14778 for (int dstTilingNdx = 0u; dstTilingNdx < DE_LENGTH_OF_ARRAY(blitDstTilings); ++dstTilingNdx)
14779 {
14780 testParams.params.dst.image.tiling = blitDstTilings[dstTilingNdx];
14781
14782 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
14783 {
14784 testParams.params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx];
14785
14786 // 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
14787 if (testParams.params.dst.image.tiling == VK_IMAGE_TILING_LINEAR &&
14788 testParams.params.dst.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
14789 continue;
14790
14791 if ((testParams.params.dst.image.tiling == VK_IMAGE_TILING_LINEAR &&
14792 !de::contains(linearOtherImageFormatsToTestSet, testParams.params.src.image.format)) ||
14793 (testParams.params.src.image.tiling == VK_IMAGE_TILING_LINEAR &&
14794 !de::contains(linearOtherImageFormatsToTestSet, testParams.params.dst.image.format)))
14795 continue;
14796
14797 testParams.params.filter = VK_FILTER_NEAREST;
14798 const std::string testName =
14799 getBlitImageTilingLayoutCaseName(testParams.params.src.image.tiling,
14800 testParams.params.src.image.operationLayout) +
14801 "_" +
14802 getBlitImageTilingLayoutCaseName(testParams.params.dst.image.tiling,
14803 testParams.params.dst.image.operationLayout);
14804 group->addChild(new BlitImageTestCase(testCtx, testName + "_nearest", testParams.params));
14805
14806 if (testParams.testFilters & FILTER_MASK_LINEAR)
14807 {
14808 testParams.params.filter = VK_FILTER_LINEAR;
14809 group->addChild(new BlitImageTestCase(testCtx, testName + "_linear", testParams.params));
14810 }
14811
14812 if (testParams.testFilters & FILTER_MASK_CUBIC)
14813 {
14814 testParams.params.filter = VK_FILTER_CUBIC_EXT;
14815 group->addChild(new BlitImageTestCase(testCtx, testName + "_cubic", testParams.params));
14816 }
14817
14818 if ((testParams.params.src.image.imageType == VK_IMAGE_TYPE_3D) &&
14819 !isCompressedFormat(testParams.params.src.image.format))
14820 {
14821 const struct
14822 {
14823 FillMode mode;
14824 const char *name;
14825 } modeList[] = {
14826 {FILL_MODE_BLUE_RED_X, "x"},
14827 {FILL_MODE_BLUE_RED_Y, "y"},
14828 {FILL_MODE_BLUE_RED_Z, "z"},
14829 };
14830
14831 auto otherParams = testParams;
14832 otherParams.params.dst.image.fillMode = FILL_MODE_WHITE;
14833
14834 for (int i = 0; i < DE_LENGTH_OF_ARRAY(modeList); ++i)
14835 {
14836 otherParams.params.src.image.fillMode = modeList[i].mode;
14837
14838 otherParams.params.filter = VK_FILTER_LINEAR;
14839 group->addChild(new BlitImageTestCase(
14840 testCtx, testName + "_linear_stripes_" + modeList[i].name, otherParams.params));
14841
14842 otherParams.params.filter = VK_FILTER_NEAREST;
14843 group->addChild(new BlitImageTestCase(
14844 testCtx, testName + "_nearest_stripes_" + modeList[i].name, otherParams.params));
14845 }
14846 }
14847 }
14848 }
14849 }
14850 }
14851 }
14852
addBlittingImageAllFormatsColorSrcFormatTests(tcu::TestCaseGroup * group,BlitColorTestParams testParams)14853 void addBlittingImageAllFormatsColorSrcFormatTests(tcu::TestCaseGroup *group, BlitColorTestParams testParams)
14854 {
14855 VkFormat srcFormat = testParams.params.src.image.format;
14856
14857 if (testParams.compatibleFormats)
14858 {
14859 for (int dstFormatIndex = 0; testParams.compatibleFormats[dstFormatIndex] != VK_FORMAT_UNDEFINED;
14860 ++dstFormatIndex)
14861 {
14862 testParams.params.dst.image.format = testParams.compatibleFormats[dstFormatIndex];
14863 if (!isSupportedByFramework(testParams.params.dst.image.format))
14864 continue;
14865
14866 if (!isAllowedBlittingAllFormatsColorSrcFormatTests(testParams))
14867 continue;
14868
14869 addTestGroup(group, getFormatCaseName(testParams.params.dst.image.format),
14870 addBlittingImageAllFormatsColorSrcFormatDstFormatTests, testParams);
14871 }
14872 }
14873
14874 // If testParams.compatibleFormats is nullptr, the destination format will be copied from the source format
14875 // When testParams.compatibleFormats is not nullptr but format is compressed we also need to add that format
14876 // as it is not on compatibleFormats list
14877 if (!testParams.compatibleFormats || isCompressedFormat(srcFormat))
14878 {
14879 testParams.params.dst.image.format = srcFormat;
14880
14881 addTestGroup(group, getFormatCaseName(srcFormat), addBlittingImageAllFormatsColorSrcFormatDstFormatTests,
14882 testParams);
14883 }
14884 }
14885
14886 const VkFormat dedicatedAllocationBlittingFormatsToTest[] = {
14887 // compatibleFormatsUInts
14888 VK_FORMAT_R8_UINT,
14889 VK_FORMAT_R64G64B64A64_UINT,
14890
14891 // compatibleFormatsSInts
14892 VK_FORMAT_R8_SINT,
14893 VK_FORMAT_R64G64B64A64_SINT,
14894
14895 // compatibleFormatsFloats
14896 VK_FORMAT_R4G4_UNORM_PACK8,
14897 VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
14898
14899 // compatibleFormatsSrgb
14900 VK_FORMAT_R8_SRGB,
14901 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
14902 };
14903
14904 // skip cubic filtering test for the following data formats
14905 const FormatSet onlyNearestAndLinearFormatsToTest = {VK_FORMAT_A8B8G8R8_USCALED_PACK32,
14906 VK_FORMAT_A8B8G8R8_SSCALED_PACK32, VK_FORMAT_A8B8G8R8_UINT_PACK32,
14907 VK_FORMAT_A8B8G8R8_SINT_PACK32};
14908
14909 // astc formats have diferent block sizes and thus require diferent resolutions for images
14910 enum class AstcImageSizeType
14911 {
14912 SIZE_64_64 = 0,
14913 SIZE_60_64,
14914 SIZE_64_60,
14915 SIZE_60_60,
14916 };
14917
14918 const std::map<VkFormat, AstcImageSizeType> astcSizes{
14919 {VK_FORMAT_ASTC_4x4_SRGB_BLOCK, AstcImageSizeType::SIZE_64_64},
14920 {VK_FORMAT_ASTC_4x4_UNORM_BLOCK, AstcImageSizeType::SIZE_64_64},
14921 {VK_FORMAT_ASTC_5x4_SRGB_BLOCK, AstcImageSizeType::SIZE_60_64},
14922 {VK_FORMAT_ASTC_5x4_UNORM_BLOCK, AstcImageSizeType::SIZE_60_64},
14923 {VK_FORMAT_ASTC_5x5_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60},
14924 {VK_FORMAT_ASTC_5x5_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60},
14925 {VK_FORMAT_ASTC_6x5_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60},
14926 {VK_FORMAT_ASTC_6x5_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60},
14927 {VK_FORMAT_ASTC_6x6_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60},
14928 {VK_FORMAT_ASTC_6x6_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60},
14929 {VK_FORMAT_ASTC_8x5_SRGB_BLOCK, AstcImageSizeType::SIZE_64_60},
14930 {VK_FORMAT_ASTC_8x5_UNORM_BLOCK, AstcImageSizeType::SIZE_64_60},
14931 {VK_FORMAT_ASTC_8x6_SRGB_BLOCK, AstcImageSizeType::SIZE_64_60},
14932 {VK_FORMAT_ASTC_8x6_UNORM_BLOCK, AstcImageSizeType::SIZE_64_60},
14933 {VK_FORMAT_ASTC_8x8_SRGB_BLOCK, AstcImageSizeType::SIZE_64_64},
14934 {VK_FORMAT_ASTC_8x8_UNORM_BLOCK, AstcImageSizeType::SIZE_64_64},
14935 {VK_FORMAT_ASTC_10x5_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60},
14936 {VK_FORMAT_ASTC_10x5_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60},
14937 {VK_FORMAT_ASTC_10x6_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60},
14938 {VK_FORMAT_ASTC_10x6_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60},
14939 {VK_FORMAT_ASTC_10x8_SRGB_BLOCK, AstcImageSizeType::SIZE_60_64},
14940 {VK_FORMAT_ASTC_10x8_UNORM_BLOCK, AstcImageSizeType::SIZE_60_64},
14941 {VK_FORMAT_ASTC_10x10_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60},
14942 {VK_FORMAT_ASTC_10x10_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60},
14943 {VK_FORMAT_ASTC_12x10_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60},
14944 {VK_FORMAT_ASTC_12x10_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60},
14945 {VK_FORMAT_ASTC_12x12_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60},
14946 {VK_FORMAT_ASTC_12x12_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60}};
14947
create2DCopyRegions(int32_t srcWidth,int32_t srcHeight,int32_t dstWidth,int32_t dstHeight)14948 std::vector<CopyRegion> create2DCopyRegions(int32_t srcWidth, int32_t srcHeight, int32_t dstWidth, int32_t dstHeight)
14949 {
14950 CopyRegion region;
14951 std::vector<CopyRegion> regionsVector;
14952
14953 int32_t fourthOfSrcWidth = srcWidth / 4;
14954 int32_t fourthOfSrcHeight = srcHeight / 4;
14955 int32_t fourthOfDstWidth = dstWidth / 4;
14956 int32_t fourthOfDstHeight = dstHeight / 4;
14957
14958 // to the top of resulting image copy whole source image but with increasingly smaller sizes
14959 for (int i = 0, j = 1; (i + fourthOfDstWidth / j < dstWidth) && (fourthOfDstWidth > j); i += fourthOfDstWidth / j++)
14960 {
14961 region.imageBlit = {
14962 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
14963 {{0, 0, 0}, {srcWidth, srcHeight, 1}}, // VkOffset3D srcOffsets[2];
14964
14965 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
14966 {{i, 0, 0}, {i + fourthOfDstWidth / j, fourthOfDstHeight / j, 1}} // VkOffset3D dstOffset[2];
14967 };
14968 regionsVector.push_back(region);
14969 }
14970
14971 // to the bottom of resulting image copy parts of source image;
14972 for (int i = 0; i < 4; ++i)
14973 {
14974 int srcX = i * fourthOfSrcWidth;
14975 int srcY = i * fourthOfSrcHeight;
14976 int dstX = i * fourthOfDstWidth;
14977
14978 region.imageBlit = {
14979 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
14980 {{srcX, srcY, 0}, {srcX + fourthOfSrcWidth, srcY + fourthOfSrcHeight, 1}}, // VkOffset3D srcOffsets[2];
14981
14982 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
14983 {{dstX, 2 * fourthOfDstHeight, 0},
14984 {dstX + fourthOfDstWidth, 3 * fourthOfDstHeight, 1}} // VkOffset3D dstOffset[2];
14985 };
14986
14987 regionsVector.push_back(region);
14988 }
14989
14990 return regionsVector;
14991 }
14992
addBufferToImageTests(tcu::TestCaseGroup * group,TestGroupParamsPtr testGroupParams)14993 void addBufferToImageTests(tcu::TestCaseGroup *group, TestGroupParamsPtr testGroupParams)
14994 {
14995 addTestGroup(group, "1d_images", add1dBufferToImageTests, testGroupParams);
14996 addTestGroup(group, "2d_images", add2dBufferToImageTests, testGroupParams);
14997 }
14998
addImageToBufferTests(tcu::TestCaseGroup * group,TestGroupParamsPtr testGroupParams)14999 void addImageToBufferTests(tcu::TestCaseGroup *group, TestGroupParamsPtr testGroupParams)
15000 {
15001 addTestGroup(group, "1d_images", add1dImageToBufferTests, testGroupParams);
15002 addTestGroup(group, "2d_images", add2dImageToBufferTests, testGroupParams);
15003 }
15004
addBlittingImageAllFormatsColorTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)15005 void addBlittingImageAllFormatsColorTests(tcu::TestCaseGroup *group, AllocationKind allocationKind,
15006 uint32_t extensionFlags)
15007 {
15008 const struct
15009 {
15010 const VkFormat *sourceFormats;
15011 const VkFormat *destinationFormats;
15012 const bool onlyNearest;
15013 } colorImageFormatsToTestBlit[] = {
15014 {compatibleFormatsUInts, compatibleFormatsUInts, true},
15015 {compatibleFormatsSInts, compatibleFormatsSInts, true},
15016 {compatibleFormatsFloats, compatibleFormatsFloats, false},
15017 {compressedFormatsFloats, compatibleFormatsFloats, false},
15018 {compatibleFormatsSrgb, compatibleFormatsSrgb, false},
15019 {compressedFormatsSrgb, compatibleFormatsSrgb, false},
15020 };
15021
15022 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
15023
15024 if (allocationKind == ALLOCATION_KIND_DEDICATED)
15025 {
15026 const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
15027 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter;
15028 ++compatibleFormatsIndex)
15029 dedicatedAllocationBlittingFormatsToTestSet.insert(
15030 dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
15031 }
15032
15033 // 2D tests.
15034 {
15035 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d"));
15036
15037 TestParams params;
15038 params.src.image.imageType = VK_IMAGE_TYPE_2D;
15039 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
15040 params.src.image.extent = defaultExtent;
15041 params.dst.image.extent = defaultExtent;
15042 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
15043 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
15044 params.allocationKind = allocationKind;
15045 params.extensionFlags = extensionFlags;
15046
15047 // create all required copy regions
15048 const std::map<AstcImageSizeType, std::vector<CopyRegion>> imageRegions{
15049 {AstcImageSizeType::SIZE_64_64, create2DCopyRegions(64, 64, 64, 64)},
15050 {AstcImageSizeType::SIZE_60_64, create2DCopyRegions(60, 64, 60, 64)},
15051 {AstcImageSizeType::SIZE_64_60, create2DCopyRegions(64, 60, 64, 60)},
15052 {AstcImageSizeType::SIZE_60_60, create2DCopyRegions(60, 60, 60, 60)},
15053 };
15054
15055 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest;
15056 ++compatibleFormatsIndex)
15057 {
15058 const VkFormat *sourceFormats = colorImageFormatsToTestBlit[compatibleFormatsIndex].sourceFormats;
15059 const VkFormat *destinationFormats = colorImageFormatsToTestBlit[compatibleFormatsIndex].destinationFormats;
15060 const bool onlyNearest = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
15061 for (int srcFormatIndex = 0; sourceFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
15062 {
15063 VkFormat srcFormat = sourceFormats[srcFormatIndex];
15064 params.src.image.format = srcFormat;
15065
15066 const bool onlyNearestAndLinear =
15067 de::contains(onlyNearestAndLinearFormatsToTest, params.src.image.format);
15068
15069 // most of tests are using regions caluculated for 64x64 size but astc formats require custom regions
15070 params.regions = imageRegions.at(AstcImageSizeType::SIZE_64_64);
15071 if (isCompressedFormat(srcFormat) && isAstcFormat(mapVkCompressedFormat(srcFormat)))
15072 params.regions = imageRegions.at(astcSizes.at(srcFormat));
15073
15074 // use the fact that first region contains the size of full source image
15075 // and make source and destination the same size - this is needed for astc formats
15076 const VkOffset3D &srcImageSize = params.regions[0].imageBlit.srcOffsets[1];
15077 VkExtent3D &srcImageExtent = params.src.image.extent;
15078 VkExtent3D &dstImageExtent = params.dst.image.extent;
15079 srcImageExtent.width = srcImageSize.x;
15080 srcImageExtent.height = srcImageSize.y;
15081 dstImageExtent.width = srcImageSize.x;
15082 dstImageExtent.height = srcImageSize.y;
15083
15084 BlitColorTestParams testParams{params, destinationFormats,
15085 makeFilterMask(onlyNearest, onlyNearestAndLinear)};
15086
15087 addTestGroup(subGroup.get(), getFormatCaseName(params.src.image.format),
15088 addBlittingImageAllFormatsColorSrcFormatTests, testParams);
15089 }
15090 }
15091
15092 group->addChild(subGroup.release());
15093 }
15094
15095 // 1D tests.
15096 {
15097 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d"));
15098
15099 TestParams params;
15100 params.src.image.imageType = VK_IMAGE_TYPE_1D;
15101 params.dst.image.imageType = VK_IMAGE_TYPE_1D;
15102 params.src.image.extent = default1dExtent;
15103 params.dst.image.extent = default1dExtent;
15104 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
15105 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
15106 params.allocationKind = allocationKind;
15107 params.extensionFlags = extensionFlags;
15108
15109 CopyRegion region;
15110 for (int i = 0; i < defaultSize; i += defaultSize / 2)
15111 {
15112 const VkImageBlit imageBlit = {
15113 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
15114 {{0, 0, 0}, {defaultSize, 1, 1}}, // VkOffset3D srcOffsets[2];
15115
15116 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
15117 {{i, 0, 0}, {i + defaultQuarterSize, 1, 1}} // VkOffset3D dstOffset[2];
15118 };
15119 region.imageBlit = imageBlit;
15120 params.regions.push_back(region);
15121 }
15122
15123 {
15124 const VkImageBlit imageBlit = {
15125 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
15126 {{0, 0, 0}, {defaultQuarterSize, 1, 1}}, // VkOffset3D srcOffsets[2];
15127
15128 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
15129 {{defaultQuarterSize, 0, 0}, {2 * defaultQuarterSize, 1, 1}} // VkOffset3D dstOffset[2];
15130 };
15131 region.imageBlit = imageBlit;
15132 params.regions.push_back(region);
15133 }
15134
15135 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest;
15136 ++compatibleFormatsIndex)
15137 {
15138 const VkFormat *sourceFormats = colorImageFormatsToTestBlit[compatibleFormatsIndex].sourceFormats;
15139 const bool onlyNearest = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
15140 for (int srcFormatIndex = 0; sourceFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
15141 {
15142 params.src.image.format = sourceFormats[srcFormatIndex];
15143 if (!isSupportedByFramework(params.src.image.format))
15144 continue;
15145
15146 // Cubic filtering can only be used with 2D images.
15147 const bool onlyNearestAndLinear = true;
15148
15149 BlitColorTestParams testParams{params, nullptr, makeFilterMask(onlyNearest, onlyNearestAndLinear)};
15150
15151 addTestGroup(subGroup.get(), getFormatCaseName(params.src.image.format),
15152 addBlittingImageAllFormatsColorSrcFormatTests, testParams);
15153 }
15154 }
15155
15156 group->addChild(subGroup.release());
15157 }
15158
15159 // 3D tests. Note we use smaller dimensions here for performance reasons.
15160 {
15161 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d"));
15162
15163 TestParams params;
15164 params.src.image.imageType = VK_IMAGE_TYPE_3D;
15165 params.dst.image.imageType = VK_IMAGE_TYPE_3D;
15166 params.src.image.extent = default3dExtent;
15167 params.dst.image.extent = default3dExtent;
15168 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
15169 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
15170 params.allocationKind = allocationKind;
15171 params.extensionFlags = extensionFlags;
15172
15173 CopyRegion region;
15174 for (int i = 0, j = 1; (i + defaultSixteenthSize / j < defaultQuarterSize) && (defaultSixteenthSize > j);
15175 i += defaultSixteenthSize / j++)
15176 {
15177 const VkImageBlit imageBlit = {
15178 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
15179 {{0, 0, 0}, {defaultQuarterSize, defaultQuarterSize, defaultQuarterSize}}, // VkOffset3D srcOffsets[2];
15180
15181 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
15182 {{i, 0, i},
15183 {i + defaultSixteenthSize / j, defaultSixteenthSize / j,
15184 i + defaultSixteenthSize / j}} // VkOffset3D dstOffset[2];
15185 };
15186 region.imageBlit = imageBlit;
15187 params.regions.push_back(region);
15188 }
15189 for (int i = 0; i < defaultQuarterSize; i += defaultSixteenthSize)
15190 {
15191 const VkImageBlit imageBlit = {
15192 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
15193 {{i, i, i},
15194 {i + defaultSixteenthSize, i + defaultSixteenthSize,
15195 i + defaultSixteenthSize}}, // VkOffset3D srcOffsets[2];
15196
15197 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
15198 {{i, defaultQuarterSize / 2, i},
15199 {i + defaultSixteenthSize, defaultQuarterSize / 2 + defaultSixteenthSize,
15200 i + defaultSixteenthSize}} // VkOffset3D dstOffset[2];
15201 };
15202 region.imageBlit = imageBlit;
15203 params.regions.push_back(region);
15204 }
15205
15206 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest;
15207 ++compatibleFormatsIndex)
15208 {
15209 const VkFormat *sourceFormats = colorImageFormatsToTestBlit[compatibleFormatsIndex].sourceFormats;
15210 const bool onlyNearest = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
15211 for (int srcFormatIndex = 0; sourceFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
15212 {
15213 params.src.image.format = sourceFormats[srcFormatIndex];
15214 if (!isSupportedByFramework(params.src.image.format))
15215 continue;
15216
15217 // Cubic filtering can only be used with 2D images.
15218 const bool onlyNearestAndLinear = true;
15219
15220 BlitColorTestParams testParams{params, nullptr, makeFilterMask(onlyNearest, onlyNearestAndLinear)};
15221
15222 addTestGroup(subGroup.get(), getFormatCaseName(params.src.image.format),
15223 addBlittingImageAllFormatsColorSrcFormatTests, testParams);
15224 }
15225 }
15226
15227 group->addChild(subGroup.release());
15228 }
15229 }
15230
addBlittingImageAllFormatsDepthStencilFormatsTests(tcu::TestCaseGroup * group,TestParams params)15231 void addBlittingImageAllFormatsDepthStencilFormatsTests(tcu::TestCaseGroup *group, TestParams params)
15232 {
15233 const VkImageLayout blitSrcLayouts[] = {VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL};
15234 const VkImageLayout blitDstLayouts[] = {VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL};
15235
15236 for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
15237 {
15238 params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx];
15239
15240 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
15241 {
15242 params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx];
15243 params.filter = VK_FILTER_NEAREST;
15244
15245 const std::string testName = getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
15246 getImageLayoutCaseName(params.dst.image.operationLayout);
15247
15248 group->addChild(new BlitImageTestCase(group->getTestContext(), testName + "_nearest", params));
15249 }
15250 }
15251 }
15252
addBlittingImageAllFormatsDepthStencilTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)15253 void addBlittingImageAllFormatsDepthStencilTests(tcu::TestCaseGroup *group, AllocationKind allocationKind,
15254 uint32_t extensionFlags)
15255 {
15256 const VkFormat depthAndStencilFormats[] = {
15257 VK_FORMAT_D16_UNORM, VK_FORMAT_X8_D24_UNORM_PACK32, VK_FORMAT_D32_SFLOAT, VK_FORMAT_S8_UINT,
15258 VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT,
15259 };
15260
15261 const VkImageSubresourceLayers defaultDepthSourceLayer = {VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u};
15262 const VkImageSubresourceLayers defaultStencilSourceLayer = {VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u};
15263 const VkImageSubresourceLayers defaultDSSourceLayer = {VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u,
15264 0u, 1u};
15265
15266 // 2D tests
15267 {
15268 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d"));
15269
15270 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats);
15271 ++compatibleFormatsIndex)
15272 {
15273 TestParams params;
15274 params.src.image.imageType = VK_IMAGE_TYPE_2D;
15275 params.src.image.extent = defaultExtent;
15276 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
15277 params.src.image.format = depthAndStencilFormats[compatibleFormatsIndex];
15278 params.dst.image.extent = defaultExtent;
15279 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
15280 params.dst.image.format = params.src.image.format;
15281 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
15282 params.allocationKind = allocationKind;
15283 params.extensionFlags = extensionFlags;
15284
15285 bool hasDepth = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
15286 bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
15287
15288 CopyRegion region;
15289 for (int i = 0, j = 1; (i + defaultQuarterSize / j < defaultSize) && (defaultQuarterSize > j);
15290 i += defaultQuarterSize / j++)
15291 {
15292 const VkOffset3D srcOffset0 = {0, 0, 0};
15293 const VkOffset3D srcOffset1 = {defaultSize, defaultSize, 1};
15294 const VkOffset3D dstOffset0 = {i, 0, 0};
15295 const VkOffset3D dstOffset1 = {i + defaultQuarterSize / j, defaultQuarterSize / j, 1};
15296
15297 if (hasDepth)
15298 {
15299 const VkImageBlit imageBlit = {
15300 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
15301 {srcOffset0, srcOffset1}, // VkOffset3D srcOffsets[2];
15302 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
15303 {dstOffset0, dstOffset1}, // VkOffset3D dstOffset[2];
15304 };
15305 region.imageBlit = imageBlit;
15306 params.regions.push_back(region);
15307 }
15308 if (hasStencil)
15309 {
15310 const VkImageBlit imageBlit = {
15311 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
15312 {srcOffset0, srcOffset1}, // VkOffset3D srcOffsets[2];
15313 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
15314 {dstOffset0, dstOffset1}, // VkOffset3D dstOffset[2];
15315 };
15316 region.imageBlit = imageBlit;
15317 params.regions.push_back(region);
15318 }
15319 }
15320 for (int i = 0; i < defaultSize; i += defaultQuarterSize)
15321 {
15322 const VkOffset3D srcOffset0 = {i, i, 0};
15323 const VkOffset3D srcOffset1 = {i + defaultQuarterSize, i + defaultQuarterSize, 1};
15324 const VkOffset3D dstOffset0 = {i, defaultSize / 2, 0};
15325 const VkOffset3D dstOffset1 = {i + defaultQuarterSize, defaultSize / 2 + defaultQuarterSize, 1};
15326
15327 if (hasDepth)
15328 {
15329 const VkImageBlit imageBlit = {
15330 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
15331 {srcOffset0, srcOffset1}, // VkOffset3D srcOffsets[2];
15332 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
15333 {dstOffset0, dstOffset1} // VkOffset3D dstOffset[2];
15334 };
15335 region.imageBlit = imageBlit;
15336 params.regions.push_back(region);
15337 }
15338 if (hasStencil)
15339 {
15340 const VkImageBlit imageBlit = {
15341 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
15342 {srcOffset0, srcOffset1}, // VkOffset3D srcOffsets[2];
15343 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
15344 {dstOffset0, dstOffset1} // VkOffset3D dstOffset[2];
15345 };
15346 region.imageBlit = imageBlit;
15347 params.regions.push_back(region);
15348 }
15349 if (hasDepth && hasStencil)
15350 {
15351 const VkOffset3D dstDSOffset0 = {i, 3 * defaultQuarterSize, 0};
15352 const VkOffset3D dstDSOffset1 = {i + defaultQuarterSize, defaultSize, 1};
15353 const VkImageBlit imageBlit = {
15354 defaultDSSourceLayer, // VkImageSubresourceLayers srcSubresource;
15355 {srcOffset0, srcOffset1}, // VkOffset3D srcOffsets[2];
15356 defaultDSSourceLayer, // VkImageSubresourceLayers dstSubresource;
15357 {dstDSOffset0, dstDSOffset1} // VkOffset3D dstOffset[2];
15358 };
15359 region.imageBlit = imageBlit;
15360 params.regions.push_back(region);
15361 }
15362 }
15363
15364 const std::string testName =
15365 getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
15366 addTestGroup(subGroup.get(), testName, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
15367
15368 if (hasDepth && hasStencil)
15369 {
15370 params.extensionFlags |= SEPARATE_DEPTH_STENCIL_LAYOUT;
15371 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" +
15372 getFormatCaseName(params.dst.image.format) + "_separate_layouts";
15373 addTestGroup(subGroup.get(), testName2, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
15374 }
15375 }
15376
15377 group->addChild(subGroup.release());
15378 }
15379
15380 // 1D tests
15381 {
15382 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d"));
15383
15384 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats);
15385 ++compatibleFormatsIndex)
15386 {
15387 TestParams params;
15388 params.src.image.imageType = VK_IMAGE_TYPE_1D;
15389 params.dst.image.imageType = VK_IMAGE_TYPE_1D;
15390 params.src.image.extent = default1dExtent;
15391 params.dst.image.extent = default1dExtent;
15392 params.src.image.format = depthAndStencilFormats[compatibleFormatsIndex];
15393 params.dst.image.format = params.src.image.format;
15394 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
15395 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
15396 params.allocationKind = allocationKind;
15397 params.extensionFlags = extensionFlags;
15398
15399 bool hasDepth = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
15400 bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
15401
15402 CopyRegion region;
15403 for (int i = 0; i < defaultSize; i += defaultSize / 2)
15404 {
15405 const VkOffset3D srcOffset0 = {0, 0, 0};
15406 const VkOffset3D srcOffset1 = {defaultSize, 1, 1};
15407 const VkOffset3D dstOffset0 = {i, 0, 0};
15408 const VkOffset3D dstOffset1 = {i + defaultQuarterSize, 1, 1};
15409
15410 if (hasDepth)
15411 {
15412 const VkImageBlit imageBlit = {
15413 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
15414 {srcOffset0, srcOffset1}, // VkOffset3D srcOffsets[2];
15415 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
15416 {dstOffset0, dstOffset1}, // VkOffset3D dstOffset[2];
15417 };
15418 region.imageBlit = imageBlit;
15419 params.regions.push_back(region);
15420 }
15421 if (hasStencil)
15422 {
15423 const VkImageBlit imageBlit = {
15424 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
15425 {srcOffset0, srcOffset1}, // VkOffset3D srcOffsets[2];
15426 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
15427 {dstOffset0, dstOffset1}, // VkOffset3D dstOffset[2];
15428 };
15429 region.imageBlit = imageBlit;
15430 params.regions.push_back(region);
15431 }
15432 }
15433
15434 {
15435 const VkOffset3D srcOffset0 = {0, 0, 0};
15436 const VkOffset3D srcOffset1 = {defaultQuarterSize, 1, 1};
15437 const VkOffset3D dstOffset0 = {defaultQuarterSize, 0, 0};
15438 const VkOffset3D dstOffset1 = {2 * defaultQuarterSize, 1, 1};
15439
15440 if (hasDepth)
15441 {
15442 const VkImageBlit imageBlit = {
15443 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
15444 {srcOffset0, srcOffset1}, // VkOffset3D srcOffsets[2];
15445 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
15446 {dstOffset0, dstOffset1} // VkOffset3D dstOffset[2];
15447 };
15448 region.imageBlit = imageBlit;
15449 params.regions.push_back(region);
15450 }
15451 if (hasStencil)
15452 {
15453 const VkImageBlit imageBlit = {
15454 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
15455 {srcOffset0, srcOffset1}, // VkOffset3D srcOffsets[2];
15456 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
15457 {dstOffset0, dstOffset1} // VkOffset3D dstOffset[2];
15458 };
15459 region.imageBlit = imageBlit;
15460 params.regions.push_back(region);
15461 }
15462 if (hasDepth && hasStencil)
15463 {
15464 const VkOffset3D dstDSOffset0 = {3 * defaultQuarterSize, 0, 0};
15465 const VkOffset3D dstDSOffset1 = {3 * defaultQuarterSize + defaultQuarterSize / 2, 1, 1};
15466 const VkImageBlit imageBlit = {
15467 defaultDSSourceLayer, // VkImageSubresourceLayers srcSubresource;
15468 {srcOffset0, srcOffset1}, // VkOffset3D srcOffsets[2];
15469 defaultDSSourceLayer, // VkImageSubresourceLayers dstSubresource;
15470 {dstDSOffset0, dstDSOffset1} // VkOffset3D dstOffset[2];
15471 };
15472 region.imageBlit = imageBlit;
15473 params.regions.push_back(region);
15474 }
15475 }
15476
15477 const std::string testName =
15478 getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
15479 addTestGroup(subGroup.get(), testName, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
15480
15481 if (hasDepth && hasStencil)
15482 {
15483 params.extensionFlags |= SEPARATE_DEPTH_STENCIL_LAYOUT;
15484 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" +
15485 getFormatCaseName(params.dst.image.format) + "_separate_layouts";
15486 addTestGroup(subGroup.get(), testName2, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
15487 }
15488 }
15489
15490 group->addChild(subGroup.release());
15491 }
15492
15493 // 3D tests. Note we use smaller dimensions here for performance reasons.
15494 {
15495 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d"));
15496
15497 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats);
15498 ++compatibleFormatsIndex)
15499 {
15500 TestParams params;
15501 params.src.image.imageType = VK_IMAGE_TYPE_3D;
15502 params.dst.image.imageType = VK_IMAGE_TYPE_3D;
15503 params.src.image.extent = default3dExtent;
15504 params.dst.image.extent = default3dExtent;
15505 params.src.image.format = depthAndStencilFormats[compatibleFormatsIndex];
15506 params.dst.image.format = params.src.image.format;
15507 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
15508 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
15509 params.allocationKind = allocationKind;
15510 params.extensionFlags = extensionFlags;
15511
15512 bool hasDepth = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
15513 bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
15514
15515 CopyRegion region;
15516 for (int i = 0, j = 1; (i + defaultSixteenthSize / j < defaultQuarterSize) && (defaultSixteenthSize > j);
15517 i += defaultSixteenthSize / j++)
15518 {
15519 const VkOffset3D srcOffset0 = {0, 0, 0};
15520 const VkOffset3D srcOffset1 = {defaultQuarterSize, defaultQuarterSize, defaultQuarterSize};
15521 const VkOffset3D dstOffset0 = {i, 0, i};
15522 const VkOffset3D dstOffset1 = {i + defaultSixteenthSize / j, defaultSixteenthSize / j,
15523 i + defaultSixteenthSize / j};
15524
15525 if (hasDepth)
15526 {
15527 const VkImageBlit imageBlit = {
15528 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
15529 {srcOffset0, srcOffset1}, // VkOffset3D srcOffsets[2];
15530 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
15531 {dstOffset0, dstOffset1}, // VkOffset3D dstOffset[2];
15532 };
15533 region.imageBlit = imageBlit;
15534 params.regions.push_back(region);
15535 }
15536 if (hasStencil)
15537 {
15538 const VkImageBlit imageBlit = {
15539 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
15540 {srcOffset0, srcOffset1}, // VkOffset3D srcOffsets[2];
15541 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
15542 {dstOffset0, dstOffset1}, // VkOffset3D dstOffset[2];
15543 };
15544 region.imageBlit = imageBlit;
15545 params.regions.push_back(region);
15546 }
15547 }
15548 for (int i = 0; i < defaultQuarterSize; i += defaultSixteenthSize)
15549 {
15550 const VkOffset3D srcOffset0 = {i, i, i};
15551 const VkOffset3D srcOffset1 = {i + defaultSixteenthSize, i + defaultSixteenthSize,
15552 i + defaultSixteenthSize};
15553 const VkOffset3D dstOffset0 = {i, defaultQuarterSize / 2, i};
15554 const VkOffset3D dstOffset1 = {i + defaultSixteenthSize, defaultQuarterSize / 2 + defaultSixteenthSize,
15555 i + defaultSixteenthSize};
15556
15557 if (hasDepth)
15558 {
15559 const VkImageBlit imageBlit = {
15560 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
15561 {srcOffset0, srcOffset1}, // VkOffset3D srcOffsets[2];
15562 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
15563 {dstOffset0, dstOffset1} // VkOffset3D dstOffset[2];
15564 };
15565 region.imageBlit = imageBlit;
15566 params.regions.push_back(region);
15567 }
15568 if (hasStencil)
15569 {
15570 const VkImageBlit imageBlit = {
15571 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
15572 {srcOffset0, srcOffset1}, // VkOffset3D srcOffsets[2];
15573 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
15574 {dstOffset0, dstOffset1} // VkOffset3D dstOffset[2];
15575 };
15576 region.imageBlit = imageBlit;
15577 params.regions.push_back(region);
15578 }
15579 if (hasDepth && hasStencil)
15580 {
15581 const VkOffset3D dstDSOffset0 = {i, 3 * defaultSixteenthSize, i};
15582 const VkOffset3D dstDSOffset1 = {i + defaultSixteenthSize, defaultQuarterSize,
15583 i + defaultSixteenthSize};
15584 const VkImageBlit imageBlit = {
15585 defaultDSSourceLayer, // VkImageSubresourceLayers srcSubresource;
15586 {srcOffset0, srcOffset1}, // VkOffset3D srcOffsets[2];
15587 defaultDSSourceLayer, // VkImageSubresourceLayers dstSubresource;
15588 {dstDSOffset0, dstDSOffset1} // VkOffset3D dstOffset[2];
15589 };
15590 region.imageBlit = imageBlit;
15591 params.regions.push_back(region);
15592 }
15593 }
15594
15595 const std::string testName =
15596 getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
15597 addTestGroup(subGroup.get(), testName, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
15598
15599 if (hasDepth && hasStencil)
15600 {
15601 params.extensionFlags |= SEPARATE_DEPTH_STENCIL_LAYOUT;
15602 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" +
15603 getFormatCaseName(params.dst.image.format) + "_separate_layouts";
15604 addTestGroup(subGroup.get(), testName2, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
15605 }
15606 }
15607
15608 group->addChild(subGroup.release());
15609 }
15610 }
15611
addBlittingImageAllFormatsMipmapFormatTests(tcu::TestCaseGroup * group,BlitColorTestParams testParams)15612 void addBlittingImageAllFormatsMipmapFormatTests(tcu::TestCaseGroup *group, BlitColorTestParams testParams)
15613 {
15614 tcu::TestContext &testCtx = group->getTestContext();
15615
15616 const VkImageLayout blitSrcLayouts[] = {VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL};
15617 const VkImageLayout blitDstLayouts[] = {VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL};
15618
15619 for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
15620 {
15621 testParams.params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx];
15622 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
15623 {
15624 testParams.params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx];
15625
15626 testParams.params.filter = VK_FILTER_NEAREST;
15627 const std::string testName = getImageLayoutCaseName(testParams.params.src.image.operationLayout) + "_" +
15628 getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
15629 group->addChild(new BlitMipmapTestCase(testCtx, testName + "_nearest", testParams.params));
15630
15631 if (testParams.testFilters & FILTER_MASK_LINEAR)
15632 {
15633 testParams.params.filter = VK_FILTER_LINEAR;
15634 group->addChild(new BlitMipmapTestCase(testCtx, testName + "_linear", testParams.params));
15635 }
15636
15637 if (testParams.testFilters & FILTER_MASK_CUBIC)
15638 {
15639 testParams.params.filter = VK_FILTER_CUBIC_EXT;
15640 group->addChild(new BlitMipmapTestCase(testCtx, testName + "_cubic", testParams.params));
15641 }
15642 }
15643 }
15644 }
15645
addBlittingImageAllFormatsBaseLevelMipmapTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)15646 void addBlittingImageAllFormatsBaseLevelMipmapTests(tcu::TestCaseGroup *group, AllocationKind allocationKind,
15647 uint32_t extensionFlags)
15648 {
15649 const struct
15650 {
15651 const VkFormat *const compatibleFormats;
15652 const bool onlyNearest;
15653 } colorImageFormatsToTestBlit[] = {
15654 {compatibleFormatsUInts, true},
15655 {compatibleFormatsSInts, true},
15656 {compatibleFormatsFloats, false},
15657 {compatibleFormatsSrgb, false},
15658 };
15659
15660 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
15661
15662 const int layerCountsToTest[] = {1, 6};
15663
15664 TestParams params;
15665 params.src.image.imageType = VK_IMAGE_TYPE_2D;
15666 params.src.image.extent = defaultExtent;
15667 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
15668 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
15669 params.dst.image.extent = defaultExtent;
15670 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
15671 params.allocationKind = allocationKind;
15672 params.extensionFlags = extensionFlags;
15673 params.mipLevels = deLog2Floor32(deMaxu32(defaultExtent.width, defaultExtent.height)) + 1u;
15674 params.singleCommand = true;
15675
15676 CopyRegion region;
15677 for (uint32_t mipLevelNdx = 0u; mipLevelNdx < params.mipLevels; mipLevelNdx++)
15678 {
15679 VkImageSubresourceLayers destLayer = defaultSourceLayer;
15680 destLayer.mipLevel = mipLevelNdx;
15681
15682 const VkImageBlit imageBlit = {
15683 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
15684 {{0, 0, 0}, {defaultSize, defaultSize, 1}}, // VkOffset3D srcOffsets[2];
15685
15686 destLayer, // VkImageSubresourceLayers dstSubresource;
15687 {{0, 0, 0}, {defaultSize >> mipLevelNdx, defaultSize >> mipLevelNdx, 1}} // VkOffset3D dstOffset[2];
15688 };
15689 region.imageBlit = imageBlit;
15690 params.regions.push_back(region);
15691 }
15692
15693 if (allocationKind == ALLOCATION_KIND_DEDICATED)
15694 {
15695 const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
15696 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter;
15697 ++compatibleFormatsIndex)
15698 dedicatedAllocationBlittingFormatsToTestSet.insert(
15699 dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
15700 }
15701
15702 for (int layerCountIndex = 0; layerCountIndex < DE_LENGTH_OF_ARRAY(layerCountsToTest); layerCountIndex++)
15703 {
15704 const int layerCount = layerCountsToTest[layerCountIndex];
15705 const std::string layerGroupName = "layercount_" + de::toString(layerCount);
15706
15707 de::MovePtr<tcu::TestCaseGroup> layerCountGroup(
15708 new tcu::TestCaseGroup(group->getTestContext(), layerGroupName.c_str()));
15709
15710 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest;
15711 ++compatibleFormatsIndex)
15712 {
15713 const VkFormat *compatibleFormats = colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
15714 const bool onlyNearest = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
15715
15716 for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
15717 {
15718 params.src.image.format = compatibleFormats[srcFormatIndex];
15719 params.dst.image.format = compatibleFormats[srcFormatIndex];
15720
15721 if (!isSupportedByFramework(params.src.image.format))
15722 continue;
15723
15724 const bool onlyNearestAndLinear =
15725 de::contains(onlyNearestAndLinearFormatsToTest, params.src.image.format);
15726
15727 BlitColorTestParams testParams;
15728 testParams.params = params;
15729 testParams.compatibleFormats = compatibleFormats;
15730 testParams.testFilters = makeFilterMask(onlyNearest, onlyNearestAndLinear);
15731
15732 testParams.params.src.image.extent.depth = layerCount;
15733 testParams.params.dst.image.extent.depth = layerCount;
15734
15735 for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
15736 {
15737 testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
15738 testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
15739 }
15740
15741 addTestGroup(layerCountGroup.get(), getFormatCaseName(params.src.image.format),
15742 addBlittingImageAllFormatsMipmapFormatTests, testParams);
15743 }
15744 }
15745 group->addChild(layerCountGroup.release());
15746 }
15747 }
15748
addBlittingImageAllFormatsPreviousLevelMipmapTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)15749 void addBlittingImageAllFormatsPreviousLevelMipmapTests(tcu::TestCaseGroup *group, AllocationKind allocationKind,
15750 uint32_t extensionFlags)
15751 {
15752 const struct
15753 {
15754 const VkFormat *const compatibleFormats;
15755 const bool onlyNearest;
15756 } colorImageFormatsToTestBlit[] = {
15757 {compatibleFormatsUInts, true},
15758 {compatibleFormatsSInts, true},
15759 {compatibleFormatsFloats, false},
15760 {compatibleFormatsSrgb, false},
15761 };
15762
15763 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
15764
15765 const int layerCountsToTest[] = {1, 6};
15766
15767 TestParams params;
15768 params.src.image.imageType = VK_IMAGE_TYPE_2D;
15769 params.src.image.extent = defaultExtent;
15770 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
15771 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
15772 params.dst.image.extent = defaultExtent;
15773 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
15774 params.allocationKind = allocationKind;
15775 params.extensionFlags = extensionFlags;
15776 params.mipLevels = deLog2Floor32(deMaxu32(defaultExtent.width, defaultExtent.height)) + 1u;
15777 params.singleCommand = false;
15778
15779 CopyRegion region;
15780 for (uint32_t mipLevelNdx = 1u; mipLevelNdx < params.mipLevels; mipLevelNdx++)
15781 {
15782 VkImageSubresourceLayers srcLayer = defaultSourceLayer;
15783 VkImageSubresourceLayers destLayer = defaultSourceLayer;
15784
15785 srcLayer.mipLevel = mipLevelNdx - 1u;
15786 destLayer.mipLevel = mipLevelNdx;
15787
15788 const VkImageBlit imageBlit = {
15789 srcLayer, // VkImageSubresourceLayers srcSubresource;
15790 {{0, 0, 0},
15791 {defaultSize >> (mipLevelNdx - 1u), defaultSize >> (mipLevelNdx - 1u), 1}}, // VkOffset3D srcOffsets[2];
15792
15793 destLayer, // VkImageSubresourceLayers dstSubresource;
15794 {{0, 0, 0}, {defaultSize >> mipLevelNdx, defaultSize >> mipLevelNdx, 1}} // VkOffset3D dstOffset[2];
15795 };
15796 region.imageBlit = imageBlit;
15797 params.regions.push_back(region);
15798 }
15799
15800 if (allocationKind == ALLOCATION_KIND_DEDICATED)
15801 {
15802 const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
15803 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter;
15804 ++compatibleFormatsIndex)
15805 dedicatedAllocationBlittingFormatsToTestSet.insert(
15806 dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
15807 }
15808
15809 for (int layerCountIndex = 0; layerCountIndex < DE_LENGTH_OF_ARRAY(layerCountsToTest); layerCountIndex++)
15810 {
15811 const int layerCount = layerCountsToTest[layerCountIndex];
15812 const std::string layerGroupName = "layercount_" + de::toString(layerCount);
15813
15814 de::MovePtr<tcu::TestCaseGroup> layerCountGroup(
15815 new tcu::TestCaseGroup(group->getTestContext(), layerGroupName.c_str()));
15816
15817 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest;
15818 ++compatibleFormatsIndex)
15819 {
15820 const VkFormat *compatibleFormats = colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
15821 const bool onlyNearest = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
15822
15823 for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
15824 {
15825 params.src.image.format = compatibleFormats[srcFormatIndex];
15826 params.dst.image.format = compatibleFormats[srcFormatIndex];
15827
15828 if (!isSupportedByFramework(params.src.image.format))
15829 continue;
15830
15831 const bool onlyNearestAndLinear =
15832 de::contains(onlyNearestAndLinearFormatsToTest, params.src.image.format);
15833
15834 BlitColorTestParams testParams;
15835 testParams.params = params;
15836 testParams.compatibleFormats = compatibleFormats;
15837 testParams.testFilters = makeFilterMask(onlyNearest, onlyNearestAndLinear);
15838
15839 testParams.params.src.image.extent.depth = layerCount;
15840 testParams.params.dst.image.extent.depth = layerCount;
15841
15842 for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
15843 {
15844 testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
15845 testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
15846 }
15847
15848 addTestGroup(layerCountGroup.get(), getFormatCaseName(params.src.image.format),
15849 addBlittingImageAllFormatsMipmapFormatTests, testParams);
15850 }
15851 }
15852 group->addChild(layerCountGroup.release());
15853 }
15854
15855 for (int multiLayer = 0; multiLayer < 2; multiLayer++)
15856 {
15857 const int layerCount = multiLayer ? 6 : 1;
15858
15859 for (int barrierCount = 1; barrierCount < 4; barrierCount++)
15860 {
15861 if (layerCount != 1 || barrierCount != 1)
15862 {
15863 const std::string barrierGroupName =
15864 (multiLayer ? "layerbarriercount_" : "mipbarriercount_") + de::toString(barrierCount);
15865
15866 de::MovePtr<tcu::TestCaseGroup> barrierCountGroup(
15867 new tcu::TestCaseGroup(group->getTestContext(), barrierGroupName.c_str()));
15868
15869 params.barrierCount = barrierCount;
15870
15871 // Only go through a few common formats
15872 for (int srcFormatIndex = 2; srcFormatIndex < 6; ++srcFormatIndex)
15873 {
15874 params.src.image.format = compatibleFormatsUInts[srcFormatIndex];
15875 params.dst.image.format = compatibleFormatsUInts[srcFormatIndex];
15876
15877 if (!isSupportedByFramework(params.src.image.format))
15878 continue;
15879
15880 BlitColorTestParams testParams;
15881 testParams.params = params;
15882 testParams.compatibleFormats = compatibleFormatsUInts;
15883 testParams.testFilters = FILTER_MASK_NEAREST;
15884
15885 testParams.params.src.image.extent.depth = layerCount;
15886 testParams.params.dst.image.extent.depth = layerCount;
15887
15888 for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
15889 {
15890 testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
15891 testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
15892 }
15893
15894 addTestGroup(barrierCountGroup.get(), getFormatCaseName(params.src.image.format),
15895 addBlittingImageAllFormatsMipmapFormatTests, testParams);
15896 }
15897 group->addChild(barrierCountGroup.release());
15898 }
15899 }
15900 }
15901 }
15902
addBlittingImageAllFormatsMipmapTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)15903 void addBlittingImageAllFormatsMipmapTests(tcu::TestCaseGroup *group, AllocationKind allocationKind,
15904 uint32_t extensionFlags)
15905 {
15906 addTestGroup(group, "from_base_level", addBlittingImageAllFormatsBaseLevelMipmapTests, allocationKind,
15907 extensionFlags);
15908 addTestGroup(group, "from_previous_level", addBlittingImageAllFormatsPreviousLevelMipmapTests, allocationKind,
15909 extensionFlags);
15910 }
15911
addBlittingImageAllFormatsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)15912 void addBlittingImageAllFormatsTests(tcu::TestCaseGroup *group, AllocationKind allocationKind, uint32_t extensionFlags)
15913 {
15914 addTestGroup(group, "color", addBlittingImageAllFormatsColorTests, allocationKind, extensionFlags);
15915 addTestGroup(group, "depth_stencil", addBlittingImageAllFormatsDepthStencilTests, allocationKind, extensionFlags);
15916 addTestGroup(group, "generate_mipmaps", addBlittingImageAllFormatsMipmapTests, allocationKind, extensionFlags);
15917 }
15918
addBlittingImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)15919 void addBlittingImageTests(tcu::TestCaseGroup *group, AllocationKind allocationKind, uint32_t extensionFlags)
15920 {
15921 addTestGroup(group, "simple_tests", addBlittingImageSimpleTests, allocationKind, extensionFlags);
15922 addTestGroup(group, "all_formats", addBlittingImageAllFormatsTests, allocationKind, extensionFlags);
15923 }
15924
15925 const VkSampleCountFlagBits samples[] = {VK_SAMPLE_COUNT_2_BIT, VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_8_BIT,
15926 VK_SAMPLE_COUNT_16_BIT, VK_SAMPLE_COUNT_32_BIT, VK_SAMPLE_COUNT_64_BIT};
15927 const VkExtent3D resolveExtent = {256u, 256u, 1};
15928
addResolveImageWholeTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)15929 void addResolveImageWholeTests(tcu::TestCaseGroup *group, AllocationKind allocationKind, uint32_t extensionFlags)
15930 {
15931 TestParams params;
15932 params.src.image.imageType = VK_IMAGE_TYPE_2D;
15933 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
15934 params.src.image.extent = resolveExtent;
15935 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
15936 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
15937 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
15938 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
15939 params.dst.image.extent = resolveExtent;
15940 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
15941 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
15942 params.allocationKind = allocationKind;
15943 params.extensionFlags = extensionFlags;
15944
15945 {
15946 const VkImageSubresourceLayers sourceLayer = {
15947 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
15948 0u, // uint32_t mipLevel;
15949 0u, // uint32_t baseArrayLayer;
15950 1u // uint32_t layerCount;
15951 };
15952 const VkImageResolve testResolve = {
15953 sourceLayer, // VkImageSubresourceLayers srcSubresource;
15954 {0, 0, 0}, // VkOffset3D srcOffset;
15955 sourceLayer, // VkImageSubresourceLayers dstSubresource;
15956 {0, 0, 0}, // VkOffset3D dstOffset;
15957 resolveExtent, // VkExtent3D extent;
15958 };
15959
15960 CopyRegion imageResolve;
15961 imageResolve.imageResolve = testResolve;
15962 params.regions.push_back(imageResolve);
15963 }
15964
15965 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
15966 {
15967 params.imageOffset = false;
15968 params.samples = samples[samplesIndex];
15969 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(),
15970 getSampleCountCaseName(samples[samplesIndex]), params));
15971 params.imageOffset = true;
15972 if (allocationKind != ALLOCATION_KIND_DEDICATED)
15973 {
15974 group->addChild(new ResolveImageToImageTestCase(
15975 group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", params));
15976 }
15977 }
15978 }
15979
addResolveImagePartialTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)15980 void addResolveImagePartialTests(tcu::TestCaseGroup *group, AllocationKind allocationKind, uint32_t extensionFlags)
15981 {
15982 TestParams params;
15983 params.src.image.imageType = VK_IMAGE_TYPE_2D;
15984 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
15985 params.src.image.extent = resolveExtent;
15986 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
15987 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
15988 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
15989 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
15990 params.dst.image.extent = resolveExtent;
15991 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
15992 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
15993 params.allocationKind = allocationKind;
15994 params.extensionFlags = extensionFlags;
15995
15996 {
15997 const VkImageSubresourceLayers sourceLayer = {
15998 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
15999 0u, // uint32_t mipLevel;
16000 0u, // uint32_t baseArrayLayer;
16001 1u // uint32_t layerCount;
16002 };
16003 const VkImageResolve testResolve = {
16004 sourceLayer, // VkImageSubresourceLayers srcSubresource;
16005 {0, 0, 0}, // VkOffset3D srcOffset;
16006 sourceLayer, // VkImageSubresourceLayers dstSubresource;
16007 {64u, 64u, 0}, // VkOffset3D dstOffset;
16008 {128u, 128u, 1u}, // VkExtent3D extent;
16009 };
16010
16011 CopyRegion imageResolve;
16012 imageResolve.imageResolve = testResolve;
16013 params.regions.push_back(imageResolve);
16014 }
16015
16016 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
16017 {
16018 params.samples = samples[samplesIndex];
16019 params.imageOffset = false;
16020 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(),
16021 getSampleCountCaseName(samples[samplesIndex]), params));
16022 params.imageOffset = true;
16023 if (allocationKind != ALLOCATION_KIND_DEDICATED)
16024 {
16025 group->addChild(new ResolveImageToImageTestCase(
16026 group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", params));
16027 }
16028 }
16029 }
16030
addResolveImageWithRegionsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)16031 void addResolveImageWithRegionsTests(tcu::TestCaseGroup *group, AllocationKind allocationKind, uint32_t extensionFlags)
16032 {
16033 TestParams params;
16034 params.src.image.imageType = VK_IMAGE_TYPE_2D;
16035 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
16036 params.src.image.extent = resolveExtent;
16037 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
16038 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
16039 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
16040 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
16041 params.dst.image.extent = resolveExtent;
16042 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
16043 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
16044 params.allocationKind = allocationKind;
16045 params.extensionFlags = extensionFlags;
16046 params.imageOffset = allocationKind != ALLOCATION_KIND_DEDICATED;
16047
16048 {
16049 const VkImageSubresourceLayers sourceLayer = {
16050 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
16051 0u, // uint32_t mipLevel;
16052 0u, // uint32_t baseArrayLayer;
16053 1u // uint32_t layerCount;
16054 };
16055
16056 for (int i = 0; i < 256; i += 64)
16057 {
16058 const VkImageResolve testResolve = {
16059 sourceLayer, // VkImageSubresourceLayers srcSubresource;
16060 {i, i, 0}, // VkOffset3D srcOffset;
16061 sourceLayer, // VkImageSubresourceLayers dstSubresource;
16062 {i, 0, 0}, // VkOffset3D dstOffset;
16063 {64u, 64u, 1u}, // VkExtent3D extent;
16064 };
16065
16066 CopyRegion imageResolve;
16067 imageResolve.imageResolve = testResolve;
16068 params.regions.push_back(imageResolve);
16069 }
16070 }
16071
16072 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
16073 {
16074 params.samples = samples[samplesIndex];
16075 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(),
16076 getSampleCountCaseName(samples[samplesIndex]), params));
16077 }
16078 }
16079
addResolveImageWholeCopyBeforeResolvingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)16080 void addResolveImageWholeCopyBeforeResolvingTests(tcu::TestCaseGroup *group, AllocationKind allocationKind,
16081 uint32_t extensionFlags)
16082 {
16083 TestParams params;
16084 params.src.image.imageType = VK_IMAGE_TYPE_2D;
16085 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
16086 params.src.image.extent = defaultExtent;
16087 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
16088 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
16089 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
16090 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
16091 params.dst.image.extent = defaultExtent;
16092 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
16093 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
16094 params.allocationKind = allocationKind;
16095 params.extensionFlags = extensionFlags;
16096
16097 {
16098 const VkImageSubresourceLayers sourceLayer = {
16099 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
16100 0u, // uint32_t mipLevel;
16101 0u, // uint32_t baseArrayLayer;
16102 1u // uint32_t layerCount;
16103 };
16104
16105 const VkImageResolve testResolve = {
16106 sourceLayer, // VkImageSubresourceLayers srcSubresource;
16107 {0, 0, 0}, // VkOffset3D srcOffset;
16108 sourceLayer, // VkImageSubresourceLayers dstSubresource;
16109 {0, 0, 0}, // VkOffset3D dstOffset;
16110 defaultExtent, // VkExtent3D extent;
16111 };
16112
16113 CopyRegion imageResolve;
16114 imageResolve.imageResolve = testResolve;
16115 params.regions.push_back(imageResolve);
16116 }
16117
16118 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
16119 {
16120 params.samples = samples[samplesIndex];
16121 params.imageOffset = false;
16122 group->addChild(new ResolveImageToImageTestCase(
16123 group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), params, COPY_MS_IMAGE_TO_MS_IMAGE));
16124 params.imageOffset = true;
16125 if (allocationKind != ALLOCATION_KIND_DEDICATED)
16126 {
16127 group->addChild(new ResolveImageToImageTestCase(
16128 group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", params,
16129 COPY_MS_IMAGE_TO_MS_IMAGE));
16130 }
16131 }
16132 }
16133
addComputeAndTransferQueueTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)16134 void addComputeAndTransferQueueTests(tcu::TestCaseGroup *group, AllocationKind allocationKind, uint32_t extensionFlags)
16135 {
16136 de::MovePtr<tcu::TestCaseGroup> computeGroup(
16137 new tcu::TestCaseGroup(group->getTestContext(), "whole_copy_before_resolving_compute"));
16138 de::MovePtr<tcu::TestCaseGroup> transferGroup(
16139 new tcu::TestCaseGroup(group->getTestContext(), "whole_copy_before_resolving_transfer"));
16140
16141 TestParams params;
16142 params.src.image.imageType = VK_IMAGE_TYPE_2D;
16143 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
16144 params.src.image.extent = defaultExtent;
16145 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
16146 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
16147 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
16148 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
16149 params.dst.image.extent = defaultExtent;
16150 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
16151 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
16152 params.allocationKind = allocationKind;
16153 params.extensionFlags = extensionFlags;
16154
16155 {
16156 const VkImageSubresourceLayers sourceLayer = {
16157 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
16158 0u, // uint32_t mipLevel;
16159 0u, // uint32_t baseArrayLayer;
16160 1u // uint32_t layerCount;
16161 };
16162
16163 const VkImageResolve testResolve = {
16164 sourceLayer, // VkImageSubresourceLayers srcSubresource;
16165 {0, 0, 0}, // VkOffset3D srcOffset;
16166 sourceLayer, // VkImageSubresourceLayers dstSubresource;
16167 {0, 0, 0}, // VkOffset3D dstOffset;
16168 defaultExtent, // VkExtent3D extent;
16169 };
16170
16171 CopyRegion imageResolve;
16172 imageResolve.imageResolve = testResolve;
16173 params.regions.push_back(imageResolve);
16174 }
16175
16176 for (const auto &sample : samples)
16177 {
16178 params.samples = sample;
16179
16180 params.queueSelection = QueueSelectionOptions::ComputeOnly;
16181 computeGroup->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(sample),
16182 params, COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE));
16183
16184 params.queueSelection = QueueSelectionOptions::TransferOnly;
16185 transferGroup->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(sample),
16186 params, COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER));
16187 }
16188
16189 group->addChild(computeGroup.release());
16190 group->addChild(transferGroup.release());
16191 }
16192
addResolveImageWholeCopyWithoutCabBeforeResolvingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)16193 void addResolveImageWholeCopyWithoutCabBeforeResolvingTests(tcu::TestCaseGroup *group, AllocationKind allocationKind,
16194 uint32_t extensionFlags)
16195 {
16196 TestParams params;
16197 params.src.image.imageType = VK_IMAGE_TYPE_2D;
16198 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
16199 params.src.image.extent = defaultExtent;
16200 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
16201 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
16202 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
16203 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
16204 params.dst.image.extent = defaultExtent;
16205 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
16206 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
16207 params.allocationKind = allocationKind;
16208 params.extensionFlags = extensionFlags;
16209
16210 {
16211 const VkImageSubresourceLayers sourceLayer = {
16212 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
16213 0u, // uint32_t mipLevel;
16214 0u, // uint32_t baseArrayLayer;
16215 1u // uint32_t layerCount;
16216 };
16217
16218 const VkImageResolve testResolve = {
16219 sourceLayer, // VkImageSubresourceLayers srcSubresource;
16220 {0, 0, 0}, // VkOffset3D srcOffset;
16221 sourceLayer, // VkImageSubresourceLayers dstSubresource;
16222 {0, 0, 0}, // VkOffset3D dstOffset;
16223 defaultExtent, // VkExtent3D extent;
16224 };
16225
16226 CopyRegion imageResolve;
16227 imageResolve.imageResolve = testResolve;
16228 params.regions.push_back(imageResolve);
16229 }
16230
16231 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
16232 {
16233 params.samples = samples[samplesIndex];
16234 params.imageOffset = false;
16235 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(),
16236 getSampleCountCaseName(samples[samplesIndex]), params,
16237 COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB));
16238 params.imageOffset = true;
16239 if (allocationKind != ALLOCATION_KIND_DEDICATED)
16240 {
16241 group->addChild(new ResolveImageToImageTestCase(
16242 group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", params,
16243 COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB));
16244 }
16245 }
16246 }
16247
addResolveImageWholeCopyDiffLayoutsBeforeResolvingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)16248 void addResolveImageWholeCopyDiffLayoutsBeforeResolvingTests(tcu::TestCaseGroup *group, AllocationKind allocationKind,
16249 uint32_t extensionFlags)
16250 {
16251 TestParams params;
16252 params.src.image.imageType = VK_IMAGE_TYPE_2D;
16253 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
16254 params.src.image.extent = defaultExtent;
16255 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
16256 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
16257 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
16258 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
16259 params.dst.image.extent = defaultExtent;
16260 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
16261 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
16262 params.allocationKind = allocationKind;
16263 params.extensionFlags = extensionFlags;
16264
16265 {
16266 const VkImageSubresourceLayers sourceLayer = {
16267 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
16268 0u, // uint32_t mipLevel;
16269 0u, // uint32_t baseArrayLayer;
16270 1u // uint32_t layerCount;
16271 };
16272
16273 const VkImageResolve testResolve = {
16274 sourceLayer, // VkImageSubresourceLayers srcSubresource;
16275 {0, 0, 0}, // VkOffset3D srcOffset;
16276 sourceLayer, // VkImageSubresourceLayers dstSubresource;
16277 {0, 0, 0}, // VkOffset3D dstOffset;
16278 defaultExtent, // VkExtent3D extent;
16279 };
16280
16281 CopyRegion imageResolve;
16282 imageResolve.imageResolve = testResolve;
16283 params.regions.push_back(imageResolve);
16284 }
16285
16286 const struct
16287 {
16288 VkImageLayout layout;
16289 std::string name;
16290 } imageLayouts[] = {{VK_IMAGE_LAYOUT_GENERAL, "general"},
16291 {VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, "transfer_src_optimal"},
16292 {VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, "transfer_dst_optimal"}};
16293
16294 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
16295 for (int srcLayoutIndex = 0; srcLayoutIndex < DE_LENGTH_OF_ARRAY(imageLayouts); ++srcLayoutIndex)
16296 for (int dstLayoutIndex = 0; dstLayoutIndex < DE_LENGTH_OF_ARRAY(imageLayouts); ++dstLayoutIndex)
16297 {
16298 params.src.image.operationLayout = imageLayouts[srcLayoutIndex].layout;
16299 params.dst.image.operationLayout = imageLayouts[dstLayoutIndex].layout;
16300 if (params.src.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ||
16301 params.dst.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)
16302 continue;
16303 params.samples = samples[samplesIndex];
16304 std::string testName = getSampleCountCaseName(samples[samplesIndex]) + "_" +
16305 imageLayouts[srcLayoutIndex].name + "_" + imageLayouts[dstLayoutIndex].name;
16306 params.imageOffset = false;
16307 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), testName, params,
16308 COPY_MS_IMAGE_TO_MS_IMAGE));
16309 params.imageOffset = true;
16310 if (allocationKind != ALLOCATION_KIND_DEDICATED)
16311 {
16312 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), testName + "_bind_offset",
16313 params, COPY_MS_IMAGE_TO_MS_IMAGE));
16314 }
16315 }
16316 }
16317
addResolveImageLayerCopyBeforeResolvingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)16318 void addResolveImageLayerCopyBeforeResolvingTests(tcu::TestCaseGroup *group, AllocationKind allocationKind,
16319 uint32_t extensionFlags)
16320 {
16321 TestParams params;
16322 params.src.image.imageType = VK_IMAGE_TYPE_2D;
16323 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
16324 params.src.image.extent = defaultExtent;
16325 params.src.image.extent.depth = 5u;
16326 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
16327 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
16328 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
16329 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
16330 params.dst.image.extent = defaultExtent;
16331 params.dst.image.extent.depth = 5u;
16332 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
16333 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
16334 params.allocationKind = allocationKind;
16335 params.extensionFlags = extensionFlags;
16336
16337 for (uint32_t layerNdx = 0; layerNdx < params.src.image.extent.depth; ++layerNdx)
16338 {
16339 const VkImageSubresourceLayers sourceLayer = {
16340 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
16341 0u, // uint32_t mipLevel;
16342 layerNdx, // uint32_t baseArrayLayer;
16343 1u // uint32_t layerCount;
16344 };
16345
16346 const VkImageResolve testResolve = {
16347 sourceLayer, // VkImageSubresourceLayers srcSubresource;
16348 {0, 0, 0}, // VkOffset3D srcOffset;
16349 sourceLayer, // VkImageSubresourceLayers dstSubresource;
16350 {0, 0, 0}, // VkOffset3D dstOffset;
16351 defaultExtent, // VkExtent3D extent;
16352 };
16353
16354 CopyRegion imageResolve;
16355 imageResolve.imageResolve = testResolve;
16356 params.regions.push_back(imageResolve);
16357 }
16358
16359 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
16360 {
16361 params.samples = samples[samplesIndex];
16362 params.imageOffset = false;
16363 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(),
16364 getSampleCountCaseName(samples[samplesIndex]), params,
16365 COPY_MS_IMAGE_LAYER_TO_MS_IMAGE));
16366 params.imageOffset = true;
16367 if (allocationKind != ALLOCATION_KIND_DEDICATED)
16368 {
16369 group->addChild(new ResolveImageToImageTestCase(
16370 group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", params,
16371 COPY_MS_IMAGE_LAYER_TO_MS_IMAGE));
16372 }
16373 }
16374 }
16375
addResolveCopyImageWithRegionsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)16376 void addResolveCopyImageWithRegionsTests(tcu::TestCaseGroup *group, AllocationKind allocationKind,
16377 uint32_t extensionFlags)
16378 {
16379 TestParams params;
16380 params.src.image.imageType = VK_IMAGE_TYPE_2D;
16381 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
16382 params.src.image.extent = resolveExtent;
16383 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
16384 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
16385 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
16386 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
16387 params.dst.image.extent = resolveExtent;
16388 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
16389 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
16390 params.allocationKind = allocationKind;
16391 params.extensionFlags = extensionFlags;
16392
16393 int32_t imageHalfWidth = getExtent3D(params.src.image).width / 2;
16394 int32_t imageHalfHeight = getExtent3D(params.src.image).height / 2;
16395 VkExtent3D halfImageExtent = {resolveExtent.width / 2, resolveExtent.height / 2, 1u};
16396
16397 // Lower right corner to lower left corner.
16398 {
16399 const VkImageSubresourceLayers sourceLayer = {
16400 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
16401 0u, // uint32_t mipLevel;
16402 0u, // uint32_t baseArrayLayer;
16403 1u // uint32_t layerCount;
16404 };
16405
16406 const VkImageResolve testResolve = {
16407 sourceLayer, // VkImageSubresourceLayers srcSubresource;
16408 {imageHalfWidth, imageHalfHeight, 0}, // VkOffset3D srcOffset;
16409 sourceLayer, // VkImageSubresourceLayers dstSubresource;
16410 {0, imageHalfHeight, 0}, // VkOffset3D dstOffset;
16411 halfImageExtent, // VkExtent3D extent;
16412 };
16413
16414 CopyRegion imageResolve;
16415 imageResolve.imageResolve = testResolve;
16416 params.regions.push_back(imageResolve);
16417 }
16418
16419 // Upper right corner to lower right corner.
16420 {
16421 const VkImageSubresourceLayers sourceLayer = {
16422 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
16423 0u, // uint32_t mipLevel;
16424 0u, // uint32_t baseArrayLayer;
16425 1u // uint32_t layerCount;
16426 };
16427
16428 const VkImageResolve testResolve = {
16429 sourceLayer, // VkImageSubresourceLayers srcSubresource;
16430 {imageHalfWidth, 0, 0}, // VkOffset3D srcOffset;
16431 sourceLayer, // VkImageSubresourceLayers dstSubresource;
16432 {imageHalfWidth, imageHalfHeight, 0}, // VkOffset3D dstOffset;
16433 halfImageExtent, // VkExtent3D extent;
16434 };
16435
16436 CopyRegion imageResolve;
16437 imageResolve.imageResolve = testResolve;
16438 params.regions.push_back(imageResolve);
16439 }
16440
16441 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
16442 {
16443 params.samples = samples[samplesIndex];
16444 params.imageOffset = false;
16445 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(),
16446 getSampleCountCaseName(samples[samplesIndex]), params,
16447 COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION));
16448 params.imageOffset = true;
16449 if (allocationKind != ALLOCATION_KIND_DEDICATED)
16450 {
16451 group->addChild(new ResolveImageToImageTestCase(
16452 group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", params,
16453 COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION));
16454 }
16455 }
16456 }
16457
addResolveImageWholeArrayImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)16458 void addResolveImageWholeArrayImageTests(tcu::TestCaseGroup *group, AllocationKind allocationKind,
16459 uint32_t extensionFlags)
16460 {
16461 TestParams params;
16462 params.src.image.imageType = VK_IMAGE_TYPE_2D;
16463 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
16464 params.src.image.extent = defaultExtent;
16465 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
16466 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
16467 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
16468 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
16469 params.dst.image.extent = defaultExtent;
16470 params.dst.image.extent.depth = 5u;
16471 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
16472 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
16473 params.allocationKind = allocationKind;
16474 params.extensionFlags = extensionFlags;
16475
16476 for (uint32_t layerNdx = 0; layerNdx < params.dst.image.extent.depth; ++layerNdx)
16477 {
16478 const VkImageSubresourceLayers sourceLayer = {
16479 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
16480 0u, // uint32_t mipLevel;
16481 layerNdx, // uint32_t baseArrayLayer;
16482 1u // uint32_t layerCount;
16483 };
16484
16485 const VkImageResolve testResolve = {
16486 sourceLayer, // VkImageSubresourceLayers srcSubresource;
16487 {0, 0, 0}, // VkOffset3D srcOffset;
16488 sourceLayer, // VkImageSubresourceLayers dstSubresource;
16489 {0, 0, 0}, // VkOffset3D dstOffset;
16490 defaultExtent, // VkExtent3D extent;
16491 };
16492
16493 CopyRegion imageResolve;
16494 imageResolve.imageResolve = testResolve;
16495 params.regions.push_back(imageResolve);
16496 }
16497
16498 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
16499 {
16500 params.samples = samples[samplesIndex];
16501 params.imageOffset = false;
16502 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(),
16503 getSampleCountCaseName(samples[samplesIndex]), params,
16504 COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
16505 params.imageOffset = true;
16506 if (allocationKind != ALLOCATION_KIND_DEDICATED)
16507 {
16508 group->addChild(new ResolveImageToImageTestCase(
16509 group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", params,
16510 COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
16511 }
16512 }
16513 }
16514
addResolveImageWholeArrayImageSingleRegionTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)16515 void addResolveImageWholeArrayImageSingleRegionTests(tcu::TestCaseGroup *group, AllocationKind allocationKind,
16516 uint32_t extensionFlags)
16517 {
16518 {
16519 TestParams params;
16520 const uint32_t layerCount = 5u;
16521 params.src.image.imageType = VK_IMAGE_TYPE_2D;
16522 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
16523 params.src.image.extent = defaultExtent;
16524 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
16525 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
16526 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
16527 params.dst.image.extent = defaultExtent;
16528 params.dst.image.extent.depth = layerCount;
16529 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
16530 params.allocationKind = allocationKind;
16531 params.extensionFlags = extensionFlags;
16532
16533 const VkImageSubresourceLayers sourceLayer = {
16534 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
16535 0u, // uint32_t mipLevel;
16536 0, // uint32_t baseArrayLayer;
16537 layerCount // uint32_t layerCount;
16538 };
16539
16540 const VkImageResolve testResolve = {
16541 sourceLayer, // VkImageSubresourceLayers srcSubresource;
16542 {0, 0, 0}, // VkOffset3D srcOffset;
16543 sourceLayer, // VkImageSubresourceLayers dstSubresource;
16544 {0, 0, 0}, // VkOffset3D dstOffset;
16545 defaultExtent, // VkExtent3D extent;
16546 };
16547
16548 CopyRegion imageResolve;
16549 imageResolve.imageResolve = testResolve;
16550 params.regions.push_back(imageResolve);
16551
16552 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
16553 {
16554 params.samples = samples[samplesIndex];
16555 params.imageOffset = false;
16556 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(),
16557 getSampleCountCaseName(samples[samplesIndex]), params,
16558 COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
16559 params.imageOffset = true;
16560 if (allocationKind != ALLOCATION_KIND_DEDICATED)
16561 {
16562 group->addChild(new ResolveImageToImageTestCase(
16563 group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", params,
16564 COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
16565 }
16566 }
16567 }
16568
16569 {
16570 TestParams params;
16571 const uint32_t baseLayer = 0u;
16572 const uint32_t layerCount = 5u;
16573 params.src.image.imageType = VK_IMAGE_TYPE_2D;
16574 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
16575 params.src.image.extent = defaultExtent;
16576 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
16577 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
16578 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
16579 params.dst.image.extent = defaultExtent;
16580 params.dst.image.extent.depth = layerCount;
16581 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
16582 params.allocationKind = allocationKind;
16583 params.extensionFlags = extensionFlags;
16584 params.extensionFlags |= MAINTENANCE_5;
16585
16586 const VkImageSubresourceLayers sourceLayer = {
16587 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
16588 0u, // uint32_t mipLevel;
16589 baseLayer, // uint32_t baseArrayLayer;
16590 VK_REMAINING_ARRAY_LAYERS // uint32_t layerCount;
16591 };
16592
16593 const VkImageResolve testResolve = {
16594 sourceLayer, // VkImageSubresourceLayers srcSubresource;
16595 {0, 0, 0}, // VkOffset3D srcOffset;
16596 sourceLayer, // VkImageSubresourceLayers dstSubresource;
16597 {0, 0, 0}, // VkOffset3D dstOffset;
16598 defaultExtent, // VkExtent3D extent;
16599 };
16600
16601 CopyRegion imageResolve;
16602 imageResolve.imageResolve = testResolve;
16603 params.regions.push_back(imageResolve);
16604
16605 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
16606 {
16607 params.samples = samples[samplesIndex];
16608 params.imageOffset = false;
16609 group->addChild(new ResolveImageToImageTestCase(
16610 group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_all_remaining_layers",
16611 params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
16612 params.imageOffset = true;
16613 if (allocationKind != ALLOCATION_KIND_DEDICATED)
16614 {
16615 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(),
16616 getSampleCountCaseName(samples[samplesIndex]) +
16617 "_all_remaining_layers_bind_offset",
16618 params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
16619 }
16620 }
16621 }
16622
16623 {
16624 TestParams params;
16625 const uint32_t baseLayer = 2u;
16626 const uint32_t layerCount = 5u;
16627 params.src.image.imageType = VK_IMAGE_TYPE_2D;
16628 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
16629 params.src.image.extent = defaultExtent;
16630 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
16631 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
16632 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
16633 params.dst.image.extent = defaultExtent;
16634 params.dst.image.extent.depth = layerCount;
16635 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
16636 params.allocationKind = allocationKind;
16637 params.extensionFlags = extensionFlags;
16638 params.extensionFlags |= MAINTENANCE_5;
16639
16640 const VkImageSubresourceLayers sourceLayer = {
16641 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
16642 0u, // uint32_t mipLevel;
16643 baseLayer, // uint32_t baseArrayLayer;
16644 VK_REMAINING_ARRAY_LAYERS // uint32_t layerCount;
16645 };
16646
16647 const VkImageResolve testResolve = {
16648 sourceLayer, // VkImageSubresourceLayers srcSubresource;
16649 {0, 0, 0}, // VkOffset3D srcOffset;
16650 sourceLayer, // VkImageSubresourceLayers dstSubresource;
16651 {0, 0, 0}, // VkOffset3D dstOffset;
16652 defaultExtent, // VkExtent3D extent;
16653 };
16654
16655 CopyRegion imageResolve;
16656 imageResolve.imageResolve = testResolve;
16657 params.regions.push_back(imageResolve);
16658
16659 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
16660 {
16661 params.samples = samples[samplesIndex];
16662 params.imageOffset = false;
16663 group->addChild(new ResolveImageToImageTestCase(
16664 group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_not_all_remaining_layers",
16665 params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
16666 params.imageOffset = true;
16667 if (allocationKind != ALLOCATION_KIND_DEDICATED)
16668 {
16669 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(),
16670 getSampleCountCaseName(samples[samplesIndex]) +
16671 "_not_all_remaining_layers_bind_offset",
16672 params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
16673 }
16674 }
16675 }
16676 }
16677
addResolveImageDiffImageSizeTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)16678 void addResolveImageDiffImageSizeTests(tcu::TestCaseGroup *group, AllocationKind allocationKind,
16679 uint32_t extensionFlags)
16680 {
16681 tcu::TestContext &testCtx = group->getTestContext();
16682 TestParams params;
16683 params.src.image.imageType = VK_IMAGE_TYPE_2D;
16684 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
16685 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
16686 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
16687 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
16688 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
16689 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
16690 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
16691 params.allocationKind = allocationKind;
16692 params.extensionFlags = extensionFlags;
16693
16694 {
16695 const VkImageSubresourceLayers sourceLayer = {
16696 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
16697 0u, // uint32_t mipLevel;
16698 0u, // uint32_t baseArrayLayer;
16699 1u // uint32_t layerCount;
16700 };
16701 const VkImageResolve testResolve = {
16702 sourceLayer, // VkImageSubresourceLayers srcSubresource;
16703 {0, 0, 0}, // VkOffset3D srcOffset;
16704 sourceLayer, // VkImageSubresourceLayers dstSubresource;
16705 {0, 0, 0}, // VkOffset3D dstOffset;
16706 resolveExtent, // VkExtent3D extent;
16707 };
16708 CopyRegion imageResolve;
16709 imageResolve.imageResolve = testResolve;
16710 params.regions.push_back(imageResolve);
16711 }
16712
16713 const VkExtent3D imageExtents[] = {{resolveExtent.width + 10, resolveExtent.height, resolveExtent.depth},
16714 {resolveExtent.width, resolveExtent.height * 2, resolveExtent.depth},
16715 {resolveExtent.width, resolveExtent.height, resolveExtent.depth + 10}};
16716
16717 for (int srcImageExtentIndex = 0; srcImageExtentIndex < DE_LENGTH_OF_ARRAY(imageExtents); ++srcImageExtentIndex)
16718 {
16719 const VkExtent3D &srcImageSize = imageExtents[srcImageExtentIndex];
16720 params.src.image.extent = srcImageSize;
16721 params.dst.image.extent = resolveExtent;
16722 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
16723 {
16724 params.samples = samples[samplesIndex];
16725 std::ostringstream testName;
16726 testName << "src_" << srcImageSize.width << "_" << srcImageSize.height << "_" << srcImageSize.depth << "_"
16727 << getSampleCountCaseName(samples[samplesIndex]);
16728 std::ostringstream description;
16729 group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str(), params));
16730 }
16731 }
16732 for (int dstImageExtentIndex = 0; dstImageExtentIndex < DE_LENGTH_OF_ARRAY(imageExtents); ++dstImageExtentIndex)
16733 {
16734 const VkExtent3D &dstImageSize = imageExtents[dstImageExtentIndex];
16735 params.src.image.extent = resolveExtent;
16736 params.dst.image.extent = dstImageSize;
16737 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
16738 {
16739 params.samples = samples[samplesIndex];
16740 std::ostringstream testName;
16741 testName << "dst_" << dstImageSize.width << "_" << dstImageSize.height << "_" << dstImageSize.depth << "_"
16742 << getSampleCountCaseName(samples[samplesIndex]);
16743 std::ostringstream description;
16744 params.imageOffset = false;
16745 group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str(), params));
16746 params.imageOffset = true;
16747 if (allocationKind != ALLOCATION_KIND_DEDICATED)
16748 {
16749 group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str() + "_bind_offset", params));
16750 }
16751 }
16752 }
16753 }
16754
addDepthStencilCopyMSAATest(tcu::TestCaseGroup * group,DepthStencilMSAA::TestParameters testCreateParams)16755 void addDepthStencilCopyMSAATest(tcu::TestCaseGroup *group, DepthStencilMSAA::TestParameters testCreateParams)
16756 {
16757 // Run all the tests with one of the bare depth format and one bare stencil format + mandatory combined formats.
16758 const struct
16759 {
16760 const std::string name;
16761 const VkFormat vkFormat;
16762 } depthAndStencilFormats[] = {
16763 {"d32_sfloat", VK_FORMAT_D32_SFLOAT},
16764 {"s8_uint", VK_FORMAT_S8_UINT},
16765 {"d16_unorm_s8_uint", VK_FORMAT_D16_UNORM_S8_UINT},
16766 {"d24_unorm_s8_uint", VK_FORMAT_D24_UNORM_S8_UINT},
16767 };
16768
16769 // Both image layouts will be tested only with full image copy tests to limit the number of tests.
16770 const VkImageLayout srcImageLayouts[] = {VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL};
16771 const VkImageLayout dstImageLayouts[] = {VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL};
16772
16773 for (const auto &srcLayout : srcImageLayouts)
16774 {
16775 for (const auto &dstLayout : dstImageLayouts)
16776 {
16777 testCreateParams.srcImageLayout = srcLayout;
16778 testCreateParams.dstImageLayout = dstLayout;
16779 for (const auto &format : depthAndStencilFormats)
16780 {
16781 testCreateParams.imageFormat = format.vkFormat;
16782 const auto textureFormat = mapVkFormat(format.vkFormat);
16783 bool hasDepth = tcu::hasDepthComponent(textureFormat.order);
16784 bool hasStencil = tcu::hasStencilComponent(textureFormat.order);
16785 std::string testNameBase =
16786 format.name + "_" +
16787 (testCreateParams.copyOptions == DepthStencilMSAA::COPY_WHOLE_IMAGE ?
16788 getImageLayoutCaseName(srcLayout) + "_" + getImageLayoutCaseName(dstLayout) + "_" :
16789 "");
16790
16791 if (hasDepth)
16792 {
16793 testCreateParams.copyAspect = VK_IMAGE_ASPECT_DEPTH_BIT;
16794 for (auto sample : samples)
16795 {
16796 testCreateParams.samples = sample;
16797 testCreateParams.imageOffset = false;
16798 group->addChild(new DepthStencilMSAATestCase(
16799 group->getTestContext(), testNameBase + "D_" + getSampleCountCaseName(sample),
16800 testCreateParams));
16801 testCreateParams.imageOffset = true;
16802 if (testCreateParams.allocationKind != ALLOCATION_KIND_DEDICATED)
16803 {
16804 group->addChild(new DepthStencilMSAATestCase(
16805 group->getTestContext(),
16806 testNameBase + "D_" + getSampleCountCaseName(sample) + "_bind_offset",
16807 testCreateParams));
16808 }
16809 }
16810 }
16811
16812 if (hasStencil)
16813 {
16814 testCreateParams.copyAspect = VK_IMAGE_ASPECT_STENCIL_BIT;
16815 for (auto sample : samples)
16816 {
16817 testCreateParams.samples = sample;
16818 testCreateParams.imageOffset = false;
16819 group->addChild(new DepthStencilMSAATestCase(
16820 group->getTestContext(), testNameBase + "S_" + getSampleCountCaseName(sample),
16821 testCreateParams));
16822 testCreateParams.imageOffset = true;
16823 if (testCreateParams.allocationKind != ALLOCATION_KIND_DEDICATED)
16824 {
16825 group->addChild(new DepthStencilMSAATestCase(
16826 group->getTestContext(),
16827 testNameBase + "S_" + getSampleCountCaseName(sample) + "_bind_offset",
16828 testCreateParams));
16829 }
16830 }
16831 }
16832 }
16833 if (testCreateParams.copyOptions != DepthStencilMSAA::COPY_WHOLE_IMAGE)
16834 break;
16835 }
16836 if (testCreateParams.copyOptions != DepthStencilMSAA::COPY_WHOLE_IMAGE)
16837 break;
16838 }
16839 }
16840
addDepthStencilCopyMSAATestGroup(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)16841 void addDepthStencilCopyMSAATestGroup(tcu::TestCaseGroup *group, AllocationKind allocationKind, uint32_t extensionFlags)
16842 {
16843 // Allocation kind, extension use copy option parameters are defined here. Rest of the parameters are defined in `addDepthStencilCopyMSAATest` function.
16844 DepthStencilMSAA::TestParameters testParams = {};
16845 testParams.allocationKind = allocationKind;
16846 testParams.extensionFlags = extensionFlags;
16847
16848 testParams.copyOptions = DepthStencilMSAA::COPY_WHOLE_IMAGE;
16849 addTestGroup(group, "whole", addDepthStencilCopyMSAATest, testParams);
16850
16851 testParams.copyOptions = DepthStencilMSAA::COPY_PARTIAL;
16852 addTestGroup(group, "partial", addDepthStencilCopyMSAATest, testParams);
16853
16854 testParams.copyOptions = DepthStencilMSAA::COPY_ARRAY_TO_ARRAY;
16855 addTestGroup(group, "array_to_array", addDepthStencilCopyMSAATest, testParams);
16856 }
16857
addBufferCopyOffsetTests(tcu::TestCaseGroup * group)16858 void addBufferCopyOffsetTests(tcu::TestCaseGroup *group)
16859 {
16860 de::MovePtr<tcu::TestCaseGroup> subGroup(
16861 new tcu::TestCaseGroup(group->getTestContext(), "buffer_to_buffer_with_offset"));
16862
16863 for (uint32_t srcOffset = 0u; srcOffset < BufferOffsetParams::kMaxOffset; ++srcOffset)
16864 for (uint32_t dstOffset = 0u; dstOffset < BufferOffsetParams::kMaxOffset; ++dstOffset)
16865 {
16866 BufferOffsetParams params{srcOffset, dstOffset};
16867 addFunctionCase(subGroup.get(), de::toString(srcOffset) + "_" + de::toString(dstOffset), bufferOffsetTest,
16868 params);
16869 }
16870
16871 group->addChild(subGroup.release());
16872 }
16873
addResolveImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)16874 void addResolveImageTests(tcu::TestCaseGroup *group, AllocationKind allocationKind, uint32_t extensionFlags)
16875 {
16876 addTestGroup(group, "whole", addResolveImageWholeTests, allocationKind, extensionFlags);
16877 addTestGroup(group, "partial", addResolveImagePartialTests, allocationKind, extensionFlags);
16878 addTestGroup(group, "with_regions", addResolveImageWithRegionsTests, allocationKind, extensionFlags);
16879 addTestGroup(group, "whole_copy_before_resolving", addResolveImageWholeCopyBeforeResolvingTests, allocationKind,
16880 extensionFlags);
16881 addTestGroup(group, "whole_copy_before_resolving_no_cab", addResolveImageWholeCopyWithoutCabBeforeResolvingTests,
16882 allocationKind, extensionFlags);
16883 addComputeAndTransferQueueTests(group, allocationKind, extensionFlags);
16884 addTestGroup(group, "diff_layout_copy_before_resolving", addResolveImageWholeCopyDiffLayoutsBeforeResolvingTests,
16885 allocationKind, extensionFlags);
16886 addTestGroup(group, "layer_copy_before_resolving", addResolveImageLayerCopyBeforeResolvingTests, allocationKind,
16887 extensionFlags);
16888 addTestGroup(group, "copy_with_regions_before_resolving", addResolveCopyImageWithRegionsTests, allocationKind,
16889 extensionFlags);
16890 addTestGroup(group, "whole_array_image", addResolveImageWholeArrayImageTests, allocationKind, extensionFlags);
16891 addTestGroup(group, "whole_array_image_one_region", addResolveImageWholeArrayImageSingleRegionTests, allocationKind,
16892 extensionFlags);
16893 addTestGroup(group, "diff_image_size", addResolveImageDiffImageSizeTests, allocationKind, extensionFlags);
16894 }
16895
addSparseCopyTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)16896 void addSparseCopyTests(tcu::TestCaseGroup *group, AllocationKind allocationKind, uint32_t extensionFlags)
16897 {
16898 DE_ASSERT((extensionFlags & COPY_COMMANDS_2) && (extensionFlags & SPARSE_BINDING));
16899
16900 {
16901 TestGroupParamsPtr universalGroupParams(new TestGroupParams{
16902 allocationKind,
16903 extensionFlags,
16904 QueueSelectionOptions::Universal,
16905 false,
16906 true,
16907 });
16908 addTestGroup(group, "image_to_image", addImageToImageTests, universalGroupParams);
16909 }
16910 }
16911
addCopiesAndBlittingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)16912 void addCopiesAndBlittingTests(tcu::TestCaseGroup *group, AllocationKind allocationKind, uint32_t extensionFlags)
16913 {
16914 TestGroupParamsPtr universalGroupParams(new TestGroupParams{
16915 allocationKind,
16916 extensionFlags,
16917 QueueSelectionOptions::Universal,
16918 false,
16919 false,
16920 });
16921
16922 addTestGroup(group, "image_to_image", addImageToImageTests, universalGroupParams);
16923 addTestGroup(group, "image_to_buffer", addImageToBufferTests, universalGroupParams);
16924 addTestGroup(group, "buffer_to_image", addBufferToImageTests, universalGroupParams);
16925 addTestGroup(group, "buffer_to_depthstencil", addBufferToDepthStencilTests, allocationKind, extensionFlags);
16926 addTestGroup(group, "buffer_to_buffer", addBufferToBufferTests, universalGroupParams);
16927 addTestGroup(group, "blit_image", addBlittingImageTests, allocationKind, extensionFlags);
16928 addTestGroup(group, "resolve_image", addResolveImageTests, allocationKind, extensionFlags);
16929 addTestGroup(group, "depth_stencil_msaa_copy", addDepthStencilCopyMSAATestGroup, allocationKind, extensionFlags);
16930
16931 if (extensionFlags == COPY_COMMANDS_2)
16932 {
16933 TestGroupParamsPtr transferOnlyGroup(new TestGroupParams{
16934 allocationKind,
16935 extensionFlags,
16936 QueueSelectionOptions::TransferOnly,
16937 false,
16938 false,
16939 });
16940 addTestGroup(group, "image_to_image_transfer_queue", addImageToImageTests, transferOnlyGroup);
16941 addTestGroup(group, "image_to_buffer_transfer_queue", addImageToBufferTests, transferOnlyGroup);
16942 addTestGroup(group, "buffer_to_image_transfer_queue", addBufferToImageTests, transferOnlyGroup);
16943 addTestGroup(group, "buffer_to_buffer_transfer_queue", addBufferToBufferTests, transferOnlyGroup);
16944
16945 TestGroupParamsPtr transferWithSecondaryBuffer(new TestGroupParams{
16946 allocationKind,
16947 extensionFlags,
16948 QueueSelectionOptions::TransferOnly,
16949 true,
16950 false,
16951 });
16952 addTestGroup(group, "image_to_image_transfer_queue_secondary", addImageToImageTestsSimpleOnly,
16953 transferWithSecondaryBuffer);
16954
16955 TestGroupParamsPtr transferWithSparse(new TestGroupParams{
16956 allocationKind,
16957 extensionFlags | SPARSE_BINDING,
16958 QueueSelectionOptions::TransferOnly,
16959 false,
16960 true,
16961 });
16962 addTestGroup(group, "image_to_image_transfer_sparse", addImageToImageTestsSimpleOnly, transferWithSparse);
16963 }
16964 }
16965
addCoreCopiesAndBlittingTests(tcu::TestCaseGroup * group)16966 void addCoreCopiesAndBlittingTests(tcu::TestCaseGroup *group)
16967 {
16968 uint32_t extensionFlags = 0;
16969 addCopiesAndBlittingTests(group, ALLOCATION_KIND_SUBALLOCATED, extensionFlags);
16970 addBufferCopyOffsetTests(group);
16971 }
16972
addDedicatedAllocationCopiesAndBlittingTests(tcu::TestCaseGroup * group)16973 void addDedicatedAllocationCopiesAndBlittingTests(tcu::TestCaseGroup *group)
16974 {
16975 uint32_t extensionFlags = 0;
16976 addCopiesAndBlittingTests(group, ALLOCATION_KIND_DEDICATED, extensionFlags);
16977 }
16978
cleanupGroup(tcu::TestCaseGroup *)16979 static void cleanupGroup(tcu::TestCaseGroup *)
16980 {
16981 }
16982
16983 } // namespace
16984
createCopiesAndBlittingTests(tcu::TestContext & testCtx)16985 tcu::TestCaseGroup *createCopiesAndBlittingTests(tcu::TestContext &testCtx)
16986 {
16987 de::MovePtr<tcu::TestCaseGroup> copiesAndBlittingTests(new tcu::TestCaseGroup(testCtx, "copy_and_blit"));
16988
16989 copiesAndBlittingTests->addChild(createTestGroup(testCtx, "core", addCoreCopiesAndBlittingTests, cleanupGroup));
16990 copiesAndBlittingTests->addChild(
16991 createTestGroup(testCtx, "dedicated_allocation", addDedicatedAllocationCopiesAndBlittingTests, cleanupGroup));
16992 copiesAndBlittingTests->addChild(createTestGroup(
16993 testCtx, "copy_commands2",
16994 [](tcu::TestCaseGroup *group) { addCopiesAndBlittingTests(group, ALLOCATION_KIND_DEDICATED, COPY_COMMANDS_2); },
16995 cleanupGroup));
16996 copiesAndBlittingTests->addChild(createTestGroup(
16997 testCtx, "sparse",
16998 [](tcu::TestCaseGroup *group)
16999 { addSparseCopyTests(group, ALLOCATION_KIND_DEDICATED, COPY_COMMANDS_2 | SPARSE_BINDING); },
17000 cleanupGroup));
17001
17002 return copiesAndBlittingTests.release();
17003 }
17004
17005 } // namespace api
17006 } // namespace vkt
17007