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 "vkBufferWithMemory.hpp"
55 #include "vkBarrierUtil.hpp"
56
57 #include "pipeline/vktPipelineImageUtil.hpp" // required for compressed image blit
58 #include "vktCustomInstancesDevices.hpp"
59 #include "vkSafetyCriticalUtil.hpp"
60
61 #include <set>
62 #include <array>
63 #include <algorithm>
64 #include <iterator>
65 #include <sstream>
66
67 namespace vkt
68 {
69
70 namespace api
71 {
72
73 namespace
74 {
75
76 enum FillMode
77 {
78 FILL_MODE_GRADIENT = 0,
79 FILL_MODE_WHITE,
80 FILL_MODE_BLACK,
81 FILL_MODE_RED,
82 FILL_MODE_MULTISAMPLE,
83 FILL_MODE_BLUE_RED_X,
84 FILL_MODE_BLUE_RED_Y,
85 FILL_MODE_BLUE_RED_Z,
86
87 FILL_MODE_LAST
88 };
89
90 enum MirrorModeBits
91 {
92 MIRROR_MODE_X = (1<<0),
93 MIRROR_MODE_Y = (1<<1),
94 MIRROR_MODE_Z = (1<<2),
95 MIRROR_MODE_LAST = (1<<3),
96 };
97
98 using MirrorMode = deUint32;
99
100 enum AllocationKind
101 {
102 ALLOCATION_KIND_SUBALLOCATED,
103 ALLOCATION_KIND_DEDICATED,
104 };
105
106 enum ExtensionUse
107 {
108 EXTENSION_USE_NONE,
109 EXTENSION_USE_COPY_COMMANDS2,
110 };
111
112 template <typename Type>
113 class BinaryCompare
114 {
115 public:
operator ()(const Type & a,const Type & b) const116 bool operator() (const Type& a, const Type& b) const
117 {
118 return deMemCmp(&a, &b, sizeof(Type)) < 0;
119 }
120 };
121
122 typedef std::set<vk::VkFormat, BinaryCompare<vk::VkFormat> > FormatSet;
123
124 FormatSet dedicatedAllocationImageToImageFormatsToTestSet;
125 FormatSet dedicatedAllocationBlittingFormatsToTestSet;
126
127 using namespace vk;
128
129 const deInt32 defaultSize = 64;
130 const deInt32 defaultHalfSize = defaultSize / 2;
131 const deInt32 defaultQuarterSize = defaultSize / 4;
132 const deInt32 defaultSixteenthSize = defaultSize / 16;
133 const VkExtent3D defaultExtent = {defaultSize, defaultSize, 1};
134 const VkExtent3D defaultHalfExtent = {defaultHalfSize, defaultHalfSize, 1};
135 const VkExtent3D default1dExtent = {defaultSize, 1, 1};
136 const VkExtent3D default3dExtent = {defaultQuarterSize, defaultQuarterSize, defaultQuarterSize};
137
138 const VkImageSubresourceLayers defaultSourceLayer =
139 {
140 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
141 0u, // deUint32 mipLevel;
142 0u, // deUint32 baseArrayLayer;
143 1u, // deUint32 layerCount;
144 };
145
convertvkImageCopyTovkImageCopy2KHR(VkImageCopy imageCopy)146 VkImageCopy2KHR convertvkImageCopyTovkImageCopy2KHR(VkImageCopy imageCopy)
147 {
148 const VkImageCopy2KHR imageCopy2 =
149 {
150 VK_STRUCTURE_TYPE_IMAGE_COPY_2_KHR, // VkStructureType sType;
151 DE_NULL, // const void* pNext;
152 imageCopy.srcSubresource, // VkImageSubresourceLayers srcSubresource;
153 imageCopy.srcOffset, // VkOffset3D srcOffset;
154 imageCopy.dstSubresource, // VkImageSubresourceLayers dstSubresource;
155 imageCopy.dstOffset, // VkOffset3D dstOffset;
156 imageCopy.extent // VkExtent3D extent;
157 };
158 return imageCopy2;
159 }
convertvkBufferCopyTovkBufferCopy2KHR(VkBufferCopy bufferCopy)160 VkBufferCopy2KHR convertvkBufferCopyTovkBufferCopy2KHR(VkBufferCopy bufferCopy)
161 {
162 const VkBufferCopy2KHR bufferCopy2 =
163 {
164 VK_STRUCTURE_TYPE_BUFFER_COPY_2_KHR, // VkStructureType sType;
165 DE_NULL, // const void* pNext;
166 bufferCopy.srcOffset, // VkDeviceSize srcOffset;
167 bufferCopy.dstOffset, // VkDeviceSize dstOffset;
168 bufferCopy.size, // VkDeviceSize size;
169 };
170 return bufferCopy2;
171 }
172
convertvkBufferImageCopyTovkBufferImageCopy2KHR(VkBufferImageCopy bufferImageCopy)173 VkBufferImageCopy2KHR convertvkBufferImageCopyTovkBufferImageCopy2KHR(VkBufferImageCopy bufferImageCopy)
174 {
175 const VkBufferImageCopy2KHR bufferImageCopy2 =
176 {
177 VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2_KHR, // VkStructureType sType;
178 DE_NULL, // const void* pNext;
179 bufferImageCopy.bufferOffset, // VkDeviceSize bufferOffset;
180 bufferImageCopy.bufferRowLength, // uint32_t bufferRowLength;
181 bufferImageCopy.bufferImageHeight, // uint32_t bufferImageHeight;
182 bufferImageCopy.imageSubresource, // VkImageSubresourceLayers imageSubresource;
183 bufferImageCopy.imageOffset, // VkOffset3D imageOffset;
184 bufferImageCopy.imageExtent // VkExtent3D imageExtent;
185 };
186 return bufferImageCopy2;
187 }
188
convertvkImageBlitTovkImageBlit2KHR(VkImageBlit imageBlit)189 VkImageBlit2KHR convertvkImageBlitTovkImageBlit2KHR(VkImageBlit imageBlit)
190 {
191 const VkImageBlit2KHR imageBlit2 =
192 {
193 VK_STRUCTURE_TYPE_IMAGE_BLIT_2_KHR, // VkStructureType sType;
194 DE_NULL, // const void* pNext;
195 imageBlit.srcSubresource, // VkImageSubresourceLayers srcSubresource;
196 { // VkOffset3D srcOffsets[2];
197 {
198 imageBlit.srcOffsets[0].x, // VkOffset3D srcOffsets[0].x;
199 imageBlit.srcOffsets[0].y, // VkOffset3D srcOffsets[0].y;
200 imageBlit.srcOffsets[0].z // VkOffset3D srcOffsets[0].z;
201 },
202 {
203 imageBlit.srcOffsets[1].x, // VkOffset3D srcOffsets[1].x;
204 imageBlit.srcOffsets[1].y, // VkOffset3D srcOffsets[1].y;
205 imageBlit.srcOffsets[1].z // VkOffset3D srcOffsets[1].z;
206 }
207 },
208 imageBlit.dstSubresource, // VkImageSubresourceLayers dstSubresource;
209 { // VkOffset3D srcOffsets[2];
210 {
211 imageBlit.dstOffsets[0].x, // VkOffset3D dstOffsets[0].x;
212 imageBlit.dstOffsets[0].y, // VkOffset3D dstOffsets[0].y;
213 imageBlit.dstOffsets[0].z // VkOffset3D dstOffsets[0].z;
214 },
215 {
216 imageBlit.dstOffsets[1].x, // VkOffset3D dstOffsets[1].x;
217 imageBlit.dstOffsets[1].y, // VkOffset3D dstOffsets[1].y;
218 imageBlit.dstOffsets[1].z // VkOffset3D dstOffsets[1].z;
219 }
220 }
221 };
222 return imageBlit2;
223 }
224
convertvkImageResolveTovkImageResolve2KHR(VkImageResolve imageResolve)225 VkImageResolve2KHR convertvkImageResolveTovkImageResolve2KHR(VkImageResolve imageResolve)
226 {
227 const VkImageResolve2KHR imageResolve2 =
228 {
229 VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR, // VkStructureType sType;
230 DE_NULL, // const void* pNext;
231 imageResolve.srcSubresource, // VkImageSubresourceLayers srcSubresource;
232 imageResolve.srcOffset, // VkOffset3D srcOffset;
233 imageResolve.dstSubresource, // VkImageSubresourceLayers dstSubresource;
234 imageResolve.dstOffset, // VkOffset3D dstOffset;
235 imageResolve.extent // VkExtent3D extent;
236 };
237 return imageResolve2;
238 }
239
getAspectFlags(tcu::TextureFormat format)240 VkImageAspectFlags getAspectFlags (tcu::TextureFormat format)
241 {
242 VkImageAspectFlags aspectFlag = 0;
243 aspectFlag |= (tcu::hasDepthComponent(format.order)? VK_IMAGE_ASPECT_DEPTH_BIT : 0);
244 aspectFlag |= (tcu::hasStencilComponent(format.order)? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
245
246 if (!aspectFlag)
247 aspectFlag = VK_IMAGE_ASPECT_COLOR_BIT;
248
249 return aspectFlag;
250 }
251
getAspectFlags(VkFormat format)252 VkImageAspectFlags getAspectFlags (VkFormat format)
253 {
254 if (isCompressedFormat(format))
255 return VK_IMAGE_ASPECT_COLOR_BIT;
256 else
257 return getAspectFlags(mapVkFormat(format));
258 }
259
getSizeCompatibleTcuTextureFormat(VkFormat format)260 tcu::TextureFormat getSizeCompatibleTcuTextureFormat (VkFormat format)
261 {
262 if (isCompressedFormat(format))
263 return (getBlockSizeInBytes(format) == 8) ? mapVkFormat(VK_FORMAT_R16G16B16A16_UINT) : mapVkFormat(VK_FORMAT_R32G32B32A32_UINT);
264 else
265 return mapVkFormat(format);
266 }
267
268 // This is effectively same as vk::isFloatFormat(mapTextureFormat(format))
269 // except that it supports some formats that are not mappable to VkFormat.
270 // When we are checking combined depth and stencil formats, each aspect is
271 // checked separately, and in some cases we construct PBA with a format that
272 // is not mappable to VkFormat.
isFloatFormat(tcu::TextureFormat format)273 bool isFloatFormat (tcu::TextureFormat format)
274 {
275 return tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
276 }
277
278 union CopyRegion
279 {
280 VkBufferCopy bufferCopy;
281 VkImageCopy imageCopy;
282 VkBufferImageCopy bufferImageCopy;
283 VkImageBlit imageBlit;
284 VkImageResolve imageResolve;
285 };
286
287 struct ImageParms
288 {
289 VkImageType imageType;
290 VkFormat format;
291 VkExtent3D extent;
292 VkImageTiling tiling;
293 VkImageLayout operationLayout;
294 VkImageCreateFlags createFlags;
295 FillMode fillMode;
296 };
297
298 struct TestParams
299 {
300 union Data
301 {
302 struct Buffer
303 {
304 VkDeviceSize size;
305 } buffer;
306
307 ImageParms image;
308 } src, dst;
309
310 std::vector<CopyRegion> regions;
311
312 union
313 {
314 VkFilter filter;
315 VkSampleCountFlagBits samples;
316 };
317
318 AllocationKind allocationKind;
319 ExtensionUse extensionUse;
320 deUint32 mipLevels;
321 deBool singleCommand;
322 deUint32 barrierCount;
323 deBool separateDepthStencilLayouts;
324 deBool clearDestination;
325 deBool imageOffset;
326
TestParamsvkt::api::__anon1525b85c0111::TestParams327 TestParams (void)
328 {
329 allocationKind = ALLOCATION_KIND_DEDICATED;
330 extensionUse = EXTENSION_USE_NONE;
331 mipLevels = 1u;
332 singleCommand = DE_TRUE;
333 barrierCount = 1u;
334 separateDepthStencilLayouts = DE_FALSE;
335 src.image.createFlags = VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM;
336 dst.image.createFlags = VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM;
337 src.image.fillMode = FILL_MODE_GRADIENT;
338 dst.image.fillMode = FILL_MODE_WHITE;
339 clearDestination = DE_FALSE;
340 samples = VK_SAMPLE_COUNT_1_BIT;
341 imageOffset = false;
342 }
343 };
344
allocateBuffer(const InstanceInterface & vki,const DeviceInterface & vkd,const VkPhysicalDevice & physDevice,const VkDevice device,const VkBuffer & buffer,const MemoryRequirement requirement,Allocator & allocator,AllocationKind allocationKind)345 de::MovePtr<Allocation> allocateBuffer (const InstanceInterface& vki,
346 const DeviceInterface& vkd,
347 const VkPhysicalDevice& physDevice,
348 const VkDevice device,
349 const VkBuffer& buffer,
350 const MemoryRequirement requirement,
351 Allocator& allocator,
352 AllocationKind allocationKind)
353 {
354 switch (allocationKind)
355 {
356 case ALLOCATION_KIND_SUBALLOCATED:
357 {
358 const VkMemoryRequirements memoryRequirements = getBufferMemoryRequirements(vkd, device, buffer);
359
360 return allocator.allocate(memoryRequirements, requirement);
361 }
362
363 case ALLOCATION_KIND_DEDICATED:
364 {
365 return allocateDedicated(vki, vkd, physDevice, device, buffer, requirement);
366 }
367
368 default:
369 {
370 TCU_THROW(InternalError, "Invalid allocation kind");
371 }
372 }
373 }
374
allocateImage(const InstanceInterface & vki,const DeviceInterface & vkd,const VkPhysicalDevice & physDevice,const VkDevice device,const VkImage & image,const MemoryRequirement requirement,Allocator & allocator,AllocationKind allocationKind,const deUint32 offset)375 de::MovePtr<Allocation> allocateImage (const InstanceInterface& vki,
376 const DeviceInterface& vkd,
377 const VkPhysicalDevice& physDevice,
378 const VkDevice device,
379 const VkImage& image,
380 const MemoryRequirement requirement,
381 Allocator& allocator,
382 AllocationKind allocationKind,
383 const deUint32 offset)
384 {
385 switch (allocationKind)
386 {
387 case ALLOCATION_KIND_SUBALLOCATED:
388 {
389 VkMemoryRequirements memoryRequirements = getImageMemoryRequirements(vkd, device, image);
390 memoryRequirements.size += offset;
391
392 return allocator.allocate(memoryRequirements, requirement);
393 }
394
395 case ALLOCATION_KIND_DEDICATED:
396 {
397 VkMemoryRequirements memoryRequirements = getImageMemoryRequirements(vkd, device, image);
398 memoryRequirements.size += offset;
399
400 const VkMemoryDedicatedAllocateInfo dedicatedAllocationInfo =
401 {
402 VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, // VkStructureType sType
403 DE_NULL, // const void* pNext
404 image, // VkImage image
405 DE_NULL // VkBuffer buffer
406 };
407
408 return allocateExtended(vki, vkd, physDevice, device, memoryRequirements, requirement, &dedicatedAllocationInfo);
409 }
410
411 default:
412 {
413 TCU_THROW(InternalError, "Invalid allocation kind");
414 }
415 }
416 }
417
418
getArraySize(const ImageParms & parms)419 inline deUint32 getArraySize(const ImageParms& parms)
420 {
421 return (parms.imageType != VK_IMAGE_TYPE_3D) ? parms.extent.depth : 1u;
422 }
423
getCreateFlags(const ImageParms & parms)424 inline VkImageCreateFlags getCreateFlags(const ImageParms& parms)
425 {
426 if (parms.createFlags == VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM)
427 return parms.imageType == VK_IMAGE_TYPE_2D && parms.extent.depth % 6 == 0 ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0;
428 else
429 return parms.createFlags;
430 }
431
getExtent3D(const ImageParms & parms,deUint32 mipLevel=0u)432 inline VkExtent3D getExtent3D(const ImageParms& parms, deUint32 mipLevel = 0u)
433 {
434 const bool isCompressed = isCompressedFormat(parms.format);
435 const deUint32 blockWidth = (isCompressed) ? getBlockWidth(parms.format) : 1u;
436 const deUint32 blockHeight = (isCompressed) ? getBlockHeight(parms.format) : 1u;
437
438 if (isCompressed && mipLevel != 0u)
439 DE_FATAL("Not implemented");
440
441 const VkExtent3D extent =
442 {
443 (parms.extent.width >> mipLevel) * blockWidth,
444 (parms.imageType != VK_IMAGE_TYPE_1D) ? ((parms.extent.height >> mipLevel) * blockHeight) : 1u,
445 (parms.imageType == VK_IMAGE_TYPE_3D) ? parms.extent.depth : 1u,
446 };
447 return extent;
448 }
449
mapCombinedToDepthTransferFormat(const tcu::TextureFormat & combinedFormat)450 const tcu::TextureFormat mapCombinedToDepthTransferFormat (const tcu::TextureFormat& combinedFormat)
451 {
452 tcu::TextureFormat format;
453 switch (combinedFormat.type)
454 {
455 case tcu::TextureFormat::UNORM_INT16:
456 case tcu::TextureFormat::UNSIGNED_INT_16_8_8:
457 format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
458 break;
459 case tcu::TextureFormat::UNSIGNED_INT_24_8_REV:
460 format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNSIGNED_INT_24_8_REV);
461 break;
462 case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
463 case tcu::TextureFormat::FLOAT:
464 format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT);
465 break;
466 default:
467 DE_ASSERT(false);
468 break;
469 }
470 return format;
471 }
472
473 class CopiesAndBlittingTestInstance : public vkt::TestInstance
474 {
475 public:
476 CopiesAndBlittingTestInstance (Context& context,
477 TestParams testParams);
478 virtual tcu::TestStatus iterate (void) = 0;
479
480 protected:
481 const TestParams m_params;
482
483 VkDevice m_device;
484 VkQueue m_queue;
485 Allocator* m_allocator;
486 Move<VkCommandPool> m_cmdPool;
487 Move<VkCommandBuffer> m_cmdBuffer;
488 de::MovePtr<tcu::TextureLevel> m_sourceTextureLevel;
489 de::MovePtr<tcu::TextureLevel> m_destinationTextureLevel;
490 de::MovePtr<tcu::TextureLevel> m_expectedTextureLevel[16];
491
492 void generateBuffer (tcu::PixelBufferAccess buffer, int width, int height, int depth = 1, FillMode = FILL_MODE_GRADIENT);
493 virtual void generateExpectedResult (void);
494 void uploadBuffer (const tcu::ConstPixelBufferAccess& bufferAccess, const Allocation& bufferAlloc);
495 void uploadImage (const tcu::ConstPixelBufferAccess& src, VkImage dst, const ImageParms& parms, const deUint32 mipLevels = 1u);
496 virtual tcu::TestStatus checkTestResult (tcu::ConstPixelBufferAccess result);
497 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u) = 0;
calculateSize(tcu::ConstPixelBufferAccess src) const498 deUint32 calculateSize (tcu::ConstPixelBufferAccess src) const
499 {
500 return src.getWidth() * src.getHeight() * src.getDepth() * tcu::getPixelSize(src.getFormat());
501 }
502
503 de::MovePtr<tcu::TextureLevel> readImage (vk::VkImage image,
504 const ImageParms& imageParms,
505 const deUint32 mipLevel = 0u);
506
507 private:
508 void uploadImageAspect (const tcu::ConstPixelBufferAccess& src,
509 const VkImage& dst,
510 const ImageParms& parms,
511 const deUint32 mipLevels = 1u);
512 void readImageAspect (vk::VkImage src,
513 const tcu::PixelBufferAccess& dst,
514 const ImageParms& parms,
515 const deUint32 mipLevel = 0u);
516 };
517
CopiesAndBlittingTestInstance(Context & context,TestParams testParams)518 CopiesAndBlittingTestInstance::CopiesAndBlittingTestInstance (Context& context, TestParams testParams)
519 : vkt::TestInstance (context)
520 , m_params (testParams)
521 {
522 // Store default device, queue and allocator. Some tests override these with custom device and queue.
523 m_device = context.getDevice();
524 m_queue = context.getUniversalQueue();
525 m_allocator = &context.getDefaultAllocator();
526 const DeviceInterface& vk = context.getDeviceInterface();
527 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
528
529 // Create command pool
530 m_cmdPool = createCommandPool(vk, m_device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
531
532 // Create command buffer
533 m_cmdBuffer = allocateCommandBuffer(vk, m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
534 }
535
generateBuffer(tcu::PixelBufferAccess buffer,int width,int height,int depth,FillMode mode)536 void CopiesAndBlittingTestInstance::generateBuffer (tcu::PixelBufferAccess buffer, int width, int height, int depth, FillMode mode)
537 {
538 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(buffer.getFormat().type);
539 tcu::Vec4 maxValue (1.0f);
540
541 if (buffer.getFormat().order == tcu::TextureFormat::S)
542 {
543 // Stencil-only is stored in the first component. Stencil is always 8 bits.
544 maxValue.x() = 1 << 8;
545 }
546 else if (buffer.getFormat().order == tcu::TextureFormat::DS)
547 {
548 // In a combined format, fillWithComponentGradients expects stencil in the fourth component.
549 maxValue.w() = 1 << 8;
550 }
551 else if (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
552 {
553 // The tcu::Vectors we use as pixels are 32-bit, so clamp to that.
554 const tcu::IVec4 bits = tcu::min(tcu::getTextureFormatBitDepth(buffer.getFormat()), tcu::IVec4(32));
555 const int signBit = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? 1 : 0);
556
557 for (int i = 0; i < 4; ++i)
558 {
559 if (bits[i] != 0)
560 maxValue[i] = static_cast<float>((deUint64(1) << (bits[i] - signBit)) - 1);
561 }
562 }
563
564 if (mode == FILL_MODE_GRADIENT)
565 {
566 tcu::fillWithComponentGradients2(buffer, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), maxValue);
567 return;
568 }
569
570 const tcu::Vec4 redColor (maxValue.x(), 0.0, 0.0, maxValue.w());
571 const tcu::Vec4 greenColor (0.0, maxValue.y(), 0.0, maxValue.w());
572 const tcu::Vec4 blueColor (0.0, 0.0, maxValue.z(), maxValue.w());
573 const tcu::Vec4 whiteColor (maxValue.x(), maxValue.y(), maxValue.z(), maxValue.w());
574 const tcu::Vec4 blackColor (0.0f, 0.0f, 0.0f, 0.0f);
575
576 for (int z = 0; z < depth; ++z)
577 for (int y = 0; y < height; ++y)
578 for (int x = 0; x < width; ++x)
579 {
580 switch (mode)
581 {
582 case FILL_MODE_WHITE:
583 if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
584 {
585 buffer.setPixDepth(1.0f, x, y, z);
586 if (tcu::hasStencilComponent(buffer.getFormat().order))
587 buffer.setPixStencil(255, x, y, z);
588 }
589 else
590 buffer.setPixel(whiteColor, x, y, z);
591 break;
592
593 case FILL_MODE_BLACK:
594 if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
595 {
596 buffer.setPixDepth(0.0f, x, y, z);
597 if (tcu::hasStencilComponent(buffer.getFormat().order))
598 buffer.setPixStencil(0, x, y, z);
599 }
600 else
601 buffer.setPixel(blackColor, x, y, z);
602 break;
603
604 case FILL_MODE_RED:
605 if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
606 {
607 buffer.setPixDepth(redColor[0], x, y, z);
608 if (tcu::hasStencilComponent(buffer.getFormat().order))
609 buffer.setPixStencil((int)redColor[3], x, y, z);
610 }
611 else
612 buffer.setPixel(redColor, x, y, z);
613 break;
614
615 case FILL_MODE_BLUE_RED_X:
616 case FILL_MODE_BLUE_RED_Y:
617 case FILL_MODE_BLUE_RED_Z:
618 bool useBlue;
619 switch (mode)
620 {
621 case FILL_MODE_BLUE_RED_X: useBlue = (x & 1); break;
622 case FILL_MODE_BLUE_RED_Y: useBlue = (y & 1); break;
623 case FILL_MODE_BLUE_RED_Z: useBlue = (z & 1); break;
624 default: DE_ASSERT(false); break;
625 }
626 if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
627 {
628 buffer.setPixDepth((useBlue ? blueColor[0] : redColor[0]), x, y, z);
629 if (tcu::hasStencilComponent(buffer.getFormat().order))
630 buffer.setPixStencil((useBlue ? (int) blueColor[3] : (int)redColor[3]), x, y, z);
631 }
632 else
633 buffer.setPixel((useBlue ? blueColor : redColor), x, y, z);
634 break;
635
636 case FILL_MODE_MULTISAMPLE:
637 {
638 float xScaled = static_cast<float>(x) / static_cast<float>(width);
639 float yScaled = static_cast<float>(y) / static_cast<float>(height);
640 buffer.setPixel((xScaled == yScaled) ? tcu::Vec4(0.0, 0.5, 0.5, 1.0) : ((xScaled > yScaled) ? greenColor : blueColor), x, y, z);
641 break;
642 }
643
644 default:
645 break;
646 }
647 }
648 }
649
uploadBuffer(const tcu::ConstPixelBufferAccess & bufferAccess,const Allocation & bufferAlloc)650 void CopiesAndBlittingTestInstance::uploadBuffer (const tcu::ConstPixelBufferAccess& bufferAccess, const Allocation& bufferAlloc)
651 {
652 const DeviceInterface& vk = m_context.getDeviceInterface();
653 const deUint32 bufferSize = calculateSize(bufferAccess);
654
655 // Write buffer data
656 deMemcpy(bufferAlloc.getHostPtr(), bufferAccess.getDataPtr(), bufferSize);
657 flushAlloc(vk, m_device, bufferAlloc);
658 }
659
uploadImageAspect(const tcu::ConstPixelBufferAccess & imageAccess,const VkImage & image,const ImageParms & parms,const deUint32 mipLevels)660 void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBufferAccess& imageAccess, const VkImage& image, const ImageParms& parms, const deUint32 mipLevels)
661 {
662 const InstanceInterface& vki = m_context.getInstanceInterface();
663 const DeviceInterface& vk = m_context.getDeviceInterface();
664 const VkPhysicalDevice vkPhysDevice = m_context.getPhysicalDevice();
665 const VkDevice vkDevice = m_device;
666 const VkQueue queue = m_queue;
667 Allocator& memAlloc = *m_allocator;
668 Move<VkBuffer> buffer;
669 const deUint32 bufferSize = calculateSize(imageAccess);
670 de::MovePtr<Allocation> bufferAlloc;
671 const deUint32 arraySize = getArraySize(parms);
672 const VkExtent3D imageExtent = getExtent3D(parms);
673 std::vector <VkBufferImageCopy> copyRegions;
674
675 // Create source buffer
676 {
677 const VkBufferCreateInfo bufferParams =
678 {
679 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
680 DE_NULL, // const void* pNext;
681 0u, // VkBufferCreateFlags flags;
682 bufferSize, // VkDeviceSize size;
683 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage;
684 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
685 0u, // deUint32 queueFamilyIndexCount;
686 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
687 };
688
689 buffer = createBuffer(vk, vkDevice, &bufferParams);
690 bufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *buffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
691 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
692 }
693
694 // Barriers for copying buffer to image
695 const VkBufferMemoryBarrier preBufferBarrier =
696 {
697 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
698 DE_NULL, // const void* pNext;
699 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask;
700 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
701 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
702 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
703 *buffer, // VkBuffer buffer;
704 0u, // VkDeviceSize offset;
705 bufferSize // VkDeviceSize size;
706 };
707
708 const VkImageAspectFlags formatAspect = (m_params.separateDepthStencilLayouts) ? getAspectFlags(imageAccess.getFormat()) : getAspectFlags(parms.format);
709 const bool skipPreImageBarrier = (m_params.separateDepthStencilLayouts) ? false : ((formatAspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) &&
710 getAspectFlags(imageAccess.getFormat()) == VK_IMAGE_ASPECT_STENCIL_BIT));
711
712 const VkImageMemoryBarrier preImageBarrier =
713 {
714 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
715 DE_NULL, // const void* pNext;
716 0u, // VkAccessFlags srcAccessMask;
717 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
718 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
719 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
720 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
721 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
722 image, // VkImage image;
723 { // VkImageSubresourceRange subresourceRange;
724 formatAspect, // VkImageAspectFlags aspect;
725 0u, // deUint32 baseMipLevel;
726 mipLevels, // deUint32 mipLevels;
727 0u, // deUint32 baseArraySlice;
728 arraySize, // deUint32 arraySize;
729 }
730 };
731
732 const VkImageMemoryBarrier postImageBarrier =
733 {
734 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
735 DE_NULL, // const void* pNext;
736 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
737 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
738 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
739 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
740 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
741 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
742 image, // VkImage image;
743 { // VkImageSubresourceRange subresourceRange;
744 formatAspect, // VkImageAspectFlags aspect;
745 0u, // deUint32 baseMipLevel;
746 mipLevels, // deUint32 mipLevels;
747 0u, // deUint32 baseArraySlice;
748 arraySize, // deUint32 arraySize;
749 }
750 };
751
752 for (deUint32 mipLevelNdx = 0; mipLevelNdx < mipLevels; mipLevelNdx++)
753 {
754 const VkExtent3D copyExtent =
755 {
756 imageExtent.width >> mipLevelNdx,
757 imageExtent.height >> mipLevelNdx,
758 imageExtent.depth
759 };
760
761 const bool isCompressed = isCompressedFormat(parms.format);
762 const deUint32 blockWidth = (isCompressed) ? getBlockWidth(parms.format) : 1u;
763 const deUint32 blockHeight = (isCompressed) ? getBlockHeight(parms.format) : 1u;
764 deUint32 rowLength = ((copyExtent.width + blockWidth-1) / blockWidth) * blockWidth;
765 deUint32 imageHeight = ((copyExtent.height + blockHeight-1) / blockHeight) * blockHeight;
766
767 const VkBufferImageCopy copyRegion =
768 {
769 0u, // VkDeviceSize bufferOffset;
770 rowLength, // deUint32 bufferRowLength;
771 imageHeight, // deUint32 bufferImageHeight;
772 {
773 getAspectFlags(imageAccess.getFormat()), // VkImageAspectFlags aspect;
774 mipLevelNdx, // deUint32 mipLevel;
775 0u, // deUint32 baseArrayLayer;
776 arraySize, // deUint32 layerCount;
777 }, // VkImageSubresourceLayers imageSubresource;
778 { 0, 0, 0 }, // VkOffset3D imageOffset;
779 copyExtent // VkExtent3D imageExtent;
780 };
781
782 copyRegions.push_back(copyRegion);
783 }
784
785 // Write buffer data
786 deMemcpy(bufferAlloc->getHostPtr(), imageAccess.getDataPtr(), bufferSize);
787 flushAlloc(vk, vkDevice, *bufferAlloc);
788
789 // Copy buffer to image
790 beginCommandBuffer(vk, *m_cmdBuffer);
791 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL,
792 1, &preBufferBarrier, (skipPreImageBarrier ? 0 : 1), (skipPreImageBarrier ? DE_NULL : &preImageBarrier));
793 vk.cmdCopyBufferToImage(*m_cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegions.size(), ©Regions[0]);
794 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
795 endCommandBuffer(vk, *m_cmdBuffer);
796
797 submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
798 m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
799 }
800
uploadImage(const tcu::ConstPixelBufferAccess & src,VkImage dst,const ImageParms & parms,const deUint32 mipLevels)801 void CopiesAndBlittingTestInstance::uploadImage (const tcu::ConstPixelBufferAccess& src, VkImage dst, const ImageParms& parms, const deUint32 mipLevels)
802 {
803 if (tcu::isCombinedDepthStencilType(src.getFormat().type))
804 {
805 if (tcu::hasDepthComponent(src.getFormat().order))
806 {
807 tcu::TextureLevel depthTexture (mapCombinedToDepthTransferFormat(src.getFormat()), src.getWidth(), src.getHeight(), src.getDepth());
808 tcu::copy(depthTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH));
809 uploadImageAspect(depthTexture.getAccess(), dst, parms, mipLevels);
810 }
811
812 if (tcu::hasStencilComponent(src.getFormat().order))
813 {
814 tcu::TextureLevel stencilTexture (tcu::getEffectiveDepthStencilTextureFormat(src.getFormat(), tcu::Sampler::MODE_STENCIL), src.getWidth(), src.getHeight(), src.getDepth());
815 tcu::copy(stencilTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL));
816 uploadImageAspect(stencilTexture.getAccess(), dst, parms, mipLevels);
817 }
818 }
819 else
820 uploadImageAspect(src, dst, parms, mipLevels);
821 }
822
checkTestResult(tcu::ConstPixelBufferAccess result)823 tcu::TestStatus CopiesAndBlittingTestInstance::checkTestResult (tcu::ConstPixelBufferAccess result)
824 {
825 const tcu::ConstPixelBufferAccess expected = m_expectedTextureLevel[0]->getAccess();
826
827 if (isFloatFormat(result.getFormat()))
828 {
829 const tcu::Vec4 threshold (0.0f);
830 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
831 return tcu::TestStatus::fail("CopiesAndBlitting test");
832 }
833 else
834 {
835 const tcu::UVec4 threshold (0u);
836 if (tcu::hasDepthComponent(result.getFormat().order) || tcu::hasStencilComponent(result.getFormat().order))
837 {
838 if (!tcu::dsThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, 0.1f, tcu::COMPARE_LOG_RESULT))
839 return tcu::TestStatus::fail("CopiesAndBlitting test");
840 }
841 else
842 {
843 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
844 return tcu::TestStatus::fail("CopiesAndBlitting test");
845 }
846 }
847
848 return tcu::TestStatus::pass("CopiesAndBlitting test");
849 }
850
generateExpectedResult(void)851 void CopiesAndBlittingTestInstance::generateExpectedResult (void)
852 {
853 const tcu::ConstPixelBufferAccess src = m_sourceTextureLevel->getAccess();
854 const tcu::ConstPixelBufferAccess dst = m_destinationTextureLevel->getAccess();
855
856 m_expectedTextureLevel[0] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
857 tcu::copy(m_expectedTextureLevel[0]->getAccess(), dst);
858
859 for (deUint32 i = 0; i < m_params.regions.size(); i++)
860 copyRegionToTextureLevel(src, m_expectedTextureLevel[0]->getAccess(), m_params.regions[i]);
861 }
862
readImageAspect(vk::VkImage image,const tcu::PixelBufferAccess & dst,const ImageParms & imageParms,const deUint32 mipLevel)863 void CopiesAndBlittingTestInstance::readImageAspect (vk::VkImage image,
864 const tcu::PixelBufferAccess& dst,
865 const ImageParms& imageParms,
866 const deUint32 mipLevel)
867 {
868 const InstanceInterface& vki = m_context.getInstanceInterface();
869 const DeviceInterface& vk = m_context.getDeviceInterface();
870 const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
871 const VkDevice device = m_device;
872 const VkQueue queue = m_queue;
873 Allocator& allocator = *m_allocator;
874
875 Move<VkBuffer> buffer;
876 de::MovePtr<Allocation> bufferAlloc;
877 const VkDeviceSize pixelDataSize = calculateSize(dst);
878 const VkExtent3D imageExtent = getExtent3D(imageParms, mipLevel);
879
880 // Create destination buffer
881 {
882 const VkBufferCreateInfo bufferParams =
883 {
884 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
885 DE_NULL, // const void* pNext;
886 0u, // VkBufferCreateFlags flags;
887 pixelDataSize, // VkDeviceSize size;
888 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
889 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
890 0u, // deUint32 queueFamilyIndexCount;
891 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
892 };
893
894 buffer = createBuffer(vk, device, &bufferParams);
895 bufferAlloc = allocateBuffer(vki, vk, physDevice, device, *buffer, MemoryRequirement::HostVisible, allocator, m_params.allocationKind);
896 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
897
898 deMemset(bufferAlloc->getHostPtr(), 0, static_cast<size_t>(pixelDataSize));
899 flushAlloc(vk, device, *bufferAlloc);
900 }
901
902 // Barriers for copying image to buffer
903 const VkImageAspectFlags formatAspect = getAspectFlags(imageParms.format);
904 const VkImageMemoryBarrier imageBarrier =
905 {
906 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
907 DE_NULL, // const void* pNext;
908 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
909 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
910 imageParms.operationLayout, // VkImageLayout oldLayout;
911 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout;
912 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
913 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
914 image, // VkImage image;
915 { // VkImageSubresourceRange subresourceRange;
916 formatAspect, // VkImageAspectFlags aspectMask;
917 mipLevel, // deUint32 baseMipLevel;
918 1u, // deUint32 mipLevels;
919 0u, // deUint32 baseArraySlice;
920 getArraySize(imageParms)// deUint32 arraySize;
921 }
922 };
923
924 const VkBufferMemoryBarrier bufferBarrier =
925 {
926 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
927 DE_NULL, // const void* pNext;
928 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
929 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
930 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
931 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
932 *buffer, // VkBuffer buffer;
933 0u, // VkDeviceSize offset;
934 pixelDataSize // VkDeviceSize size;
935 };
936
937 const VkImageMemoryBarrier postImageBarrier =
938 {
939 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
940 DE_NULL, // const void* pNext;
941 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags srcAccessMask;
942 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
943 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout oldLayout;
944 imageParms.operationLayout, // VkImageLayout newLayout;
945 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
946 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
947 image, // VkImage image;
948 {
949 formatAspect, // VkImageAspectFlags aspectMask;
950 mipLevel, // deUint32 baseMipLevel;
951 1u, // deUint32 mipLevels;
952 0u, // deUint32 baseArraySlice;
953 getArraySize(imageParms) // deUint32 arraySize;
954 } // VkImageSubresourceRange subresourceRange;
955 };
956
957 // Copy image to buffer
958 const bool isCompressed = isCompressedFormat(imageParms.format);
959 const deUint32 blockWidth = (isCompressed) ? getBlockWidth(imageParms.format) : 1u;
960 const deUint32 blockHeight = (isCompressed) ? getBlockHeight(imageParms.format) : 1u;
961 deUint32 rowLength = ((imageExtent.width + blockWidth-1) / blockWidth) * blockWidth;
962 deUint32 imageHeight = ((imageExtent.height + blockHeight-1) / blockHeight) * blockHeight;
963
964 // Copy image to buffer - note that there are cases where m_params.dst.image.format is not the same as dst.getFormat()
965 const VkImageAspectFlags aspect = isCompressedFormat(m_params.dst.image.format) ?
966 static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_COLOR_BIT) : getAspectFlags(dst.getFormat());
967 const VkBufferImageCopy copyRegion =
968 {
969 0u, // VkDeviceSize bufferOffset;
970 rowLength, // deUint32 bufferRowLength;
971 imageHeight, // deUint32 bufferImageHeight;
972 {
973 aspect, // VkImageAspectFlags aspect;
974 mipLevel, // deUint32 mipLevel;
975 0u, // deUint32 baseArrayLayer;
976 getArraySize(imageParms), // deUint32 layerCount;
977 }, // VkImageSubresourceLayers imageSubresource;
978 { 0, 0, 0 }, // VkOffset3D imageOffset;
979 imageExtent // VkExtent3D imageExtent;
980 };
981
982 beginCommandBuffer(vk, *m_cmdBuffer);
983 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier);
984 vk.cmdCopyImageToBuffer(*m_cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, ©Region);
985 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT|VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 1, &postImageBarrier);
986 endCommandBuffer(vk, *m_cmdBuffer);
987
988 submitCommandsAndWait(vk, device, queue, *m_cmdBuffer);
989 m_context.resetCommandPoolForVKSC(device, *m_cmdPool);
990
991 // Read buffer data
992 invalidateAlloc(vk, device, *bufferAlloc);
993 tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferAlloc->getHostPtr()));
994 }
995
readImage(vk::VkImage image,const ImageParms & parms,const deUint32 mipLevel)996 de::MovePtr<tcu::TextureLevel> CopiesAndBlittingTestInstance::readImage (vk::VkImage image,
997 const ImageParms& parms,
998 const deUint32 mipLevel)
999 {
1000 const tcu::TextureFormat imageFormat = getSizeCompatibleTcuTextureFormat(parms.format);
1001 de::MovePtr<tcu::TextureLevel> resultLevel (new tcu::TextureLevel(imageFormat, parms.extent.width >> mipLevel, parms.extent.height >> mipLevel, parms.extent.depth));
1002
1003 if (tcu::isCombinedDepthStencilType(imageFormat.type))
1004 {
1005 if (tcu::hasDepthComponent(imageFormat.order))
1006 {
1007 tcu::TextureLevel depthTexture (mapCombinedToDepthTransferFormat(imageFormat), parms.extent.width >> mipLevel, parms.extent.height >> mipLevel, parms.extent.depth);
1008 readImageAspect(image, depthTexture.getAccess(), parms, mipLevel);
1009 tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_DEPTH), depthTexture.getAccess());
1010 }
1011
1012 if (tcu::hasStencilComponent(imageFormat.order))
1013 {
1014 tcu::TextureLevel stencilTexture (tcu::getEffectiveDepthStencilTextureFormat(imageFormat, tcu::Sampler::MODE_STENCIL), parms.extent.width >> mipLevel, parms.extent.height >> mipLevel, parms.extent.depth);
1015 readImageAspect(image, stencilTexture.getAccess(), parms, mipLevel);
1016 tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_STENCIL), stencilTexture.getAccess());
1017 }
1018 }
1019 else
1020 readImageAspect(image, resultLevel->getAccess(), parms, mipLevel);
1021
1022 return resultLevel;
1023 }
1024
1025 // Copy from image to image.
1026
1027 class CopyImageToImage : public CopiesAndBlittingTestInstance
1028 {
1029 public:
1030 CopyImageToImage (Context& context,
1031 TestParams params);
1032 virtual tcu::TestStatus iterate (void);
1033
1034 protected:
1035 virtual tcu::TestStatus checkTestResult (tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess());
1036
1037 private:
1038 Move<VkImage> m_source;
1039 de::MovePtr<Allocation> m_sourceImageAlloc;
1040 Move<VkImage> m_destination;
1041 de::MovePtr<Allocation> m_destinationImageAlloc;
1042
1043 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
1044 };
1045
CopyImageToImage(Context & context,TestParams params)1046 CopyImageToImage::CopyImageToImage (Context& context, TestParams params)
1047 : CopiesAndBlittingTestInstance(context, params)
1048 {
1049 const InstanceInterface& vki = context.getInstanceInterface();
1050 const DeviceInterface& vk = context.getDeviceInterface();
1051 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
1052 const VkDevice vkDevice = m_device;
1053 Allocator& memAlloc = context.getDefaultAllocator();
1054
1055 // Create source image
1056 {
1057 const VkImageCreateInfo sourceImageParams =
1058 {
1059 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1060 DE_NULL, // const void* pNext;
1061 getCreateFlags(m_params.src.image), // VkImageCreateFlags flags;
1062 m_params.src.image.imageType, // VkImageType imageType;
1063 m_params.src.image.format, // VkFormat format;
1064 getExtent3D(m_params.src.image), // VkExtent3D extent;
1065 1u, // deUint32 mipLevels;
1066 getArraySize(m_params.src.image), // deUint32 arraySize;
1067 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
1068 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1069 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1070 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
1071 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1072 0u, // deUint32 queueFamilyIndexCount;
1073 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
1074 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
1075 };
1076
1077 m_source = createImage(vk, vkDevice, &sourceImageParams);
1078 m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
1079 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
1080 }
1081
1082 // Create destination image
1083 {
1084 const VkImageCreateInfo destinationImageParams =
1085 {
1086 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1087 DE_NULL, // const void* pNext;
1088 getCreateFlags(m_params.dst.image), // VkImageCreateFlags flags;
1089 m_params.dst.image.imageType, // VkImageType imageType;
1090 m_params.dst.image.format, // VkFormat format;
1091 getExtent3D(m_params.dst.image), // VkExtent3D extent;
1092 1u, // deUint32 mipLevels;
1093 getArraySize(m_params.dst.image), // deUint32 arraySize;
1094 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
1095 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1096 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1097 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
1098 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1099 0u, // deUint32 queueFamilyIndexCount;
1100 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
1101 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
1102 };
1103
1104 m_destination = createImage(vk, vkDevice, &destinationImageParams);
1105 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
1106 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
1107 }
1108 }
1109
iterate(void)1110 tcu::TestStatus CopyImageToImage::iterate (void)
1111 {
1112 const bool srcCompressed = isCompressedFormat(m_params.src.image.format);
1113 const bool dstCompressed = isCompressedFormat(m_params.dst.image.format);
1114
1115 const tcu::TextureFormat srcTcuFormat = getSizeCompatibleTcuTextureFormat(m_params.src.image.format);
1116 const tcu::TextureFormat dstTcuFormat = getSizeCompatibleTcuTextureFormat(m_params.dst.image.format);
1117
1118 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
1119 (int)m_params.src.image.extent.width,
1120 (int)m_params.src.image.extent.height,
1121 (int)m_params.src.image.extent.depth));
1122 generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth, FILL_MODE_GRADIENT);
1123 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
1124 (int)m_params.dst.image.extent.width,
1125 (int)m_params.dst.image.extent.height,
1126 (int)m_params.dst.image.extent.depth));
1127 generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth, m_params.clearDestination ? FILL_MODE_WHITE : FILL_MODE_GRADIENT);
1128 generateExpectedResult();
1129
1130 uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
1131 uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
1132
1133 const DeviceInterface& vk = m_context.getDeviceInterface();
1134 const VkDevice vkDevice = m_device;
1135 const VkQueue queue = m_queue;
1136
1137 std::vector<VkImageCopy> imageCopies;
1138 std::vector<VkImageCopy2KHR> imageCopies2KHR;
1139 for (deUint32 i = 0; i < m_params.regions.size(); i++)
1140 {
1141 VkImageCopy imageCopy = m_params.regions[i].imageCopy;
1142
1143 // When copying between compressed and uncompressed formats the extent
1144 // members represent the texel dimensions of the source image.
1145 if (srcCompressed)
1146 {
1147 const deUint32 blockWidth = getBlockWidth(m_params.src.image.format);
1148 const deUint32 blockHeight = getBlockHeight(m_params.src.image.format);
1149
1150 imageCopy.srcOffset.x *= blockWidth;
1151 imageCopy.srcOffset.y *= blockHeight;
1152 imageCopy.extent.width *= blockWidth;
1153 imageCopy.extent.height *= blockHeight;
1154 }
1155
1156 if (dstCompressed)
1157 {
1158 const deUint32 blockWidth = getBlockWidth(m_params.dst.image.format);
1159 const deUint32 blockHeight = getBlockHeight(m_params.dst.image.format);
1160
1161 imageCopy.dstOffset.x *= blockWidth;
1162 imageCopy.dstOffset.y *= blockHeight;
1163 }
1164
1165 if (m_params.extensionUse == EXTENSION_USE_NONE)
1166 {
1167 imageCopies.push_back(imageCopy);
1168 }
1169 else
1170 {
1171 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1172 imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
1173 }
1174 }
1175
1176 VkImageMemoryBarrier imageBarriers[] =
1177 {
1178 // source image
1179 {
1180 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1181 DE_NULL, // const void* pNext;
1182 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1183 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
1184 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1185 m_params.src.image.operationLayout, // VkImageLayout newLayout;
1186 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1187 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
1188 m_source.get(), // VkImage image;
1189 { // VkImageSubresourceRange subresourceRange;
1190 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
1191 0u, // deUint32 baseMipLevel;
1192 1u, // deUint32 mipLevels;
1193 0u, // deUint32 baseArraySlice;
1194 getArraySize(m_params.src.image)// deUint32 arraySize;
1195 }
1196 },
1197 // destination image
1198 {
1199 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1200 DE_NULL, // const void* pNext;
1201 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1202 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1203 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1204 m_params.dst.image.operationLayout, // VkImageLayout newLayout;
1205 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1206 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
1207 m_destination.get(), // VkImage image;
1208 { // VkImageSubresourceRange subresourceRange;
1209 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
1210 0u, // deUint32 baseMipLevel;
1211 1u, // deUint32 mipLevels;
1212 0u, // deUint32 baseArraySlice;
1213 getArraySize(m_params.dst.image)// deUint32 arraySize;
1214 }
1215 },
1216 };
1217
1218 beginCommandBuffer(vk, *m_cmdBuffer);
1219 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers);
1220
1221 if (m_params.clearDestination)
1222 {
1223 VkImageSubresourceRange range = { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u };
1224 VkClearColorValue clearColor;
1225
1226 clearColor.float32[0] = 1.0f;
1227 clearColor.float32[1] = 1.0f;
1228 clearColor.float32[2] = 1.0f;
1229 clearColor.float32[3] = 1.0f;
1230 vk.cmdClearColorImage(*m_cmdBuffer, m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1u, &range);
1231 imageBarriers[0].oldLayout = imageBarriers[0].newLayout;
1232 imageBarriers[1].oldLayout = imageBarriers[1].newLayout;
1233 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers);
1234 }
1235
1236 if (m_params.extensionUse == EXTENSION_USE_NONE)
1237 {
1238 vk.cmdCopyImage(*m_cmdBuffer, m_source.get(), m_params.src.image.operationLayout, m_destination.get(), m_params.dst.image.operationLayout, (deUint32)imageCopies.size(), imageCopies.data());
1239 }
1240 #ifndef CTS_USES_VULKANSC
1241 else
1242 {
1243 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1244 const VkCopyImageInfo2KHR copyImageInfo2KHR =
1245 {
1246 VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR, // VkStructureType sType;
1247 DE_NULL, // const void* pNext;
1248 m_source.get(), // VkImage srcImage;
1249 m_params.src.image.operationLayout, // VkImageLayout srcImageLayout;
1250 m_destination.get(), // VkImage dstImage;
1251 m_params.dst.image.operationLayout, // VkImageLayout dstImageLayout;
1252 (deUint32)imageCopies2KHR.size(), // uint32_t regionCount;
1253 imageCopies2KHR.data() // const VkImageCopy2KHR* pRegions;
1254 };
1255
1256 vk.cmdCopyImage2(*m_cmdBuffer, ©ImageInfo2KHR);
1257 }
1258 #endif // CTS_USES_VULKANSC
1259
1260 endCommandBuffer(vk, *m_cmdBuffer);
1261
1262 submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
1263 m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
1264
1265 de::MovePtr<tcu::TextureLevel> resultTextureLevel = readImage(*m_destination, m_params.dst.image);
1266
1267 return checkTestResult(resultTextureLevel->getAccess());
1268 }
1269
checkTestResult(tcu::ConstPixelBufferAccess result)1270 tcu::TestStatus CopyImageToImage::checkTestResult (tcu::ConstPixelBufferAccess result)
1271 {
1272 const tcu::Vec4 fThreshold (0.0f);
1273 const tcu::UVec4 uThreshold (0u);
1274
1275 if (tcu::isCombinedDepthStencilType(result.getFormat().type))
1276 {
1277 if (tcu::hasDepthComponent(result.getFormat().order))
1278 {
1279 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_DEPTH;
1280 const tcu::ConstPixelBufferAccess depthResult = tcu::getEffectiveDepthStencilAccess(result, mode);
1281 const tcu::ConstPixelBufferAccess expectedResult = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
1282
1283 if (isFloatFormat(result.getFormat()))
1284 {
1285 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1286 return tcu::TestStatus::fail("CopiesAndBlitting test");
1287 }
1288 else
1289 {
1290 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1291 return tcu::TestStatus::fail("CopiesAndBlitting test");
1292 }
1293 }
1294
1295 if (tcu::hasStencilComponent(result.getFormat().order))
1296 {
1297 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_STENCIL;
1298 const tcu::ConstPixelBufferAccess stencilResult = tcu::getEffectiveDepthStencilAccess(result, mode);
1299 const tcu::ConstPixelBufferAccess expectedResult = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
1300
1301 if (isFloatFormat(result.getFormat()))
1302 {
1303 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1304 return tcu::TestStatus::fail("CopiesAndBlitting test");
1305 }
1306 else
1307 {
1308 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1309 return tcu::TestStatus::fail("CopiesAndBlitting test");
1310 }
1311 }
1312 }
1313 else
1314 {
1315 if (isFloatFormat(result.getFormat()))
1316 {
1317 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", m_expectedTextureLevel[0]->getAccess(), result, fThreshold, tcu::COMPARE_LOG_RESULT))
1318 return tcu::TestStatus::fail("CopiesAndBlitting test");
1319 }
1320 else
1321 {
1322 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", m_expectedTextureLevel[0]->getAccess(), result, uThreshold, tcu::COMPARE_LOG_RESULT))
1323 return tcu::TestStatus::fail("CopiesAndBlitting test");
1324 }
1325 }
1326
1327 return tcu::TestStatus::pass("CopiesAndBlitting test");
1328 }
1329
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)1330 void CopyImageToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
1331 {
1332 DE_UNREF(mipLevel);
1333
1334 VkOffset3D srcOffset = region.imageCopy.srcOffset;
1335 VkOffset3D dstOffset = region.imageCopy.dstOffset;
1336 VkExtent3D extent = region.imageCopy.extent;
1337
1338 if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && m_params.dst.image.imageType == VK_IMAGE_TYPE_2D)
1339 {
1340 dstOffset.z = srcOffset.z;
1341 extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.dstSubresource.layerCount);
1342 }
1343 if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && m_params.dst.image.imageType == VK_IMAGE_TYPE_3D)
1344 {
1345 srcOffset.z = dstOffset.z;
1346 extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.srcSubresource.layerCount);
1347 }
1348
1349
1350 if (tcu::isCombinedDepthStencilType(src.getFormat().type))
1351 {
1352 DE_ASSERT(src.getFormat() == dst.getFormat());
1353
1354 // Copy depth.
1355 if (tcu::hasDepthComponent(src.getFormat().order))
1356 {
1357 const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1358 const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1359 tcu::copy(dstSubRegion, srcSubRegion);
1360 }
1361
1362 // Copy stencil.
1363 if (tcu::hasStencilComponent(src.getFormat().order))
1364 {
1365 const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1366 const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1367 tcu::copy(dstSubRegion, srcSubRegion);
1368 }
1369 }
1370 else
1371 {
1372 const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
1373 // CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
1374 const tcu::PixelBufferAccess dstWithSrcFormat (srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
1375 const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
1376
1377 tcu::copy(dstSubRegion, srcSubRegion);
1378 }
1379 }
1380
1381 class CopyImageToImageTestCase : public vkt::TestCase
1382 {
1383 public:
CopyImageToImageTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)1384 CopyImageToImageTestCase (tcu::TestContext& testCtx,
1385 const std::string& name,
1386 const std::string& description,
1387 const TestParams params)
1388 : vkt::TestCase (testCtx, name, description)
1389 , m_params (params)
1390 {}
1391
createInstance(Context & context) const1392 virtual TestInstance* createInstance (Context& context) const
1393 {
1394 return new CopyImageToImage(context, m_params);
1395 }
1396
checkSupport(Context & context) const1397 virtual void checkSupport (Context& context) const
1398 {
1399 if (m_params.allocationKind == ALLOCATION_KIND_DEDICATED)
1400 {
1401 if (!context.isDeviceFunctionalitySupported("VK_KHR_dedicated_allocation"))
1402 TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported");
1403 }
1404
1405 if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
1406 {
1407 if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
1408 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
1409 }
1410
1411 if (m_params.separateDepthStencilLayouts)
1412 if (!context.isDeviceFunctionalitySupported("VK_KHR_separate_depth_stencil_layouts"))
1413 TCU_THROW(NotSupportedError, "VK_KHR_separate_depth_stencil_layouts is not supported");
1414
1415 if ((m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && m_params.src.image.imageType == VK_IMAGE_TYPE_2D) ||
1416 (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && m_params.src.image.imageType == VK_IMAGE_TYPE_3D))
1417 {
1418 if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance1"))
1419 TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported");
1420 }
1421
1422 const VkPhysicalDeviceLimits limits = context.getDeviceProperties().limits;
1423 VkImageFormatProperties properties;
1424
1425 if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1426 m_params.src.image.format,
1427 m_params.src.image.imageType,
1428 VK_IMAGE_TILING_OPTIMAL,
1429 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1430 0,
1431 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
1432 (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1433 m_params.dst.image.format,
1434 m_params.dst.image.imageType,
1435 VK_IMAGE_TILING_OPTIMAL,
1436 VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1437 0,
1438 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
1439 {
1440 TCU_THROW(NotSupportedError, "Format not supported");
1441 }
1442
1443 // Check maxImageDimension1D
1444 {
1445 if (m_params.src.image.imageType == VK_IMAGE_TYPE_1D && m_params.src.image.extent.width > limits.maxImageDimension1D)
1446 TCU_THROW(NotSupportedError, "Requested 1D src image dimensions not supported");
1447
1448 if (m_params.dst.image.imageType == VK_IMAGE_TYPE_1D && m_params.dst.image.extent.width > limits.maxImageDimension1D)
1449 TCU_THROW(NotSupportedError, "Requested 1D dst image dimensions not supported");
1450 }
1451
1452 // Check maxImageDimension2D
1453 {
1454 if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && (m_params.src.image.extent.width > limits.maxImageDimension2D
1455 || m_params.src.image.extent.height > limits.maxImageDimension2D))
1456 {
1457 TCU_THROW(NotSupportedError, "Requested 2D src image dimensions not supported");
1458 }
1459
1460 if (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && (m_params.dst.image.extent.width > limits.maxImageDimension2D
1461 || m_params.dst.image.extent.height > limits.maxImageDimension2D))
1462 {
1463 TCU_THROW(NotSupportedError, "Requested 2D dst image dimensions not supported");
1464 }
1465 }
1466
1467 // Check maxImageDimension3D
1468 {
1469 if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && (m_params.src.image.extent.width > limits.maxImageDimension3D
1470 || m_params.src.image.extent.height > limits.maxImageDimension3D
1471 || m_params.src.image.extent.depth > limits.maxImageDimension3D))
1472 {
1473 TCU_THROW(NotSupportedError, "Requested 3D src image dimensions not supported");
1474 }
1475
1476 if (m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && (m_params.dst.image.extent.width > limits.maxImageDimension3D
1477 || m_params.dst.image.extent.height > limits.maxImageDimension3D
1478 || m_params.src.image.extent.depth > limits.maxImageDimension3D))
1479 {
1480 TCU_THROW(NotSupportedError, "Requested 3D dst image dimensions not supported");
1481 }
1482 }
1483 }
1484
1485 private:
1486 TestParams m_params;
1487 };
1488
1489 class CopyImageToImageMipmap : public CopiesAndBlittingTestInstance
1490 {
1491 public:
1492 CopyImageToImageMipmap (Context& context,
1493 TestParams params);
1494 virtual tcu::TestStatus iterate (void);
1495
1496 protected:
1497 tcu::TestStatus checkResult (tcu::ConstPixelBufferAccess result, tcu::ConstPixelBufferAccess expected);
1498
1499 private:
1500 Move<VkImage> m_source;
1501 de::MovePtr<Allocation> m_sourceImageAlloc;
1502 Move<VkImage> m_destination;
1503 de::MovePtr<Allocation> m_destinationImageAlloc;
1504
1505 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
1506
1507 };
1508
CopyImageToImageMipmap(Context & context,TestParams params)1509 CopyImageToImageMipmap::CopyImageToImageMipmap (Context& context, TestParams params)
1510 : CopiesAndBlittingTestInstance(context, params)
1511 {
1512 const InstanceInterface& vki = context.getInstanceInterface();
1513 const DeviceInterface& vk = context.getDeviceInterface();
1514 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
1515 const VkDevice vkDevice = m_device;
1516 Allocator& memAlloc = context.getDefaultAllocator();
1517
1518 // Create source image
1519 {
1520 const VkImageCreateInfo sourceImageParams =
1521 {
1522 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1523 DE_NULL, // const void* pNext;
1524 getCreateFlags(m_params.src.image), // VkImageCreateFlags flags;
1525 m_params.src.image.imageType, // VkImageType imageType;
1526 m_params.src.image.format, // VkFormat format;
1527 getExtent3D(m_params.src.image), // VkExtent3D extent;
1528 params.mipLevels, // deUint32 mipLevels;
1529 getArraySize(m_params.src.image), // deUint32 arraySize;
1530 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
1531 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1532 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1533 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
1534 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1535 0u, // deUint32 queueFamilyIndexCount;
1536 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
1537 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
1538 };
1539
1540 m_source = createImage(vk, vkDevice, &sourceImageParams);
1541 m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
1542 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
1543 }
1544
1545 // Create destination image
1546 {
1547 const VkImageCreateInfo destinationImageParams =
1548 {
1549 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1550 DE_NULL, // const void* pNext;
1551 getCreateFlags(m_params.dst.image), // VkImageCreateFlags flags;
1552 m_params.dst.image.imageType, // VkImageType imageType;
1553 m_params.dst.image.format, // VkFormat format;
1554 getExtent3D(m_params.dst.image), // VkExtent3D extent;
1555 params.mipLevels, // deUint32 mipLevels;
1556 getArraySize(m_params.dst.image), // deUint32 arraySize;
1557 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
1558 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1559 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1560 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
1561 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1562 0u, // deUint32 queueFamilyIndexCount;
1563 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
1564 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
1565 };
1566
1567 m_destination = createImage(vk, vkDevice, &destinationImageParams);
1568 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
1569 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
1570 }
1571 }
1572
iterate(void)1573 tcu::TestStatus CopyImageToImageMipmap::iterate (void)
1574 {
1575 const bool srcCompressed = isCompressedFormat(m_params.src.image.format);
1576 const bool dstCompressed = isCompressedFormat(m_params.dst.image.format);
1577
1578 const tcu::TextureFormat srcTcuFormat = getSizeCompatibleTcuTextureFormat(m_params.src.image.format);
1579 const tcu::TextureFormat dstTcuFormat = getSizeCompatibleTcuTextureFormat(m_params.dst.image.format);
1580
1581 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
1582 (int)m_params.src.image.extent.width,
1583 (int)m_params.src.image.extent.height,
1584 (int)m_params.src.image.extent.depth));
1585 generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth, FILL_MODE_GRADIENT);
1586 uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image, m_params.mipLevels);
1587
1588 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
1589 (int)m_params.dst.image.extent.width,
1590 (int)m_params.dst.image.extent.height,
1591 (int)m_params.dst.image.extent.depth));
1592 generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth, FILL_MODE_RED);
1593 uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, m_params.mipLevels);
1594
1595 const DeviceInterface& vk = m_context.getDeviceInterface();
1596 const VkDevice vkDevice = m_device;
1597 const VkQueue queue = m_queue;
1598
1599 std::vector<VkImageCopy> imageCopies;
1600 std::vector<VkImageCopy2KHR> imageCopies2KHR;
1601 for (deUint32 i = 0; i < m_params.regions.size(); i++)
1602 {
1603 VkImageCopy imageCopy = m_params.regions[i].imageCopy;
1604
1605 // When copying between compressed and uncompressed formats the extent
1606 // members represent the texel dimensions of the source image.
1607 if (srcCompressed)
1608 {
1609 const deUint32 blockWidth = getBlockWidth(m_params.src.image.format);
1610 const deUint32 blockHeight = getBlockHeight(m_params.src.image.format);
1611
1612 imageCopy.srcOffset.x *= blockWidth;
1613 imageCopy.srcOffset.y *= blockHeight;
1614 imageCopy.extent.width *= blockWidth;
1615 imageCopy.extent.height *= blockHeight;
1616 }
1617
1618 if (dstCompressed)
1619 {
1620 const deUint32 blockWidth = getBlockWidth(m_params.dst.image.format);
1621 const deUint32 blockHeight = getBlockHeight(m_params.dst.image.format);
1622
1623 imageCopy.dstOffset.x *= blockWidth;
1624 imageCopy.dstOffset.y *= blockHeight;
1625 }
1626
1627 if (m_params.extensionUse == EXTENSION_USE_NONE)
1628 {
1629 imageCopies.push_back(imageCopy);
1630 }
1631 else
1632 {
1633 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1634 imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
1635 }
1636 }
1637
1638 VkImageMemoryBarrier imageBarriers[] =
1639 {
1640 // source image
1641 {
1642 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1643 DE_NULL, // const void* pNext;
1644 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1645 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
1646 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1647 m_params.src.image.operationLayout, // VkImageLayout newLayout;
1648 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1649 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
1650 m_source.get(), // VkImage image;
1651 { // VkImageSubresourceRange subresourceRange;
1652 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
1653 0u, // deUint32 baseMipLevel;
1654 m_params.mipLevels, // deUint32 mipLevels;
1655 0u, // deUint32 baseArraySlice;
1656 getArraySize(m_params.src.image)// deUint32 arraySize;
1657 }
1658 },
1659 // destination image
1660 {
1661 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1662 DE_NULL, // const void* pNext;
1663 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1664 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1665 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1666 m_params.dst.image.operationLayout, // VkImageLayout newLayout;
1667 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1668 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
1669 m_destination.get(), // VkImage image;
1670 { // VkImageSubresourceRange subresourceRange;
1671 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
1672 0u, // deUint32 baseMipLevel;
1673 m_params.mipLevels, // deUint32 mipLevels;
1674 0u, // deUint32 baseArraySlice;
1675 getArraySize(m_params.dst.image)// deUint32 arraySize;
1676 }
1677 },
1678 };
1679
1680 beginCommandBuffer(vk, *m_cmdBuffer);
1681 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers);
1682
1683 if (m_params.extensionUse == EXTENSION_USE_NONE)
1684 {
1685 vk.cmdCopyImage(*m_cmdBuffer, m_source.get(), m_params.src.image.operationLayout, m_destination.get(), m_params.dst.image.operationLayout, (deUint32)imageCopies.size(), imageCopies.data());
1686 }
1687 #ifndef CTS_USES_VULKANSC
1688 else
1689 {
1690 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1691 const VkCopyImageInfo2KHR copyImageInfo2KHR =
1692 {
1693 VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR, // VkStructureType sType;
1694 DE_NULL, // const void* pNext;
1695 m_source.get(), // VkImage srcImage;
1696 m_params.src.image.operationLayout, // VkImageLayout srcImageLayout;
1697 m_destination.get(), // VkImage dstImage;
1698 m_params.dst.image.operationLayout, // VkImageLayout dstImageLayout;
1699 (deUint32)imageCopies2KHR.size(), // uint32_t regionCount;
1700 imageCopies2KHR.data() // const VkImageCopy2KHR* pRegions;
1701 };
1702
1703 vk.cmdCopyImage2(*m_cmdBuffer, ©ImageInfo2KHR);
1704 }
1705 #endif // CTS_USES_VULKANSC
1706
1707 endCommandBuffer(vk, *m_cmdBuffer);
1708
1709 submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
1710 m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
1711
1712 for (deUint32 miplevel = 0; miplevel < m_params.mipLevels; miplevel++)
1713 {
1714 de::MovePtr<tcu::TextureLevel> resultTextureLevel = readImage(*m_destination, m_params.dst.image, miplevel);
1715 de::MovePtr<tcu::TextureLevel> expectedTextureLevel = readImage(*m_source, m_params.src.image, miplevel);
1716
1717 tcu::TestStatus result = checkResult(resultTextureLevel->getAccess(), expectedTextureLevel->getAccess());
1718 if (result.getCode() != QP_TEST_RESULT_PASS)
1719 return result;
1720 }
1721 return tcu::TestStatus::pass("Pass");
1722 }
1723
checkResult(tcu::ConstPixelBufferAccess result,tcu::ConstPixelBufferAccess expected)1724 tcu::TestStatus CopyImageToImageMipmap::checkResult (tcu::ConstPixelBufferAccess result, tcu::ConstPixelBufferAccess expected)
1725 {
1726 const tcu::Vec4 fThreshold (0.0f);
1727 const tcu::UVec4 uThreshold (0u);
1728
1729 if (tcu::isCombinedDepthStencilType(result.getFormat().type))
1730 {
1731 if (tcu::hasDepthComponent(result.getFormat().order))
1732 {
1733 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_DEPTH;
1734 const tcu::ConstPixelBufferAccess depthResult = tcu::getEffectiveDepthStencilAccess(result, mode);
1735 const tcu::ConstPixelBufferAccess expectedResult = tcu::getEffectiveDepthStencilAccess(expected, mode);
1736
1737 if (isFloatFormat(result.getFormat()))
1738 {
1739 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1740 return tcu::TestStatus::fail("CopiesAndBlitting test");
1741 }
1742 else
1743 {
1744 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1745 return tcu::TestStatus::fail("CopiesAndBlitting test");
1746 }
1747 }
1748
1749 if (tcu::hasStencilComponent(result.getFormat().order))
1750 {
1751 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_STENCIL;
1752 const tcu::ConstPixelBufferAccess stencilResult = tcu::getEffectiveDepthStencilAccess(result, mode);
1753 const tcu::ConstPixelBufferAccess expectedResult = tcu::getEffectiveDepthStencilAccess(expected, mode);
1754
1755 if (isFloatFormat(result.getFormat()))
1756 {
1757 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1758 return tcu::TestStatus::fail("CopiesAndBlitting test");
1759 }
1760 else
1761 {
1762 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1763 return tcu::TestStatus::fail("CopiesAndBlitting test");
1764 }
1765 }
1766 }
1767 else
1768 {
1769 if (isFloatFormat(result.getFormat()))
1770 {
1771 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, fThreshold, tcu::COMPARE_LOG_RESULT))
1772 return tcu::TestStatus::fail("CopiesAndBlitting test");
1773 }
1774 else if (isSnormFormat(mapTextureFormat(result.getFormat())))
1775 {
1776 // There may be an ambiguity between two possible binary representations of 1.0.
1777 // Get rid of that by expanding the data to floats and re-normalizing again.
1778
1779 tcu::TextureLevel resultSnorm (result.getFormat(), result.getWidth(), result.getHeight(), result.getDepth());
1780 {
1781 tcu::TextureLevel resultFloat (tcu::TextureFormat(resultSnorm.getFormat().order, tcu::TextureFormat::FLOAT), resultSnorm.getWidth(), resultSnorm.getHeight(), resultSnorm.getDepth());
1782
1783 tcu::copy(resultFloat.getAccess(), result);
1784 tcu::copy(resultSnorm, resultFloat.getAccess());
1785 }
1786
1787 tcu::TextureLevel expectedSnorm (expected.getFormat(), expected.getWidth(), expected.getHeight(), expected.getDepth());
1788
1789 {
1790 tcu::TextureLevel expectedFloat (tcu::TextureFormat(expectedSnorm.getFormat().order, tcu::TextureFormat::FLOAT), expectedSnorm.getWidth(), expectedSnorm.getHeight(), expectedSnorm.getDepth());
1791
1792 tcu::copy(expectedFloat.getAccess(), m_expectedTextureLevel[0]->getAccess());
1793 tcu::copy(expectedSnorm, expectedFloat.getAccess());
1794 }
1795
1796 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedSnorm.getAccess(), resultSnorm.getAccess(), uThreshold, tcu::COMPARE_LOG_RESULT))
1797 return tcu::TestStatus::fail("CopiesAndBlitting test");
1798 }
1799 else
1800 {
1801 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, uThreshold, tcu::COMPARE_LOG_RESULT))
1802 return tcu::TestStatus::fail("CopiesAndBlitting test");
1803 }
1804 }
1805
1806 return tcu::TestStatus::pass("CopiesAndBlitting test");
1807 }
1808
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)1809 void CopyImageToImageMipmap::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
1810 {
1811 DE_UNREF(mipLevel);
1812
1813 VkOffset3D srcOffset = region.imageCopy.srcOffset;
1814 VkOffset3D dstOffset = region.imageCopy.dstOffset;
1815 VkExtent3D extent = region.imageCopy.extent;
1816
1817 if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && m_params.dst.image.imageType == VK_IMAGE_TYPE_2D)
1818 {
1819 dstOffset.z = srcOffset.z;
1820 extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.dstSubresource.layerCount);
1821 }
1822 if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && m_params.dst.image.imageType == VK_IMAGE_TYPE_3D)
1823 {
1824 srcOffset.z = dstOffset.z;
1825 extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.srcSubresource.layerCount);
1826 }
1827
1828
1829 if (tcu::isCombinedDepthStencilType(src.getFormat().type))
1830 {
1831 DE_ASSERT(src.getFormat() == dst.getFormat());
1832
1833 // Copy depth.
1834 if (tcu::hasDepthComponent(src.getFormat().order))
1835 {
1836 const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1837 const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1838 tcu::copy(dstSubRegion, srcSubRegion);
1839 }
1840
1841 // Copy stencil.
1842 if (tcu::hasStencilComponent(src.getFormat().order))
1843 {
1844 const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1845 const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1846 tcu::copy(dstSubRegion, srcSubRegion);
1847 }
1848 }
1849 else
1850 {
1851 const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
1852 // CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
1853 const tcu::PixelBufferAccess dstWithSrcFormat (srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
1854 const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
1855
1856 tcu::copy(dstSubRegion, srcSubRegion);
1857 }
1858 }
1859
1860 class CopyImageToImageMipmapTestCase : public vkt::TestCase
1861 {
1862 public:
CopyImageToImageMipmapTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)1863 CopyImageToImageMipmapTestCase (tcu::TestContext& testCtx,
1864 const std::string& name,
1865 const std::string& description,
1866 const TestParams params)
1867 : vkt::TestCase (testCtx, name, description)
1868 , m_params (params)
1869 {}
1870
createInstance(Context & context) const1871 virtual TestInstance* createInstance (Context& context) const
1872 {
1873 return new CopyImageToImageMipmap(context, m_params);
1874 }
1875
checkSupport(Context & context) const1876 virtual void checkSupport (Context& context) const
1877 {
1878 if (m_params.allocationKind == ALLOCATION_KIND_DEDICATED)
1879 {
1880 if (!context.isDeviceFunctionalitySupported("VK_KHR_dedicated_allocation"))
1881 TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported");
1882 }
1883
1884 if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
1885 {
1886 if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
1887 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
1888 }
1889
1890 if (m_params.separateDepthStencilLayouts)
1891 if (!context.isDeviceFunctionalitySupported("VK_KHR_separate_depth_stencil_layouts"))
1892 TCU_THROW(NotSupportedError, "VK_KHR_separate_depth_stencil_layouts is not supported");
1893
1894 if ((m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && m_params.src.image.imageType == VK_IMAGE_TYPE_2D) ||
1895 (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && m_params.src.image.imageType == VK_IMAGE_TYPE_3D))
1896 {
1897 if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance1"))
1898 TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported");
1899 }
1900
1901 const VkPhysicalDeviceLimits limits = context.getDeviceProperties().limits;
1902 VkImageFormatProperties properties;
1903
1904 if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1905 m_params.src.image.format,
1906 m_params.src.image.imageType,
1907 VK_IMAGE_TILING_OPTIMAL,
1908 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1909 0,
1910 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
1911 (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1912 m_params.dst.image.format,
1913 m_params.dst.image.imageType,
1914 VK_IMAGE_TILING_OPTIMAL,
1915 VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1916 0,
1917 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
1918 {
1919 TCU_THROW(NotSupportedError, "Format not supported");
1920 }
1921
1922 // Check maxImageDimension1D
1923 {
1924 if (m_params.src.image.imageType == VK_IMAGE_TYPE_1D && m_params.src.image.extent.width > limits.maxImageDimension1D)
1925 TCU_THROW(NotSupportedError, "Requested 1D src image dimensions not supported");
1926
1927 if (m_params.dst.image.imageType == VK_IMAGE_TYPE_1D && m_params.dst.image.extent.width > limits.maxImageDimension1D)
1928 TCU_THROW(NotSupportedError, "Requested 1D dst image dimensions not supported");
1929 }
1930
1931 // Check maxImageDimension2D
1932 {
1933 if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && (m_params.src.image.extent.width > limits.maxImageDimension2D
1934 || m_params.src.image.extent.height > limits.maxImageDimension2D))
1935 {
1936 TCU_THROW(NotSupportedError, "Requested 2D src image dimensions not supported");
1937 }
1938
1939 if (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && (m_params.dst.image.extent.width > limits.maxImageDimension2D
1940 || m_params.dst.image.extent.height > limits.maxImageDimension2D))
1941 {
1942 TCU_THROW(NotSupportedError, "Requested 2D dst image dimensions not supported");
1943 }
1944 }
1945
1946 // Check maxImageDimension3D
1947 {
1948 if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && (m_params.src.image.extent.width > limits.maxImageDimension3D
1949 || m_params.src.image.extent.height > limits.maxImageDimension3D
1950 || m_params.src.image.extent.depth > limits.maxImageDimension3D))
1951 {
1952 TCU_THROW(NotSupportedError, "Requested 3D src image dimensions not supported");
1953 }
1954
1955 if (m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && (m_params.dst.image.extent.width > limits.maxImageDimension3D
1956 || m_params.dst.image.extent.height > limits.maxImageDimension3D
1957 || m_params.src.image.extent.depth > limits.maxImageDimension3D))
1958 {
1959 TCU_THROW(NotSupportedError, "Requested 3D dst image dimensions not supported");
1960 }
1961 }
1962 }
1963
1964 private:
1965 TestParams m_params;
1966 };
1967
1968 // Copy from buffer to buffer.
1969
1970 class CopyBufferToBuffer : public CopiesAndBlittingTestInstance
1971 {
1972 public:
1973 CopyBufferToBuffer (Context& context, TestParams params);
1974 virtual tcu::TestStatus iterate (void);
1975 private:
1976 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess, tcu::PixelBufferAccess, CopyRegion, deUint32 mipLevel = 0u);
1977 Move<VkBuffer> m_source;
1978 de::MovePtr<Allocation> m_sourceBufferAlloc;
1979 Move<VkBuffer> m_destination;
1980 de::MovePtr<Allocation> m_destinationBufferAlloc;
1981 };
1982
CopyBufferToBuffer(Context & context,TestParams params)1983 CopyBufferToBuffer::CopyBufferToBuffer (Context& context, TestParams params)
1984 : CopiesAndBlittingTestInstance (context, params)
1985 {
1986 const InstanceInterface& vki = context.getInstanceInterface();
1987 const DeviceInterface& vk = context.getDeviceInterface();
1988 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
1989 const VkDevice vkDevice = m_device;
1990 Allocator& memAlloc = context.getDefaultAllocator();
1991
1992 // Create source buffer
1993 {
1994 const VkBufferCreateInfo sourceBufferParams =
1995 {
1996 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1997 DE_NULL, // const void* pNext;
1998 0u, // VkBufferCreateFlags flags;
1999 m_params.src.buffer.size, // VkDeviceSize size;
2000 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage;
2001 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2002 0u, // deUint32 queueFamilyIndexCount;
2003 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
2004 };
2005
2006 m_source = createBuffer(vk, vkDevice, &sourceBufferParams);
2007 m_sourceBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
2008 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
2009 }
2010
2011 // Create destination buffer
2012 {
2013 const VkBufferCreateInfo destinationBufferParams =
2014 {
2015 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2016 DE_NULL, // const void* pNext;
2017 0u, // VkBufferCreateFlags flags;
2018 m_params.dst.buffer.size, // VkDeviceSize size;
2019 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
2020 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2021 0u, // deUint32 queueFamilyIndexCount;
2022 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
2023 };
2024
2025 m_destination = createBuffer(vk, vkDevice, &destinationBufferParams);
2026 m_destinationBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
2027 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
2028 }
2029 }
2030
iterate(void)2031 tcu::TestStatus CopyBufferToBuffer::iterate (void)
2032 {
2033 const int srcLevelWidth = (int)(m_params.src.buffer.size/4); // Here the format is VK_FORMAT_R32_UINT, we need to divide the buffer size by 4
2034 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), srcLevelWidth, 1));
2035 generateBuffer(m_sourceTextureLevel->getAccess(), srcLevelWidth, 1, 1, FILL_MODE_RED);
2036
2037 const int dstLevelWidth = (int)(m_params.dst.buffer.size/4);
2038 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
2039 generateBuffer(m_destinationTextureLevel->getAccess(), dstLevelWidth, 1, 1, FILL_MODE_BLACK);
2040
2041 generateExpectedResult();
2042
2043 uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
2044 uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
2045
2046 const DeviceInterface& vk = m_context.getDeviceInterface();
2047 const VkDevice vkDevice = m_device;
2048 const VkQueue queue = m_queue;
2049
2050 const VkBufferMemoryBarrier srcBufferBarrier =
2051 {
2052 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
2053 DE_NULL, // const void* pNext;
2054 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask;
2055 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
2056 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
2057 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
2058 *m_source, // VkBuffer buffer;
2059 0u, // VkDeviceSize offset;
2060 m_params.src.buffer.size // VkDeviceSize size;
2061 };
2062
2063 const VkBufferMemoryBarrier dstBufferBarrier =
2064 {
2065 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
2066 DE_NULL, // const void* pNext;
2067 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
2068 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
2069 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
2070 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
2071 *m_destination, // VkBuffer buffer;
2072 0u, // VkDeviceSize offset;
2073 m_params.dst.buffer.size // VkDeviceSize size;
2074 };
2075
2076 std::vector<VkBufferCopy> bufferCopies;
2077 std::vector<VkBufferCopy2KHR> bufferCopies2KHR;
2078 for (deUint32 i = 0; i < m_params.regions.size(); i++)
2079 {
2080 if (m_params.extensionUse == EXTENSION_USE_NONE)
2081 {
2082 bufferCopies.push_back(m_params.regions[i].bufferCopy);
2083 }
2084 else
2085 {
2086 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2087 bufferCopies2KHR.push_back(convertvkBufferCopyTovkBufferCopy2KHR(m_params.regions[i].bufferCopy));
2088 }
2089 }
2090
2091 beginCommandBuffer(vk, *m_cmdBuffer);
2092 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &srcBufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
2093
2094 if (m_params.extensionUse == EXTENSION_USE_NONE)
2095 {
2096 vk.cmdCopyBuffer(*m_cmdBuffer, m_source.get(), m_destination.get(), (deUint32)m_params.regions.size(), &bufferCopies[0]);
2097 }
2098 #ifndef CTS_USES_VULKANSC
2099 else
2100 {
2101 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2102 const VkCopyBufferInfo2KHR copyBufferInfo2KHR =
2103 {
2104 VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2_KHR, // VkStructureType sType;
2105 DE_NULL, // const void* pNext;
2106 m_source.get(), // VkBuffer srcBuffer;
2107 m_destination.get(), // VkBuffer dstBuffer;
2108 (deUint32)m_params.regions.size(), // uint32_t regionCount;
2109 &bufferCopies2KHR[0] // const VkBufferCopy2KHR* pRegions;
2110 };
2111
2112 vk.cmdCopyBuffer2(*m_cmdBuffer, ©BufferInfo2KHR);
2113 }
2114 #endif // CTS_USES_VULKANSC
2115
2116 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &dstBufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
2117 endCommandBuffer(vk, *m_cmdBuffer);
2118 submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
2119 m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
2120
2121 // Read buffer data
2122 de::MovePtr<tcu::TextureLevel> resultLevel (new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
2123 invalidateAlloc(vk, vkDevice, *m_destinationBufferAlloc);
2124 tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr()));
2125
2126 return checkTestResult(resultLevel->getAccess());
2127 }
2128
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)2129 void CopyBufferToBuffer::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
2130 {
2131 DE_UNREF(mipLevel);
2132
2133 deMemcpy((deUint8*) dst.getDataPtr() + region.bufferCopy.dstOffset,
2134 (deUint8*) src.getDataPtr() + region.bufferCopy.srcOffset,
2135 (size_t)region.bufferCopy.size);
2136 }
2137
2138 class BufferToBufferTestCase : public vkt::TestCase
2139 {
2140 public:
BufferToBufferTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)2141 BufferToBufferTestCase (tcu::TestContext& testCtx,
2142 const std::string& name,
2143 const std::string& description,
2144 const TestParams params)
2145 : vkt::TestCase (testCtx, name, description)
2146 , m_params (params)
2147 {}
2148
createInstance(Context & context) const2149 virtual TestInstance* createInstance (Context& context) const
2150 {
2151 return new CopyBufferToBuffer(context, m_params);
2152 }
2153
checkSupport(Context & context) const2154 virtual void checkSupport(Context& context) const
2155 {
2156 if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
2157 {
2158 if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
2159 {
2160 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
2161 }
2162 }
2163 }
2164
2165 private:
2166 TestParams m_params;
2167 };
2168
2169 // Copy from image to buffer.
2170
2171 class CopyImageToBuffer : public CopiesAndBlittingTestInstance
2172 {
2173 public:
2174 CopyImageToBuffer (Context& context,
2175 TestParams testParams);
2176 virtual tcu::TestStatus iterate (void);
2177 private:
2178 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
2179
2180 tcu::TextureFormat m_textureFormat;
2181 VkDeviceSize m_bufferSize;
2182
2183 Move<VkImage> m_source;
2184 de::MovePtr<Allocation> m_sourceImageAlloc;
2185 Move<VkBuffer> m_destination;
2186 de::MovePtr<Allocation> m_destinationBufferAlloc;
2187 };
2188
CopyImageToBuffer(Context & context,TestParams testParams)2189 CopyImageToBuffer::CopyImageToBuffer (Context& context, TestParams testParams)
2190 : CopiesAndBlittingTestInstance(context, testParams)
2191 , m_textureFormat(mapVkFormat(testParams.src.image.format))
2192 , m_bufferSize(m_params.dst.buffer.size * tcu::getPixelSize(m_textureFormat))
2193 {
2194 const InstanceInterface& vki = context.getInstanceInterface();
2195 const DeviceInterface& vk = context.getDeviceInterface();
2196 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
2197 const VkDevice vkDevice = m_device;
2198 Allocator& memAlloc = context.getDefaultAllocator();
2199
2200 // Create source image
2201 {
2202 const VkImageCreateInfo sourceImageParams =
2203 {
2204 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
2205 DE_NULL, // const void* pNext;
2206 getCreateFlags(m_params.src.image), // VkImageCreateFlags flags;
2207 m_params.src.image.imageType, // VkImageType imageType;
2208 m_params.src.image.format, // VkFormat format;
2209 getExtent3D(m_params.src.image), // VkExtent3D extent;
2210 1u, // deUint32 mipLevels;
2211 getArraySize(m_params.src.image), // deUint32 arraySize;
2212 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
2213 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
2214 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2215 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
2216 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2217 0u, // deUint32 queueFamilyIndexCount;
2218 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
2219 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
2220 };
2221
2222 m_source = createImage(vk, vkDevice, &sourceImageParams);
2223 m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
2224 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
2225 }
2226
2227 // Create destination buffer
2228 {
2229 const VkBufferCreateInfo destinationBufferParams =
2230 {
2231 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2232 DE_NULL, // const void* pNext;
2233 0u, // VkBufferCreateFlags flags;
2234 m_bufferSize, // VkDeviceSize size;
2235 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
2236 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2237 0u, // deUint32 queueFamilyIndexCount;
2238 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
2239 };
2240
2241 m_destination = createBuffer(vk, vkDevice, &destinationBufferParams);
2242 m_destinationBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
2243 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
2244 }
2245 }
2246
iterate(void)2247 tcu::TestStatus CopyImageToBuffer::iterate (void)
2248 {
2249 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
2250 m_params.src.image.extent.width,
2251 m_params.src.image.extent.height,
2252 m_params.src.image.extent.depth));
2253 generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth);
2254 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
2255 generateBuffer(m_destinationTextureLevel->getAccess(), (int)m_params.dst.buffer.size, 1, 1);
2256
2257 generateExpectedResult();
2258
2259 uploadImage(m_sourceTextureLevel->getAccess(), *m_source, m_params.src.image);
2260 uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
2261
2262 const DeviceInterface& vk = m_context.getDeviceInterface();
2263 const VkDevice vkDevice = m_device;
2264 const VkQueue queue = m_queue;
2265
2266 // Barriers for copying image to buffer
2267 const VkImageMemoryBarrier imageBarrier =
2268 {
2269 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
2270 DE_NULL, // const void* pNext;
2271 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
2272 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
2273 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
2274 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout;
2275 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
2276 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
2277 *m_source, // VkImage image;
2278 { // VkImageSubresourceRange subresourceRange;
2279 getAspectFlags(m_textureFormat), // VkImageAspectFlags aspectMask;
2280 0u, // deUint32 baseMipLevel;
2281 1u, // deUint32 mipLevels;
2282 0u, // deUint32 baseArraySlice;
2283 getArraySize(m_params.src.image) // deUint32 arraySize;
2284 }
2285 };
2286
2287 const VkBufferMemoryBarrier bufferBarrier =
2288 {
2289 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
2290 DE_NULL, // const void* pNext;
2291 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
2292 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
2293 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
2294 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
2295 *m_destination, // VkBuffer buffer;
2296 0u, // VkDeviceSize offset;
2297 m_bufferSize // VkDeviceSize size;
2298 };
2299
2300 // Copy from image to buffer
2301 std::vector<VkBufferImageCopy> bufferImageCopies;
2302 std::vector<VkBufferImageCopy2KHR> bufferImageCopies2KHR;
2303 for (deUint32 i = 0; i < m_params.regions.size(); i++)
2304 {
2305 if (m_params.extensionUse == EXTENSION_USE_NONE)
2306 {
2307 bufferImageCopies.push_back(m_params.regions[i].bufferImageCopy);
2308 }
2309 else
2310 {
2311 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2312 bufferImageCopies2KHR.push_back(convertvkBufferImageCopyTovkBufferImageCopy2KHR(m_params.regions[i].bufferImageCopy));
2313 }
2314 }
2315
2316 beginCommandBuffer(vk, *m_cmdBuffer);
2317 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier);
2318
2319 if (m_params.extensionUse == EXTENSION_USE_NONE)
2320 {
2321 vk.cmdCopyImageToBuffer(*m_cmdBuffer, m_source.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_destination.get(), (deUint32)m_params.regions.size(), &bufferImageCopies[0]);
2322 }
2323 #ifndef CTS_USES_VULKANSC
2324 else
2325 {
2326 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2327 const VkCopyImageToBufferInfo2KHR copyImageToBufferInfo2KHR =
2328 {
2329 VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2_KHR, // VkStructureType sType;
2330 DE_NULL, // const void* pNext;
2331 m_source.get(), // VkImage srcImage;
2332 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout srcImageLayout;
2333 m_destination.get(), // VkBuffer dstBuffer;
2334 (deUint32)m_params.regions.size(), // uint32_t regionCount;
2335 &bufferImageCopies2KHR[0] // const VkBufferImageCopy2KHR* pRegions;
2336 };
2337
2338 vk.cmdCopyImageToBuffer2(*m_cmdBuffer, ©ImageToBufferInfo2KHR);
2339 }
2340 #endif // CTS_USES_VULKANSC
2341
2342 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
2343 endCommandBuffer(vk, *m_cmdBuffer);
2344
2345 submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
2346 m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
2347
2348 // Read buffer data
2349 de::MovePtr<tcu::TextureLevel> resultLevel (new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
2350 invalidateAlloc(vk, vkDevice, *m_destinationBufferAlloc);
2351 tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr()));
2352
2353 return checkTestResult(resultLevel->getAccess());
2354 }
2355
2356 class CopyImageToBufferTestCase : public vkt::TestCase
2357 {
2358 public:
CopyImageToBufferTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)2359 CopyImageToBufferTestCase (tcu::TestContext& testCtx,
2360 const std::string& name,
2361 const std::string& description,
2362 const TestParams params)
2363 : vkt::TestCase (testCtx, name, description)
2364 , m_params (params)
2365 {}
2366
createInstance(Context & context) const2367 virtual TestInstance* createInstance (Context& context) const
2368 {
2369 return new CopyImageToBuffer(context, m_params);
2370 }
2371
checkSupport(Context & context) const2372 virtual void checkSupport (Context& context) const
2373 {
2374 if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
2375 (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
2376 {
2377 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
2378 }
2379 }
2380
2381 private:
2382 TestParams m_params;
2383 };
2384
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)2385 void CopyImageToBuffer::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
2386 {
2387 DE_UNREF(mipLevel);
2388
2389 deUint32 rowLength = region.bufferImageCopy.bufferRowLength;
2390 if (!rowLength)
2391 rowLength = region.bufferImageCopy.imageExtent.width;
2392
2393 deUint32 imageHeight = region.bufferImageCopy.bufferImageHeight;
2394 if (!imageHeight)
2395 imageHeight = region.bufferImageCopy.imageExtent.height;
2396
2397 const int texelSize = src.getFormat().getPixelSize();
2398 const VkExtent3D extent = region.bufferImageCopy.imageExtent;
2399 const VkOffset3D srcOffset = region.bufferImageCopy.imageOffset;
2400 const int texelOffset = (int) region.bufferImageCopy.bufferOffset / texelSize;
2401 const deUint32 baseArrayLayer = region.bufferImageCopy.imageSubresource.baseArrayLayer;
2402
2403 for (deUint32 z = 0; z < extent.depth; z++)
2404 {
2405 for (deUint32 y = 0; y < extent.height; y++)
2406 {
2407 int texelIndex = texelOffset + (z * imageHeight + y) * rowLength;
2408 const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, srcOffset.x, srcOffset.y + y, srcOffset.z + z + baseArrayLayer,
2409 region.bufferImageCopy.imageExtent.width, 1, 1);
2410 const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dst, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
2411 tcu::copy(dstSubRegion, srcSubRegion);
2412 }
2413 }
2414 }
2415
2416 // Copy from buffer to image.
2417
2418 class CopyBufferToImage : public CopiesAndBlittingTestInstance
2419 {
2420 public:
2421 CopyBufferToImage (Context& context,
2422 TestParams testParams);
2423 virtual tcu::TestStatus iterate (void);
2424
2425 private:
2426 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
2427
2428 tcu::TextureFormat m_textureFormat;
2429 VkDeviceSize m_bufferSize;
2430
2431 Move<VkBuffer> m_source;
2432 de::MovePtr<Allocation> m_sourceBufferAlloc;
2433 Move<VkImage> m_destination;
2434 de::MovePtr<Allocation> m_destinationImageAlloc;
2435 };
2436
CopyBufferToImage(Context & context,TestParams testParams)2437 CopyBufferToImage::CopyBufferToImage (Context& context, TestParams testParams)
2438 : CopiesAndBlittingTestInstance(context, testParams)
2439 , m_textureFormat(mapVkFormat(testParams.dst.image.format))
2440 , m_bufferSize(m_params.src.buffer.size * tcu::getPixelSize(m_textureFormat))
2441 {
2442 const InstanceInterface& vki = context.getInstanceInterface();
2443 const DeviceInterface& vk = context.getDeviceInterface();
2444 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
2445 const VkDevice vkDevice = m_device;
2446 Allocator& memAlloc = context.getDefaultAllocator();
2447
2448 // Create source buffer
2449 {
2450 const VkBufferCreateInfo sourceBufferParams =
2451 {
2452 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2453 DE_NULL, // const void* pNext;
2454 0u, // VkBufferCreateFlags flags;
2455 m_bufferSize, // VkDeviceSize size;
2456 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage;
2457 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2458 0u, // deUint32 queueFamilyIndexCount;
2459 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
2460 };
2461
2462 m_source = createBuffer(vk, vkDevice, &sourceBufferParams);
2463 m_sourceBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
2464 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
2465 }
2466
2467 // Create destination image
2468 {
2469 const VkImageCreateInfo destinationImageParams =
2470 {
2471 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
2472 DE_NULL, // const void* pNext;
2473 getCreateFlags(m_params.dst.image), // VkImageCreateFlags flags;
2474 m_params.dst.image.imageType, // VkImageType imageType;
2475 m_params.dst.image.format, // VkFormat format;
2476 getExtent3D(m_params.dst.image), // VkExtent3D extent;
2477 1u, // deUint32 mipLevels;
2478 getArraySize(m_params.dst.image), // deUint32 arraySize;
2479 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
2480 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
2481 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2482 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
2483 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2484 0u, // deUint32 queueFamilyIndexCount;
2485 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
2486 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
2487 };
2488
2489 m_destination = createImage(vk, vkDevice, &destinationImageParams);
2490 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
2491 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
2492 }
2493 }
2494
iterate(void)2495 tcu::TestStatus CopyBufferToImage::iterate (void)
2496 {
2497 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.src.buffer.size, 1));
2498 generateBuffer(m_sourceTextureLevel->getAccess(), (int)m_params.src.buffer.size, 1, 1);
2499 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
2500 m_params.dst.image.extent.width,
2501 m_params.dst.image.extent.height,
2502 m_params.dst.image.extent.depth));
2503
2504 generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
2505
2506 generateExpectedResult();
2507
2508 uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
2509 uploadImage(m_destinationTextureLevel->getAccess(), *m_destination, m_params.dst.image);
2510
2511 const DeviceInterface& vk = m_context.getDeviceInterface();
2512 const VkDevice vkDevice = m_device;
2513 const VkQueue queue = m_queue;
2514
2515 const VkImageMemoryBarrier imageBarrier =
2516 {
2517 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
2518 DE_NULL, // const void* pNext;
2519 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
2520 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
2521 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
2522 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
2523 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
2524 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
2525 *m_destination, // VkImage image;
2526 { // VkImageSubresourceRange subresourceRange;
2527 getAspectFlags(m_textureFormat), // VkImageAspectFlags aspectMask;
2528 0u, // deUint32 baseMipLevel;
2529 1u, // deUint32 mipLevels;
2530 0u, // deUint32 baseArraySlice;
2531 getArraySize(m_params.dst.image) // deUint32 arraySize;
2532 }
2533 };
2534
2535 // Copy from buffer to image
2536 std::vector<VkBufferImageCopy> bufferImageCopies;
2537 std::vector<VkBufferImageCopy2KHR> bufferImageCopies2KHR;
2538 for (deUint32 i = 0; i < m_params.regions.size(); i++)
2539 {
2540 if (m_params.extensionUse == EXTENSION_USE_NONE)
2541 {
2542 bufferImageCopies.push_back(m_params.regions[i].bufferImageCopy);
2543 }
2544 else
2545 {
2546 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2547 bufferImageCopies2KHR.push_back(convertvkBufferImageCopyTovkBufferImageCopy2KHR(m_params.regions[i].bufferImageCopy));
2548 }
2549 }
2550
2551 beginCommandBuffer(vk, *m_cmdBuffer);
2552 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier);
2553
2554 if (m_params.extensionUse == EXTENSION_USE_NONE)
2555 {
2556 vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), bufferImageCopies.data());
2557 }
2558 #ifndef CTS_USES_VULKANSC
2559 else
2560 {
2561 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2562 const VkCopyBufferToImageInfo2KHR copyBufferToImageInfo2KHR =
2563 {
2564 VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR, // VkStructureType sType;
2565 DE_NULL, // const void* pNext;
2566 m_source.get(), // VkBuffer srcBuffer;
2567 m_destination.get(), // VkImage dstImage;
2568 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout dstImageLayout;
2569 (deUint32)m_params.regions.size(), // uint32_t regionCount;
2570 bufferImageCopies2KHR.data() // const VkBufferImageCopy2KHR* pRegions;
2571 };
2572
2573 vk.cmdCopyBufferToImage2(*m_cmdBuffer, ©BufferToImageInfo2KHR);
2574 }
2575 #endif // CTS_USES_VULKANSC
2576
2577 endCommandBuffer(vk, *m_cmdBuffer);
2578
2579 submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
2580 m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
2581
2582 de::MovePtr<tcu::TextureLevel> resultLevel = readImage(*m_destination, m_params.dst.image);
2583
2584 return checkTestResult(resultLevel->getAccess());
2585 }
2586
2587 class CopyBufferToImageTestCase : public vkt::TestCase
2588 {
2589 public:
CopyBufferToImageTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)2590 CopyBufferToImageTestCase (tcu::TestContext& testCtx,
2591 const std::string& name,
2592 const std::string& description,
2593 const TestParams params)
2594 : vkt::TestCase (testCtx, name, description)
2595 , m_params (params)
2596 {}
2597
~CopyBufferToImageTestCase(void)2598 virtual ~CopyBufferToImageTestCase (void) {}
2599
createInstance(Context & context) const2600 virtual TestInstance* createInstance (Context& context) const
2601 {
2602 return new CopyBufferToImage(context, m_params);
2603 }
2604
checkSupport(Context & context) const2605 virtual void checkSupport (Context& context) const
2606 {
2607 if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
2608 (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
2609 {
2610 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
2611 }
2612 }
2613
2614
2615 private:
2616 TestParams m_params;
2617 };
2618
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)2619 void CopyBufferToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
2620 {
2621 DE_UNREF(mipLevel);
2622
2623 deUint32 rowLength = region.bufferImageCopy.bufferRowLength;
2624 if (!rowLength)
2625 rowLength = region.bufferImageCopy.imageExtent.width;
2626
2627 deUint32 imageHeight = region.bufferImageCopy.bufferImageHeight;
2628 if (!imageHeight)
2629 imageHeight = region.bufferImageCopy.imageExtent.height;
2630
2631 const int texelSize = dst.getFormat().getPixelSize();
2632 const VkExtent3D extent = region.bufferImageCopy.imageExtent;
2633 const VkOffset3D dstOffset = region.bufferImageCopy.imageOffset;
2634 const int texelOffset = (int) region.bufferImageCopy.bufferOffset / texelSize;
2635 const deUint32 baseArrayLayer = region.bufferImageCopy.imageSubresource.baseArrayLayer;
2636
2637 for (deUint32 z = 0; z < extent.depth; z++)
2638 {
2639 for (deUint32 y = 0; y < extent.height; y++)
2640 {
2641 int texelIndex = texelOffset + (z * imageHeight + y) * rowLength;
2642 const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
2643 const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dst, dstOffset.x, dstOffset.y + y, dstOffset.z + z + baseArrayLayer,
2644 region.bufferImageCopy.imageExtent.width, 1, 1);
2645 tcu::copy(dstSubRegion, srcSubRegion);
2646 }
2647 }
2648 }
2649
2650 class CopyBufferToDepthStencil : public CopiesAndBlittingTestInstance
2651 {
2652 public:
2653 CopyBufferToDepthStencil (Context& context,
2654 TestParams testParams);
2655 virtual tcu::TestStatus iterate (void);
2656 private:
2657 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
2658
2659 tcu::TextureFormat m_textureFormat;
2660 VkDeviceSize m_bufferSize;
2661
2662 Move<VkBuffer> m_source;
2663 de::MovePtr<Allocation> m_sourceBufferAlloc;
2664 Move<VkImage> m_destination;
2665 de::MovePtr<Allocation> m_destinationImageAlloc;
2666 };
2667
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)2668 void CopyBufferToDepthStencil::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
2669 {
2670 DE_UNREF(mipLevel);
2671
2672 deUint32 rowLength = region.bufferImageCopy.bufferRowLength;
2673 if (!rowLength)
2674 rowLength = region.bufferImageCopy.imageExtent.width;
2675
2676 deUint32 imageHeight = region.bufferImageCopy.bufferImageHeight;
2677 if (!imageHeight)
2678 imageHeight = region.bufferImageCopy.imageExtent.height;
2679
2680 const int texelSize = dst.getFormat().getPixelSize();
2681 const VkExtent3D extent = region.bufferImageCopy.imageExtent;
2682 const VkOffset3D dstOffset = region.bufferImageCopy.imageOffset;
2683 const int texelOffset = (int)region.bufferImageCopy.bufferOffset / texelSize;
2684
2685 for (deUint32 z = 0; z < extent.depth; z++)
2686 {
2687 for (deUint32 y = 0; y < extent.height; y++)
2688 {
2689 int texelIndex = texelOffset + (z * imageHeight + y) * rowLength;
2690 const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
2691 const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dst, dstOffset.x, dstOffset.y + y, dstOffset.z + z,
2692 region.bufferImageCopy.imageExtent.width, 1, 1);
2693
2694 if (region.bufferImageCopy.imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)
2695 {
2696 tcu::copy(dstSubRegion, tcu::getEffectiveDepthStencilAccess(srcSubRegion, tcu::Sampler::MODE_DEPTH), DE_FALSE);
2697 }
2698 else
2699 {
2700 tcu::copy(dstSubRegion, tcu::getEffectiveDepthStencilAccess(srcSubRegion, tcu::Sampler::MODE_STENCIL), DE_FALSE);
2701 }
2702 }
2703 }
2704 }
2705
isSupportedDepthStencilFormat(const InstanceInterface & vki,const VkPhysicalDevice physDevice,const VkFormat format)2706 bool isSupportedDepthStencilFormat(const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format)
2707 {
2708 VkFormatProperties formatProps;
2709 vki.getPhysicalDeviceFormatProperties(physDevice, format, &formatProps);
2710 return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0;
2711 }
2712
CopyBufferToDepthStencil(Context & context,TestParams testParams)2713 CopyBufferToDepthStencil::CopyBufferToDepthStencil(Context& context, TestParams testParams)
2714 : CopiesAndBlittingTestInstance(context, testParams)
2715 , m_textureFormat(mapVkFormat(testParams.dst.image.format))
2716 , m_bufferSize(0)
2717 {
2718 const InstanceInterface& vki = context.getInstanceInterface();
2719 const DeviceInterface& vk = context.getDeviceInterface();
2720 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
2721 const VkDevice vkDevice = m_device;
2722 Allocator& memAlloc = context.getDefaultAllocator();
2723 const bool hasDepth = tcu::hasDepthComponent(mapVkFormat(m_params.dst.image.format).order);
2724 const bool hasStencil = tcu::hasStencilComponent(mapVkFormat(m_params.dst.image.format).order);
2725
2726 if (!isSupportedDepthStencilFormat(vki, vkPhysDevice, testParams.dst.image.format))
2727 {
2728 TCU_THROW(NotSupportedError, "Image format not supported.");
2729 }
2730
2731 if (hasDepth)
2732 {
2733 glw::GLuint texelSize = m_textureFormat.getPixelSize();
2734 if (texelSize > sizeof(float))
2735 {
2736 // We must have D32F_S8 format, depth must be packed so we only need
2737 // to allocate space for the D32F part. Stencil will be separate
2738 texelSize = sizeof(float);
2739 }
2740 m_bufferSize += static_cast<VkDeviceSize>(m_params.dst.image.extent.width) * static_cast<VkDeviceSize>(m_params.dst.image.extent.height) * static_cast<VkDeviceSize>(texelSize);
2741 }
2742 if (hasStencil)
2743 {
2744 // Stencil is always 8bits and packed.
2745 m_bufferSize += static_cast<VkDeviceSize>(m_params.dst.image.extent.width) * static_cast<VkDeviceSize>(m_params.dst.image.extent.height);
2746 }
2747
2748 // Create source buffer, this is where the depth & stencil data will go that's used by test's regions.
2749 {
2750 const VkBufferCreateInfo sourceBufferParams =
2751 {
2752 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2753 DE_NULL, // const void* pNext;
2754 0u, // VkBufferCreateFlags flags;
2755 m_bufferSize, // VkDeviceSize size;
2756 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage;
2757 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2758 0u, // deUint32 queueFamilyIndexCount;
2759 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
2760 };
2761
2762 m_source = createBuffer(vk, vkDevice, &sourceBufferParams);
2763 m_sourceBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
2764 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
2765 }
2766
2767 // Create destination image
2768 {
2769 const VkImageCreateInfo destinationImageParams =
2770 {
2771 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
2772 DE_NULL, // const void* pNext;
2773 getCreateFlags(m_params.dst.image), // VkImageCreateFlags flags;
2774 m_params.dst.image.imageType, // VkImageType imageType;
2775 m_params.dst.image.format, // VkFormat format;
2776 getExtent3D(m_params.dst.image), // VkExtent3D extent;
2777 1u, // deUint32 mipLevels;
2778 getArraySize(m_params.dst.image), // deUint32 arraySize;
2779 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
2780 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
2781 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2782 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
2783 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2784 0u, // deUint32 queueFamilyIndexCount;
2785 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
2786 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
2787 };
2788
2789 m_destination = createImage(vk, vkDevice, &destinationImageParams);
2790 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
2791 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
2792 }
2793 }
2794
iterate(void)2795 tcu::TestStatus CopyBufferToDepthStencil::iterate(void)
2796 {
2797 // Create source depth/stencil content. Treat as 1D texture to get different pattern
2798 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.src.buffer.size, 1));
2799 // Fill buffer with linear gradiant
2800 generateBuffer(m_sourceTextureLevel->getAccess(), (int)m_params.src.buffer.size, 1, 1);
2801
2802 // Create image layer for depth/stencil
2803 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
2804 m_params.dst.image.extent.width,
2805 m_params.dst.image.extent.height,
2806 m_params.dst.image.extent.depth));
2807
2808 // Fill image layer with 2D gradiant
2809 generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
2810
2811 // Fill m_extendedTextureLevel with copy of m_destinationTextureLevel
2812 // Then iterate over each of the regions given in m_params.regions and copy m_sourceTextureLevel content to m_extendedTextureLevel
2813 // This emulates what the HW will be doing.
2814 generateExpectedResult();
2815
2816 // Upload our source depth/stencil content to the source buffer
2817 // This is the buffer that will be used by region commands
2818 std::vector<VkBufferImageCopy> bufferImageCopies;
2819 std::vector<VkBufferImageCopy2KHR> bufferImageCopies2KHR;
2820 VkDeviceSize bufferOffset = 0;
2821 const VkDevice vkDevice = m_device;
2822 const DeviceInterface& vk = m_context.getDeviceInterface();
2823 const VkQueue queue = m_queue;
2824 char* dstPtr = reinterpret_cast<char*>(m_sourceBufferAlloc->getHostPtr());
2825 bool depthLoaded = DE_FALSE;
2826 bool stencilLoaded = DE_FALSE;
2827 VkDeviceSize depthOffset = 0;
2828 VkDeviceSize stencilOffset = 0;
2829
2830 // To be able to test ordering depth & stencil differently
2831 // we take the given copy regions and use that as the desired order
2832 // and copy the appropriate data into place and compute the appropriate
2833 // data offsets to be used in the copy command.
2834 for (deUint32 i = 0; i < m_params.regions.size(); i++)
2835 {
2836 tcu::ConstPixelBufferAccess bufferAccess = m_sourceTextureLevel->getAccess();
2837 deUint32 bufferSize = bufferAccess.getWidth() * bufferAccess.getHeight() * bufferAccess.getDepth();
2838 VkBufferImageCopy copyData = m_params.regions[i].bufferImageCopy;
2839 char* srcPtr;
2840
2841 if (copyData.imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT && !depthLoaded)
2842 {
2843 // Create level that is same component as depth buffer (e.g. D16, D24, D32F)
2844 tcu::TextureLevel depthTexture(mapCombinedToDepthTransferFormat(bufferAccess.getFormat()), bufferAccess.getWidth(), bufferAccess.getHeight(), bufferAccess.getDepth());
2845 bufferSize *= tcu::getPixelSize(depthTexture.getFormat());
2846 // Copy depth component only from source data. This gives us packed depth-only data.
2847 tcu::copy(depthTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(bufferAccess, tcu::Sampler::MODE_DEPTH));
2848 srcPtr = (char*)depthTexture.getAccess().getDataPtr();
2849 // Copy packed depth-only data to output buffer
2850 deMemcpy(dstPtr, srcPtr, bufferSize);
2851 depthLoaded = DE_TRUE;
2852 depthOffset = bufferOffset;
2853 dstPtr += bufferSize;
2854 bufferOffset += bufferSize;
2855 copyData.bufferOffset += depthOffset;
2856 }
2857 else if (!stencilLoaded)
2858 {
2859 // Create level that is same component as stencil buffer (always 8-bits)
2860 tcu::TextureLevel stencilTexture(tcu::getEffectiveDepthStencilTextureFormat(bufferAccess.getFormat(), tcu::Sampler::MODE_STENCIL), bufferAccess.getWidth(), bufferAccess.getHeight(), bufferAccess.getDepth());
2861 // Copy stencil component only from source data. This gives us packed stencil-only data.
2862 tcu::copy(stencilTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(bufferAccess, tcu::Sampler::MODE_STENCIL));
2863 srcPtr = (char*)stencilTexture.getAccess().getDataPtr();
2864 // Copy packed stencil-only data to output buffer
2865 deMemcpy(dstPtr, srcPtr, bufferSize);
2866 stencilLoaded = DE_TRUE;
2867 stencilOffset = bufferOffset;
2868 dstPtr += bufferSize;
2869 bufferOffset += bufferSize;
2870
2871 // Reference image generation uses pixel offsets based on buffer offset.
2872 // We need to adjust the offset now that the stencil data is not interleaved.
2873 copyData.bufferOffset /= tcu::getPixelSize(m_textureFormat);
2874
2875 copyData.bufferOffset += stencilOffset;
2876 }
2877
2878 if (m_params.extensionUse == EXTENSION_USE_NONE)
2879 {
2880 bufferImageCopies.push_back(copyData);
2881 }
2882 else
2883 {
2884 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2885 bufferImageCopies2KHR.push_back(convertvkBufferImageCopyTovkBufferImageCopy2KHR(copyData));
2886 }
2887 }
2888
2889 flushAlloc(vk, vkDevice, *m_sourceBufferAlloc);
2890
2891 // Upload the depth/stencil data from m_destinationTextureLevel to initialize
2892 // depth and stencil to known values.
2893 // Uses uploadImageAspect so makes its own buffers for depth and stencil
2894 // aspects (as needed) and copies them with independent vkCmdCopyBufferToImage commands.
2895 uploadImage(m_destinationTextureLevel->getAccess(), *m_destination, m_params.dst.image);
2896
2897 const VkImageMemoryBarrier imageBarrier =
2898 {
2899 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
2900 DE_NULL, // const void* pNext;
2901 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
2902 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
2903 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
2904 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
2905 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
2906 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
2907 *m_destination, // VkImage image;
2908 { // VkImageSubresourceRange subresourceRange;
2909 getAspectFlags(m_textureFormat), // VkImageAspectFlags aspectMask;
2910 0u, // deUint32 baseMipLevel;
2911 1u, // deUint32 mipLevels;
2912 0u, // deUint32 baseArraySlice;
2913 1u // deUint32 arraySize;
2914 }
2915 };
2916
2917 // Copy from buffer to depth/stencil image
2918
2919 beginCommandBuffer(vk, *m_cmdBuffer);
2920 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier);
2921
2922 if (m_params.extensionUse == EXTENSION_USE_NONE)
2923 {
2924 if (m_params.singleCommand)
2925 {
2926 // Issue a single copy command with regions defined by the test.
2927 vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), bufferImageCopies.data());
2928 }
2929 else
2930 {
2931 // Issue a a copy command per region defined by the test.
2932 for (deUint32 i = 0; i < bufferImageCopies.size(); i++)
2933 {
2934 vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferImageCopies[i]);
2935 }
2936 }
2937 }
2938 #ifndef CTS_USES_VULKANSC
2939 else
2940 {
2941 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2942
2943 if (m_params.singleCommand)
2944 {
2945 // Issue a single copy command with regions defined by the test.
2946 const VkCopyBufferToImageInfo2KHR copyBufferToImageInfo2KHR =
2947 {
2948 VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR, // VkStructureType sType;
2949 DE_NULL, // const void* pNext;
2950 m_source.get(), // VkBuffer srcBuffer;
2951 m_destination.get(), // VkImage dstImage;
2952 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout dstImageLayout;
2953 (deUint32)m_params.regions.size(), // uint32_t regionCount;
2954 bufferImageCopies2KHR.data() // const VkBufferImageCopy2KHR* pRegions;
2955 };
2956 vk.cmdCopyBufferToImage2(*m_cmdBuffer, ©BufferToImageInfo2KHR);
2957 }
2958 else
2959 {
2960 // Issue a a copy command per region defined by the test.
2961 for (deUint32 i = 0; i < bufferImageCopies2KHR.size(); i++)
2962 {
2963 const VkCopyBufferToImageInfo2KHR copyBufferToImageInfo2KHR =
2964 {
2965 VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR, // VkStructureType sType;
2966 DE_NULL, // const void* pNext;
2967 m_source.get(), // VkBuffer srcBuffer;
2968 m_destination.get(), // VkImage dstImage;
2969 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout dstImageLayout;
2970 1, // uint32_t regionCount;
2971 &bufferImageCopies2KHR[i] // const VkBufferImageCopy2KHR* pRegions;
2972 };
2973 // Issue a single copy command with regions defined by the test.
2974 vk.cmdCopyBufferToImage2(*m_cmdBuffer, ©BufferToImageInfo2KHR);
2975 }
2976 }
2977 }
2978 #endif // CTS_USES_VULKANSC
2979
2980 endCommandBuffer(vk, *m_cmdBuffer);
2981
2982 submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
2983 m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
2984
2985 de::MovePtr<tcu::TextureLevel> resultLevel = readImage(*m_destination, m_params.dst.image);
2986
2987 // For combined depth/stencil formats both aspects are checked even when the test only
2988 // copies one. Clear such aspects here for both the result and the reference.
2989 if (tcu::hasDepthComponent(m_textureFormat.order) && !depthLoaded)
2990 {
2991 tcu::clearDepth(m_expectedTextureLevel[0]->getAccess(), 0.0f);
2992 tcu::clearDepth(resultLevel->getAccess(), 0.0f);
2993 }
2994 if (tcu::hasStencilComponent(m_textureFormat.order) && !stencilLoaded)
2995 {
2996 tcu::clearStencil(m_expectedTextureLevel[0]->getAccess(), 0);
2997 tcu::clearStencil(resultLevel->getAccess(), 0);
2998 }
2999
3000 return checkTestResult(resultLevel->getAccess());
3001 }
3002
3003 class CopyBufferToDepthStencilTestCase : public vkt::TestCase
3004 {
3005 public:
CopyBufferToDepthStencilTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)3006 CopyBufferToDepthStencilTestCase (tcu::TestContext& testCtx,
3007 const std::string& name,
3008 const std::string& description,
3009 const TestParams params)
3010 : vkt::TestCase(testCtx, name, description)
3011 , m_params(params)
3012 {}
3013
~CopyBufferToDepthStencilTestCase(void)3014 virtual ~CopyBufferToDepthStencilTestCase (void) {}
3015
createInstance(Context & context) const3016 virtual TestInstance* createInstance (Context& context) const
3017 {
3018 return new CopyBufferToDepthStencil(context, m_params);
3019 }
3020
checkSupport(Context & context) const3021 virtual void checkSupport (Context& context) const
3022 {
3023 if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
3024 (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
3025 {
3026 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
3027 }
3028 }
3029
3030 private:
3031 TestParams m_params;
3032 };
3033
3034 // CompressedTextureForBlit is a helper class that stores compressed texture data.
3035 // Implementation is based on pipeline::TestTexture2D but it allocates only one level
3036 // and has special cases needed for blits to some formats.
3037
3038 class CompressedTextureForBlit
3039 {
3040 public:
3041 CompressedTextureForBlit(const tcu::CompressedTexFormat& srcFormat, int width, int height, int depth);
3042
3043 tcu::PixelBufferAccess getDecompressedAccess() const;
3044 const tcu::CompressedTexture& getCompressedTexture() const;
3045
3046 protected:
3047
3048 tcu::CompressedTexture m_compressedTexture;
3049 de::ArrayBuffer<deUint8> m_decompressedData;
3050 tcu::PixelBufferAccess m_decompressedAccess;
3051 };
3052
CompressedTextureForBlit(const tcu::CompressedTexFormat & srcFormat,int width,int height,int depth)3053 CompressedTextureForBlit::CompressedTextureForBlit(const tcu::CompressedTexFormat& srcFormat, int width, int height, int depth)
3054 : m_compressedTexture(srcFormat, width, height, depth)
3055 {
3056 de::Random random (123);
3057
3058 const int compressedDataSize (m_compressedTexture.getDataSize());
3059 deUint8* compressedData ((deUint8*)m_compressedTexture.getData());
3060
3061 tcu::TextureFormat decompressedSrcFormat (tcu::getUncompressedFormat(srcFormat));
3062 const int decompressedDataSize (tcu::getPixelSize(decompressedSrcFormat) * width * height * depth);
3063
3064 // generate random data for compresed textre
3065 if (tcu::isAstcFormat(srcFormat))
3066 {
3067 // comparison doesn't currently handle invalid blocks correctly so we use only valid blocks
3068 tcu::astc::generateRandomValidBlocks(compressedData, compressedDataSize / tcu::astc::BLOCK_SIZE_BYTES,
3069 srcFormat, tcu::TexDecompressionParams::ASTCMODE_LDR, random.getUint32());
3070 }
3071 else if ((srcFormat == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK) ||
3072 (srcFormat == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK))
3073 {
3074 // special case - when we are blitting compressed floating-point image we can't have both big and small values
3075 // in compressed image; to resolve this we are constructing source texture out of set of predefined compressed
3076 // blocks that after decompression will have components in proper range
3077
3078 struct BC6HBlock
3079 {
3080 deUint32 data[4];
3081 };
3082 std::vector<BC6HBlock> validBlocks;
3083
3084 if (srcFormat == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK)
3085 {
3086 // define set of few valid blocks that contain values from <0; 1> range
3087 validBlocks =
3088 {
3089 { { 1686671500, 3957317723, 3010132342, 2420137890 } },
3090 { { 3538027716, 298848033, 1925786021, 2022072301 } },
3091 { { 2614043466, 1636155440, 1023731774, 1894349986 } },
3092 { { 3433039318, 1294346072, 1587319645, 1738449906 } },
3093 { { 1386298160, 1639492154, 1273285776, 361562050 } },
3094 { { 1310110688, 526460754, 3630858047, 537617591 } },
3095 { { 3270356556, 2432993217, 2415924417, 1792488857 } },
3096 { { 1204947583, 353249154, 3739153467, 2068076443 } },
3097 };
3098 }
3099 else
3100 {
3101 // define set of few valid blocks that contain values from <-1; 1> range
3102 validBlocks =
3103 {
3104 { { 2120678840, 3264271120, 4065378848, 3479743703 } },
3105 { { 1479697556, 3480872527, 3369382558, 568252340 } },
3106 { { 1301480032, 1607738094, 3055221704, 3663953681 } },
3107 { { 3531657186, 2285472028, 1429601507, 1969308187 } },
3108 { { 73229044, 650504649, 1120954865, 2626631975 } },
3109 { { 3872486086, 15326178, 2565171269, 2857722432 } },
3110 { { 1301480032, 1607738094, 3055221704, 3663953681 } },
3111 { { 73229044, 650504649, 1120954865, 2626631975 } },
3112 };
3113 }
3114
3115 deUint32* compressedDataUint32 = reinterpret_cast<deUint32*>(compressedData);
3116 const int blocksCount = compressedDataSize / static_cast<int>(sizeof(BC6HBlock));
3117
3118 // fill data using randomly selected valid blocks
3119 for (int blockNdx = 0; blockNdx < blocksCount; blockNdx++)
3120 {
3121 deUint32 selectedBlock = random.getUint32() % static_cast<deUint32>(validBlocks.size());
3122 deMemcpy(compressedDataUint32, validBlocks[selectedBlock].data, sizeof(BC6HBlock));
3123 compressedDataUint32 += 4;
3124 }
3125 }
3126 else if (srcFormat != tcu::COMPRESSEDTEXFORMAT_ETC1_RGB8)
3127 {
3128 // random initial values cause assertion during the decompression in case of COMPRESSEDTEXFORMAT_ETC1_RGB8 format
3129 for (int byteNdx = 0; byteNdx < compressedDataSize; byteNdx++)
3130 compressedData[byteNdx] = 0xFF & random.getUint32();
3131 }
3132
3133 // alocate space for decompressed texture
3134 m_decompressedData.setStorage(decompressedDataSize);
3135 m_decompressedAccess = tcu::PixelBufferAccess(decompressedSrcFormat, width, height, depth, m_decompressedData.getPtr());
3136
3137 // store decompressed data
3138 m_compressedTexture.decompress(m_decompressedAccess, tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR));
3139 }
3140
getDecompressedAccess() const3141 tcu::PixelBufferAccess CompressedTextureForBlit::getDecompressedAccess() const
3142 {
3143 return m_decompressedAccess;
3144 }
3145
getCompressedTexture() const3146 const tcu::CompressedTexture& CompressedTextureForBlit::getCompressedTexture() const
3147 {
3148 return m_compressedTexture;
3149 }
3150
3151 // Copy from image to image with scaling.
3152
3153 class BlittingImages : public CopiesAndBlittingTestInstance
3154 {
3155 public:
3156 BlittingImages (Context& context,
3157 TestParams params);
3158 virtual tcu::TestStatus iterate (void);
3159 protected:
3160 virtual tcu::TestStatus checkTestResult (tcu::ConstPixelBufferAccess result);
3161 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src,
3162 tcu::PixelBufferAccess dst,
3163 CopyRegion region,
3164 deUint32 mipLevel = 0u);
3165 virtual void generateExpectedResult (void);
3166 void uploadCompressedImage (const VkImage& image, const ImageParms& parms);
3167 private:
3168 bool checkNonNearestFilteredResult (const tcu::ConstPixelBufferAccess& result,
3169 const tcu::ConstPixelBufferAccess& clampedReference,
3170 const tcu::ConstPixelBufferAccess& unclampedReference,
3171 const tcu::TextureFormat& sourceFormat);
3172 bool checkNearestFilteredResult (const tcu::ConstPixelBufferAccess& result,
3173 const tcu::ConstPixelBufferAccess& source);
3174
3175 bool checkCompressedNonNearestFilteredResult (const tcu::ConstPixelBufferAccess& result,
3176 const tcu::ConstPixelBufferAccess& clampedReference,
3177 const tcu::ConstPixelBufferAccess& unclampedReference,
3178 const tcu::CompressedTexFormat format);
3179 bool checkCompressedNearestFilteredResult (const tcu::ConstPixelBufferAccess& result,
3180 const tcu::ConstPixelBufferAccess& source,
3181 const tcu::CompressedTexFormat format);
3182
3183
3184 Move<VkImage> m_source;
3185 de::MovePtr<Allocation> m_sourceImageAlloc;
3186 Move<VkImage> m_destination;
3187 de::MovePtr<Allocation> m_destinationImageAlloc;
3188
3189 de::MovePtr<tcu::TextureLevel> m_unclampedExpectedTextureLevel;
3190
3191 // helper used only when bliting from compressed formats
3192 typedef de::SharedPtr<CompressedTextureForBlit> CompressedTextureForBlitSp;
3193 CompressedTextureForBlitSp m_sourceCompressedTexture;
3194 CompressedTextureForBlitSp m_destinationCompressedTexture;
3195 };
3196
BlittingImages(Context & context,TestParams params)3197 BlittingImages::BlittingImages (Context& context, TestParams params)
3198 : CopiesAndBlittingTestInstance(context, params)
3199 {
3200 const InstanceInterface& vki = context.getInstanceInterface();
3201 const DeviceInterface& vk = context.getDeviceInterface();
3202 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
3203 const VkDevice vkDevice = m_device;
3204 Allocator& memAlloc = context.getDefaultAllocator();
3205
3206 // Create source image
3207 {
3208 const VkImageCreateInfo sourceImageParams =
3209 {
3210 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
3211 DE_NULL, // const void* pNext;
3212 getCreateFlags(m_params.src.image), // VkImageCreateFlags flags;
3213 m_params.src.image.imageType, // VkImageType imageType;
3214 m_params.src.image.format, // VkFormat format;
3215 getExtent3D(m_params.src.image), // VkExtent3D extent;
3216 1u, // deUint32 mipLevels;
3217 getArraySize(m_params.src.image), // deUint32 arraySize;
3218 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
3219 m_params.src.image.tiling, // VkImageTiling tiling;
3220 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
3221 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
3222 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
3223 0u, // deUint32 queueFamilyIndexCount;
3224 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
3225 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
3226 };
3227
3228 m_source = createImage(vk, vkDevice, &sourceImageParams);
3229 m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
3230 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
3231 }
3232
3233 // Create destination image
3234 {
3235 const VkImageCreateInfo destinationImageParams =
3236 {
3237 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
3238 DE_NULL, // const void* pNext;
3239 getCreateFlags(m_params.dst.image), // VkImageCreateFlags flags;
3240 m_params.dst.image.imageType, // VkImageType imageType;
3241 m_params.dst.image.format, // VkFormat format;
3242 getExtent3D(m_params.dst.image), // VkExtent3D extent;
3243 1u, // deUint32 mipLevels;
3244 getArraySize(m_params.dst.image), // deUint32 arraySize;
3245 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
3246 m_params.dst.image.tiling, // VkImageTiling tiling;
3247 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
3248 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
3249 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
3250 0u, // deUint32 queueFamilyIndexCount;
3251 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
3252 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
3253 };
3254
3255 m_destination = createImage(vk, vkDevice, &destinationImageParams);
3256 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
3257 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
3258 }
3259 }
3260
iterate(void)3261 tcu::TestStatus BlittingImages::iterate (void)
3262 {
3263 const DeviceInterface& vk = m_context.getDeviceInterface();
3264 const VkDevice vkDevice = m_device;
3265 const VkQueue queue = m_queue;
3266
3267 const ImageParms& srcImageParams = m_params.src.image;
3268 const int srcWidth = static_cast<int>(srcImageParams.extent.width);
3269 const int srcHeight = static_cast<int>(srcImageParams.extent.height);
3270 const int srcDepth = static_cast<int>(srcImageParams.extent.depth);
3271 const ImageParms& dstImageParams = m_params.dst.image;
3272 const int dstWidth = static_cast<int>(dstImageParams.extent.width);
3273 const int dstHeight = static_cast<int>(dstImageParams.extent.height);
3274 const int dstDepth = static_cast<int>(dstImageParams.extent.depth);
3275
3276 std::vector<VkImageBlit> regions;
3277 std::vector<VkImageBlit2KHR> regions2KHR;
3278
3279 // setup blit regions - they are also needed for reference generation
3280 if (m_params.extensionUse == EXTENSION_USE_NONE)
3281 {
3282 regions.reserve(m_params.regions.size());
3283 for (const auto& r : m_params.regions)
3284 regions.push_back(r.imageBlit);
3285 }
3286 else
3287 {
3288 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
3289 regions2KHR.reserve(m_params.regions.size());
3290 for (const auto& r : m_params.regions)
3291 regions2KHR.push_back(convertvkImageBlitTovkImageBlit2KHR(r.imageBlit));
3292 }
3293
3294 // generate source image
3295 if (isCompressedFormat(srcImageParams.format))
3296 {
3297 // for compressed images srcImageParams.fillMode is not used - we are using random data
3298 tcu::CompressedTexFormat compressedFormat = mapVkCompressedFormat(srcImageParams.format);
3299 m_sourceCompressedTexture = CompressedTextureForBlitSp(new CompressedTextureForBlit(compressedFormat, srcWidth, srcHeight, srcDepth));
3300 uploadCompressedImage(m_source.get(), srcImageParams);
3301 }
3302 else
3303 {
3304 // non-compressed image is filled with selected fillMode
3305 const tcu::TextureFormat srcTcuFormat = mapVkFormat(srcImageParams.format);
3306 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat, srcWidth, srcHeight, srcDepth));
3307 generateBuffer(m_sourceTextureLevel->getAccess(), srcWidth, srcHeight, srcDepth, srcImageParams.fillMode);
3308 uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), srcImageParams);
3309 }
3310
3311 // generate destination image
3312 if (isCompressedFormat(dstImageParams.format))
3313 {
3314 // compressed images are filled with random data
3315 tcu::CompressedTexFormat compressedFormat = mapVkCompressedFormat(dstImageParams.format);
3316 m_destinationCompressedTexture = CompressedTextureForBlitSp(new CompressedTextureForBlit(compressedFormat, srcWidth, srcHeight, srcDepth));
3317 uploadCompressedImage(m_destination.get(), dstImageParams);
3318 }
3319 else
3320 {
3321 // non-compressed image is filled with white background
3322 const tcu::TextureFormat dstTcuFormat = mapVkFormat(dstImageParams.format);
3323 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat, dstWidth, dstHeight, dstDepth));
3324 generateBuffer(m_destinationTextureLevel->getAccess(), dstWidth, dstHeight, dstDepth, dstImageParams.fillMode);
3325 uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), dstImageParams);
3326 }
3327
3328 generateExpectedResult();
3329
3330 // Barriers for copying images to buffer
3331 const VkImageMemoryBarrier imageBarriers[]
3332 {
3333 {
3334 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
3335 DE_NULL, // const void* pNext;
3336 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
3337 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
3338 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
3339 srcImageParams.operationLayout, // VkImageLayout newLayout;
3340 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
3341 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
3342 m_source.get(), // VkImage image;
3343 { // VkImageSubresourceRange subresourceRange;
3344 getAspectFlags(srcImageParams.format), // VkImageAspectFlags aspectMask;
3345 0u, // deUint32 baseMipLevel;
3346 1u, // deUint32 mipLevels;
3347 0u, // deUint32 baseArraySlice;
3348 1u // deUint32 arraySize;
3349 }
3350 },
3351 {
3352 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
3353 DE_NULL, // const void* pNext;
3354 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
3355 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
3356 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
3357 dstImageParams.operationLayout, // VkImageLayout newLayout;
3358 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
3359 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
3360 m_destination.get(), // VkImage image;
3361 { // VkImageSubresourceRange subresourceRange;
3362 getAspectFlags(dstImageParams.format), // VkImageAspectFlags aspectMask;
3363 0u, // deUint32 baseMipLevel;
3364 1u, // deUint32 mipLevels;
3365 0u, // deUint32 baseArraySlice;
3366 1u // deUint32 arraySize;
3367 }
3368 }
3369 };
3370
3371 beginCommandBuffer(vk, *m_cmdBuffer);
3372 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 2, imageBarriers);
3373
3374 if (m_params.extensionUse == EXTENSION_USE_NONE)
3375 {
3376 vk.cmdBlitImage(*m_cmdBuffer, m_source.get(), srcImageParams.operationLayout, m_destination.get(), dstImageParams.operationLayout, (deUint32)m_params.regions.size(), ®ions[0], m_params.filter);
3377 }
3378 #ifndef CTS_USES_VULKANSC
3379 else
3380 {
3381 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
3382 const VkBlitImageInfo2KHR blitImageInfo2KHR
3383 {
3384 VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR, // VkStructureType sType;
3385 DE_NULL, // const void* pNext;
3386 m_source.get(), // VkImage srcImage;
3387 srcImageParams.operationLayout, // VkImageLayout srcImageLayout;
3388 m_destination.get(), // VkImage dstImage;
3389 dstImageParams.operationLayout, // VkImageLayout dstImageLayout;
3390 (deUint32)m_params.regions.size(), // uint32_t regionCount;
3391 ®ions2KHR[0], // const VkImageBlit2KHR* pRegions;
3392 m_params.filter, // VkFilter filter;
3393 };
3394 vk.cmdBlitImage2(*m_cmdBuffer, &blitImageInfo2KHR);
3395 }
3396 #endif // CTS_USES_VULKANSC
3397
3398 endCommandBuffer(vk, *m_cmdBuffer);
3399 submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
3400 m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
3401
3402 de::MovePtr<tcu::TextureLevel> resultLevel = readImage(*m_destination, dstImageParams);
3403 tcu::PixelBufferAccess resultAccess = resultLevel->getAccess();
3404
3405 // if blit was done to a compressed format we need to decompress it to be able to verify it
3406 if (m_destinationCompressedTexture)
3407 {
3408 deUint8* const compressedDataSrc (static_cast<deUint8*>(resultAccess.getDataPtr()));
3409 const tcu::CompressedTexFormat dstCompressedFormat (mapVkCompressedFormat(dstImageParams.format));
3410 tcu::TextureLevel decompressedLevel (getUncompressedFormat(dstCompressedFormat), dstWidth, dstHeight, dstDepth);
3411 tcu::PixelBufferAccess decompressedAccess (decompressedLevel.getAccess());
3412
3413 tcu::decompress(decompressedAccess, dstCompressedFormat, compressedDataSrc);
3414
3415 return checkTestResult(decompressedAccess);
3416 }
3417
3418 return checkTestResult(resultAccess);
3419 }
3420
calculateFloatConversionError(int srcBits)3421 static float calculateFloatConversionError (int srcBits)
3422 {
3423 if (srcBits > 0)
3424 {
3425 const int clampedBits = de::clamp<int>(srcBits, 0, 32);
3426 const float srcMaxValue = de::max((float)(1ULL<<clampedBits) - 1.0f, 1.0f);
3427 const float error = 1.0f / srcMaxValue;
3428
3429 return de::clamp<float>(error, 0.0f, 1.0f);
3430 }
3431 else
3432 return 1.0f;
3433 }
3434
getFormatThreshold(const tcu::TextureFormat & format)3435 tcu::Vec4 getFormatThreshold (const tcu::TextureFormat& format)
3436 {
3437 tcu::Vec4 threshold(0.01f);
3438
3439 switch (format.type)
3440 {
3441 case tcu::TextureFormat::HALF_FLOAT:
3442 threshold = tcu::Vec4(0.005f);
3443 break;
3444
3445 case tcu::TextureFormat::FLOAT:
3446 case tcu::TextureFormat::FLOAT64:
3447 threshold = tcu::Vec4(0.001f);
3448 break;
3449
3450 case tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
3451 threshold = tcu::Vec4(0.02f, 0.02f, 0.0625f, 1.0f);
3452 break;
3453
3454 case tcu::TextureFormat::UNSIGNED_INT_999_E5_REV:
3455 threshold = tcu::Vec4(0.05f, 0.05f, 0.05f, 1.0f);
3456 break;
3457
3458 case tcu::TextureFormat::UNORM_INT_1010102_REV:
3459 threshold = tcu::Vec4(0.002f, 0.002f, 0.002f, 0.3f);
3460 break;
3461
3462 case tcu:: TextureFormat::UNORM_INT8:
3463 threshold = tcu::Vec4(0.008f, 0.008f, 0.008f, 0.008f);
3464 break;
3465
3466 default:
3467 const tcu::IVec4 bits = tcu::getTextureFormatMantissaBitDepth(format);
3468 threshold = tcu::Vec4(calculateFloatConversionError(bits.x()),
3469 calculateFloatConversionError(bits.y()),
3470 calculateFloatConversionError(bits.z()),
3471 calculateFloatConversionError(bits.w()));
3472 }
3473
3474 // Return value matching the channel order specified by the format
3475 if (format.order == tcu::TextureFormat::BGR || format.order == tcu::TextureFormat::BGRA)
3476 return threshold.swizzle(2, 1, 0, 3);
3477 else
3478 return threshold;
3479 }
3480
getCompressedFormatThreshold(const tcu::CompressedTexFormat & format)3481 tcu::Vec4 getCompressedFormatThreshold(const tcu::CompressedTexFormat& format)
3482 {
3483 bool isSigned(false);
3484 tcu::IVec4 bitDepth(0);
3485
3486 switch (format)
3487 {
3488 case tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_R11:
3489 bitDepth = { 7, 0, 0, 0 };
3490 isSigned = true;
3491 break;
3492
3493 case tcu::COMPRESSEDTEXFORMAT_EAC_R11:
3494 bitDepth = { 8, 0, 0, 0 };
3495 break;
3496
3497 case tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11:
3498 bitDepth = { 7, 7, 0, 0 };
3499 isSigned = true;
3500 break;
3501
3502 case tcu::COMPRESSEDTEXFORMAT_EAC_RG11:
3503 bitDepth = { 8, 8, 0, 0 };
3504 break;
3505
3506 case tcu::COMPRESSEDTEXFORMAT_ETC1_RGB8:
3507 case tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8:
3508 case tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8:
3509 bitDepth = { 8, 8, 8, 0 };
3510 break;
3511
3512 case tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
3513 case tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
3514 bitDepth = { 8, 8, 8, 1 };
3515 break;
3516
3517 case tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8:
3518 case tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8:
3519 case tcu::COMPRESSEDTEXFORMAT_ASTC_4x4_RGBA:
3520 case tcu::COMPRESSEDTEXFORMAT_ASTC_5x4_RGBA:
3521 case tcu::COMPRESSEDTEXFORMAT_ASTC_5x5_RGBA:
3522 case tcu::COMPRESSEDTEXFORMAT_ASTC_6x5_RGBA:
3523 case tcu::COMPRESSEDTEXFORMAT_ASTC_6x6_RGBA:
3524 case tcu::COMPRESSEDTEXFORMAT_ASTC_8x5_RGBA:
3525 case tcu::COMPRESSEDTEXFORMAT_ASTC_8x6_RGBA:
3526 case tcu::COMPRESSEDTEXFORMAT_ASTC_8x8_RGBA:
3527 case tcu::COMPRESSEDTEXFORMAT_ASTC_10x5_RGBA:
3528 case tcu::COMPRESSEDTEXFORMAT_ASTC_10x6_RGBA:
3529 case tcu::COMPRESSEDTEXFORMAT_ASTC_10x8_RGBA:
3530 case tcu::COMPRESSEDTEXFORMAT_ASTC_10x10_RGBA:
3531 case tcu::COMPRESSEDTEXFORMAT_ASTC_12x10_RGBA:
3532 case tcu::COMPRESSEDTEXFORMAT_ASTC_12x12_RGBA:
3533 case tcu::COMPRESSEDTEXFORMAT_ASTC_4x4_SRGB8_ALPHA8:
3534 case tcu::COMPRESSEDTEXFORMAT_ASTC_5x4_SRGB8_ALPHA8:
3535 case tcu::COMPRESSEDTEXFORMAT_ASTC_5x5_SRGB8_ALPHA8:
3536 case tcu::COMPRESSEDTEXFORMAT_ASTC_6x5_SRGB8_ALPHA8:
3537 case tcu::COMPRESSEDTEXFORMAT_ASTC_6x6_SRGB8_ALPHA8:
3538 case tcu::COMPRESSEDTEXFORMAT_ASTC_8x5_SRGB8_ALPHA8:
3539 case tcu::COMPRESSEDTEXFORMAT_ASTC_8x6_SRGB8_ALPHA8:
3540 case tcu::COMPRESSEDTEXFORMAT_ASTC_8x8_SRGB8_ALPHA8:
3541 case tcu::COMPRESSEDTEXFORMAT_ASTC_10x5_SRGB8_ALPHA8:
3542 case tcu::COMPRESSEDTEXFORMAT_ASTC_10x6_SRGB8_ALPHA8:
3543 case tcu::COMPRESSEDTEXFORMAT_ASTC_10x8_SRGB8_ALPHA8:
3544 case tcu::COMPRESSEDTEXFORMAT_ASTC_10x10_SRGB8_ALPHA8:
3545 case tcu::COMPRESSEDTEXFORMAT_ASTC_12x10_SRGB8_ALPHA8:
3546 case tcu::COMPRESSEDTEXFORMAT_ASTC_12x12_SRGB8_ALPHA8:
3547 bitDepth = { 8, 8, 8, 8 };
3548 break;
3549
3550 case tcu::COMPRESSEDTEXFORMAT_BC1_RGB_UNORM_BLOCK:
3551 case tcu::COMPRESSEDTEXFORMAT_BC1_RGB_SRGB_BLOCK:
3552 case tcu::COMPRESSEDTEXFORMAT_BC2_UNORM_BLOCK:
3553 case tcu::COMPRESSEDTEXFORMAT_BC2_SRGB_BLOCK:
3554 case tcu::COMPRESSEDTEXFORMAT_BC3_UNORM_BLOCK:
3555 case tcu::COMPRESSEDTEXFORMAT_BC3_SRGB_BLOCK:
3556 bitDepth = { 5, 6, 5, 0 };
3557 break;
3558
3559 case tcu::COMPRESSEDTEXFORMAT_BC1_RGBA_UNORM_BLOCK:
3560 case tcu::COMPRESSEDTEXFORMAT_BC1_RGBA_SRGB_BLOCK:
3561 case tcu::COMPRESSEDTEXFORMAT_BC7_UNORM_BLOCK:
3562 case tcu::COMPRESSEDTEXFORMAT_BC7_SRGB_BLOCK:
3563 bitDepth = { 5, 5, 5, 1 };
3564 break;
3565
3566 case tcu::COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK:
3567 bitDepth = { 7, 0, 0, 0 };
3568 isSigned = true;
3569 break;
3570
3571 case tcu::COMPRESSEDTEXFORMAT_BC4_UNORM_BLOCK:
3572 bitDepth = { 8, 0, 0, 0 };
3573 break;
3574
3575 case tcu::COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK:
3576 bitDepth = { 7, 7, 0, 0 };
3577 isSigned = true;
3578 break;
3579
3580 case tcu::COMPRESSEDTEXFORMAT_BC5_UNORM_BLOCK:
3581 bitDepth = { 8, 8, 0, 0 };
3582 break;
3583
3584 case tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK:
3585 return tcu::Vec4(0.01f);
3586 case tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK:
3587 return tcu::Vec4(0.005f);
3588
3589 default:
3590 DE_ASSERT(DE_FALSE);
3591 }
3592
3593 const float range = isSigned ? 1.0f - (-1.0f)
3594 : 1.0f - 0.0f;
3595 tcu::Vec4 v;
3596 for (int i = 0; i < 4; ++i)
3597 {
3598 if (bitDepth[i] == 0)
3599 v[i] = 1.0f;
3600 else
3601 v[i] = range / static_cast<float>((1 << bitDepth[i]) - 1);
3602 }
3603 return v;
3604 }
3605
checkNonNearestFilteredResult(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & clampedExpected,const tcu::ConstPixelBufferAccess & unclampedExpected,const tcu::TextureFormat & srcFormat)3606 bool BlittingImages::checkNonNearestFilteredResult (const tcu::ConstPixelBufferAccess& result,
3607 const tcu::ConstPixelBufferAccess& clampedExpected,
3608 const tcu::ConstPixelBufferAccess& unclampedExpected,
3609 const tcu::TextureFormat& srcFormat)
3610 {
3611 tcu::TestLog& log (m_context.getTestContext().getLog());
3612 const tcu::TextureFormat dstFormat = result.getFormat();
3613 const tcu::TextureChannelClass dstChannelClass = tcu::getTextureChannelClass(dstFormat.type);
3614 const tcu::TextureChannelClass srcChannelClass = tcu::getTextureChannelClass(srcFormat.type);
3615 bool isOk = false;
3616
3617 log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
3618
3619 // if either of srcImage or dstImage stores values as a signed/unsigned integer,
3620 // the other must also store values a signed/unsigned integer
3621 // e.g. blit unorm to uscaled is not allowed as uscaled formats store data as integers
3622 // despite the fact that both formats are sampled as floats
3623 bool dstImageIsIntClass = dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
3624 dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
3625 bool srcImageIsIntClass = srcChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
3626 srcChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
3627 if (dstImageIsIntClass != srcImageIsIntClass)
3628 {
3629 log << tcu::TestLog::EndSection;
3630 return false;
3631 }
3632
3633 if (isFloatFormat(dstFormat))
3634 {
3635 const bool srcIsSRGB = tcu::isSRGB(srcFormat);
3636 const tcu::Vec4 srcMaxDiff = getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2.0f : 1.0f);
3637 const tcu::Vec4 dstMaxDiff = getFormatThreshold(dstFormat);
3638 const tcu::Vec4 threshold = ( srcMaxDiff + dstMaxDiff ) * ((m_params.filter == VK_FILTER_CUBIC_EXT) ? 1.5f : 1.0f);
3639
3640 isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
3641 log << tcu::TestLog::EndSection;
3642
3643 if (!isOk)
3644 {
3645 log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
3646 isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
3647 log << tcu::TestLog::EndSection;
3648 }
3649 }
3650 else
3651 {
3652 tcu::UVec4 threshold;
3653 // Calculate threshold depending on channel width of destination format.
3654 const tcu::IVec4 dstBitDepth = tcu::getTextureFormatBitDepth(dstFormat);
3655 const tcu::IVec4 srcBitDepth = tcu::getTextureFormatBitDepth(srcFormat);
3656 for (deUint32 i = 0; i < 4; ++i)
3657 threshold[i] = 1 + de::max( ( ( 1 << dstBitDepth[i] ) - 1 ) / de::clamp((1 << srcBitDepth[i]) - 1, 1, 256), 1);
3658
3659 isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
3660 log << tcu::TestLog::EndSection;
3661
3662 if (!isOk)
3663 {
3664 log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
3665 isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
3666 log << tcu::TestLog::EndSection;
3667 }
3668 }
3669
3670 return isOk;
3671 }
3672
checkCompressedNonNearestFilteredResult(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & clampedReference,const tcu::ConstPixelBufferAccess & unclampedReference,const tcu::CompressedTexFormat format)3673 bool BlittingImages::checkCompressedNonNearestFilteredResult(const tcu::ConstPixelBufferAccess& result,
3674 const tcu::ConstPixelBufferAccess& clampedReference,
3675 const tcu::ConstPixelBufferAccess& unclampedReference,
3676 const tcu::CompressedTexFormat format)
3677 {
3678 tcu::TestLog& log = m_context.getTestContext().getLog();
3679 const tcu::TextureFormat dstFormat = result.getFormat();
3680
3681 // there are rare cases wher one or few pixels have slightly bigger error
3682 // in one of channels this accepted error allows those casses to pass
3683 const tcu::Vec4 acceptedError (0.06f);
3684
3685 const tcu::Vec4 srcMaxDiff = getCompressedFormatThreshold(format);
3686 const tcu::Vec4 dstMaxDiff = m_destinationCompressedTexture ?
3687 getCompressedFormatThreshold(m_destinationCompressedTexture->getCompressedTexture().getFormat()) :
3688 getFormatThreshold(dstFormat);
3689 const tcu::Vec4 threshold = (srcMaxDiff + dstMaxDiff) * ((m_params.filter == VK_FILTER_CUBIC_EXT) ? 1.5f : 1.0f) + acceptedError;
3690
3691 bool filteredResultVerification(false);
3692 tcu::Vec4 filteredResultMinValue(-6e6);
3693 tcu::Vec4 filteredResultMaxValue(6e6);
3694 tcu::TextureLevel filteredResult;
3695 tcu::TextureLevel filteredClampedReference;
3696 tcu::TextureLevel filteredUnclampedReference;
3697
3698 if (((format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK) ||
3699 (format == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK)))
3700 {
3701 if ((dstFormat.type == tcu::TextureFormat::FLOAT) ||
3702 (dstFormat.type == tcu::TextureFormat::HALF_FLOAT))
3703 {
3704 // for compressed formats we are using random data and for bc6h formats
3705 // this will give us also large color values; when we are bliting to
3706 // a format that accepts large values we can end up with large diferences
3707 // betwean filtered result and reference; to avoid that we need to remove
3708 // values that are to big from verification
3709 filteredResultVerification = true;
3710 filteredResultMinValue = tcu::Vec4(-10.0f);
3711 filteredResultMaxValue = tcu::Vec4( 10.0f);
3712 }
3713 else if (dstFormat.type == tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV)
3714 {
3715 // we need to clamp some formats to <0;1> range as it has
3716 // small precision for big numbers compared to reference
3717 filteredResultVerification = true;
3718 filteredResultMinValue = tcu::Vec4(0.0f);
3719 filteredResultMaxValue = tcu::Vec4(1.0f);
3720 }
3721 // else don't use filtered verification
3722 }
3723
3724 if (filteredResultVerification)
3725 {
3726 filteredResult.setStorage(dstFormat, result.getWidth(), result.getHeight(), result.getDepth());
3727 tcu::PixelBufferAccess filteredResultAcccess(filteredResult.getAccess());
3728
3729 filteredClampedReference.setStorage(dstFormat, result.getWidth(), result.getHeight(), result.getDepth());
3730 tcu::PixelBufferAccess filteredClampedAcccess(filteredClampedReference.getAccess());
3731
3732 filteredUnclampedReference.setStorage(dstFormat, result.getWidth(), result.getHeight(), result.getDepth());
3733 tcu::PixelBufferAccess filteredUnclampedResultAcccess(filteredUnclampedReference.getAccess());
3734
3735 for (deInt32 z = 0; z < result.getDepth(); z++)
3736 for (deInt32 y = 0; y < result.getHeight(); y++)
3737 for (deInt32 x = 0; x < result.getWidth(); x++)
3738 {
3739 tcu::Vec4 resultTexel = result.getPixel(x, y, z);
3740 tcu::Vec4 clampedReferenceTexel = clampedReference.getPixel(x, y, z);
3741 tcu::Vec4 unclampedReferenceTexel = unclampedReference.getPixel(x, y, z);
3742
3743 resultTexel = tcu::clamp(resultTexel, filteredResultMinValue, filteredResultMaxValue);
3744 clampedReferenceTexel = tcu::clamp(clampedReferenceTexel, filteredResultMinValue, filteredResultMaxValue);
3745 unclampedReferenceTexel = tcu::clamp(unclampedReferenceTexel, filteredResultMinValue, filteredResultMaxValue);
3746
3747 filteredResultAcccess.setPixel(resultTexel, x, y, z);
3748 filteredClampedAcccess.setPixel(clampedReferenceTexel, x, y, z);
3749 filteredUnclampedResultAcccess.setPixel(unclampedReferenceTexel, x, y, z);
3750 }
3751 }
3752
3753 const tcu::ConstPixelBufferAccess clampedRef = filteredResultVerification ? filteredClampedReference.getAccess() : clampedReference;
3754 const tcu::ConstPixelBufferAccess res = filteredResultVerification ? filteredResult.getAccess() : result;
3755
3756 log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
3757 bool isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedRef, res, threshold, tcu::COMPARE_LOG_RESULT);
3758 log << tcu::TestLog::EndSection;
3759
3760 if (!isOk)
3761 {
3762 const tcu::ConstPixelBufferAccess unclampedRef = filteredResultVerification ? filteredUnclampedReference.getAccess() : unclampedReference;
3763
3764 log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
3765 isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedRef, res, threshold, tcu::COMPARE_LOG_RESULT);
3766 log << tcu::TestLog::EndSection;
3767 }
3768
3769 return isOk;
3770 }
3771
3772 //! Utility to encapsulate coordinate computation and loops.
3773 struct CompareEachPixelInEachRegion
3774 {
~CompareEachPixelInEachRegionvkt::api::__anon1525b85c0111::CompareEachPixelInEachRegion3775 virtual ~CompareEachPixelInEachRegion (void) {}
3776 virtual bool compare (const void* pUserData, const int x, const int y, const int z, const tcu::Vec3& srcNormCoord) const = 0;
3777
forEachvkt::api::__anon1525b85c0111::CompareEachPixelInEachRegion3778 bool forEach (const void* pUserData,
3779 const std::vector<CopyRegion>& regions,
3780 const int sourceWidth,
3781 const int sourceHeight,
3782 const int sourceDepth,
3783 const tcu::PixelBufferAccess& errorMask) const
3784 {
3785 bool compareOk = true;
3786
3787 for (std::vector<CopyRegion>::const_iterator regionIter = regions.begin(); regionIter != regions.end(); ++regionIter)
3788 {
3789 const VkImageBlit& blit = regionIter->imageBlit;
3790
3791 const int xStart = deMin32(blit.dstOffsets[0].x, blit.dstOffsets[1].x);
3792 const int yStart = deMin32(blit.dstOffsets[0].y, blit.dstOffsets[1].y);
3793 const int zStart = deMin32(blit.dstOffsets[0].z, blit.dstOffsets[1].z);
3794 const int xEnd = deMax32(blit.dstOffsets[0].x, blit.dstOffsets[1].x);
3795 const int yEnd = deMax32(blit.dstOffsets[0].y, blit.dstOffsets[1].y);
3796 const int zEnd = deMax32(blit.dstOffsets[0].z, blit.dstOffsets[1].z);
3797 const float xScale = static_cast<float>(blit.srcOffsets[1].x - blit.srcOffsets[0].x) / static_cast<float>(blit.dstOffsets[1].x - blit.dstOffsets[0].x);
3798 const float yScale = static_cast<float>(blit.srcOffsets[1].y - blit.srcOffsets[0].y) / static_cast<float>(blit.dstOffsets[1].y - blit.dstOffsets[0].y);
3799 const float zScale = static_cast<float>(blit.srcOffsets[1].z - blit.srcOffsets[0].z) / static_cast<float>(blit.dstOffsets[1].z - blit.dstOffsets[0].z);
3800 const float srcInvW = 1.0f / static_cast<float>(sourceWidth);
3801 const float srcInvH = 1.0f / static_cast<float>(sourceHeight);
3802 const float srcInvD = 1.0f / static_cast<float>(sourceDepth);
3803
3804 for (int z = zStart; z < zEnd; z++)
3805 for (int y = yStart; y < yEnd; y++)
3806 for (int x = xStart; x < xEnd; x++)
3807 {
3808 const tcu::Vec3 srcNormCoord
3809 (
3810 (xScale * (static_cast<float>(x - blit.dstOffsets[0].x) + 0.5f) + static_cast<float>(blit.srcOffsets[0].x)) * srcInvW,
3811 (yScale * (static_cast<float>(y - blit.dstOffsets[0].y) + 0.5f) + static_cast<float>(blit.srcOffsets[0].y)) * srcInvH,
3812 (zScale * (static_cast<float>(z - blit.dstOffsets[0].z) + 0.5f) + static_cast<float>(blit.srcOffsets[0].z)) * srcInvD
3813 );
3814
3815 if (!compare(pUserData, x, y, z, srcNormCoord))
3816 {
3817 errorMask.setPixel(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y, z);
3818 compareOk = false;
3819 }
3820 }
3821 }
3822 return compareOk;
3823 }
3824 };
3825
getFloatOrFixedPointFormatThreshold(const tcu::TextureFormat & format)3826 tcu::Vec4 getFloatOrFixedPointFormatThreshold (const tcu::TextureFormat& format)
3827 {
3828 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
3829 const tcu::IVec4 bitDepth = tcu::getTextureFormatBitDepth(format);
3830
3831 if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
3832 {
3833 return getFormatThreshold(format);
3834 }
3835 else if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
3836 channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT)
3837 {
3838 const bool isSigned = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT);
3839 const float range = isSigned ? 1.0f - (-1.0f)
3840 : 1.0f - 0.0f;
3841
3842 tcu::Vec4 v;
3843 for (int i = 0; i < 4; ++i)
3844 {
3845 if (bitDepth[i] == 0)
3846 v[i] = 1.0f;
3847 else
3848 v[i] = range / static_cast<float>((1 << bitDepth[i]) - 1);
3849 }
3850 return v;
3851 }
3852 else
3853 {
3854 DE_ASSERT(0);
3855 return tcu::Vec4();
3856 }
3857 }
3858
floatNearestBlitCompare(const tcu::ConstPixelBufferAccess & source,const tcu::ConstPixelBufferAccess & result,const tcu::Vec4 & sourceThreshold,const tcu::Vec4 & resultThreshold,const tcu::PixelBufferAccess & errorMask,const std::vector<CopyRegion> & regions)3859 bool floatNearestBlitCompare (const tcu::ConstPixelBufferAccess& source,
3860 const tcu::ConstPixelBufferAccess& result,
3861 const tcu::Vec4& sourceThreshold,
3862 const tcu::Vec4& resultThreshold,
3863 const tcu::PixelBufferAccess& errorMask,
3864 const std::vector<CopyRegion>& regions)
3865 {
3866 const tcu::Sampler sampler (tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::NEAREST, tcu::Sampler::NEAREST,
3867 0.0f, true, tcu::Sampler::COMPAREMODE_NONE, 0, tcu::Vec4(0.0f), true);
3868 const tcu::IVec4 dstBitDepth (tcu::getTextureFormatBitDepth(result.getFormat()));
3869 tcu::LookupPrecision precision;
3870
3871 precision.colorMask = tcu::notEqual(dstBitDepth, tcu::IVec4(0));
3872 precision.colorThreshold = tcu::max(sourceThreshold, resultThreshold);
3873
3874 const struct Capture
3875 {
3876 const tcu::ConstPixelBufferAccess& source;
3877 const tcu::ConstPixelBufferAccess& result;
3878 const tcu::Sampler& sampler;
3879 const tcu::LookupPrecision& precision;
3880 const bool isSRGB;
3881 } capture =
3882 {
3883 source, result, sampler, precision, tcu::isSRGB(result.getFormat())
3884 };
3885
3886 const struct Loop : CompareEachPixelInEachRegion
3887 {
3888 Loop (void) {}
3889
3890 bool compare (const void* pUserData, const int x, const int y, const int z, const tcu::Vec3& srcNormCoord) const
3891 {
3892 const Capture& c = *static_cast<const Capture*>(pUserData);
3893 const tcu::TexLookupScaleMode lookupScaleDontCare = tcu::TEX_LOOKUP_SCALE_MINIFY;
3894 tcu::Vec4 dstColor = c.result.getPixel(x, y, z);
3895
3896 // TexLookupVerifier performs a conversion to linear space, so we have to as well
3897 if (c.isSRGB)
3898 dstColor = tcu::sRGBToLinear(dstColor);
3899
3900 return tcu::isLevel3DLookupResultValid(c.source, c.sampler, lookupScaleDontCare, c.precision, srcNormCoord, dstColor);
3901 }
3902 } loop;
3903
3904 return loop.forEach(&capture, regions, source.getWidth(), source.getHeight(), source.getDepth(), errorMask);
3905 }
3906
intNearestBlitCompare(const tcu::ConstPixelBufferAccess & source,const tcu::ConstPixelBufferAccess & result,const tcu::PixelBufferAccess & errorMask,const std::vector<CopyRegion> & regions)3907 bool intNearestBlitCompare (const tcu::ConstPixelBufferAccess& source,
3908 const tcu::ConstPixelBufferAccess& result,
3909 const tcu::PixelBufferAccess& errorMask,
3910 const std::vector<CopyRegion>& regions)
3911 {
3912 const tcu::Sampler sampler (tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::NEAREST, tcu::Sampler::NEAREST,
3913 0.0f, true, tcu::Sampler::COMPAREMODE_NONE, 0, tcu::Vec4(0.0f), true);
3914 tcu::IntLookupPrecision precision;
3915
3916 {
3917 const tcu::IVec4 srcBitDepth = tcu::getTextureFormatBitDepth(source.getFormat());
3918 const tcu::IVec4 dstBitDepth = tcu::getTextureFormatBitDepth(result.getFormat());
3919
3920 for (deUint32 i = 0; i < 4; ++i) {
3921 precision.colorThreshold[i] = de::max(de::max(srcBitDepth[i] / 8, dstBitDepth[i] / 8), 1);
3922 precision.colorMask[i] = dstBitDepth[i] != 0;
3923 }
3924 }
3925
3926 // Prepare a source image with a matching (converted) pixel format. Ideally, we would've used a wrapper that
3927 // does the conversion on the fly without wasting memory, but this approach is more straightforward.
3928 tcu::TextureLevel convertedSourceTexture (result.getFormat(), source.getWidth(), source.getHeight(), source.getDepth());
3929 const tcu::PixelBufferAccess convertedSource = convertedSourceTexture.getAccess();
3930
3931 for (int z = 0; z < source.getDepth(); ++z)
3932 for (int y = 0; y < source.getHeight(); ++y)
3933 for (int x = 0; x < source.getWidth(); ++x)
3934 convertedSource.setPixel(source.getPixelInt(x, y, z), x, y, z); // will be clamped to max. representable value
3935
3936 const struct Capture
3937 {
3938 const tcu::ConstPixelBufferAccess& source;
3939 const tcu::ConstPixelBufferAccess& result;
3940 const tcu::Sampler& sampler;
3941 const tcu::IntLookupPrecision& precision;
3942 } capture =
3943 {
3944 convertedSource, result, sampler, precision
3945 };
3946
3947 const struct Loop : CompareEachPixelInEachRegion
3948 {
3949 Loop (void) {}
3950
3951 bool compare (const void* pUserData, const int x, const int y, const int z, const tcu::Vec3& srcNormCoord) const
3952 {
3953 const Capture& c = *static_cast<const Capture*>(pUserData);
3954 const tcu::TexLookupScaleMode lookupScaleDontCare = tcu::TEX_LOOKUP_SCALE_MINIFY;
3955 const tcu::IVec4 dstColor = c.result.getPixelInt(x, y, z);
3956
3957 return tcu::isLevel3DLookupResultValid(c.source, c.sampler, lookupScaleDontCare, c.precision, srcNormCoord, dstColor);
3958 }
3959 } loop;
3960
3961 return loop.forEach(&capture, regions, source.getWidth(), source.getHeight(), source.getDepth(), errorMask);
3962 }
3963
checkNearestFilteredResult(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & source)3964 bool BlittingImages::checkNearestFilteredResult (const tcu::ConstPixelBufferAccess& result,
3965 const tcu::ConstPixelBufferAccess& source)
3966 {
3967 tcu::TestLog& log (m_context.getTestContext().getLog());
3968 const tcu::TextureFormat dstFormat = result.getFormat();
3969 const tcu::TextureFormat srcFormat = source.getFormat();
3970 const tcu::TextureChannelClass dstChannelClass = tcu::getTextureChannelClass(dstFormat.type);
3971 const tcu::TextureChannelClass srcChannelClass = tcu::getTextureChannelClass(srcFormat.type);
3972
3973 tcu::TextureLevel errorMaskStorage (tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), result.getWidth(), result.getHeight(), result.getDepth());
3974 tcu::PixelBufferAccess errorMask = errorMaskStorage.getAccess();
3975 tcu::Vec4 pixelBias (0.0f, 0.0f, 0.0f, 0.0f);
3976 tcu::Vec4 pixelScale (1.0f, 1.0f, 1.0f, 1.0f);
3977 bool ok = false;
3978
3979 tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
3980
3981 // if either of srcImage or dstImage stores values as a signed/unsigned integer,
3982 // the other must also store values a signed/unsigned integer
3983 // e.g. blit unorm to uscaled is not allowed as uscaled formats store data as integers
3984 // despite the fact that both formats are sampled as floats
3985 bool dstImageIsIntClass = dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
3986 dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
3987 bool srcImageIsIntClass = srcChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
3988 srcChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
3989 if (dstImageIsIntClass != srcImageIsIntClass)
3990 return false;
3991
3992 if (dstImageIsIntClass)
3993 {
3994 ok = intNearestBlitCompare(source, result, errorMask, m_params.regions);
3995 }
3996 else
3997 {
3998 const tcu::Vec4 srcMaxDiff = getFloatOrFixedPointFormatThreshold(source.getFormat());
3999 const tcu::Vec4 dstMaxDiff = getFloatOrFixedPointFormatThreshold(result.getFormat());
4000 ok = floatNearestBlitCompare(source, result, srcMaxDiff, dstMaxDiff, errorMask, m_params.regions);
4001 }
4002
4003 if (result.getFormat() != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
4004 tcu::computePixelScaleBias(result, pixelScale, pixelBias);
4005
4006 if (!ok)
4007 {
4008 log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
4009 << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
4010 << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask)
4011 << tcu::TestLog::EndImageSet;
4012 }
4013 else
4014 {
4015 log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
4016 << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
4017 << tcu::TestLog::EndImageSet;
4018 }
4019
4020 return ok;
4021 }
4022
checkCompressedNearestFilteredResult(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & source,const tcu::CompressedTexFormat format)4023 bool BlittingImages::checkCompressedNearestFilteredResult (const tcu::ConstPixelBufferAccess& result,
4024 const tcu::ConstPixelBufferAccess& source,
4025 const tcu::CompressedTexFormat format)
4026 {
4027 tcu::TestLog& log (m_context.getTestContext().getLog());
4028 tcu::TextureFormat errorMaskFormat (tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8);
4029 tcu::TextureLevel errorMaskStorage (errorMaskFormat, result.getWidth(), result.getHeight(), result.getDepth());
4030 tcu::PixelBufferAccess errorMask (errorMaskStorage.getAccess());
4031 tcu::Vec4 pixelBias (0.0f, 0.0f, 0.0f, 0.0f);
4032 tcu::Vec4 pixelScale (1.0f, 1.0f, 1.0f, 1.0f);
4033 const tcu::TextureFormat& resultFormat (result.getFormat());
4034 VkFormat nativeResultFormat (mapTextureFormat(resultFormat));
4035
4036 // there are rare cases wher one or few pixels have slightly bigger error
4037 // in one of channels this accepted error allows those casses to pass
4038 const tcu::Vec4 acceptedError (0.04f);
4039 const tcu::Vec4 srcMaxDiff (acceptedError + getCompressedFormatThreshold(format));
4040 const tcu::Vec4 dstMaxDiff (acceptedError + (m_destinationCompressedTexture ?
4041 getCompressedFormatThreshold(m_destinationCompressedTexture->getCompressedTexture().getFormat()) :
4042 getFloatOrFixedPointFormatThreshold(resultFormat)));
4043
4044 tcu::TextureLevel clampedSourceLevel;
4045 bool clampSource (false);
4046 tcu::Vec4 clampSourceMinValue (-1.0f);
4047 tcu::Vec4 clampSourceMaxValue (1.0f);
4048 tcu::TextureLevel clampedResultLevel;
4049 bool clampResult (false);
4050
4051 tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
4052
4053 if (resultFormat != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
4054 tcu::computePixelScaleBias(result, pixelScale, pixelBias);
4055
4056 log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
4057 << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias);
4058
4059 // for compressed formats source buffer access is not actual compressed format
4060 // but equivalent uncompressed format that is some cases needs additional
4061 // modifications so that sampling it will produce valid reference
4062 if ((format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK) ||
4063 (format == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK))
4064 {
4065 if (resultFormat.type == tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV)
4066 {
4067 // for compressed formats we are using random data and for some formats it
4068 // can be outside of <-1;1> range - for cases where result is not a float
4069 // format we need to clamp source to <-1;1> range as this will be done on
4070 // the device but not in software sampler in framework
4071 clampSource = true;
4072 // for this format we also need to clamp the result as precision of
4073 // this format is smaller then precision of calculations in framework;
4074 // the biger color valus are the bigger errors can be
4075 clampResult = true;
4076
4077 if (format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK)
4078 clampSourceMinValue = tcu::Vec4(0.0f);
4079 }
4080 else if ((resultFormat.type != tcu::TextureFormat::FLOAT) &&
4081 (resultFormat.type != tcu::TextureFormat::HALF_FLOAT))
4082 {
4083 // clamp source for all non float formats
4084 clampSource = true;
4085 }
4086 }
4087
4088 if (isUnormFormat(nativeResultFormat) || isUfloatFormat(nativeResultFormat))
4089 {
4090 // when tested compressed format is signed but the result format
4091 // is unsigned we need to clamp source to <0; x> so that proper
4092 // reference is calculated
4093 if ((format == tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_R11) ||
4094 (format == tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11) ||
4095 (format == tcu::COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK) ||
4096 (format == tcu::COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK) ||
4097 (format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK))
4098 {
4099 clampSource = true;
4100 clampSourceMinValue = tcu::Vec4(0.0f);
4101 }
4102 }
4103
4104 if (clampSource || clampResult)
4105 {
4106 if (clampSource)
4107 {
4108 clampedSourceLevel.setStorage(source.getFormat(), source.getWidth(), source.getHeight(), source.getDepth());
4109 tcu::PixelBufferAccess clampedSourceAcccess(clampedSourceLevel.getAccess());
4110
4111 for (deInt32 z = 0; z < source.getDepth() ; z++)
4112 for (deInt32 y = 0; y < source.getHeight() ; y++)
4113 for (deInt32 x = 0; x < source.getWidth() ; x++)
4114 {
4115 tcu::Vec4 texel = source.getPixel(x, y, z);
4116 texel = tcu::clamp(texel, tcu::Vec4(clampSourceMinValue), tcu::Vec4(clampSourceMaxValue));
4117 clampedSourceAcccess.setPixel(texel, x, y, z);
4118 }
4119 }
4120
4121 if (clampResult)
4122 {
4123 clampedResultLevel.setStorage(result.getFormat(), result.getWidth(), result.getHeight(), result.getDepth());
4124 tcu::PixelBufferAccess clampedResultAcccess(clampedResultLevel.getAccess());
4125
4126 for (deInt32 z = 0; z < result.getDepth() ; z++)
4127 for (deInt32 y = 0; y < result.getHeight() ; y++)
4128 for (deInt32 x = 0; x < result.getWidth() ; x++)
4129 {
4130 tcu::Vec4 texel = result.getPixel(x, y, z);
4131 texel = tcu::clamp(texel, tcu::Vec4(-1.0f), tcu::Vec4(1.0f));
4132 clampedResultAcccess.setPixel(texel, x, y, z);
4133 }
4134 }
4135 }
4136
4137 const tcu::ConstPixelBufferAccess src = clampSource ? clampedSourceLevel.getAccess() : source;
4138 const tcu::ConstPixelBufferAccess res = clampResult ? clampedResultLevel.getAccess() : result;
4139
4140 if (floatNearestBlitCompare(src, res, srcMaxDiff, dstMaxDiff, errorMask, m_params.regions))
4141 {
4142 log << tcu::TestLog::EndImageSet;
4143 return true;
4144 }
4145
4146 log << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask)
4147 << tcu::TestLog::EndImageSet;
4148 return false;
4149 }
4150
checkTestResult(tcu::ConstPixelBufferAccess result)4151 tcu::TestStatus BlittingImages::checkTestResult (tcu::ConstPixelBufferAccess result)
4152 {
4153 DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR || m_params.filter == VK_FILTER_CUBIC_EXT);
4154 const std::string failMessage("Result image is incorrect");
4155
4156 if (m_params.filter != VK_FILTER_NEAREST)
4157 {
4158 if (tcu::isCombinedDepthStencilType(result.getFormat().type))
4159 {
4160 if (tcu::hasDepthComponent(result.getFormat().order))
4161 {
4162 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_DEPTH;
4163 const tcu::ConstPixelBufferAccess depthResult = tcu::getEffectiveDepthStencilAccess(result, mode);
4164 const tcu::ConstPixelBufferAccess clampedExpected = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
4165 const tcu::ConstPixelBufferAccess unclampedExpected = tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode);
4166 const tcu::TextureFormat sourceFormat = tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode);
4167
4168 if (!checkNonNearestFilteredResult(depthResult, clampedExpected, unclampedExpected, sourceFormat))
4169 return tcu::TestStatus::fail(failMessage);
4170 }
4171
4172 if (tcu::hasStencilComponent(result.getFormat().order))
4173 {
4174 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_STENCIL;
4175 const tcu::ConstPixelBufferAccess stencilResult = tcu::getEffectiveDepthStencilAccess(result, mode);
4176 const tcu::ConstPixelBufferAccess clampedExpected = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
4177 const tcu::ConstPixelBufferAccess unclampedExpected = tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode);
4178 const tcu::TextureFormat sourceFormat = tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode);
4179
4180 if (!checkNonNearestFilteredResult(stencilResult, clampedExpected, unclampedExpected, sourceFormat))
4181 return tcu::TestStatus::fail(failMessage);
4182 }
4183 }
4184 else if (m_sourceCompressedTexture)
4185 {
4186 const tcu::CompressedTexture& compressedLevel = m_sourceCompressedTexture->getCompressedTexture();
4187 if (!checkCompressedNonNearestFilteredResult(result, m_expectedTextureLevel[0]->getAccess(), m_unclampedExpectedTextureLevel->getAccess(), compressedLevel.getFormat()))
4188 return tcu::TestStatus::fail(failMessage);
4189 }
4190 else
4191 {
4192 const tcu::TextureFormat sourceFormat = mapVkFormat(m_params.src.image.format);
4193 if (!checkNonNearestFilteredResult(result, m_expectedTextureLevel[0]->getAccess(), m_unclampedExpectedTextureLevel->getAccess(), sourceFormat))
4194 return tcu::TestStatus::fail(failMessage);
4195 }
4196 }
4197 else // NEAREST filtering
4198 {
4199 if (tcu::isCombinedDepthStencilType(result.getFormat().type))
4200 {
4201 if (tcu::hasDepthComponent(result.getFormat().order))
4202 {
4203 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_DEPTH;
4204 const tcu::ConstPixelBufferAccess depthResult = tcu::getEffectiveDepthStencilAccess(result, mode);
4205 const tcu::ConstPixelBufferAccess depthSource = tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode);
4206
4207 if (!checkNearestFilteredResult(depthResult, depthSource))
4208 return tcu::TestStatus::fail(failMessage);
4209 }
4210
4211 if (tcu::hasStencilComponent(result.getFormat().order))
4212 {
4213 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_STENCIL;
4214 const tcu::ConstPixelBufferAccess stencilResult = tcu::getEffectiveDepthStencilAccess(result, mode);
4215 const tcu::ConstPixelBufferAccess stencilSource = tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode);
4216
4217 if (!checkNearestFilteredResult(stencilResult, stencilSource))
4218 return tcu::TestStatus::fail(failMessage);
4219 }
4220 }
4221 else if (m_sourceCompressedTexture)
4222 {
4223 const tcu::CompressedTexture& compressedLevel = m_sourceCompressedTexture->getCompressedTexture();
4224 const tcu::PixelBufferAccess& decompressedLevel = m_sourceCompressedTexture->getDecompressedAccess();
4225
4226 if (!checkCompressedNearestFilteredResult(result, decompressedLevel, compressedLevel.getFormat()))
4227 return tcu::TestStatus::fail(failMessage);
4228 }
4229 else if (!checkNearestFilteredResult(result, m_sourceTextureLevel->getAccess()))
4230 return tcu::TestStatus::fail(failMessage);
4231 }
4232
4233 return tcu::TestStatus::pass("Pass");
4234 }
4235
linearToSRGBIfNeeded(const tcu::TextureFormat & format,const tcu::Vec4 & color)4236 tcu::Vec4 linearToSRGBIfNeeded (const tcu::TextureFormat& format, const tcu::Vec4& color)
4237 {
4238 return isSRGB(format) ? linearToSRGB(color) : color;
4239 }
4240
scaleFromWholeSrcBuffer(const tcu::PixelBufferAccess & dst,const tcu::ConstPixelBufferAccess & src,const VkOffset3D regionOffset,const VkOffset3D regionExtent,tcu::Sampler::FilterMode filter,const MirrorMode mirrorMode=0u)4241 void scaleFromWholeSrcBuffer (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const VkOffset3D regionOffset, const VkOffset3D regionExtent, tcu::Sampler::FilterMode filter, const MirrorMode mirrorMode = 0u)
4242 {
4243 DE_ASSERT(filter == tcu::Sampler::LINEAR || filter == tcu::Sampler::CUBIC);
4244
4245 tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
4246 filter, filter, 0.0f, false, tcu::Sampler::COMPAREMODE_NONE, 0, tcu::Vec4(0.0f), true);
4247
4248 float sX = (float)regionExtent.x / (float)dst.getWidth();
4249 float sY = (float)regionExtent.y / (float)dst.getHeight();
4250 float sZ = (float)regionExtent.z / (float)dst.getDepth();
4251
4252 for (int z = 0; z < dst.getDepth(); z++)
4253 for (int y = 0; y < dst.getHeight(); y++)
4254 for (int x = 0; x < dst.getWidth(); x++)
4255 {
4256 float srcX = ((mirrorMode & MIRROR_MODE_X) != 0) ? (float)regionExtent.x + (float)regionOffset.x - ((float)x+0.5f)*sX : (float)regionOffset.x + ((float)x+0.5f)*sX;
4257 float srcY = ((mirrorMode & MIRROR_MODE_Y) != 0) ? (float)regionExtent.y + (float)regionOffset.y - ((float)y+0.5f)*sY : (float)regionOffset.y + ((float)y+0.5f)*sY;
4258 float srcZ = ((mirrorMode & MIRROR_MODE_Z) != 0) ? (float)regionExtent.z + (float)regionOffset.z - ((float)z+0.5f)*sZ : (float)regionOffset.z + ((float)z+0.5f)*sZ;
4259 if (dst.getDepth() > 1)
4260 dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample3D(sampler, filter, srcX, srcY, srcZ)), x, y, z);
4261 else
4262 dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample2D(sampler, filter, srcX, srcY, 0)), x, y);
4263 }
4264 }
4265
blit(const tcu::PixelBufferAccess & dst,const tcu::ConstPixelBufferAccess & src,const tcu::Sampler::FilterMode filter,const MirrorMode mirrorMode)4266 void blit (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const tcu::Sampler::FilterMode filter, const MirrorMode mirrorMode)
4267 {
4268 DE_ASSERT(filter == tcu::Sampler::NEAREST || filter == tcu::Sampler::LINEAR || filter == tcu::Sampler::CUBIC);
4269
4270 tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
4271 filter, filter, 0.0f, false, tcu::Sampler::COMPAREMODE_NONE, 0, tcu::Vec4(0.0f), true);
4272
4273 const float sX = (float)src.getWidth() / (float)dst.getWidth();
4274 const float sY = (float)src.getHeight() / (float)dst.getHeight();
4275 const float sZ = (float)src.getDepth() / (float)dst.getDepth();
4276
4277 const int xOffset = (mirrorMode & MIRROR_MODE_X) ? dst.getWidth() - 1 : 0;
4278 const int yOffset = (mirrorMode & MIRROR_MODE_Y) ? dst.getHeight() - 1 : 0;
4279 const int zOffset = (mirrorMode & MIRROR_MODE_Z) ? dst.getDepth() - 1 : 0;
4280
4281 const int xScale = (mirrorMode & MIRROR_MODE_X) ? -1 : 1;
4282 const int yScale = (mirrorMode & MIRROR_MODE_Y) ? -1 : 1;
4283 const int zScale = (mirrorMode & MIRROR_MODE_Z) ? -1 : 1;
4284
4285 for (int z = 0; z < dst.getDepth(); ++z)
4286 for (int y = 0; y < dst.getHeight(); ++y)
4287 for (int x = 0; x < dst.getWidth(); ++x)
4288 {
4289 dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample3D(sampler, filter, ((float)x + 0.5f) * sX, ((float)y + 0.5f) * sY, ((float)z + 0.5f) * sZ)), x * xScale + xOffset, y * yScale + yOffset, z * zScale + zOffset);
4290 }
4291 }
4292
flipCoordinates(CopyRegion & region,const MirrorMode mirrorMode)4293 void flipCoordinates (CopyRegion& region, const MirrorMode mirrorMode)
4294 {
4295 const VkOffset3D dstOffset0 = region.imageBlit.dstOffsets[0];
4296 const VkOffset3D dstOffset1 = region.imageBlit.dstOffsets[1];
4297 const VkOffset3D srcOffset0 = region.imageBlit.srcOffsets[0];
4298 const VkOffset3D srcOffset1 = region.imageBlit.srcOffsets[1];
4299
4300 if (mirrorMode != 0u)
4301 {
4302 //sourceRegion
4303 region.imageBlit.srcOffsets[0].x = std::min(srcOffset0.x, srcOffset1.x);
4304 region.imageBlit.srcOffsets[0].y = std::min(srcOffset0.y, srcOffset1.y);
4305 region.imageBlit.srcOffsets[0].z = std::min(srcOffset0.z, srcOffset1.z);
4306
4307 region.imageBlit.srcOffsets[1].x = std::max(srcOffset0.x, srcOffset1.x);
4308 region.imageBlit.srcOffsets[1].y = std::max(srcOffset0.y, srcOffset1.y);
4309 region.imageBlit.srcOffsets[1].z = std::max(srcOffset0.z, srcOffset1.z);
4310
4311 //destinationRegion
4312 region.imageBlit.dstOffsets[0].x = std::min(dstOffset0.x, dstOffset1.x);
4313 region.imageBlit.dstOffsets[0].y = std::min(dstOffset0.y, dstOffset1.y);
4314 region.imageBlit.dstOffsets[0].z = std::min(dstOffset0.z, dstOffset1.z);
4315
4316 region.imageBlit.dstOffsets[1].x = std::max(dstOffset0.x, dstOffset1.x);
4317 region.imageBlit.dstOffsets[1].y = std::max(dstOffset0.y, dstOffset1.y);
4318 region.imageBlit.dstOffsets[1].z = std::max(dstOffset0.z, dstOffset1.z);
4319 }
4320 }
4321
4322 // Mirror X, Y and Z as required by the offset values in the 3 axes.
getMirrorMode(const VkOffset3D from,const VkOffset3D to)4323 MirrorMode getMirrorMode(const VkOffset3D from, const VkOffset3D to)
4324 {
4325 MirrorMode mode = 0u;
4326
4327 if (from.x > to.x)
4328 mode |= MIRROR_MODE_X;
4329
4330 if (from.y > to.y)
4331 mode |= MIRROR_MODE_Y;
4332
4333 if (from.z > to.z)
4334 mode |= MIRROR_MODE_Z;
4335
4336 return mode;
4337 }
4338
4339 // 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)4340 MirrorMode getMirrorMode(const VkOffset3D s1, const VkOffset3D s2, const VkOffset3D d1, const VkOffset3D d2)
4341 {
4342 static const MirrorModeBits kBits[] = { MIRROR_MODE_X, MIRROR_MODE_Y, MIRROR_MODE_Z };
4343
4344 const MirrorMode source = getMirrorMode(s1, s2);
4345 const MirrorMode destination = getMirrorMode(d1, d2);
4346
4347 MirrorMode mode = 0u;
4348
4349 for (int i = 0; i < DE_LENGTH_OF_ARRAY(kBits); ++i)
4350 {
4351 const MirrorModeBits bit = kBits[i];
4352 if ((source & bit) != (destination & bit))
4353 mode |= bit;
4354 }
4355
4356 return mode;
4357 }
4358
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)4359 void BlittingImages::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
4360 {
4361 DE_UNREF(mipLevel);
4362
4363 const MirrorMode mirrorMode = getMirrorMode(region.imageBlit.srcOffsets[0],
4364 region.imageBlit.srcOffsets[1],
4365 region.imageBlit.dstOffsets[0],
4366 region.imageBlit.dstOffsets[1]);
4367
4368 flipCoordinates(region, mirrorMode);
4369
4370 const VkOffset3D srcOffset = region.imageBlit.srcOffsets[0];
4371 const VkOffset3D srcExtent =
4372 {
4373 region.imageBlit.srcOffsets[1].x - srcOffset.x,
4374 region.imageBlit.srcOffsets[1].y - srcOffset.y,
4375 region.imageBlit.srcOffsets[1].z - srcOffset.z,
4376 };
4377 const VkOffset3D dstOffset = region.imageBlit.dstOffsets[0];
4378 const VkOffset3D dstExtent =
4379 {
4380 region.imageBlit.dstOffsets[1].x - dstOffset.x,
4381 region.imageBlit.dstOffsets[1].y - dstOffset.y,
4382 region.imageBlit.dstOffsets[1].z - dstOffset.z,
4383 };
4384
4385 tcu::Sampler::FilterMode filter;
4386 switch (m_params.filter)
4387 {
4388 case VK_FILTER_LINEAR: filter = tcu::Sampler::LINEAR; break;
4389 case VK_FILTER_CUBIC_EXT: filter = tcu::Sampler::CUBIC; break;
4390 case VK_FILTER_NEAREST:
4391 default: filter = tcu::Sampler::NEAREST; break;
4392 }
4393
4394 if (tcu::isCombinedDepthStencilType(src.getFormat().type))
4395 {
4396 DE_ASSERT(src.getFormat() == dst.getFormat());
4397
4398 // Scale depth.
4399 if (tcu::hasDepthComponent(src.getFormat().order))
4400 {
4401 const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, srcExtent.x, srcExtent.y, srcExtent.z), tcu::Sampler::MODE_DEPTH);
4402 const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z), tcu::Sampler::MODE_DEPTH);
4403 tcu::scale(dstSubRegion, srcSubRegion, filter);
4404
4405 if (filter != tcu::Sampler::NEAREST)
4406 {
4407 const tcu::ConstPixelBufferAccess depthSrc = getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH);
4408 const tcu::PixelBufferAccess unclampedSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z), tcu::Sampler::MODE_DEPTH);
4409 scaleFromWholeSrcBuffer(unclampedSubRegion, depthSrc, srcOffset, srcExtent, filter, mirrorMode);
4410 }
4411 }
4412
4413 // Scale stencil.
4414 if (tcu::hasStencilComponent(src.getFormat().order))
4415 {
4416 const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, srcExtent.x, srcExtent.y, srcExtent.z), tcu::Sampler::MODE_STENCIL);
4417 const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z), tcu::Sampler::MODE_STENCIL);
4418 blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
4419
4420 if (filter != tcu::Sampler::NEAREST)
4421 {
4422 const tcu::ConstPixelBufferAccess stencilSrc = getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL);
4423 const tcu::PixelBufferAccess unclampedSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z), tcu::Sampler::MODE_STENCIL);
4424 scaleFromWholeSrcBuffer(unclampedSubRegion, stencilSrc, srcOffset, srcExtent, filter, mirrorMode);
4425 }
4426 }
4427 }
4428 else
4429 {
4430 const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, srcExtent.x, srcExtent.y, srcExtent.z);
4431 const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z);
4432 blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
4433
4434 if (filter != tcu::Sampler::NEAREST)
4435 {
4436 const tcu::PixelBufferAccess unclampedSubRegion = tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z);
4437 scaleFromWholeSrcBuffer(unclampedSubRegion, src, srcOffset, srcExtent, filter, mirrorMode);
4438 }
4439 }
4440 }
4441
generateExpectedResult(void)4442 void BlittingImages::generateExpectedResult (void)
4443 {
4444 const tcu::ConstPixelBufferAccess src = m_sourceCompressedTexture ? m_sourceCompressedTexture->getDecompressedAccess() : m_sourceTextureLevel->getAccess();
4445 const tcu::ConstPixelBufferAccess dst = m_destinationCompressedTexture ? m_destinationCompressedTexture->getDecompressedAccess() : m_destinationTextureLevel->getAccess();
4446
4447 m_expectedTextureLevel[0] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
4448 tcu::copy(m_expectedTextureLevel[0]->getAccess(), dst);
4449
4450 if (m_params.filter != VK_FILTER_NEAREST)
4451 {
4452 m_unclampedExpectedTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
4453 tcu::copy(m_unclampedExpectedTextureLevel->getAccess(), dst);
4454 }
4455
4456 for (deUint32 i = 0; i < m_params.regions.size(); i++)
4457 {
4458 CopyRegion region = m_params.regions[i];
4459 copyRegionToTextureLevel(src, m_expectedTextureLevel[0]->getAccess(), region);
4460 }
4461 }
4462
uploadCompressedImage(const VkImage & image,const ImageParms & parms)4463 void BlittingImages::uploadCompressedImage (const VkImage& image, const ImageParms& parms)
4464 {
4465 DE_ASSERT(m_sourceCompressedTexture);
4466
4467 const InstanceInterface& vki = m_context.getInstanceInterface();
4468 const DeviceInterface& vk = m_context.getDeviceInterface();
4469 const VkPhysicalDevice vkPhysDevice = m_context.getPhysicalDevice();
4470 const VkDevice vkDevice = m_device;
4471 const VkQueue queue = m_queue;
4472 Allocator& memAlloc = *m_allocator;
4473 Move<VkBuffer> buffer;
4474 const deUint32 bufferSize = m_sourceCompressedTexture->getCompressedTexture().getDataSize();
4475 de::MovePtr<Allocation> bufferAlloc;
4476 const deUint32 arraySize = getArraySize(parms);
4477 const VkExtent3D imageExtent
4478 {
4479 parms.extent.width,
4480 (parms.imageType != VK_IMAGE_TYPE_1D) ? parms.extent.height : 1u,
4481 (parms.imageType == VK_IMAGE_TYPE_3D) ? parms.extent.depth : 1u,
4482 };
4483
4484 // Create source buffer
4485 {
4486 const VkBufferCreateInfo bufferParams
4487 {
4488 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
4489 DE_NULL, // const void* pNext;
4490 0u, // VkBufferCreateFlags flags;
4491 bufferSize, // VkDeviceSize size;
4492 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage;
4493 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
4494 0u, // deUint32 queueFamilyIndexCount;
4495 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
4496 };
4497
4498 buffer = createBuffer(vk, vkDevice, &bufferParams);
4499 bufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *buffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
4500 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
4501 }
4502
4503 // Barriers for copying buffer to image
4504 const VkBufferMemoryBarrier preBufferBarrier
4505 {
4506 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
4507 DE_NULL, // const void* pNext;
4508 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask;
4509 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
4510 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
4511 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
4512 *buffer, // VkBuffer buffer;
4513 0u, // VkDeviceSize offset;
4514 bufferSize // VkDeviceSize size;
4515 };
4516
4517 const VkImageMemoryBarrier preImageBarrier
4518 {
4519 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
4520 DE_NULL, // const void* pNext;
4521 0u, // VkAccessFlags srcAccessMask;
4522 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
4523 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
4524 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
4525 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
4526 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
4527 image, // VkImage image;
4528 { // VkImageSubresourceRange subresourceRange;
4529 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect;
4530 0u, // deUint32 baseMipLevel;
4531 1u, // deUint32 mipLevels;
4532 0u, // deUint32 baseArraySlice;
4533 arraySize, // deUint32 arraySize;
4534 }
4535 };
4536
4537 const VkImageMemoryBarrier postImageBarrier
4538 {
4539 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
4540 DE_NULL, // const void* pNext;
4541 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
4542 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
4543 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
4544 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
4545 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
4546 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
4547 image, // VkImage image;
4548 { // VkImageSubresourceRange subresourceRange;
4549 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect;
4550 0u, // deUint32 baseMipLevel;
4551 1u, // deUint32 mipLevels;
4552 0u, // deUint32 baseArraySlice;
4553 arraySize, // deUint32 arraySize;
4554 }
4555 };
4556
4557 const VkExtent3D copyExtent
4558 {
4559 imageExtent.width,
4560 imageExtent.height,
4561 imageExtent.depth
4562 };
4563
4564 VkBufferImageCopy copyRegion
4565 {
4566 0u, // VkDeviceSize bufferOffset;
4567 copyExtent.width, // deUint32 bufferRowLength;
4568 copyExtent.height, // deUint32 bufferImageHeight;
4569 {
4570 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect;
4571 0u, // deUint32 mipLevel;
4572 0u, // deUint32 baseArrayLayer;
4573 arraySize, // deUint32 layerCount;
4574 }, // VkImageSubresourceLayers imageSubresource;
4575 { 0, 0, 0 }, // VkOffset3D imageOffset;
4576 copyExtent // VkExtent3D imageExtent;
4577 };
4578
4579 // Write buffer data
4580 deMemcpy(bufferAlloc->getHostPtr(), m_sourceCompressedTexture->getCompressedTexture().getData(), bufferSize);
4581 flushAlloc(vk, vkDevice, *bufferAlloc);
4582
4583 // Copy buffer to image
4584 beginCommandBuffer(vk, *m_cmdBuffer);
4585 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL,
4586 1, &preBufferBarrier, 1, &preImageBarrier);
4587 vk.cmdCopyBufferToImage(*m_cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ©Region);
4588 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
4589 endCommandBuffer(vk, *m_cmdBuffer);
4590
4591 submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
4592 m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
4593 }
4594
4595
4596 class BlitImageTestCase : public vkt::TestCase
4597 {
4598 public:
BlitImageTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)4599 BlitImageTestCase (tcu::TestContext& testCtx,
4600 const std::string& name,
4601 const std::string& description,
4602 const TestParams params)
4603 : vkt::TestCase (testCtx, name, description)
4604 , m_params (params)
4605 {}
4606
createInstance(Context & context) const4607 virtual TestInstance* createInstance (Context& context) const
4608 {
4609 return new BlittingImages(context, m_params);
4610 }
4611
checkSupport(Context & context) const4612 virtual void checkSupport (Context& context) const
4613 {
4614 VkImageFormatProperties properties;
4615 if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
4616 m_params.src.image.format,
4617 m_params.src.image.imageType,
4618 m_params.src.image.tiling,
4619 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
4620 0,
4621 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
4622 {
4623 TCU_THROW(NotSupportedError, "Source format not supported");
4624 }
4625 if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
4626 m_params.dst.image.format,
4627 m_params.dst.image.imageType,
4628 m_params.dst.image.tiling,
4629 VK_IMAGE_USAGE_TRANSFER_DST_BIT,
4630 0,
4631 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
4632 {
4633 TCU_THROW(NotSupportedError, "Destination format not supported");
4634 }
4635
4636 VkFormatProperties srcFormatProperties;
4637 context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_params.src.image.format, &srcFormatProperties);
4638 VkFormatFeatureFlags srcFormatFeatures = m_params.src.image.tiling == VK_IMAGE_TILING_LINEAR ? srcFormatProperties.linearTilingFeatures : srcFormatProperties.optimalTilingFeatures;
4639 if (!(srcFormatFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT))
4640 {
4641 TCU_THROW(NotSupportedError, "Format feature blit source not supported");
4642 }
4643
4644 VkFormatProperties dstFormatProperties;
4645 context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_params.dst.image.format, &dstFormatProperties);
4646 VkFormatFeatureFlags dstFormatFeatures = m_params.dst.image.tiling == VK_IMAGE_TILING_LINEAR ? dstFormatProperties.linearTilingFeatures : dstFormatProperties.optimalTilingFeatures;
4647 if (!(dstFormatFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT))
4648 {
4649 TCU_THROW(NotSupportedError, "Format feature blit destination not supported");
4650 }
4651
4652 if (m_params.filter == VK_FILTER_LINEAR && !(srcFormatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
4653 {
4654 TCU_THROW(NotSupportedError, "Source format feature sampled image filter linear not supported");
4655 }
4656
4657 if (m_params.filter == VK_FILTER_CUBIC_EXT)
4658 {
4659 context.requireDeviceFunctionality("VK_EXT_filter_cubic");
4660
4661 if (!(srcFormatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT))
4662 {
4663 TCU_THROW(NotSupportedError, "Source format feature sampled image filter cubic not supported");
4664 }
4665 }
4666
4667 if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
4668 {
4669 if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
4670 {
4671 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
4672 }
4673 }
4674 }
4675
4676 private:
4677 TestParams m_params;
4678 };
4679
4680 class BlittingMipmaps : public CopiesAndBlittingTestInstance
4681 {
4682 public:
4683 BlittingMipmaps (Context& context,
4684 TestParams params);
4685 virtual tcu::TestStatus iterate (void);
4686 protected:
4687 virtual tcu::TestStatus checkTestResult (tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess());
4688 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
4689 virtual void generateExpectedResult (void);
4690 private:
4691 bool checkNonNearestFilteredResult (void);
4692 bool checkNearestFilteredResult (void);
4693
4694 Move<VkImage> m_source;
4695 de::MovePtr<Allocation> m_sourceImageAlloc;
4696 Move<VkImage> m_destination;
4697 de::MovePtr<Allocation> m_destinationImageAlloc;
4698
4699 de::MovePtr<tcu::TextureLevel> m_unclampedExpectedTextureLevel[16];
4700 };
4701
BlittingMipmaps(Context & context,TestParams params)4702 BlittingMipmaps::BlittingMipmaps (Context& context, TestParams params)
4703 : CopiesAndBlittingTestInstance (context, params)
4704 {
4705 const InstanceInterface& vki = context.getInstanceInterface();
4706 const DeviceInterface& vk = context.getDeviceInterface();
4707 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
4708 const VkDevice vkDevice = m_device;
4709 Allocator& memAlloc = context.getDefaultAllocator();
4710
4711 // Create source image
4712 {
4713 const VkImageCreateInfo sourceImageParams =
4714 {
4715 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
4716 DE_NULL, // const void* pNext;
4717 getCreateFlags(m_params.src.image), // VkImageCreateFlags flags;
4718 m_params.src.image.imageType, // VkImageType imageType;
4719 m_params.src.image.format, // VkFormat format;
4720 getExtent3D(m_params.src.image), // VkExtent3D extent;
4721 1u, // deUint32 mipLevels;
4722 getArraySize(m_params.src.image), // deUint32 arraySize;
4723 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
4724 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
4725 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
4726 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
4727 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
4728 0u, // deUint32 queueFamilyIndexCount;
4729 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
4730 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
4731 };
4732
4733 m_source = createImage(vk, vkDevice, &sourceImageParams);
4734 m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
4735 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
4736 }
4737
4738 // Create destination image
4739 {
4740 const VkImageCreateInfo destinationImageParams =
4741 {
4742 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
4743 DE_NULL, // const void* pNext;
4744 getCreateFlags(m_params.dst.image), // VkImageCreateFlags flags;
4745 m_params.dst.image.imageType, // VkImageType imageType;
4746 m_params.dst.image.format, // VkFormat format;
4747 getExtent3D(m_params.dst.image), // VkExtent3D extent;
4748 m_params.mipLevels, // deUint32 mipLevels;
4749 getArraySize(m_params.dst.image), // deUint32 arraySize;
4750 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
4751 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
4752 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
4753 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
4754 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
4755 0u, // deUint32 queueFamilyIndexCount;
4756 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
4757 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
4758 };
4759
4760 m_destination = createImage(vk, vkDevice, &destinationImageParams);
4761 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
4762 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
4763 }
4764 }
4765
iterate(void)4766 tcu::TestStatus BlittingMipmaps::iterate (void)
4767 {
4768 const tcu::TextureFormat srcTcuFormat = mapVkFormat(m_params.src.image.format);
4769 const tcu::TextureFormat dstTcuFormat = mapVkFormat(m_params.dst.image.format);
4770 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
4771 m_params.src.image.extent.width,
4772 m_params.src.image.extent.height,
4773 m_params.src.image.extent.depth));
4774 generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth, m_params.src.image.fillMode);
4775 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
4776 (int)m_params.dst.image.extent.width,
4777 (int)m_params.dst.image.extent.height,
4778 (int)m_params.dst.image.extent.depth));
4779 generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth, m_params.dst.image.fillMode);
4780 generateExpectedResult();
4781
4782 uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
4783
4784 uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, m_params.mipLevels);
4785
4786 const DeviceInterface& vk = m_context.getDeviceInterface();
4787 const VkDevice vkDevice = m_device;
4788 const VkQueue queue = m_queue;
4789
4790 std::vector<VkImageBlit> regions;
4791 std::vector<VkImageBlit2KHR> regions2KHR;
4792 for (deUint32 i = 0; i < m_params.regions.size(); i++)
4793 {
4794 if (m_params.extensionUse == EXTENSION_USE_NONE)
4795 {
4796 regions.push_back(m_params.regions[i].imageBlit);
4797 }
4798 else
4799 {
4800 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
4801 regions2KHR.push_back(convertvkImageBlitTovkImageBlit2KHR(m_params.regions[i].imageBlit));
4802 }
4803 }
4804
4805 // Copy source image to mip level 0 when generating mipmaps with multiple blit commands
4806 if (!m_params.singleCommand)
4807 uploadImage(m_sourceTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, 1u);
4808
4809 beginCommandBuffer(vk, *m_cmdBuffer);
4810
4811 // Blit all mip levels with a single blit command
4812 if (m_params.singleCommand)
4813 {
4814 {
4815 // Source image layout
4816 const VkImageMemoryBarrier srcImageBarrier =
4817 {
4818 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
4819 DE_NULL, // const void* pNext;
4820 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
4821 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
4822 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
4823 m_params.src.image.operationLayout, // VkImageLayout newLayout;
4824 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
4825 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
4826 m_source.get(), // VkImage image;
4827 { // VkImageSubresourceRange subresourceRange;
4828 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
4829 0u, // deUint32 baseMipLevel;
4830 1u, // deUint32 mipLevels;
4831 0u, // deUint32 baseArraySlice;
4832 getArraySize(m_params.src.image) // deUint32 arraySize;
4833 }
4834 };
4835
4836 // Destination image layout
4837 const VkImageMemoryBarrier dstImageBarrier =
4838 {
4839 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
4840 DE_NULL, // const void* pNext;
4841 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
4842 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
4843 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
4844 m_params.dst.image.operationLayout, // VkImageLayout newLayout;
4845 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
4846 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
4847 m_destination.get(), // VkImage image;
4848 { // VkImageSubresourceRange subresourceRange;
4849 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
4850 0u, // deUint32 baseMipLevel;
4851 m_params.mipLevels, // deUint32 mipLevels;
4852 0u, // deUint32 baseArraySlice;
4853 getArraySize(m_params.dst.image) // deUint32 arraySize;
4854 }
4855 };
4856
4857 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &srcImageBarrier);
4858 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &dstImageBarrier);
4859
4860 if (m_params.extensionUse == EXTENSION_USE_NONE)
4861 {
4862 vk.cmdBlitImage(*m_cmdBuffer, m_source.get(), m_params.src.image.operationLayout, m_destination.get(), m_params.dst.image.operationLayout, (deUint32)m_params.regions.size(), ®ions[0], m_params.filter);
4863 }
4864 #ifndef CTS_USES_VULKANSC
4865 else
4866 {
4867 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
4868 const VkBlitImageInfo2KHR BlitImageInfo2KHR =
4869 {
4870 VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR, // VkStructureType sType;
4871 DE_NULL, // const void* pNext;
4872 m_source.get(), // VkImage srcImage;
4873 m_params.src.image.operationLayout, // VkImageLayout srcImageLayout;
4874 m_destination.get(), // VkImage dstImage;
4875 m_params.dst.image.operationLayout, // VkImageLayout dstImageLayout;
4876 (deUint32)m_params.regions.size(), // uint32_t regionCount;
4877 ®ions2KHR[0], // const VkImageBlit2KHR* pRegions;
4878 m_params.filter // VkFilter filter;
4879 };
4880 vk.cmdBlitImage2(*m_cmdBuffer, &BlitImageInfo2KHR);
4881 }
4882 #endif // CTS_USES_VULKANSC
4883 }
4884 }
4885 // Blit mip levels with multiple blit commands
4886 else
4887 {
4888 // Prepare all mip levels for reading
4889 {
4890 for (deUint32 barrierno = 0; barrierno < m_params.barrierCount; barrierno++)
4891 {
4892 VkImageMemoryBarrier preImageBarrier =
4893 {
4894 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
4895 DE_NULL, // const void* pNext;
4896 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
4897 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
4898 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
4899 m_params.src.image.operationLayout, // VkImageLayout newLayout;
4900 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
4901 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
4902 m_destination.get(), // VkImage image;
4903 { // VkImageSubresourceRange subresourceRange;
4904 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
4905 0u, // deUint32 baseMipLevel;
4906 VK_REMAINING_MIP_LEVELS, // deUint32 mipLevels;
4907 0u, // deUint32 baseArraySlice;
4908 getArraySize(m_params.src.image) // deUint32 arraySize;
4909 }
4910 };
4911
4912 if (getArraySize(m_params.src.image) == 1)
4913 {
4914 DE_ASSERT(barrierno < m_params.mipLevels);
4915 preImageBarrier.subresourceRange.baseMipLevel = barrierno;
4916 preImageBarrier.subresourceRange.levelCount = (barrierno + 1 < m_params.barrierCount) ? 1 : VK_REMAINING_MIP_LEVELS;
4917 }
4918 else
4919 {
4920 preImageBarrier.subresourceRange.baseArrayLayer = barrierno;
4921 preImageBarrier.subresourceRange.layerCount = (barrierno + 1 < m_params.barrierCount) ? 1 : VK_REMAINING_ARRAY_LAYERS;
4922 }
4923 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &preImageBarrier);
4924 }
4925 }
4926
4927 for (deUint32 regionNdx = 0u; regionNdx < (deUint32)m_params.regions.size(); regionNdx++)
4928 {
4929 const deUint32 mipLevel = m_params.regions[regionNdx].imageBlit.dstSubresource.mipLevel;
4930
4931 // Prepare single mip level for writing
4932 const VkImageMemoryBarrier preImageBarrier =
4933 {
4934 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
4935 DE_NULL, // const void* pNext;
4936 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags srcAccessMask;
4937 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
4938 m_params.src.image.operationLayout, // VkImageLayout oldLayout;
4939 m_params.dst.image.operationLayout, // VkImageLayout newLayout;
4940 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
4941 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
4942 m_destination.get(), // VkImage image;
4943 { // VkImageSubresourceRange subresourceRange;
4944 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
4945 mipLevel, // deUint32 baseMipLevel;
4946 1u, // deUint32 mipLevels;
4947 0u, // deUint32 baseArraySlice;
4948 getArraySize(m_params.dst.image) // deUint32 arraySize;
4949 }
4950 };
4951
4952 // Prepare single mip level for reading
4953 const VkImageMemoryBarrier postImageBarrier =
4954 {
4955 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
4956 DE_NULL, // const void* pNext;
4957 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
4958 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
4959 m_params.dst.image.operationLayout, // VkImageLayout oldLayout;
4960 m_params.src.image.operationLayout, // VkImageLayout newLayout;
4961 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
4962 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
4963 m_destination.get(), // VkImage image;
4964 { // VkImageSubresourceRange subresourceRange;
4965 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
4966 mipLevel, // deUint32 baseMipLevel;
4967 1u, // deUint32 mipLevels;
4968 0u, // deUint32 baseArraySlice;
4969 getArraySize(m_params.src.image) // deUint32 arraySize;
4970 }
4971 };
4972
4973 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &preImageBarrier);
4974
4975 if (m_params.extensionUse == EXTENSION_USE_NONE)
4976 {
4977 vk.cmdBlitImage(*m_cmdBuffer, m_destination.get(), m_params.src.image.operationLayout, m_destination.get(), m_params.dst.image.operationLayout, 1u, ®ions[regionNdx], m_params.filter);
4978 }
4979 #ifndef CTS_USES_VULKANSC
4980 else
4981 {
4982 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
4983 const VkBlitImageInfo2KHR BlitImageInfo2KHR =
4984 {
4985 VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR, // VkStructureType sType;
4986 DE_NULL, // const void* pNext;
4987 m_destination.get(), // VkImage srcImage;
4988 m_params.src.image.operationLayout, // VkImageLayout srcImageLayout;
4989 m_destination.get(), // VkImage dstImage;
4990 m_params.dst.image.operationLayout, // VkImageLayout dstImageLayout;
4991 1u, // uint32_t regionCount;
4992 ®ions2KHR[regionNdx], // const VkImageBlit2KHR* pRegions;
4993 m_params.filter // VkFilter filter;
4994 };
4995 vk.cmdBlitImage2(*m_cmdBuffer, &BlitImageInfo2KHR);
4996 }
4997 #endif // CTS_USES_VULKANSC
4998
4999 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
5000 }
5001
5002 // Prepare all mip levels for writing
5003 {
5004 const VkImageMemoryBarrier postImageBarrier =
5005 {
5006 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
5007 DE_NULL, // const void* pNext;
5008 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags srcAccessMask;
5009 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
5010 m_params.src.image.operationLayout, // VkImageLayout oldLayout;
5011 m_params.dst.image.operationLayout, // VkImageLayout newLayout;
5012 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
5013 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
5014 m_destination.get(), // VkImage image;
5015 { // VkImageSubresourceRange subresourceRange;
5016 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
5017 0u, // deUint32 baseMipLevel;
5018 VK_REMAINING_MIP_LEVELS, // deUint32 mipLevels;
5019 0u, // deUint32 baseArraySlice;
5020 getArraySize(m_params.dst.image) // deUint32 arraySize;
5021 }
5022 };
5023
5024 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
5025 }
5026 }
5027
5028 endCommandBuffer(vk, *m_cmdBuffer);
5029 submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
5030 m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
5031
5032 return checkTestResult();
5033 }
5034
checkNonNearestFilteredResult(void)5035 bool BlittingMipmaps::checkNonNearestFilteredResult (void)
5036 {
5037 tcu::TestLog& log (m_context.getTestContext().getLog());
5038 bool allLevelsOk = true;
5039
5040 for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
5041 {
5042 // Update reference results with previous results that have been verified.
5043 // This needs to be done such that accumulated errors don't exceed the fixed threshold.
5044 for (deUint32 i = 0; i < m_params.regions.size(); i++)
5045 {
5046 const CopyRegion region = m_params.regions[i];
5047 const deUint32 srcMipLevel = m_params.regions[i].imageBlit.srcSubresource.mipLevel;
5048 const deUint32 dstMipLevel = m_params.regions[i].imageBlit.dstSubresource.mipLevel;
5049 de::MovePtr<tcu::TextureLevel> prevResultLevel;
5050 tcu::ConstPixelBufferAccess src;
5051 if (srcMipLevel < mipLevelNdx)
5052 {
5053 // Generate expected result from rendered result that was previously verified
5054 prevResultLevel = readImage(*m_destination, m_params.dst.image, srcMipLevel);
5055 src = prevResultLevel->getAccess();
5056 }
5057 else
5058 {
5059 // Previous reference mipmaps might have changed, so recompute expected result
5060 src = m_expectedTextureLevel[srcMipLevel]->getAccess();
5061 }
5062 copyRegionToTextureLevel(src, m_expectedTextureLevel[dstMipLevel]->getAccess(), region, dstMipLevel);
5063 }
5064
5065 de::MovePtr<tcu::TextureLevel> resultLevel = readImage(*m_destination, m_params.dst.image, mipLevelNdx);
5066 const tcu::ConstPixelBufferAccess& resultAccess = resultLevel->getAccess();
5067
5068 const tcu::Sampler::DepthStencilMode mode = tcu::hasDepthComponent(resultAccess.getFormat().order) ? tcu::Sampler::MODE_DEPTH :
5069 tcu::hasStencilComponent(resultAccess.getFormat().order) ? tcu::Sampler::MODE_STENCIL :
5070 tcu::Sampler::MODE_LAST;
5071 const tcu::ConstPixelBufferAccess result = tcu::hasDepthComponent(resultAccess.getFormat().order) ? getEffectiveDepthStencilAccess(resultAccess, mode) :
5072 tcu::hasStencilComponent(resultAccess.getFormat().order) ? getEffectiveDepthStencilAccess(resultAccess, mode) :
5073 resultAccess;
5074 const tcu::ConstPixelBufferAccess clampedLevel = tcu::hasDepthComponent(resultAccess.getFormat().order) ? getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
5075 tcu::hasStencilComponent(resultAccess.getFormat().order) ? getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
5076 m_expectedTextureLevel[mipLevelNdx]->getAccess();
5077 const tcu::ConstPixelBufferAccess unclampedLevel = tcu::hasDepthComponent(resultAccess.getFormat().order) ? getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
5078 tcu::hasStencilComponent(resultAccess.getFormat().order) ? getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
5079 m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess();
5080 const tcu::TextureFormat srcFormat = tcu::hasDepthComponent(resultAccess.getFormat().order) ? tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode) :
5081 tcu::hasStencilComponent(resultAccess.getFormat().order) ? tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode) :
5082 mapVkFormat(m_params.src.image.format);
5083
5084 const tcu::TextureFormat dstFormat = result.getFormat();
5085 bool singleLevelOk = false;
5086 std::vector <CopyRegion> mipLevelRegions;
5087
5088 for (size_t regionNdx = 0u; regionNdx < m_params.regions.size(); regionNdx++)
5089 if (m_params.regions.at(regionNdx).imageBlit.dstSubresource.mipLevel == mipLevelNdx)
5090 mipLevelRegions.push_back(m_params.regions.at(regionNdx));
5091
5092 log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
5093
5094 if (isFloatFormat(dstFormat))
5095 {
5096 const bool srcIsSRGB = tcu::isSRGB(srcFormat);
5097 const tcu::Vec4 srcMaxDiff = getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2.0f : 1.0f);
5098 const tcu::Vec4 dstMaxDiff = getFormatThreshold(dstFormat);
5099 const tcu::Vec4 threshold = ( srcMaxDiff + dstMaxDiff ) * ((m_params.filter == VK_FILTER_CUBIC_EXT)? 1.5f : 1.0f);
5100
5101 singleLevelOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
5102 log << tcu::TestLog::EndSection;
5103
5104 if (!singleLevelOk)
5105 {
5106 log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
5107 singleLevelOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
5108 log << tcu::TestLog::EndSection;
5109 }
5110 }
5111 else
5112 {
5113 tcu::UVec4 threshold;
5114 // Calculate threshold depending on channel width of destination format.
5115 const tcu::IVec4 dstBitDepth = tcu::getTextureFormatBitDepth(dstFormat);
5116 const tcu::IVec4 srcBitDepth = tcu::getTextureFormatBitDepth(srcFormat);
5117 for (deUint32 i = 0; i < 4; ++i)
5118 threshold[i] = 1 + de::max(((1 << dstBitDepth[i]) - 1) / de::clamp((1 << srcBitDepth[i]) - 1, 1, 256), 1);
5119
5120 singleLevelOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
5121 log << tcu::TestLog::EndSection;
5122
5123 if (!singleLevelOk)
5124 {
5125 log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
5126 singleLevelOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", unclampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
5127 log << tcu::TestLog::EndSection;
5128 }
5129 }
5130 allLevelsOk &= singleLevelOk;
5131 }
5132
5133 return allLevelsOk;
5134 }
5135
checkNearestFilteredResult(void)5136 bool BlittingMipmaps::checkNearestFilteredResult (void)
5137 {
5138 bool allLevelsOk = true;
5139 tcu::TestLog& log (m_context.getTestContext().getLog());
5140
5141 for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
5142 {
5143 de::MovePtr<tcu::TextureLevel> resultLevel = readImage(*m_destination, m_params.dst.image, mipLevelNdx);
5144 const tcu::ConstPixelBufferAccess& resultAccess = resultLevel->getAccess();
5145
5146 const tcu::Sampler::DepthStencilMode mode = tcu::hasDepthComponent(resultAccess.getFormat().order) ? tcu::Sampler::MODE_DEPTH :
5147 tcu::hasStencilComponent(resultAccess.getFormat().order) ? tcu::Sampler::MODE_STENCIL :
5148 tcu::Sampler::MODE_LAST;
5149 const tcu::ConstPixelBufferAccess result = tcu::hasDepthComponent(resultAccess.getFormat().order) ? getEffectiveDepthStencilAccess(resultAccess, mode) :
5150 tcu::hasStencilComponent(resultAccess.getFormat().order) ? getEffectiveDepthStencilAccess(resultAccess, mode) :
5151 resultAccess;
5152 const tcu::ConstPixelBufferAccess source = (m_params.singleCommand || mipLevelNdx == 0) ? // Read from source image
5153 tcu::hasDepthComponent(resultAccess.getFormat().order) ? tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode) :
5154 tcu::hasStencilComponent(resultAccess.getFormat().order) ? tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode) :
5155 m_sourceTextureLevel->getAccess()
5156 // Read from destination image
5157 : tcu::hasDepthComponent(resultAccess.getFormat().order) ? tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess(), mode) :
5158 tcu::hasStencilComponent(resultAccess.getFormat().order) ? tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess(), mode) :
5159 m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess();
5160 const tcu::TextureFormat dstFormat = result.getFormat();
5161 const tcu::TextureChannelClass dstChannelClass = tcu::getTextureChannelClass(dstFormat.type);
5162 bool singleLevelOk = false;
5163 std::vector <CopyRegion> mipLevelRegions;
5164
5165 for (size_t regionNdx = 0u; regionNdx < m_params.regions.size(); regionNdx++)
5166 if (m_params.regions.at(regionNdx).imageBlit.dstSubresource.mipLevel == mipLevelNdx)
5167 mipLevelRegions.push_back(m_params.regions.at(regionNdx));
5168
5169 tcu::TextureLevel errorMaskStorage (tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), result.getWidth(), result.getHeight(), result.getDepth());
5170 tcu::PixelBufferAccess errorMask = errorMaskStorage.getAccess();
5171 tcu::Vec4 pixelBias (0.0f, 0.0f, 0.0f, 0.0f);
5172 tcu::Vec4 pixelScale (1.0f, 1.0f, 1.0f, 1.0f);
5173
5174 tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
5175
5176 if (dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
5177 dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
5178 {
5179 singleLevelOk = intNearestBlitCompare(source, result, errorMask, mipLevelRegions);
5180 }
5181 else
5182 {
5183 const tcu::Vec4 srcMaxDiff = getFloatOrFixedPointFormatThreshold(source.getFormat());
5184 const tcu::Vec4 dstMaxDiff = getFloatOrFixedPointFormatThreshold(result.getFormat());
5185
5186 singleLevelOk = floatNearestBlitCompare(source, result, srcMaxDiff, dstMaxDiff, errorMask, mipLevelRegions);
5187 }
5188
5189 if (dstFormat != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
5190 tcu::computePixelScaleBias(result, pixelScale, pixelBias);
5191
5192 if (!singleLevelOk)
5193 {
5194 log << tcu::TestLog::ImageSet("Compare", "Result comparsion, level " + de::toString(mipLevelNdx))
5195 << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
5196 << tcu::TestLog::Image("Reference", "Reference", source, pixelScale, pixelBias)
5197 << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask)
5198 << tcu::TestLog::EndImageSet;
5199 }
5200 else
5201 {
5202 log << tcu::TestLog::ImageSet("Compare", "Result comparsion, level " + de::toString(mipLevelNdx))
5203 << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
5204 << tcu::TestLog::EndImageSet;
5205 }
5206
5207 allLevelsOk &= singleLevelOk;
5208 }
5209
5210 return allLevelsOk;
5211 }
5212
checkTestResult(tcu::ConstPixelBufferAccess result)5213 tcu::TestStatus BlittingMipmaps::checkTestResult (tcu::ConstPixelBufferAccess result)
5214 {
5215 DE_UNREF(result);
5216 DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR || m_params.filter == VK_FILTER_CUBIC_EXT);
5217 const std::string failMessage("Result image is incorrect");
5218
5219 if (m_params.filter != VK_FILTER_NEAREST)
5220 {
5221 if (!checkNonNearestFilteredResult())
5222 return tcu::TestStatus::fail(failMessage);
5223 }
5224 else // NEAREST filtering
5225 {
5226 if (!checkNearestFilteredResult())
5227 return tcu::TestStatus::fail(failMessage);
5228 }
5229
5230 return tcu::TestStatus::pass("Pass");
5231 }
5232
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)5233 void BlittingMipmaps::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
5234 {
5235 DE_ASSERT(src.getDepth() == dst.getDepth());
5236
5237 const MirrorMode mirrorMode = getMirrorMode(region.imageBlit.srcOffsets[0],
5238 region.imageBlit.srcOffsets[1],
5239 region.imageBlit.dstOffsets[0],
5240 region.imageBlit.dstOffsets[1]);
5241
5242 flipCoordinates(region, mirrorMode);
5243
5244 const VkOffset3D srcOffset = region.imageBlit.srcOffsets[0];
5245 const VkOffset3D srcExtent =
5246 {
5247 region.imageBlit.srcOffsets[1].x - srcOffset.x,
5248 region.imageBlit.srcOffsets[1].y - srcOffset.y,
5249 region.imageBlit.srcOffsets[1].z - srcOffset.z
5250 };
5251 const VkOffset3D dstOffset = region.imageBlit.dstOffsets[0];
5252 const VkOffset3D dstExtent =
5253 {
5254 region.imageBlit.dstOffsets[1].x - dstOffset.x,
5255 region.imageBlit.dstOffsets[1].y - dstOffset.y,
5256 region.imageBlit.dstOffsets[1].z - dstOffset.z
5257 };
5258
5259 tcu::Sampler::FilterMode filter;
5260 switch (m_params.filter)
5261 {
5262 case VK_FILTER_LINEAR: filter = tcu::Sampler::LINEAR; break;
5263 case VK_FILTER_CUBIC_EXT: filter = tcu::Sampler::CUBIC; break;
5264 case VK_FILTER_NEAREST:
5265 default: filter = tcu::Sampler::NEAREST; break;
5266 }
5267
5268 if (tcu::isCombinedDepthStencilType(src.getFormat().type))
5269 {
5270 DE_ASSERT(src.getFormat() == dst.getFormat());
5271 // Scale depth.
5272 if (tcu::hasDepthComponent(src.getFormat().order))
5273 {
5274 const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_DEPTH);
5275 const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH);
5276 tcu::scale(dstSubRegion, srcSubRegion, filter);
5277
5278 if (filter != tcu::Sampler::NEAREST)
5279 {
5280 const tcu::ConstPixelBufferAccess depthSrc = getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH);
5281 const tcu::PixelBufferAccess unclampedSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel[0]->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH);
5282 scaleFromWholeSrcBuffer(unclampedSubRegion, depthSrc, srcOffset, srcExtent, filter);
5283 }
5284 }
5285
5286 // Scale stencil.
5287 if (tcu::hasStencilComponent(src.getFormat().order))
5288 {
5289 const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_STENCIL);
5290 const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
5291 blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
5292
5293 if (filter != tcu::Sampler::NEAREST)
5294 {
5295 const tcu::ConstPixelBufferAccess stencilSrc = getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL);
5296 const tcu::PixelBufferAccess unclampedSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel[0]->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
5297 scaleFromWholeSrcBuffer(unclampedSubRegion, stencilSrc, srcOffset, srcExtent, filter);
5298 }
5299 }
5300 }
5301 else
5302 {
5303 for (int layerNdx = 0u; layerNdx < src.getDepth(); layerNdx++)
5304 {
5305 const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, srcOffset.x, srcOffset.y, layerNdx, srcExtent.x, srcExtent.y, 1);
5306 const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dst, dstOffset.x, dstOffset.y, layerNdx, dstExtent.x, dstExtent.y, 1);
5307 blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
5308
5309 if (filter != tcu::Sampler::NEAREST)
5310 {
5311 const tcu::PixelBufferAccess unclampedSubRegion = tcu::getSubregion(m_unclampedExpectedTextureLevel[mipLevel]->getAccess(), dstOffset.x, dstOffset.y, layerNdx, dstExtent.x, dstExtent.y, 1);
5312 scaleFromWholeSrcBuffer(unclampedSubRegion, srcSubRegion, srcOffset, srcExtent, filter);
5313 }
5314 }
5315 }
5316 }
5317
generateExpectedResult(void)5318 void BlittingMipmaps::generateExpectedResult (void)
5319 {
5320 const tcu::ConstPixelBufferAccess src = m_sourceTextureLevel->getAccess();
5321 const tcu::ConstPixelBufferAccess dst = m_destinationTextureLevel->getAccess();
5322
5323 for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
5324 m_expectedTextureLevel[mipLevelNdx] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth() >> mipLevelNdx, dst.getHeight() >> mipLevelNdx, dst.getDepth()));
5325
5326 tcu::copy(m_expectedTextureLevel[0]->getAccess(), src);
5327
5328 if (m_params.filter != VK_FILTER_NEAREST)
5329 {
5330 for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
5331 m_unclampedExpectedTextureLevel[mipLevelNdx] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth() >> mipLevelNdx, dst.getHeight() >> mipLevelNdx, dst.getDepth()));
5332
5333 tcu::copy(m_unclampedExpectedTextureLevel[0]->getAccess(), src);
5334 }
5335
5336 for (deUint32 i = 0; i < m_params.regions.size(); i++)
5337 {
5338 CopyRegion region = m_params.regions[i];
5339 copyRegionToTextureLevel(m_expectedTextureLevel[m_params.regions[i].imageBlit.srcSubresource.mipLevel]->getAccess(), m_expectedTextureLevel[m_params.regions[i].imageBlit.dstSubresource.mipLevel]->getAccess(), region, m_params.regions[i].imageBlit.dstSubresource.mipLevel);
5340 }
5341 }
5342
5343 class BlitMipmapTestCase : public vkt::TestCase
5344 {
5345 public:
BlitMipmapTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)5346 BlitMipmapTestCase (tcu::TestContext& testCtx,
5347 const std::string& name,
5348 const std::string& description,
5349 const TestParams params)
5350 : vkt::TestCase (testCtx, name, description)
5351 , m_params (params)
5352 {}
5353
createInstance(Context & context) const5354 virtual TestInstance* createInstance (Context& context) const
5355 {
5356 return new BlittingMipmaps(context, m_params);
5357 }
5358
checkSupport(Context & context) const5359 virtual void checkSupport (Context& context) const
5360 {
5361 const InstanceInterface& vki = context.getInstanceInterface();
5362 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
5363 {
5364 VkImageFormatProperties properties;
5365 if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
5366 m_params.src.image.format,
5367 VK_IMAGE_TYPE_2D,
5368 VK_IMAGE_TILING_OPTIMAL,
5369 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
5370 0,
5371 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
5372 {
5373 TCU_THROW(NotSupportedError, "Format not supported");
5374 }
5375 else if ((m_params.src.image.extent.width > properties.maxExtent.width) ||
5376 (m_params.src.image.extent.height > properties.maxExtent.height) ||
5377 (m_params.src.image.extent.depth > properties.maxArrayLayers))
5378 {
5379 TCU_THROW(NotSupportedError, "Image size not supported");
5380 }
5381 }
5382
5383 {
5384 VkImageFormatProperties properties;
5385 if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
5386 m_params.dst.image.format,
5387 VK_IMAGE_TYPE_2D,
5388 VK_IMAGE_TILING_OPTIMAL,
5389 VK_IMAGE_USAGE_TRANSFER_DST_BIT,
5390 0,
5391 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
5392 {
5393 TCU_THROW(NotSupportedError, "Format not supported");
5394 }
5395 else if ((m_params.dst.image.extent.width > properties.maxExtent.width) ||
5396 (m_params.dst.image.extent.height > properties.maxExtent.height) ||
5397 (m_params.dst.image.extent.depth > properties.maxArrayLayers))
5398 {
5399 TCU_THROW(NotSupportedError, "Image size not supported");
5400 }
5401 else if (m_params.mipLevels > properties.maxMipLevels)
5402 {
5403 TCU_THROW(NotSupportedError, "Number of mip levels not supported");
5404 }
5405 else if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
5406 (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
5407 {
5408 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
5409 }
5410 }
5411
5412 const VkFormatProperties srcFormatProperties = getPhysicalDeviceFormatProperties (vki, vkPhysDevice, m_params.src.image.format);
5413 if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT))
5414 {
5415 TCU_THROW(NotSupportedError, "Format feature blit source not supported");
5416 }
5417
5418 const VkFormatProperties dstFormatProperties = getPhysicalDeviceFormatProperties (vki, vkPhysDevice, m_params.dst.image.format);
5419 if (!(dstFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT))
5420 {
5421 TCU_THROW(NotSupportedError, "Format feature blit destination not supported");
5422 }
5423
5424 if (m_params.filter == VK_FILTER_LINEAR && !(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
5425 TCU_THROW(NotSupportedError, "Source format feature sampled image filter linear not supported");
5426
5427 if (m_params.filter == VK_FILTER_CUBIC_EXT)
5428 {
5429 context.requireDeviceFunctionality("VK_EXT_filter_cubic");
5430
5431 if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT))
5432 {
5433 TCU_THROW(NotSupportedError, "Source format feature sampled image filter cubic not supported");
5434 }
5435 }
5436 }
5437
5438 private:
5439 TestParams m_params;
5440 };
5441
5442 // Resolve image to image.
5443
5444 enum ResolveImageToImageOptions{NO_OPTIONAL_OPERATION = 0,
5445 COPY_MS_IMAGE_TO_MS_IMAGE,
5446 COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE,
5447 COPY_MS_IMAGE_LAYER_TO_MS_IMAGE,
5448 COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION,
5449 COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB,
5450 COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE,
5451 COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER};
5452
removeExtensions(const std::vector<std::string> & a,const std::vector<const char * > & b)5453 std::vector<std::string> removeExtensions (const std::vector<std::string>& a, const std::vector<const char*>& b)
5454 {
5455 std::vector<std::string> res;
5456 std::set<std::string> removeExts (b.begin(), b.end());
5457
5458 for (const auto & aIter : a)
5459 {
5460 if (!de::contains(removeExts, aIter))
5461 res.push_back(aIter);
5462 }
5463
5464 return res;
5465 }
5466
5467
5468 // Creates a device that has queues for graphics/compute capabilities and compute or transfer capabilities without graphics.
createCustomDevice(Context & context,const ResolveImageToImageOptions imageCreateOptions,const CustomInstance & customInstance,uint32_t & queueFamilyIndex)5469 Move<VkDevice> createCustomDevice (Context& context,
5470 const ResolveImageToImageOptions imageCreateOptions,
5471 #ifdef CTS_USES_VULKANSC
5472 const CustomInstance& customInstance,
5473 #endif // CTS_USES_VULKANSC
5474 uint32_t& queueFamilyIndex)
5475 {
5476 #ifdef CTS_USES_VULKANSC
5477 const InstanceInterface& instanceDriver = customInstance.getDriver();
5478 const VkPhysicalDevice physicalDevice = chooseDevice(instanceDriver, customInstance, context.getTestContext().getCommandLine());
5479 #else
5480 const InstanceInterface& instanceDriver = context.getInstanceInterface();
5481 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
5482 #endif // CTS_USES_VULKANSC
5483
5484 // This function can only be used to create a device with compute only or transfer only queue.
5485 DE_ASSERT(imageCreateOptions == COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE || imageCreateOptions == COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER);
5486
5487 // When testing with compute or transfer queue, find a queue family that supports compute or transfer queue, but does NOT support graphics queue.
5488 const std::vector<VkQueueFamilyProperties> queueFamilies = getPhysicalDeviceQueueFamilyProperties(context.getInstanceInterface(), context.getPhysicalDevice());
5489
5490 queueFamilyIndex = 0;
5491 for (const auto &queueFamily: queueFamilies)
5492 {
5493 if (imageCreateOptions == COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE)
5494 {
5495 if (queueFamily.queueFlags & VK_QUEUE_COMPUTE_BIT && !(queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT))
5496 break;
5497 else
5498 queueFamilyIndex++;
5499 }
5500 else if (imageCreateOptions == COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER)
5501 {
5502 if (queueFamily.queueFlags & VK_QUEUE_TRANSFER_BIT && !(queueFamily.queueFlags & VK_QUEUE_COMPUTE_BIT) && !(queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT))
5503 break;
5504 else
5505 queueFamilyIndex++;
5506 }
5507 }
5508
5509 // One should be found, because this is checked in "checkSupport" function.
5510 DE_ASSERT(queueFamilyIndex < queueFamilies.size());
5511
5512 const float queuePriority = 1.0f;
5513 const VkDeviceQueueCreateInfo deviceQueueCreateInfos[] = {
5514 {
5515 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // VkStructureType sType;
5516 DE_NULL, // const void* pNext;
5517 (VkDeviceQueueCreateFlags)0u, // VkDeviceQueueCreateFlags flags;
5518 context.getUniversalQueueFamilyIndex(), // uint32_t queueFamilyIndex;
5519 1u, // uint32_t queueCount;
5520 &queuePriority, // const float* pQueuePriorities;
5521 },
5522 {
5523 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // VkStructureType sType;
5524 DE_NULL, // const void* pNext;
5525 (VkDeviceQueueCreateFlags)0u, // VkDeviceQueueCreateFlags flags;
5526 queueFamilyIndex, // uint32_t queueFamilyIndex;
5527 1u, // uint32_t queueCount;
5528 &queuePriority, // const float* pQueuePriorities;
5529 }
5530 };
5531
5532 // context.getDeviceExtensions() returns supported device extension including extensions that have been promoted to
5533 // Vulkan core. The core extensions must be removed from the list.
5534 std::vector<const char*> coreExtensions;
5535 getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
5536 std::vector<std::string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));
5537
5538 std::vector<const char*> extensionNames;
5539 extensionNames.reserve(nonCoreExtensions.size());
5540 for (const std::string& extension : nonCoreExtensions)
5541 extensionNames.push_back(extension.c_str());
5542
5543 const auto& deviceFeatures2 = context.getDeviceFeatures2();
5544
5545 const void *pNext = &deviceFeatures2;
5546 #ifdef CTS_USES_VULKANSC
5547 VkDeviceObjectReservationCreateInfo memReservationInfo = context.getTestContext().getCommandLine().isSubProcess() ? context.getResourceInterface()->getStatMax() : resetDeviceObjectReservationCreateInfo();
5548 memReservationInfo.pNext = pNext;
5549 pNext = &memReservationInfo;
5550
5551 VkPipelineCacheCreateInfo pcCI;
5552 std::vector<VkPipelinePoolSize> poolSizes;
5553 if (context.getTestContext().getCommandLine().isSubProcess())
5554 {
5555 if (context.getResourceInterface()->getCacheDataSize() > 0)
5556 {
5557 pcCI =
5558 {
5559 VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, // VkStructureType sType;
5560 DE_NULL, // const void* pNext;
5561 VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT |
5562 VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT, // VkPipelineCacheCreateFlags flags;
5563 context.getResourceInterface()->getCacheDataSize(), // deUintptr initialDataSize;
5564 context.getResourceInterface()->getCacheData() // const void* pInitialData;
5565 };
5566 memReservationInfo.pipelineCacheCreateInfoCount = 1;
5567 memReservationInfo.pPipelineCacheCreateInfos = &pcCI;
5568 }
5569 poolSizes = context.getResourceInterface()->getPipelinePoolSizes();
5570 if (!poolSizes.empty())
5571 {
5572 memReservationInfo.pipelinePoolSizeCount = deUint32(poolSizes.size());
5573 memReservationInfo.pPipelinePoolSizes = poolSizes.data();
5574 }
5575 }
5576 #endif // CTS_USES_VULKANSC
5577
5578 const VkDeviceCreateInfo deviceCreateInfo =
5579 {
5580 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // VkStructureType sType;
5581 pNext, // const void* pNext;
5582 (VkDeviceCreateFlags)0u, // VkDeviceCreateFlags flags;
5583 DE_LENGTH_OF_ARRAY(deviceQueueCreateInfos), // uint32_t queueCreateInfoCount;
5584 deviceQueueCreateInfos, // const VkDeviceQueueCreateInfo* pQueueCreateInfos;
5585 0u, // uint32_t enabledLayerCount;
5586 DE_NULL, // const char* const* ppEnabledLayerNames;
5587 static_cast<uint32_t>(extensionNames.size()), // uint32_t enabledExtensionCount;
5588 extensionNames.data(), // const char* const* ppEnabledExtensionNames;
5589 DE_NULL, // const VkPhysicalDeviceFeatures* pEnabledFeatures;
5590 };
5591
5592 #ifndef CTS_USES_VULKANSC
5593 return vkt::createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), context.getPlatformInterface(), context.getInstance(), instanceDriver, physicalDevice, &deviceCreateInfo);
5594 #else
5595 return vkt::createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), context.getPlatformInterface(), customInstance, instanceDriver, physicalDevice, &deviceCreateInfo);
5596 #endif // CTS_USES_VULKANSC
5597 }
5598
5599 class ResolveImageToImage : public CopiesAndBlittingTestInstance
5600 {
5601 public:
5602 ResolveImageToImage (Context& context,
5603 TestParams params,
5604 ResolveImageToImageOptions options);
5605 virtual tcu::TestStatus iterate (void);
shouldVerifyIntermediateResults(ResolveImageToImageOptions option)5606 static inline bool shouldVerifyIntermediateResults (ResolveImageToImageOptions option)
5607 {
5608 return option == COPY_MS_IMAGE_TO_MS_IMAGE || option == COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE || option == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE || option == COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE || option == COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER;
5609 }
~ResolveImageToImage()5610 ~ResolveImageToImage()
5611 {
5612 // Destroy the command pool (and free the related command buffer).
5613 // This must be done before the m_customDevice is destroyed.
5614 m_cmdBuffer = Move<VkCommandBuffer>();
5615 m_cmdPool = Move<VkCommandPool>();
5616 }
5617 protected:
5618 virtual tcu::TestStatus checkTestResult (tcu::ConstPixelBufferAccess result);
5619 void copyMSImageToMSImage (deUint32 copyArraySize);
5620 tcu::TestStatus checkIntermediateCopy (void);
5621 private:
5622 const CustomInstance m_customInstance;
5623 Move<VkDevice> m_customDevice;
5624
5625 #ifndef CTS_USES_VULKANSC
5626 de::MovePtr<vk::DeviceDriver> m_deviceDriver;
5627 #else
5628 de::MovePtr<DeviceDriverSC, DeinitDeviceDeleter> m_deviceDriver;
5629 #endif // CTS_USES_VULKANSC
5630
5631 Move<VkCommandPool> m_alternativeCmdPool;
5632 Move<VkCommandBuffer> m_alternativeCmdBuffer;
5633 VkQueue m_alternativeQueue;
5634 uint32_t m_alternativeQueueFamilyIndex;
5635 de::MovePtr<vk::Allocator> m_alternativeAllocator;
5636 Move<VkImage> m_multisampledImage;
5637 de::MovePtr<Allocation> m_multisampledImageAlloc;
5638
5639 Move<VkImage> m_destination;
5640 de::MovePtr<Allocation> m_destinationImageAlloc;
5641
5642 Move<VkImage> m_multisampledCopyImage;
5643 de::MovePtr<Allocation> m_multisampledCopyImageAlloc;
5644 Move<VkImage> m_multisampledCopyNoCabImage;
5645 de::MovePtr<Allocation> m_multisampledCopyImageNoCabAlloc;
5646
5647 const ResolveImageToImageOptions m_options;
5648
5649 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src,
5650 tcu::PixelBufferAccess dst,
5651 CopyRegion region,
5652 deUint32 mipLevel = 0u);
5653 };
5654
ResolveImageToImage(Context & context,TestParams params,const ResolveImageToImageOptions options)5655 ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, const ResolveImageToImageOptions options)
5656 : CopiesAndBlittingTestInstance (context, params)
5657 , m_customInstance (createCustomInstanceFromContext(context))
5658 , m_options (options)
5659 {
5660
5661
5662 #ifdef CTS_USES_VULKANSC
5663 const InstanceInterface& vki = m_customInstance.getDriver();
5664 #else
5665 const InstanceInterface& vki = m_context.getInstanceInterface();
5666 #endif // CTS_USES_VULKANSC
5667
5668 uint32_t queueFamilyIndex = 0;
5669 // Create custom device for compute and transfer only queue tests.
5670 if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER)
5671 {
5672 // 'queueFamilyIndex' will be updated in 'createCustomDevice()' to match the requested queue type.
5673 #ifdef CTS_USES_VULKANSC
5674 m_customDevice = createCustomDevice(context, m_options, m_customInstance, queueFamilyIndex);
5675 #else
5676 m_customDevice = createCustomDevice(context, m_options, queueFamilyIndex);
5677 #endif // CTS_USES_VULKANSC
5678 m_device = m_customDevice.get();
5679
5680 #ifndef CTS_USES_VULKANSC
5681 m_deviceDriver = de::MovePtr<DeviceDriver>(new DeviceDriver(context.getPlatformInterface(), m_customInstance, m_device));
5682 #else
5683 m_deviceDriver = de::MovePtr<DeviceDriverSC, DeinitDeviceDeleter>(new DeviceDriverSC(context.getPlatformInterface(), m_customInstance, m_device, context.getTestContext().getCommandLine(), context.getResourceInterface(), context.getDeviceVulkanSC10Properties(), context.getDeviceProperties()), vk::DeinitDeviceDeleter(context.getResourceInterface().get(), m_device));
5684 #endif // CTS_USES_VULKANSC
5685
5686 m_queue = getDeviceQueue(m_context.getDeviceInterface(), m_device, context.getUniversalQueueFamilyIndex(), 0u);
5687 m_alternativeQueue = getDeviceQueue(m_context.getDeviceInterface(), m_device, queueFamilyIndex, 0u);
5688 }
5689
5690 m_alternativeQueueFamilyIndex = queueFamilyIndex;
5691
5692 #ifndef CTS_USES_VULKANSC
5693 const DeviceInterface& vk = m_context.getDeviceInterface();
5694 #else
5695 const DeviceInterface& vk = (DE_NULL != m_deviceDriver) ? *m_deviceDriver : m_context.getDeviceInterface();
5696 #endif // CTS_USES_VULKANSC
5697
5698 m_alternativeAllocator = de::MovePtr<Allocator>(new SimpleAllocator(vk, m_device, getPhysicalDeviceMemoryProperties(vki, context.getPhysicalDevice())));
5699 m_allocator = m_alternativeAllocator.get();
5700
5701 // Release the command buffer.
5702 m_cmdBuffer = Move<VkCommandBuffer>();
5703
5704 // Create a new command pool and allocate a command buffer with universal queue family index and destroy the old one.
5705 m_cmdPool = createCommandPool(vk, m_device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, context.getUniversalQueueFamilyIndex());
5706 m_cmdBuffer = allocateCommandBuffer(vk, m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
5707
5708 // Create a command pool and allocate a command buffer from the queue family supporting compute / transfer capabilities.
5709 m_alternativeCmdPool = createCommandPool(vk, m_device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
5710 m_alternativeCmdBuffer = allocateCommandBuffer(vk, m_device, *m_alternativeCmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
5711
5712 Allocator& memAlloc = *m_allocator;
5713 const VkPhysicalDevice vkPhysDevice = m_context.getPhysicalDevice();
5714 const VkDevice vkDevice = m_device;
5715 const VkComponentMapping componentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
5716 Move<VkRenderPass> renderPass;
5717
5718 Move<VkShaderModule> vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
5719 Move<VkShaderModule> fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
5720 std::vector<tcu::Vec4> vertices;
5721
5722 Move<VkBuffer> vertexBuffer;
5723 de::MovePtr<Allocation> vertexBufferAlloc;
5724
5725 Move<VkPipelineLayout> pipelineLayout;
5726 Move<VkPipeline> graphicsPipeline;
5727
5728 const VkSampleCountFlagBits rasterizationSamples = m_params.samples;
5729
5730 // Create color image.
5731 {
5732 VkImageCreateInfo colorImageParams =
5733 {
5734 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
5735 DE_NULL, // const void* pNext;
5736 getCreateFlags(m_params.src.image), // VkImageCreateFlags flags;
5737 m_params.src.image.imageType, // VkImageType imageType;
5738 m_params.src.image.format, // VkFormat format;
5739 getExtent3D(m_params.src.image), // VkExtent3D extent;
5740 1u, // deUint32 mipLevels;
5741 getArraySize(m_params.src.image), // deUint32 arrayLayers;
5742 rasterizationSamples, // VkSampleCountFlagBits samples;
5743 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
5744 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT // VkImageUsageFlags usage;
5745 | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
5746 | VK_IMAGE_USAGE_TRANSFER_DST_BIT
5747 | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
5748 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
5749 0u, // deUint32 queueFamilyIndexCount;
5750 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
5751 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
5752 };
5753
5754 m_multisampledImage = createImage(vk, vkDevice, &colorImageParams);
5755 VkMemoryRequirements req = getImageMemoryRequirements(vk, vkDevice, *m_multisampledImage);
5756
5757 // Allocate and bind color image memory.
5758 deUint32 offset = m_params.imageOffset ? static_cast<deUint32>(req.alignment) : 0u;
5759 m_multisampledImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledImage, MemoryRequirement::Any,
5760 memAlloc, m_params.allocationKind, offset);
5761
5762 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledImage, m_multisampledImageAlloc->getMemory(), offset));
5763
5764 switch (m_options)
5765 {
5766 case COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION:
5767 case COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE:
5768 case COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER:
5769 case COPY_MS_IMAGE_TO_MS_IMAGE:
5770 {
5771 colorImageParams.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
5772 m_multisampledCopyImage = createImage(vk, vkDevice, &colorImageParams);
5773 // Allocate and bind color image memory.
5774 m_multisampledCopyImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
5775 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
5776 break;
5777 }
5778 case COPY_MS_IMAGE_LAYER_TO_MS_IMAGE:
5779 case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
5780 {
5781 colorImageParams.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
5782 colorImageParams.arrayLayers = getArraySize(m_params.dst.image);
5783 m_multisampledCopyImage = createImage(vk, vkDevice, &colorImageParams);
5784 // Allocate and bind color image memory.
5785 m_multisampledCopyImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
5786 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
5787 break;
5788 }
5789 case COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB:
5790 {
5791 colorImageParams.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
5792 colorImageParams.arrayLayers = getArraySize(m_params.dst.image);
5793 m_multisampledCopyImage = createImage(vk, vkDevice, &colorImageParams);
5794 m_multisampledCopyNoCabImage = createImage(vk, vkDevice, &colorImageParams);
5795 // Allocate and bind color image memory.
5796 m_multisampledCopyImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
5797 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
5798 m_multisampledCopyImageNoCabAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyNoCabImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
5799 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyNoCabImage, m_multisampledCopyImageNoCabAlloc->getMemory(), m_multisampledCopyImageNoCabAlloc->getOffset()));
5800 break;
5801 }
5802
5803 default :
5804 break;
5805 }
5806 }
5807
5808 // Create destination image.
5809 {
5810 const VkImageCreateInfo destinationImageParams =
5811 {
5812 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
5813 DE_NULL, // const void* pNext;
5814 getCreateFlags(m_params.dst.image), // VkImageCreateFlags flags;
5815 m_params.dst.image.imageType, // VkImageType imageType;
5816 m_params.dst.image.format, // VkFormat format;
5817 getExtent3D(m_params.dst.image), // VkExtent3D extent;
5818 1u, // deUint32 mipLevels;
5819 getArraySize(m_params.dst.image), // deUint32 arraySize;
5820 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
5821 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
5822 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
5823 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
5824 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
5825 0u, // deUint32 queueFamilyIndexCount;
5826 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
5827 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
5828 };
5829
5830 m_destination = createImage(vk, vkDevice, &destinationImageParams);
5831 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
5832 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
5833 }
5834
5835 // Barriers for image clearing.
5836 std::vector<VkImageMemoryBarrier> srcImageBarriers;
5837
5838 const VkImageMemoryBarrier m_multisampledImageBarrier =
5839 {
5840 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
5841 DE_NULL, // const void* pNext;
5842 0u, // VkAccessFlags srcAccessMask;
5843 VK_ACCESS_MEMORY_WRITE_BIT, // VkAccessFlags dstAccessMask;
5844 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
5845 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
5846 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
5847 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
5848 m_multisampledImage.get(), // VkImage image;
5849 { // VkImageSubresourceRange subresourceRange;
5850 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
5851 0u, // deUint32 baseMipLevel;
5852 1u, // deUint32 mipLevels;
5853 0u, // deUint32 baseArraySlice;
5854 getArraySize(m_params.src.image) // deUint32 arraySize;
5855 }
5856 };
5857 const VkImageMemoryBarrier m_multisampledCopyImageBarrier =
5858 {
5859 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
5860 DE_NULL, // const void* pNext;
5861 0u, // VkAccessFlags srcAccessMask;
5862 VK_ACCESS_MEMORY_WRITE_BIT, // VkAccessFlags dstAccessMask;
5863 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
5864 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
5865 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
5866 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
5867 m_multisampledCopyImage.get(), // VkImage image;
5868 { // VkImageSubresourceRange subresourceRange;
5869 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
5870 0u, // deUint32 baseMipLevel;
5871 1u, // deUint32 mipLevels;
5872 0u, // deUint32 baseArraySlice;
5873 getArraySize(m_params.dst.image) // deUint32 arraySize;
5874 }
5875 };
5876 const VkImageMemoryBarrier m_multisampledCopyImageNoCabBarrier =
5877 {
5878 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
5879 DE_NULL, // const void* pNext;
5880 0u, // VkAccessFlags srcAccessMask;
5881 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
5882 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
5883 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
5884 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
5885 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
5886 m_multisampledCopyNoCabImage.get(), // VkImage image;
5887 { // VkImageSubresourceRange subresourceRange;
5888 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
5889 0u, // deUint32 baseMipLevel;
5890 1u, // deUint32 mipLevels;
5891 0u, // deUint32 baseArraySlice;
5892 getArraySize(m_params.dst.image) // deUint32 arraySize;
5893 }
5894 };
5895
5896 // Only use one barrier if no options have been given.
5897 if (m_options != DE_NULL)
5898 {
5899 srcImageBarriers.push_back(m_multisampledImageBarrier);
5900 srcImageBarriers.push_back(m_multisampledCopyImageBarrier);
5901 // Add the third barrier if option is as below.
5902 if(m_options == COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB)
5903 srcImageBarriers.push_back(m_multisampledCopyImageNoCabBarrier);
5904 }
5905 else
5906 {
5907 srcImageBarriers.push_back(m_multisampledImageBarrier);
5908 }
5909
5910 // Create render pass.
5911 {
5912 const VkAttachmentDescription attachmentDescription =
5913 {
5914 0u, // VkAttachmentDescriptionFlags flags;
5915 m_params.src.image.format, // VkFormat format;
5916 rasterizationSamples, // VkSampleCountFlagBits samples;
5917 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
5918 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
5919 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
5920 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
5921 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout initialLayout;
5922 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL // VkImageLayout finalLayout;
5923 };
5924
5925 const VkAttachmentReference colorAttachmentReference =
5926 {
5927 0u, // deUint32 attachment;
5928 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
5929 };
5930
5931 const VkSubpassDescription subpassDescription =
5932 {
5933 0u, // VkSubpassDescriptionFlags flags;
5934 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
5935 0u, // deUint32 inputAttachmentCount;
5936 DE_NULL, // const VkAttachmentReference* pInputAttachments;
5937 1u, // deUint32 colorAttachmentCount;
5938 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments;
5939 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
5940 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
5941 0u, // deUint32 preserveAttachmentCount;
5942 DE_NULL // const VkAttachmentReference* pPreserveAttachments;
5943 };
5944
5945 // Subpass dependency is used to synchronize the memory access of the image clear and color attachment write in some test cases.
5946 const VkSubpassDependency subpassDependency =
5947 {
5948 VK_SUBPASS_EXTERNAL, //uint32_t srcSubpass;
5949 0u, //uint32_t dstSubpass;
5950 VK_PIPELINE_STAGE_TRANSFER_BIT, //VkPipelineStageFlags srcStageMask;
5951 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, //VkPipelineStageFlags dstStageMask;
5952 VK_ACCESS_TRANSFER_WRITE_BIT, //VkAccessFlags srcAccessMask;
5953 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, //VkAccessFlags dstAccessMask;
5954 0u //VkDependencyFlags dependencyFlags;
5955 };
5956
5957 const deBool useSubpassDependency = m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION;
5958 const VkRenderPassCreateInfo renderPassParams =
5959 {
5960 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
5961 DE_NULL, // const void* pNext;
5962 0u, // VkRenderPassCreateFlags flags;
5963 1u, // deUint32 attachmentCount;
5964 &attachmentDescription, // const VkAttachmentDescription* pAttachments;
5965 1u, // deUint32 subpassCount;
5966 &subpassDescription, // const VkSubpassDescription* pSubpasses;
5967 useSubpassDependency ? 1u : 0u, // deUint32 dependencyCount;
5968 &subpassDependency // const VkSubpassDependency* pDependencies;
5969 };
5970
5971 renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
5972 }
5973
5974 // Create pipeline layout
5975 {
5976 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
5977 {
5978 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
5979 DE_NULL, // const void* pNext;
5980 0u, // VkPipelineLayoutCreateFlags flags;
5981 0u, // deUint32 setLayoutCount;
5982 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
5983 0u, // deUint32 pushConstantRangeCount;
5984 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
5985 };
5986
5987 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
5988 }
5989
5990 // Create upper half triangle.
5991 {
5992 const tcu::Vec4 a (-1.0, -1.0, 0.0, 1.0);
5993 const tcu::Vec4 b (1.0, -1.0, 0.0, 1.0);
5994 const tcu::Vec4 c (1.0, 1.0, 0.0, 1.0);
5995 // Add triangle.
5996 vertices.push_back(a);
5997 vertices.push_back(c);
5998 vertices.push_back(b);
5999 }
6000
6001 // Create vertex buffer.
6002 {
6003 const VkDeviceSize vertexDataSize = vertices.size() * sizeof(tcu::Vec4);
6004 const VkBufferCreateInfo vertexBufferParams =
6005 {
6006 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
6007 DE_NULL, // const void* pNext;
6008 0u, // VkBufferCreateFlags flags;
6009 vertexDataSize, // VkDeviceSize size;
6010 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
6011 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
6012 0u, // deUint32 queueFamilyIndexCount;
6013 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
6014 };
6015
6016 vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
6017 vertexBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *vertexBuffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
6018 VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset()));
6019
6020 // Load vertices into vertex buffer.
6021 deMemcpy(vertexBufferAlloc->getHostPtr(), vertices.data(), (size_t)vertexDataSize);
6022 flushAlloc(vk, vkDevice, *vertexBufferAlloc);
6023 }
6024
6025 {
6026 Move<VkFramebuffer> framebuffer;
6027 Move<VkImageView> sourceAttachmentView;
6028
6029 uint32_t baseArrayLayer = m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE ? 2u : 0u;
6030
6031 // Create color attachment view.
6032 {
6033 const VkImageViewCreateInfo colorAttachmentViewParams =
6034 {
6035 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
6036 DE_NULL, // const void* pNext;
6037 0u, // VkImageViewCreateFlags flags;
6038 *m_multisampledImage, // VkImage image;
6039 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
6040 m_params.src.image.format, // VkFormat format;
6041 componentMappingRGBA, // VkComponentMapping components;
6042 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, baseArrayLayer, 1u } // VkImageSubresourceRange subresourceRange;
6043 };
6044 sourceAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
6045 }
6046
6047 // Create framebuffer
6048 {
6049 const VkFramebufferCreateInfo framebufferParams =
6050 {
6051 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
6052 DE_NULL, // const void* pNext;
6053 0u, // VkFramebufferCreateFlags flags;
6054 *renderPass, // VkRenderPass renderPass;
6055 1u, // deUint32 attachmentCount;
6056 &sourceAttachmentView.get(), // const VkImageView* pAttachments;
6057 m_params.src.image.extent.width, // deUint32 width;
6058 m_params.src.image.extent.height, // deUint32 height;
6059 1u // deUint32 layers;
6060 };
6061
6062 framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
6063 }
6064
6065 // Create pipeline
6066 {
6067 const std::vector<VkViewport> viewports (1, makeViewport(m_params.src.image.extent));
6068 const std::vector<VkRect2D> scissors (1, makeRect2D(m_params.src.image.extent));
6069
6070 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
6071 {
6072 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
6073 DE_NULL, // const void* pNext;
6074 0u, // VkPipelineMultisampleStateCreateFlags flags;
6075 rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples;
6076 VK_FALSE, // VkBool32 sampleShadingEnable;
6077 0.0f, // float minSampleShading;
6078 DE_NULL, // const VkSampleMask* pSampleMask;
6079 VK_FALSE, // VkBool32 alphaToCoverageEnable;
6080 VK_FALSE // VkBool32 alphaToOneEnable;
6081 };
6082
6083 graphicsPipeline = makeGraphicsPipeline(vk, // const DeviceInterface& vk
6084 vkDevice, // const VkDevice device
6085 *pipelineLayout, // const VkPipelineLayout pipelineLayout
6086 *vertexShaderModule, // const VkShaderModule vertexShaderModule
6087 DE_NULL, // const VkShaderModule tessellationControlModule
6088 DE_NULL, // const VkShaderModule tessellationEvalModule
6089 DE_NULL, // const VkShaderModule geometryShaderModule
6090 *fragmentShaderModule, // const VkShaderModule fragmentShaderModule
6091 *renderPass, // const VkRenderPass renderPass
6092 viewports, // const std::vector<VkViewport>& viewports
6093 scissors, // const std::vector<VkRect2D>& scissors
6094 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
6095 0u, // const deUint32 subpass
6096 0u, // const deUint32 patchControlPoints
6097 DE_NULL, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
6098 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
6099 &multisampleStateParams); // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
6100 }
6101
6102 // Create command buffer
6103 {
6104 beginCommandBuffer(vk, *m_cmdBuffer, 0u);
6105
6106 if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION)
6107 {
6108 // Change the image layouts.
6109 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, (uint32_t)srcImageBarriers.size(), srcImageBarriers.data());
6110
6111 // Clear the 'm_multisampledImage'.
6112 {
6113 const VkClearColorValue clearValue = {{0.0f, 0.0f, 0.0f, 1.0f}};
6114 const auto clearRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, m_params.src.image.extent.depth);
6115 vk.cmdClearColorImage(*m_cmdBuffer, m_multisampledImage.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue, 1u, &clearRange);
6116 }
6117
6118 // Clear the 'm_multisampledCopyImage' with different color.
6119 {
6120 const VkClearColorValue clearValue = {{1.0f, 1.0f, 1.0f, 1.0f}};
6121 const auto clearRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, m_params.src.image.extent.depth);
6122 vk.cmdClearColorImage(*m_cmdBuffer, m_multisampledCopyImage.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue, 1u, &clearRange);
6123 }
6124 }
6125 else
6126 {
6127 // Change the image layouts.
6128 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, (uint32_t)srcImageBarriers.size(), srcImageBarriers.data());
6129 }
6130
6131 beginRenderPass(vk, *m_cmdBuffer, *renderPass, *framebuffer, makeRect2D(0, 0, m_params.src.image.extent.width, m_params.src.image.extent.height), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
6132
6133 const VkDeviceSize vertexBufferOffset = 0u;
6134
6135 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
6136 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
6137 vk.cmdDraw(*m_cmdBuffer, (deUint32)vertices.size(), 1, 0, 0);
6138
6139 endRenderPass(vk, *m_cmdBuffer);
6140 endCommandBuffer(vk, *m_cmdBuffer);
6141 }
6142
6143 // Queue submit.
6144 {
6145 submitCommandsAndWait (vk, vkDevice, m_queue, *m_cmdBuffer);
6146 m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
6147 }
6148 }
6149 }
6150
iterate(void)6151 tcu::TestStatus ResolveImageToImage::iterate (void)
6152 {
6153 const tcu::TextureFormat srcTcuFormat = mapVkFormat(m_params.src.image.format);
6154 const tcu::TextureFormat dstTcuFormat = mapVkFormat(m_params.dst.image.format);
6155
6156 // upload the destination image
6157 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
6158 (int)m_params.dst.image.extent.width,
6159 (int)m_params.dst.image.extent.height,
6160 (int)m_params.dst.image.extent.depth));
6161 generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
6162 uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
6163
6164 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
6165 (int)m_params.src.image.extent.width,
6166 (int)m_params.src.image.extent.height,
6167 (int)m_params.dst.image.extent.depth));
6168
6169 generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.dst.image.extent.depth, FILL_MODE_MULTISAMPLE);
6170 generateExpectedResult();
6171
6172 VkImage sourceImage = m_multisampledImage.get();
6173 deUint32 sourceArraySize = getArraySize(m_params.src.image);
6174
6175 switch (m_options)
6176 {
6177 case COPY_MS_IMAGE_LAYER_TO_MS_IMAGE:
6178 case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
6179 // Duplicate the multisampled image to a multisampled image array
6180 sourceArraySize = getArraySize(m_params.dst.image); // fall through
6181 case COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION:
6182 case COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB:
6183 case COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE:
6184 case COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER:
6185 case COPY_MS_IMAGE_TO_MS_IMAGE:
6186 copyMSImageToMSImage(sourceArraySize);
6187 sourceImage = m_multisampledCopyImage.get();
6188 break;
6189 default:
6190 break;
6191 }
6192
6193 const DeviceInterface& vk = m_context.getDeviceInterface();
6194 const VkDevice vkDevice = m_device;
6195 const VkQueue queue = m_queue;
6196
6197 std::vector<VkImageResolve> imageResolves;
6198 std::vector<VkImageResolve2KHR> imageResolves2KHR;
6199 for (CopyRegion region : m_params.regions)
6200 {
6201 // If copying multiple regions, make sure that the same regions are
6202 // used for resolving as the ones used for copying.
6203 if(m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION)
6204 {
6205 VkExtent3D partialExtent = {getExtent3D(m_params.src.image).width / 2,
6206 getExtent3D(m_params.src.image).height / 2,
6207 getExtent3D(m_params.src.image).depth};
6208
6209 const VkImageResolve imageResolve =
6210 {
6211 region.imageResolve.srcSubresource, // VkImageSubresourceLayers srcSubresource;
6212 region.imageResolve.dstOffset, // VkOffset3D srcOffset;
6213 region.imageResolve.dstSubresource, // VkImageSubresourceLayers dstSubresource;
6214 region.imageResolve.dstOffset, // VkOffset3D dstOffset;
6215 partialExtent, // VkExtent3D extent;
6216 };
6217
6218 if (m_params.extensionUse == EXTENSION_USE_NONE)
6219 {
6220 imageResolves.push_back(imageResolve);
6221 }
6222 else
6223 {
6224 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6225 imageResolves2KHR.push_back(convertvkImageResolveTovkImageResolve2KHR(imageResolve));
6226 }
6227 }
6228 else
6229 {
6230 if (m_params.extensionUse == EXTENSION_USE_NONE)
6231 {
6232 imageResolves.push_back(region.imageResolve);
6233 }
6234 else
6235 {
6236 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6237 imageResolves2KHR.push_back(convertvkImageResolveTovkImageResolve2KHR(region.imageResolve));
6238 }
6239 }
6240 }
6241
6242 const VkImageMemoryBarrier imageBarriers[] =
6243 {
6244 // source image
6245 {
6246 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
6247 DE_NULL, // const void* pNext;
6248 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask;
6249 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
6250 m_options == NO_OPTIONAL_OPERATION ?
6251 m_params.dst.image.operationLayout :
6252 m_params.src.image.operationLayout, // VkImageLayout oldLayout;
6253 m_params.src.image.operationLayout, // VkImageLayout newLayout;
6254 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
6255 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
6256 sourceImage, // VkImage image;
6257 { // VkImageSubresourceRange subresourceRange;
6258 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
6259 0u, // deUint32 baseMipLevel;
6260 1u, // deUint32 mipLevels;
6261 0u, // deUint32 baseArraySlice;
6262 sourceArraySize // deUint32 arraySize;
6263 }
6264 },
6265 // destination image
6266 {
6267 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
6268 DE_NULL, // const void* pNext;
6269 0u, // VkAccessFlags srcAccessMask;
6270 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
6271 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
6272 m_params.dst.image.operationLayout, // VkImageLayout newLayout;
6273 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
6274 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
6275 m_destination.get(), // VkImage image;
6276 { // VkImageSubresourceRange subresourceRange;
6277 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
6278 0u, // deUint32 baseMipLevel;
6279 1u, // deUint32 mipLevels;
6280 0u, // deUint32 baseArraySlice;
6281 getArraySize(m_params.dst.image) // deUint32 arraySize;
6282 }
6283 },
6284 };
6285
6286 const VkImageMemoryBarrier postImageBarrier =
6287 {
6288 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
6289 DE_NULL, // const void* pNext;
6290 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
6291 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
6292 m_params.dst.image.operationLayout, // VkImageLayout oldLayout;
6293 m_params.dst.image.operationLayout, // VkImageLayout newLayout;
6294 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
6295 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
6296 m_destination.get(), // VkImage image;
6297 { // VkImageSubresourceRange subresourceRange;
6298 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
6299 0u, // deUint32 baseMipLevel;
6300 1u, // deUint32 mipLevels;
6301 0u, // deUint32 baseArraySlice;
6302 getArraySize(m_params.dst.image) // deUint32 arraySize;
6303 }
6304 };
6305
6306 beginCommandBuffer(vk, *m_cmdBuffer);
6307 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers);
6308
6309 if (m_params.extensionUse == EXTENSION_USE_NONE)
6310 {
6311 vk.cmdResolveImage(*m_cmdBuffer, sourceImage, m_params.src.image.operationLayout, m_destination.get(), m_params.dst.image.operationLayout, (deUint32)m_params.regions.size(), imageResolves.data());
6312 }
6313 #ifndef CTS_USES_VULKANSC
6314 else
6315 {
6316 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6317 const VkResolveImageInfo2KHR ResolveImageInfo2KHR =
6318 {
6319 VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2_KHR, // VkStructureType sType;
6320 DE_NULL, // const void* pNext;
6321 sourceImage, // VkImage srcImage;
6322 m_params.src.image.operationLayout, // VkImageLayout srcImageLayout;
6323 m_destination.get(), // VkImage dstImage;
6324 m_params.dst.image.operationLayout, // VkImageLayout dstImageLayout;
6325 (deUint32)m_params.regions.size(), // uint32_t regionCount;
6326 imageResolves2KHR.data() // const VkImageResolve2KHR* pRegions;
6327 };
6328 vk.cmdResolveImage2(*m_cmdBuffer, &ResolveImageInfo2KHR);
6329 }
6330 #endif // CTS_USES_VULKANSC
6331
6332 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
6333 endCommandBuffer(vk, *m_cmdBuffer);
6334 submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
6335 m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
6336
6337 de::MovePtr<tcu::TextureLevel> resultTextureLevel = readImage(*m_destination, m_params.dst.image);
6338
6339 if (shouldVerifyIntermediateResults(m_options))
6340 {
6341 // Verify the intermediate multisample copy operation happens properly instead of, for example, shuffling samples around or
6342 // resolving the image and giving every sample the same value.
6343 const auto intermediateResult = checkIntermediateCopy();
6344 if (intermediateResult.getCode() != QP_TEST_RESULT_PASS)
6345 return intermediateResult;
6346 }
6347
6348 return checkTestResult(resultTextureLevel->getAccess());
6349 }
6350
checkTestResult(tcu::ConstPixelBufferAccess result)6351 tcu::TestStatus ResolveImageToImage::checkTestResult (tcu::ConstPixelBufferAccess result)
6352 {
6353 const tcu::ConstPixelBufferAccess expected = m_expectedTextureLevel[0]->getAccess();
6354 const float fuzzyThreshold = 0.01f;
6355
6356 if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
6357 {
6358 // Check that all the layers that have not been written to are solid white.
6359 tcu::Vec4 expectedColor (1.0f, 1.0f, 1.0f, 1.0f);
6360 for (int arrayLayerNdx = 0; arrayLayerNdx < (int)getArraySize(m_params.dst.image) - 1; ++arrayLayerNdx)
6361 {
6362 const tcu::ConstPixelBufferAccess resultSub = getSubregion (result, 0u, 0u, arrayLayerNdx, result.getWidth(), result.getHeight(), 1u);
6363 if(resultSub.getPixel(0, 0) != expectedColor)
6364 return tcu::TestStatus::fail("CopiesAndBlitting test. Layers image differs from initialized value.");
6365 }
6366
6367 // Check that the layer that has been copied to is the same as the layer that has been copied from.
6368 const tcu::ConstPixelBufferAccess expectedSub = getSubregion (expected, 0u, 0u, 2u, expected.getWidth(), expected.getHeight(), 1u);
6369 const tcu::ConstPixelBufferAccess resultSub = getSubregion (result, 0u, 0u, 4u, result.getWidth(), result.getHeight(), 1u);
6370 if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedSub, resultSub, fuzzyThreshold, tcu::COMPARE_LOG_RESULT))
6371 return tcu::TestStatus::fail("CopiesAndBlitting test");
6372 }
6373 else
6374 {
6375 for (int arrayLayerNdx = 0; arrayLayerNdx < (int)getArraySize(m_params.dst.image); ++arrayLayerNdx)
6376 {
6377 const tcu::ConstPixelBufferAccess expectedSub = getSubregion (expected, 0u, 0u, arrayLayerNdx, expected.getWidth(), expected.getHeight(), 1u);
6378 const tcu::ConstPixelBufferAccess resultSub = getSubregion (result, 0u, 0u, arrayLayerNdx, result.getWidth(), result.getHeight(), 1u);
6379 if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedSub, resultSub, fuzzyThreshold, tcu::COMPARE_LOG_RESULT))
6380 return tcu::TestStatus::fail("CopiesAndBlitting test");
6381 }
6382 }
6383
6384 return tcu::TestStatus::pass("CopiesAndBlitting test");
6385 }
6386
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)6387 void ResolveImageToImage::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
6388 {
6389 DE_UNREF(mipLevel);
6390
6391 VkOffset3D srcOffset = region.imageResolve.srcOffset;
6392 srcOffset.z = region.imageResolve.srcSubresource.baseArrayLayer;
6393 VkOffset3D dstOffset = region.imageResolve.dstOffset;
6394 dstOffset.z = region.imageResolve.dstSubresource.baseArrayLayer;
6395 VkExtent3D extent = region.imageResolve.extent;
6396 extent.depth = region.imageResolve.srcSubresource.layerCount;
6397
6398 const tcu::ConstPixelBufferAccess srcSubRegion = getSubregion (src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
6399 // CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
6400 const tcu::PixelBufferAccess dstWithSrcFormat (srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
6401 const tcu::PixelBufferAccess dstSubRegion = getSubregion (dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
6402
6403 tcu::copy(dstSubRegion, srcSubRegion);
6404 }
6405
checkIntermediateCopy(void)6406 tcu::TestStatus ResolveImageToImage::checkIntermediateCopy (void)
6407 {
6408 const auto& vkd = m_context.getDeviceInterface();
6409 const auto device = m_device;
6410 const auto queue = m_queue;
6411 const auto queueIndex = m_context.getUniversalQueueFamilyIndex();
6412 auto& alloc = *m_allocator;
6413 const auto currentLayout = m_params.src.image.operationLayout;
6414 const auto numDstLayers = getArraySize(m_params.dst.image);
6415 const auto numInputAttachments = m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE ? 2u : numDstLayers + 1u; // For the source image.
6416 constexpr auto numSets = 2u; // 1 for the output buffer, 1 for the input attachments.
6417 const auto fbWidth = m_params.src.image.extent.width;
6418 const auto fbHeight = m_params.src.image.extent.height;
6419
6420 // Push constants.
6421 const std::array<int, 3> pushConstantData =
6422 {{
6423 static_cast<int>(fbWidth),
6424 static_cast<int>(fbHeight),
6425 static_cast<int>(m_params.samples),
6426 }};
6427 const auto pushConstantSize = static_cast<deUint32>(pushConstantData.size() * sizeof(decltype(pushConstantData)::value_type));
6428
6429 // Shader modules.
6430 const auto vertexModule = createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
6431 const auto verificationModule = createShaderModule(vkd, device, m_context.getBinaryCollection().get("verify"), 0u);
6432
6433 // Descriptor sets.
6434 DescriptorPoolBuilder poolBuilder;
6435 poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
6436 poolBuilder.addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, numInputAttachments);
6437 const auto descriptorPool = poolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, numSets);
6438
6439 DescriptorSetLayoutBuilder layoutBuilderBuffer;
6440 layoutBuilderBuffer.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
6441 const auto outputBufferSetLayout = layoutBuilderBuffer.build(vkd, device);
6442
6443 DescriptorSetLayoutBuilder layoutBuilderAttachments;
6444 for (deUint32 i = 0u; i < numInputAttachments; ++i)
6445 layoutBuilderAttachments.addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT);
6446 const auto inputAttachmentsSetLayout = layoutBuilderAttachments.build(vkd, device);
6447
6448 const auto descriptorSetBuffer = makeDescriptorSet(vkd, device, descriptorPool.get(), outputBufferSetLayout.get());
6449 const auto descriptorSetAttachments = makeDescriptorSet(vkd, device, descriptorPool.get(), inputAttachmentsSetLayout.get());
6450
6451 // Array with raw descriptor sets.
6452 const std::array<VkDescriptorSet, numSets> descriptorSets =
6453 {{
6454 descriptorSetBuffer.get(),
6455 descriptorSetAttachments.get(),
6456 }};
6457
6458 // Pipeline layout.
6459 const std::array<VkDescriptorSetLayout, numSets> setLayouts =
6460 {{
6461 outputBufferSetLayout.get(),
6462 inputAttachmentsSetLayout.get(),
6463 }};
6464
6465 const VkPushConstantRange pushConstantRange =
6466 {
6467 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
6468 0u, // deUint32 offset;
6469 pushConstantSize, // deUint32 size;
6470 };
6471
6472 const VkPipelineLayoutCreateInfo pipelineLayoutInfo =
6473 {
6474 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
6475 nullptr, // const void* pNext;
6476 0u, // VkPipelineLayoutCreateFlags flags;
6477 static_cast<deUint32>(setLayouts.size()), // deUint32 setLayoutCount;
6478 setLayouts.data(), // const VkDescriptorSetLayout* pSetLayouts;
6479 1u, // deUint32 pushConstantRangeCount;
6480 &pushConstantRange, // const VkPushConstantRange* pPushConstantRanges;
6481 };
6482
6483 const auto pipelineLayout = createPipelineLayout(vkd, device, &pipelineLayoutInfo);
6484
6485 // Render pass.
6486 const VkAttachmentDescription commonAttachmentDescription =
6487 {
6488 0u, // VkAttachmentDescriptionFlags flags;
6489 m_params.src.image.format, // VkFormat format;
6490 m_params.samples, // VkSampleCountFlagBits samples;
6491 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
6492 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
6493 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
6494 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
6495 currentLayout, // VkImageLayout initialLayout;
6496 currentLayout, // VkImageLayout finalLayout;
6497 };
6498 const std::vector<VkAttachmentDescription> attachmentDescriptions(numInputAttachments, commonAttachmentDescription);
6499
6500 std::vector<VkAttachmentReference> inputAttachmentReferences;
6501 inputAttachmentReferences.reserve(numInputAttachments);
6502 for (deUint32 i = 0u; i < numInputAttachments; ++i)
6503 {
6504 const VkAttachmentReference reference = { i, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL };
6505 inputAttachmentReferences.push_back(reference);
6506 }
6507
6508 const VkSubpassDescription subpassDescription =
6509 {
6510 0u, // VkSubpassDescriptionFlags flags;
6511 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
6512 static_cast<deUint32>(inputAttachmentReferences.size()), // deUint32 inputAttachmentCount;
6513 inputAttachmentReferences.data(), // const VkAttachmentReference* pInputAttachments;
6514 0u, // deUint32 colorAttachmentCount;
6515 nullptr, // const VkAttachmentReference* pColorAttachments;
6516 nullptr, // const VkAttachmentReference* pResolveAttachments;
6517 nullptr, // const VkAttachmentReference* pDepthStencilAttachment;
6518 0u, // deUint32 preserveAttachmentCount;
6519 nullptr, // const deUint32* pPreserveAttachments;
6520 };
6521
6522 const VkRenderPassCreateInfo renderPassInfo =
6523 {
6524 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
6525 nullptr, // const void* pNext;
6526 0u, // VkRenderPassCreateFlags flags;
6527 static_cast<deUint32>(attachmentDescriptions.size()), // deUint32 attachmentCount;
6528 attachmentDescriptions.data(), // const VkAttachmentDescription* pAttachments;
6529 1u, // deUint32 subpassCount;
6530 &subpassDescription, // const VkSubpassDescription* pSubpasses;
6531 0u, // deUint32 dependencyCount;
6532 nullptr, // const VkSubpassDependency* pDependencies;
6533 };
6534
6535 const auto renderPass = createRenderPass(vkd, device, &renderPassInfo);
6536
6537 // Framebuffer.
6538 std::vector<Move<VkImageView>> imageViews;
6539 std::vector<VkImageView> imageViewsRaw;
6540
6541
6542 if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
6543 {
6544 imageViews.push_back(makeImageView(vkd, device, m_multisampledImage.get(), VK_IMAGE_VIEW_TYPE_2D, m_params.src.image.format, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 2u, 1u)));
6545 imageViews.push_back(makeImageView(vkd, device, m_multisampledCopyImage.get(), VK_IMAGE_VIEW_TYPE_2D, m_params.src.image.format, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 4u, 1u)));
6546 }
6547 else
6548 {
6549 imageViews.push_back(makeImageView(vkd, device, m_multisampledImage.get(), VK_IMAGE_VIEW_TYPE_2D, m_params.src.image.format, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u)));
6550 for (deUint32 i = 0u; i < numDstLayers; ++i)
6551 {
6552 const auto subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, i, 1u);
6553 imageViews.push_back(makeImageView(vkd, device, m_multisampledCopyImage.get(), VK_IMAGE_VIEW_TYPE_2D, m_params.dst.image.format, subresourceRange));
6554 }
6555 }
6556
6557
6558 imageViewsRaw.reserve(imageViews.size());
6559 std::transform(begin(imageViews), end(imageViews), std::back_inserter(imageViewsRaw), [](const Move<VkImageView>& ptr) { return ptr.get(); });
6560
6561 const auto framebuffer = makeFramebuffer(vkd, device, renderPass.get(), static_cast<deUint32>(imageViewsRaw.size()), imageViewsRaw.data(), fbWidth, fbHeight);
6562
6563 // Storage buffer.
6564 const auto bufferCount = static_cast<size_t>(fbWidth * fbHeight * m_params.samples);
6565 const auto bufferSize = static_cast<VkDeviceSize>(bufferCount * sizeof(deInt32));
6566 BufferWithMemory buffer (vkd, device, alloc, makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible);
6567 auto& bufferAlloc = buffer.getAllocation();
6568 void* bufferData = bufferAlloc.getHostPtr();
6569
6570 // Update descriptor sets.
6571 DescriptorSetUpdateBuilder updater;
6572
6573 const auto bufferInfo = makeDescriptorBufferInfo(buffer.get(), 0ull, bufferSize);
6574 updater.writeSingle(descriptorSetBuffer.get(), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferInfo);
6575
6576 std::vector<VkDescriptorImageInfo> imageInfos;
6577 imageInfos.reserve(imageViewsRaw.size());
6578 for (size_t i = 0; i < imageViewsRaw.size(); ++i)
6579 imageInfos.push_back(makeDescriptorImageInfo(DE_NULL, imageViewsRaw[i], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL));
6580
6581 for (size_t i = 0; i < imageInfos.size(); ++i)
6582 updater.writeSingle(descriptorSetAttachments.get(), DescriptorSetUpdateBuilder::Location::binding(static_cast<deUint32>(i)), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &imageInfos[i]);
6583
6584 updater.update(vkd, device);
6585
6586 // Vertex buffer.
6587 std::vector<tcu::Vec4> fullScreenQuad;
6588 {
6589 // Full screen quad so every framebuffer pixel and sample location is verified by the shader.
6590 const tcu::Vec4 topLeft (-1.0f, -1.0f, 0.0f, 1.0f);
6591 const tcu::Vec4 topRight ( 1.0f, -1.0f, 0.0f, 1.0f);
6592 const tcu::Vec4 bottomLeft (-1.0f, 1.0f, 0.0f, 1.0f);
6593 const tcu::Vec4 bottomRight ( 1.0f, 1.0f, 0.0f, 1.0f);
6594
6595 fullScreenQuad.reserve(6u);
6596 fullScreenQuad.push_back(topLeft);
6597 fullScreenQuad.push_back(topRight);
6598 fullScreenQuad.push_back(bottomRight);
6599 fullScreenQuad.push_back(topLeft);
6600 fullScreenQuad.push_back(bottomRight);
6601 fullScreenQuad.push_back(bottomLeft);
6602 }
6603
6604 const auto vertexBufferSize = static_cast<VkDeviceSize>(fullScreenQuad.size() * sizeof(decltype(fullScreenQuad)::value_type));
6605 const auto vertexBufferInfo = makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
6606 const BufferWithMemory vertexBuffer (vkd, device, alloc, vertexBufferInfo, MemoryRequirement::HostVisible);
6607 const auto vertexBufferHandler = vertexBuffer.get();
6608 auto& vertexBufferAlloc = vertexBuffer.getAllocation();
6609 void* vertexBufferData = vertexBufferAlloc.getHostPtr();
6610 const VkDeviceSize vertexBufferOffset = 0ull;
6611
6612 deMemcpy(vertexBufferData, fullScreenQuad.data(), static_cast<size_t>(vertexBufferSize));
6613 flushAlloc(vkd, device, vertexBufferAlloc);
6614
6615 // Graphics pipeline.
6616 const std::vector<VkViewport> viewports (1, makeViewport(m_params.src.image.extent));
6617 const std::vector<VkRect2D> scissors (1, makeRect2D(m_params.src.image.extent));
6618
6619 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
6620 {
6621 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
6622 nullptr, // const void* pNext;
6623 0u, // VkPipelineMultisampleStateCreateFlags flags;
6624 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
6625 VK_FALSE, // VkBool32 sampleShadingEnable;
6626 0.0f, // float minSampleShading;
6627 nullptr, // const VkSampleMask* pSampleMask;
6628 VK_FALSE, // VkBool32 alphaToCoverageEnable;
6629 VK_FALSE // VkBool32 alphaToOneEnable;
6630 };
6631
6632 const auto graphicsPipeline = makeGraphicsPipeline(
6633 vkd, // const DeviceInterface& vk
6634 device, // const VkDevice device
6635 pipelineLayout.get(), // const VkPipelineLayout pipelineLayout
6636 vertexModule.get(), // const VkShaderModule vertexShaderModule
6637 DE_NULL, // const VkShaderModule tessellationControlModule
6638 DE_NULL, // const VkShaderModule tessellationEvalModule
6639 DE_NULL, // const VkShaderModule geometryShaderModule
6640 verificationModule.get(), // const VkShaderModule fragmentShaderModule
6641 renderPass.get(), // const VkRenderPass renderPass
6642 viewports, // const std::vector<VkViewport>& viewports
6643 scissors, // const std::vector<VkRect2D>& scissors
6644 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
6645 0u, // const deUint32 subpass
6646 0u, // const deUint32 patchControlPoints
6647 nullptr, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
6648 nullptr, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
6649 &multisampleStateParams); // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
6650
6651 // Command buffer.
6652 const auto cmdPool = makeCommandPool(vkd, device, queueIndex);
6653 const auto cmdBufferPtr = allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
6654 const auto cmdBuffer = cmdBufferPtr.get();
6655
6656 // Make sure multisample copy data is available to the fragment shader.
6657 const auto imagesBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT);
6658
6659 // Make sure verification buffer data is available on the host.
6660 const auto bufferBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
6661
6662 // Record and submit command buffer.
6663 beginCommandBuffer(vkd, cmdBuffer);
6664 vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 1u, &imagesBarrier, 0u, nullptr, 0u, nullptr);
6665 beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffer.get(), makeRect2D(m_params.src.image.extent));
6666 vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline.get());
6667 vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBufferHandler, &vertexBufferOffset);
6668 vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), VK_SHADER_STAGE_FRAGMENT_BIT, 0u, pushConstantSize, pushConstantData.data());
6669 vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u, static_cast<deUint32>(descriptorSets.size()), descriptorSets.data(), 0u, nullptr);
6670 vkd.cmdDraw(cmdBuffer, static_cast<deUint32>(fullScreenQuad.size()), 1u, 0u, 0u);
6671 endRenderPass(vkd, cmdBuffer);
6672 vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &bufferBarrier, 0u, nullptr, 0u, nullptr);
6673 endCommandBuffer(vkd, cmdBuffer);
6674 submitCommandsAndWait(vkd, device, queue, cmdBuffer);
6675 m_context.resetCommandPoolForVKSC(device, *cmdPool);
6676
6677 // Verify intermediate results.
6678 invalidateAlloc(vkd, device, bufferAlloc);
6679 std::vector<deInt32> outputFlags (bufferCount, 0);
6680 deMemcpy(outputFlags.data(), bufferData, static_cast<size_t>(bufferSize));
6681
6682 auto& log = m_context.getTestContext().getLog();
6683 log << tcu::TestLog::Message << "Verifying intermediate multisample copy results" << tcu::TestLog::EndMessage;
6684
6685 const auto sampleCount = static_cast<deUint32>(m_params.samples);
6686
6687 for (deUint32 x = 0u; x < fbWidth; ++x)
6688 for (deUint32 y = 0u; y < fbHeight; ++y)
6689 for (deUint32 s = 0u; s < sampleCount; ++s)
6690 {
6691 const auto index = (y * fbWidth + x) * sampleCount + s;
6692 if (!outputFlags[index])
6693 {
6694 std::ostringstream msg;
6695 msg << "Intermediate verification failed for coordinates (" << x << ", " << y << ") sample " << s;
6696 return tcu::TestStatus::fail(msg.str());
6697 }
6698 }
6699
6700 log << tcu::TestLog::Message << "Intermediate multisample copy verification passed" << tcu::TestLog::EndMessage;
6701 return tcu::TestStatus::pass("Pass");
6702 }
6703
copyMSImageToMSImage(deUint32 copyArraySize)6704 void ResolveImageToImage::copyMSImageToMSImage (deUint32 copyArraySize)
6705 {
6706 const bool useTwoQueues = m_options == COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER;
6707 const DeviceInterface& vk = m_context.getDeviceInterface();
6708 const VkDevice vkDevice = m_device;
6709 const VkQueue queue = useTwoQueues ? m_alternativeQueue : m_queue;
6710 const VkCommandBuffer commandBuffer = useTwoQueues ? m_alternativeCmdBuffer.get() : m_cmdBuffer.get();
6711 const VkCommandPool commandPool = useTwoQueues ? m_alternativeCmdPool.get() : m_cmdPool.get();
6712 const tcu::TextureFormat srcTcuFormat = mapVkFormat(m_params.src.image.format);
6713 std::vector<VkImageCopy> imageCopies;
6714 std::vector<VkImageCopy2KHR> imageCopies2KHR;
6715
6716 if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
6717 {
6718 const VkImageSubresourceLayers sourceSubresourceLayers =
6719 {
6720 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
6721 0u, // deUint32 mipLevel;
6722 2u, // deUint32 baseArrayLayer;
6723 1u // deUint32 layerCount;
6724 };
6725
6726 const VkImageSubresourceLayers destinationSubresourceLayers =
6727 {
6728 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;//getAspectFlags(dstTcuFormat)
6729 0u, // deUint32 mipLevel;
6730 4u, // deUint32 baseArrayLayer;
6731 1u // deUint32 layerCount;
6732 };
6733
6734 const VkImageCopy imageCopy =
6735 {
6736 sourceSubresourceLayers, // VkImageSubresourceLayers srcSubresource;
6737 {0, 0, 0}, // VkOffset3D srcOffset;
6738 destinationSubresourceLayers, // VkImageSubresourceLayers dstSubresource;
6739 {0, 0, 0}, // VkOffset3D dstOffset;
6740 getExtent3D(m_params.src.image), // VkExtent3D extent;
6741 };
6742
6743 if (m_params.extensionUse == EXTENSION_USE_NONE)
6744 {
6745 imageCopies.push_back(imageCopy);
6746 }
6747 else
6748 {
6749 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6750 imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
6751 }
6752 }
6753 else if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION)
6754 {
6755 VkExtent3D partialExtent = {getExtent3D(m_params.src.image).width / 2,
6756 getExtent3D(m_params.src.image).height / 2,
6757 getExtent3D(m_params.src.image).depth};
6758
6759 for (CopyRegion region : m_params.regions)
6760 {
6761 const VkImageCopy imageCopy =
6762 {
6763 region.imageResolve.srcSubresource, // VkImageSubresourceLayers srcSubresource;
6764 region.imageResolve.srcOffset, // VkOffset3D srcOffset;
6765 region.imageResolve.dstSubresource, // VkImageSubresourceLayers dstSubresource;
6766 region.imageResolve.dstOffset, // VkOffset3D dstOffset;
6767 partialExtent, // VkExtent3D extent;
6768 };
6769
6770 if (m_params.extensionUse == EXTENSION_USE_NONE)
6771 {
6772 imageCopies.push_back(imageCopy);
6773 }
6774 else
6775 {
6776 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6777 imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
6778 }
6779 }
6780 }
6781 else
6782 {
6783 for (deUint32 layerNdx = 0; layerNdx < copyArraySize; ++layerNdx)
6784 {
6785 const VkImageSubresourceLayers sourceSubresourceLayers =
6786 {
6787 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
6788 0u, // deUint32 mipLevel;
6789 0u, // deUint32 baseArrayLayer;
6790 1u // deUint32 layerCount;
6791 };
6792
6793 const VkImageSubresourceLayers destinationSubresourceLayers =
6794 {
6795 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;//getAspectFlags(dstTcuFormat)
6796 0u, // deUint32 mipLevel;
6797 layerNdx, // deUint32 baseArrayLayer;
6798 1u // deUint32 layerCount;
6799 };
6800
6801 const VkImageCopy imageCopy =
6802 {
6803 sourceSubresourceLayers, // VkImageSubresourceLayers srcSubresource;
6804 {0, 0, 0}, // VkOffset3D srcOffset;
6805 destinationSubresourceLayers, // VkImageSubresourceLayers dstSubresource;
6806 {0, 0, 0}, // VkOffset3D dstOffset;
6807 getExtent3D(m_params.src.image), // VkExtent3D extent;
6808 };
6809
6810 if (m_params.extensionUse == EXTENSION_USE_NONE)
6811 {
6812 imageCopies.push_back(imageCopy);
6813 }
6814 else
6815 {
6816 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6817 imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
6818 }
6819 }
6820 }
6821
6822 VkImageSubresourceRange subresourceRange = {
6823 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask
6824 0u, // deUint32 baseMipLevel
6825 1u, // deUint32 mipLevels
6826 0u, // deUint32 baseArraySlice
6827 copyArraySize // deUint32 arraySize
6828 };
6829
6830 // m_multisampledImage
6831 const VkImageMemoryBarrier m_multisampledImageBarrier =
6832 {
6833 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
6834 DE_NULL, // const void* pNext;
6835 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask;
6836 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
6837 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
6838 m_params.src.image.operationLayout, // VkImageLayout newLayout;
6839 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
6840 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
6841 m_multisampledImage.get(), // VkImage image;
6842 { // VkImageSubresourceRange subresourceRange;
6843 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
6844 0u, // deUint32 baseMipLevel;
6845 1u, // deUint32 mipLevels;
6846 0u, // deUint32 baseArraySlice;
6847 getArraySize(m_params.src.image) // deUint32 arraySize;
6848 }
6849 };
6850 // m_multisampledCopyImage
6851 VkImageMemoryBarrier m_multisampledCopyImageBarrier =
6852 {
6853 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
6854 DE_NULL, // const void* pNext;
6855 0, // VkAccessFlags srcAccessMask;
6856 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
6857 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
6858 m_params.dst.image.operationLayout, // VkImageLayout newLayout;
6859 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
6860 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
6861 m_multisampledCopyImage.get(), // VkImage image;
6862 subresourceRange // VkImageSubresourceRange subresourceRange;
6863 };
6864
6865 // m_multisampledCopyNoCabImage (no USAGE_COLOR_ATTACHMENT_BIT)
6866 const VkImageMemoryBarrier m_multisampledCopyNoCabImageBarrier =
6867 {
6868 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
6869 DE_NULL, // const void* pNext;
6870 0, // VkAccessFlags srcAccessMask;
6871 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
6872 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
6873 m_params.dst.image.operationLayout, // VkImageLayout newLayout;
6874 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
6875 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
6876 m_multisampledCopyNoCabImage.get(), // VkImage image;
6877 subresourceRange // VkImageSubresourceRange subresourceRange;
6878 };
6879
6880 // destination image
6881 const VkImageMemoryBarrier multisampledCopyImagePostBarrier =
6882 {
6883 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
6884 DE_NULL, // const void* pNext;
6885 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
6886 VK_ACCESS_MEMORY_READ_BIT, // VkAccessFlags dstAccessMask;
6887 m_params.dst.image.operationLayout, // VkImageLayout oldLayout;
6888 m_params.src.image.operationLayout, // VkImageLayout newLayout;
6889 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
6890 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
6891 m_multisampledCopyImage.get(), // VkImage image;
6892 subresourceRange // VkImageSubresourceRange subresourceRange;
6893 };
6894
6895 // destination image (no USAGE_COLOR_ATTACHMENT_BIT)
6896 const VkImageMemoryBarrier betweenCopyImageBarrier =
6897 {
6898 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
6899 DE_NULL, // const void* pNext;
6900 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
6901 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
6902 m_params.dst.image.operationLayout, // VkImageLayout oldLayout;
6903 m_params.src.image.operationLayout, // VkImageLayout newLayout;
6904 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
6905 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
6906 m_multisampledCopyNoCabImage.get(), // VkImage image;
6907 subresourceRange // VkImageSubresourceRange subresourceRange;
6908 };
6909
6910 // Queue family ownership transfer. Move ownership of the m_multisampledImage and m_multisampledImageCopy to the compute/transfer queue.
6911 if (useTwoQueues)
6912 {
6913 // Release ownership from graphics queue.
6914 {
6915 std::vector<VkImageMemoryBarrier> barriers;
6916 barriers.reserve(2);
6917
6918 // Barrier for m_multisampledImage
6919 VkImageMemoryBarrier releaseBarrier = m_multisampledImageBarrier;
6920 releaseBarrier.dstAccessMask = 0u; // dstAccessMask is ignored in ownership release operation.
6921 releaseBarrier.srcQueueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
6922 releaseBarrier.dstQueueFamilyIndex = m_alternativeQueueFamilyIndex;
6923 barriers.push_back(releaseBarrier);
6924
6925 // Barrier for m_multisampledCopyImage
6926 releaseBarrier = m_multisampledCopyImageBarrier;
6927 releaseBarrier.dstAccessMask = 0u; // dstAccessMask is ignored in ownership release operation.
6928 releaseBarrier.srcQueueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
6929 releaseBarrier.dstQueueFamilyIndex = m_alternativeQueueFamilyIndex;
6930 barriers.push_back(releaseBarrier);
6931
6932 beginCommandBuffer(vk, m_cmdBuffer.get());
6933 vk.cmdPipelineBarrier(m_cmdBuffer.get(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, (uint32_t)barriers.size(), barriers.data());
6934 endCommandBuffer(vk, m_cmdBuffer.get());
6935 submitCommandsAndWait(vk, vkDevice, m_queue, m_cmdBuffer.get());
6936 m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
6937 }
6938
6939 // Acquire ownership to compute / transfer queue.
6940 {
6941 std::vector<VkImageMemoryBarrier> barriers;
6942 barriers.reserve(2);
6943
6944 // Barrier for m_multisampledImage
6945 VkImageMemoryBarrier acquireBarrier = m_multisampledImageBarrier;
6946 acquireBarrier.srcAccessMask = 0u; // srcAccessMask is ignored in ownership acquire operation.
6947 acquireBarrier.srcQueueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
6948 acquireBarrier.dstQueueFamilyIndex = m_alternativeQueueFamilyIndex;
6949 barriers.push_back(acquireBarrier);
6950
6951 // Barrier for m_multisampledImage
6952 acquireBarrier = m_multisampledCopyImageBarrier;
6953 acquireBarrier.srcAccessMask = 0u; // srcAccessMask is ignored in ownership acquire operation.
6954 acquireBarrier.srcQueueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
6955 acquireBarrier.dstQueueFamilyIndex = m_alternativeQueueFamilyIndex;
6956 barriers.push_back(acquireBarrier);
6957
6958 beginCommandBuffer(vk, commandBuffer);
6959 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, (uint32_t)barriers.size(), barriers.data());
6960 endCommandBuffer(vk, commandBuffer);
6961 submitCommandsAndWait(vk, vkDevice, queue, commandBuffer);
6962 m_context.resetCommandPoolForVKSC(vkDevice, commandPool);
6963 }
6964
6965 beginCommandBuffer(vk, commandBuffer);
6966 }
6967 else
6968 {
6969 std::vector<VkImageMemoryBarrier> imageBarriers;
6970
6971 imageBarriers.push_back(m_multisampledImageBarrier);
6972 // Only use one barrier if no options have been given.
6973 if (m_options != NO_OPTIONAL_OPERATION)
6974 {
6975 imageBarriers.push_back(m_multisampledCopyImageBarrier);
6976 // Add the third barrier if option is as below.
6977 if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB)
6978 imageBarriers.push_back(m_multisampledCopyNoCabImageBarrier);
6979 }
6980
6981 beginCommandBuffer(vk, commandBuffer);
6982 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, (uint32_t)imageBarriers.size(), imageBarriers.data());
6983 }
6984
6985 if (m_params.extensionUse == EXTENSION_USE_NONE)
6986 {
6987 if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB)
6988 {
6989 vk.cmdCopyImage(commandBuffer, m_multisampledImage.get(), m_params.src.image.operationLayout, m_multisampledCopyNoCabImage.get(), m_params.dst.image.operationLayout, (deUint32)imageCopies.size(), imageCopies.data());
6990 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1u, &betweenCopyImageBarrier);
6991 vk.cmdCopyImage(commandBuffer, m_multisampledCopyNoCabImage.get(), m_params.src.image.operationLayout, m_multisampledCopyImage.get(), m_params.dst.image.operationLayout, (deUint32)imageCopies.size(), imageCopies.data());
6992 }
6993 else
6994 {
6995 vk.cmdCopyImage(commandBuffer, m_multisampledImage.get(), m_params.src.image.operationLayout, m_multisampledCopyImage.get(), m_params.dst.image.operationLayout, (deUint32)imageCopies.size(), imageCopies.data());
6996 }
6997 }
6998 #ifndef CTS_USES_VULKANSC
6999 else
7000 {
7001 if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB)
7002 {
7003 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
7004 const VkCopyImageInfo2KHR copyImageInfo2KHR =
7005 {
7006 VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR, // VkStructureType sType;
7007 DE_NULL, // const void* pNext;
7008 m_multisampledImage.get(), // VkImage srcImage;
7009 m_params.src.image.operationLayout, // VkImageLayout srcImageLayout;
7010 m_multisampledCopyNoCabImage.get(), // VkImage dstImage;
7011 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout dstImageLayout;
7012 (deUint32)imageCopies2KHR.size(), // uint32_t regionCount;
7013 imageCopies2KHR.data() // const VkImageCopy2KHR* pRegions;
7014 };
7015 const VkCopyImageInfo2KHR copyImageInfo2KHRCopy =
7016 {
7017 VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR, // VkStructureType sType;
7018 DE_NULL, // const void* pNext;
7019 m_multisampledCopyNoCabImage.get(), // VkImage srcImage;
7020 vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout srcImageLayout;
7021 m_multisampledCopyImage.get(), // VkImage dstImage;
7022 m_params.dst.image.operationLayout, // VkImageLayout dstImageLayout;
7023 (deUint32)imageCopies2KHR.size(), // uint32_t regionCount;
7024 imageCopies2KHR.data() // const VkImageCopy2KHR* pRegions;
7025 };
7026
7027 vk.cmdCopyImage2(commandBuffer, ©ImageInfo2KHR);
7028 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1u, &betweenCopyImageBarrier);
7029 vk.cmdCopyImage2(commandBuffer, ©ImageInfo2KHRCopy);
7030 }
7031 else
7032 {
7033 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
7034 const VkCopyImageInfo2KHR copyImageInfo2KHR =
7035 {
7036 VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR, // VkStructureType sType;
7037 DE_NULL, // const void* pNext;
7038 m_multisampledImage.get(), // VkImage srcImage;
7039 m_params.src.image.operationLayout, // VkImageLayout srcImageLayout;
7040 m_multisampledCopyImage.get(), // VkImage dstImage;
7041 m_params.dst.image.operationLayout, // VkImageLayout dstImageLayout;
7042 (deUint32)imageCopies2KHR.size(), // uint32_t regionCount;
7043 imageCopies2KHR.data() // const VkImageCopy2KHR* pRegions;
7044 };
7045 vk.cmdCopyImage2(commandBuffer, ©ImageInfo2KHR);
7046 }
7047 }
7048 #endif // CTS_USES_VULKANSC
7049
7050 if (useTwoQueues)
7051 {
7052 endCommandBuffer(vk, commandBuffer);
7053 submitCommandsAndWait(vk, vkDevice, queue, commandBuffer);
7054 m_context.resetCommandPoolForVKSC(vkDevice, commandPool);
7055
7056 VkImageMemoryBarrier srcImageBarrier = makeImageMemoryBarrier(
7057 0u,
7058 0u,
7059 m_params.src.image.operationLayout,
7060 m_params.src.image.operationLayout,
7061 m_multisampledImage.get(),
7062 m_multisampledImageBarrier.subresourceRange,
7063 m_alternativeQueueFamilyIndex,
7064 m_context.getUniversalQueueFamilyIndex());
7065 // Release ownership from compute / transfer queue.
7066 {
7067 std::vector<VkImageMemoryBarrier> barriers;
7068 barriers.reserve(2);
7069
7070 VkImageMemoryBarrier releaseBarrier = multisampledCopyImagePostBarrier;
7071 releaseBarrier.dstAccessMask = 0u; // dstAccessMask is ignored in ownership release operation.
7072 releaseBarrier.srcQueueFamilyIndex = m_alternativeQueueFamilyIndex;
7073 releaseBarrier.dstQueueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
7074 barriers.push_back(releaseBarrier);
7075
7076 releaseBarrier = srcImageBarrier;
7077 releaseBarrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
7078 releaseBarrier.dstAccessMask = 0u; // dstAccessMask is ignored in ownership release operation.
7079 barriers.push_back(releaseBarrier);
7080
7081 beginCommandBuffer(vk, commandBuffer);
7082 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, (uint32_t)barriers.size(), barriers.data());
7083 endCommandBuffer(vk, commandBuffer);
7084 submitCommandsAndWait(vk, vkDevice, queue, commandBuffer);
7085 m_context.resetCommandPoolForVKSC(vkDevice, commandPool);
7086 }
7087
7088 // Acquire ownership to graphics queue.
7089 {
7090 std::vector<VkImageMemoryBarrier> barriers;
7091 barriers.reserve(2);
7092
7093 VkImageMemoryBarrier acquireBarrier = multisampledCopyImagePostBarrier;
7094 acquireBarrier.srcAccessMask = 0u; // srcAccessMask is ignored in ownership acquire operation.
7095 acquireBarrier.srcQueueFamilyIndex = m_alternativeQueueFamilyIndex;
7096 acquireBarrier.dstQueueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
7097 barriers.push_back(acquireBarrier);
7098
7099 acquireBarrier = srcImageBarrier;
7100 acquireBarrier.srcAccessMask = 0u; // srcAccessMask is ignored in ownership acquire operation.
7101 acquireBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
7102 barriers.push_back(acquireBarrier);
7103
7104 beginCommandBuffer(vk, m_cmdBuffer.get());
7105 vk.cmdPipelineBarrier(m_cmdBuffer.get(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, (uint32_t)barriers.size(), barriers.data());
7106 endCommandBuffer(vk, m_cmdBuffer.get());
7107 submitCommandsAndWait(vk, vkDevice, m_queue, m_cmdBuffer.get());
7108 m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
7109 }
7110 }
7111 else
7112 {
7113 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1u, &multisampledCopyImagePostBarrier);
7114 endCommandBuffer(vk, commandBuffer);
7115 submitCommandsAndWait (vk, vkDevice, queue, commandBuffer);
7116 m_context.resetCommandPoolForVKSC(vkDevice, commandPool);
7117 }
7118 }
7119
7120 class ResolveImageToImageTestCase : public vkt::TestCase
7121 {
7122 public:
ResolveImageToImageTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params,const ResolveImageToImageOptions options=NO_OPTIONAL_OPERATION)7123 ResolveImageToImageTestCase (tcu::TestContext& testCtx,
7124 const std::string& name,
7125 const std::string& description,
7126 const TestParams params,
7127 const ResolveImageToImageOptions options = NO_OPTIONAL_OPERATION)
7128 : vkt::TestCase (testCtx, name, description)
7129 , m_params (params)
7130 , m_options (options)
7131 {}
7132
7133 virtual void initPrograms (SourceCollections& programCollection) const;
7134
createInstance(Context & context) const7135 virtual TestInstance* createInstance (Context& context) const
7136 {
7137 return new ResolveImageToImage(context, m_params, m_options);
7138 }
7139
checkSupport(Context & context) const7140 virtual void checkSupport (Context& context) const
7141 {
7142 const VkSampleCountFlagBits rasterizationSamples = m_params.samples;
7143
7144 // Intermediate result check uses fragmentStoresAndAtomics.
7145 if (ResolveImageToImage::shouldVerifyIntermediateResults(m_options) && !context.getDeviceFeatures().fragmentStoresAndAtomics)
7146 {
7147 TCU_THROW(NotSupportedError, "fragmentStoresAndAtomics not supported");
7148 }
7149
7150 if (!(context.getDeviceProperties().limits.framebufferColorSampleCounts & rasterizationSamples))
7151 throw tcu::NotSupportedError("Unsupported number of rasterization samples");
7152
7153 VkImageFormatProperties properties;
7154 if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
7155 m_params.src.image.format,
7156 m_params.src.image.imageType,
7157 VK_IMAGE_TILING_OPTIMAL,
7158 VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
7159 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
7160 (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
7161 m_params.dst.image.format,
7162 m_params.dst.image.imageType,
7163 VK_IMAGE_TILING_OPTIMAL,
7164 VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0,
7165 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
7166 {
7167 TCU_THROW(NotSupportedError, "Format not supported");
7168 }
7169
7170 if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
7171 (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
7172 {
7173 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
7174 }
7175
7176 // Find at least one queue family that supports compute queue but does NOT support graphics queue.
7177 if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE)
7178 {
7179 bool foundQueue = false;
7180 const std::vector<VkQueueFamilyProperties> queueFamilies = getPhysicalDeviceQueueFamilyProperties(context.getInstanceInterface(), context.getPhysicalDevice());
7181 for (const auto& queueFamily : queueFamilies)
7182 {
7183 if (queueFamily.queueFlags & VK_QUEUE_COMPUTE_BIT && !(queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT))
7184 {
7185 foundQueue = true;
7186 break;
7187 }
7188 }
7189 if (!foundQueue)
7190 TCU_THROW(NotSupportedError, "No queue family found that only supports compute queue.");
7191 }
7192
7193 // Find at least one queue family that supports transfer queue but does NOT support graphics and compute queue.
7194 if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER)
7195 {
7196 bool foundQueue = false;
7197 const std::vector<VkQueueFamilyProperties> queueFamilies = getPhysicalDeviceQueueFamilyProperties(context.getInstanceInterface(), context.getPhysicalDevice());
7198 for (const auto& queueFamily : queueFamilies)
7199 {
7200 if (queueFamily.queueFlags & VK_QUEUE_TRANSFER_BIT && !(queueFamily.queueFlags & VK_QUEUE_COMPUTE_BIT) && !(queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT))
7201 {
7202 foundQueue = true;
7203 break;
7204 }
7205 }
7206 if (!foundQueue)
7207 TCU_THROW(NotSupportedError, "No queue family found that only supports transfer queue.");
7208 }
7209 }
7210
7211 private:
7212 TestParams m_params;
7213 const ResolveImageToImageOptions m_options;
7214 };
7215
initPrograms(SourceCollections & programCollection) const7216 void ResolveImageToImageTestCase::initPrograms (SourceCollections& programCollection) const
7217 {
7218 programCollection.glslSources.add("vert") << glu::VertexSource(
7219 "#version 310 es\n"
7220 "layout (location = 0) in highp vec4 a_position;\n"
7221 "void main()\n"
7222 "{\n"
7223 " gl_Position = a_position;\n"
7224 "}\n");
7225
7226
7227 programCollection.glslSources.add("frag") << glu::FragmentSource(
7228 "#version 310 es\n"
7229 "layout (location = 0) out highp vec4 o_color;\n"
7230 "void main()\n"
7231 "{\n"
7232 " o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
7233 "}\n");
7234
7235 if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE || m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER)
7236 {
7237 // The shader verifies all layers in the copied image are the same as the source image.
7238 // This needs an image view per layer in the copied image.
7239 // Set 0 contains the output buffer.
7240 // Set 1 contains the input attachments.
7241
7242 std::ostringstream verificationShader;
7243
7244 verificationShader
7245 << "#version 450\n"
7246 << "\n"
7247 << "layout (push_constant, std430) uniform PushConstants {\n"
7248 << " int width;\n"
7249 << " int height;\n"
7250 << " int samples;\n"
7251 << "};\n"
7252 << "layout (set=0, binding=0) buffer VerificationResults {\n"
7253 << " int verificationFlags[];\n"
7254 << "};\n"
7255 << "layout (input_attachment_index=0, set=1, binding=0) uniform subpassInputMS attachment0;\n"
7256 ;
7257
7258 const auto dstLayers = getArraySize(m_params.dst.image);
7259
7260 if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
7261 {
7262 verificationShader << "layout (input_attachment_index=1, set=1, binding=1) uniform subpassInputMS attachment1;\n";
7263 }
7264 else
7265 {
7266 for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
7267 {
7268 const auto i = layerNdx + 1u;
7269 verificationShader << "layout (input_attachment_index=" << i << ", set=1, binding=" << i << ") uniform subpassInputMS attachment" << i << ";\n";
7270 }
7271 }
7272
7273 // Using a loop to iterate over each sample avoids the need for the sampleRateShading feature. The pipeline needs to be
7274 // created with a single sample.
7275 verificationShader
7276 << "\n"
7277 << "void main() {\n"
7278 << " for (int sampleID = 0; sampleID < samples; ++sampleID) {\n"
7279 << " vec4 orig = subpassLoad(attachment0, sampleID);\n"
7280 ;
7281
7282 std::ostringstream testCondition;
7283 if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
7284 {
7285 verificationShader << " vec4 copy = subpassLoad(attachment1, sampleID);\n";
7286 testCondition << "orig == copy";
7287 }
7288 else
7289 {
7290 for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
7291 {
7292 const auto i = layerNdx + 1u;
7293 verificationShader << " vec4 copy" << i << " = subpassLoad(attachment" << i << ", sampleID);\n";
7294 }
7295
7296 for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
7297 {
7298 const auto i = layerNdx + 1u;
7299 testCondition << (layerNdx == 0u ? "" : " && ") << "orig == copy" << i;
7300 }
7301 }
7302
7303 verificationShader
7304 << "\n"
7305 << " ivec3 coords = ivec3(int(gl_FragCoord.x), int(gl_FragCoord.y), sampleID);\n"
7306 << " int bufferPos = (coords.y * width + coords.x) * samples + coords.z;\n"
7307 << "\n"
7308 << " verificationFlags[bufferPos] = ((" << testCondition.str() << ") ? 1 : 0); \n"
7309 << " }\n"
7310 << "}\n"
7311 ;
7312
7313 programCollection.glslSources.add("verify") << glu::FragmentSource(verificationShader.str());
7314 }
7315 }
7316
7317 class DepthStencilMSAA : public vkt::TestInstance
7318 {
7319 public:
7320 enum CopyOptions {COPY_WHOLE_IMAGE, COPY_ARRAY_TO_ARRAY, COPY_PARTIAL};
7321
7322 struct TestParameters
7323 {
7324 AllocationKind allocationKind;
7325 ExtensionUse extensionUse;
7326 CopyOptions copyOptions;
7327 VkSampleCountFlagBits samples;
7328 VkImageLayout srcImageLayout;
7329 VkImageLayout dstImageLayout;
7330 VkFormat imageFormat;
7331 VkImageAspectFlags copyAspect;
7332 deBool imageOffset;
7333 };
7334
7335 DepthStencilMSAA (Context& context,
7336 TestParameters testParameters);
7337 tcu::TestStatus iterate (void) override;
7338 protected:
7339 tcu::TestStatus checkCopyResults (VkCommandBuffer cmdBuffer,
7340 const VkImageAspectFlagBits& aspectToVerify,
7341 VkImage srcImage,
7342 VkImage dstImage);
7343
7344 private:
7345 // Returns image aspects used in the copy regions.
getUsedImageAspects()7346 VkImageAspectFlags getUsedImageAspects ()
7347 {
7348 auto aspectFlags = (VkImageAspectFlags)0;
7349 for (const auto ®ion : m_regions)
7350 {
7351 aspectFlags |= region.imageCopy.srcSubresource.aspectMask;
7352 }
7353 return aspectFlags;
7354 }
7355
7356 ImageParms m_srcImage;
7357 ImageParms m_dstImage;
7358 std::vector<CopyRegion> m_regions;
7359 const TestParameters m_params;
7360 const float m_clearValue = 0.0f;
7361 };
7362
DepthStencilMSAA(Context & context,TestParameters testParameters)7363 DepthStencilMSAA::DepthStencilMSAA (Context& context, TestParameters testParameters)
7364 : vkt::TestInstance(context)
7365 , m_params(testParameters)
7366 {
7367 // params.src.image is the parameters used to create the copy source image
7368 m_srcImage.imageType = VK_IMAGE_TYPE_2D;
7369 m_srcImage.format = testParameters.imageFormat;
7370 m_srcImage.extent = defaultExtent;
7371 m_srcImage.tiling = VK_IMAGE_TILING_OPTIMAL;
7372 m_srcImage.operationLayout = testParameters.srcImageLayout;
7373 m_srcImage.createFlags = 0u;
7374
7375 // params.src.image is the parameters used to create the copy destination image
7376 m_dstImage.imageType = VK_IMAGE_TYPE_2D;
7377 m_dstImage.format = testParameters.imageFormat;
7378 m_dstImage.extent = defaultExtent;
7379 m_dstImage.tiling = VK_IMAGE_TILING_OPTIMAL;
7380 m_dstImage.operationLayout = testParameters.dstImageLayout;
7381 m_dstImage.createFlags = 0u;
7382
7383 const VkImageSubresourceLayers depthSubresourceLayers =
7384 {
7385 VK_IMAGE_ASPECT_DEPTH_BIT, // VkImageAspectFlags aspectMask;
7386 0u, // uint32_t mipLevel;
7387 0u, // uint32_t baseArrayLayer;
7388 1u // uint32_t layerCount;
7389 };
7390
7391 const VkImageSubresourceLayers stencilSubresourceLayers =
7392 {
7393 VK_IMAGE_ASPECT_STENCIL_BIT, // VkImageAspectFlags aspectMask;
7394 0u, // uint32_t mipLevel;
7395 0u, // uint32_t baseArrayLayer;
7396 1u // uint32_t layerCount;
7397 };
7398
7399 VkImageCopy depthCopy =
7400 {
7401 depthSubresourceLayers, // VkImageSubresourceLayers srcSubresource;
7402 {0, 0, 0}, // VkOffset3D srcOffset;
7403 depthSubresourceLayers, // VkImageSubresourceLayers dstSubresource;
7404 {0, 0, 0}, // VkOffset3D dstOffset;
7405 defaultExtent, // VkExtent3D extent;
7406 };
7407
7408 VkImageCopy stencilCopy =
7409 {
7410 stencilSubresourceLayers, // VkImageSubresourceLayers srcSubresource;
7411 {0, 0, 0}, // VkOffset3D srcOffset;
7412 stencilSubresourceLayers, // VkImageSubresourceLayers dstSubresource;
7413 {0, 0, 0}, // VkOffset3D dstOffset;
7414 defaultExtent, // VkExtent3D extent;
7415 };
7416
7417 if (testParameters.copyOptions == DepthStencilMSAA::COPY_ARRAY_TO_ARRAY)
7418 {
7419 m_srcImage.extent.depth = 5u;
7420 depthCopy.srcSubresource.baseArrayLayer = 2u;
7421 depthCopy.dstSubresource.baseArrayLayer = 3u;
7422 stencilCopy.srcSubresource.baseArrayLayer = 2u;
7423 stencilCopy.dstSubresource.baseArrayLayer = 3u;
7424 }
7425
7426 CopyRegion depthCopyRegion;
7427 CopyRegion stencilCopyRegion;
7428 depthCopyRegion.imageCopy = depthCopy;
7429 stencilCopyRegion.imageCopy = stencilCopy;
7430
7431 std::vector<CopyRegion> depthRegions;
7432 std::vector<CopyRegion> stencilRegions;
7433
7434 if (testParameters.copyOptions == DepthStencilMSAA::COPY_PARTIAL)
7435 {
7436 if (testParameters.copyAspect & VK_IMAGE_ASPECT_DEPTH_BIT)
7437 {
7438 depthCopyRegion.imageCopy.extent = {defaultHalfSize, defaultHalfSize, 1};
7439 // Copy region from bottom right to bottom left
7440 depthCopyRegion.imageCopy.srcOffset = {defaultHalfSize, defaultHalfSize, 0};
7441 depthCopyRegion.imageCopy.dstOffset = {0, defaultHalfSize, 0};
7442 depthRegions.push_back(depthCopyRegion);
7443 // Copy region from top right to bottom right
7444 depthCopyRegion.imageCopy.srcOffset = {defaultHalfSize, 0, 0};
7445 depthCopyRegion.imageCopy.dstOffset = {defaultHalfSize, defaultHalfSize, 0};
7446 depthRegions.push_back(depthCopyRegion);
7447 }
7448 if (testParameters.copyAspect & VK_IMAGE_ASPECT_STENCIL_BIT)
7449 {
7450 stencilCopyRegion.imageCopy.extent = {defaultHalfSize, defaultHalfSize, 1};
7451 // Copy region from bottom right to bottom left
7452 stencilCopyRegion.imageCopy.srcOffset = {defaultHalfSize, defaultHalfSize, 0};
7453 stencilCopyRegion.imageCopy.dstOffset = {0, defaultHalfSize, 0};
7454 stencilRegions.push_back(stencilCopyRegion);
7455 // Copy region from top right to bottom right
7456 stencilCopyRegion.imageCopy.srcOffset = {defaultHalfSize, 0, 0};
7457 stencilCopyRegion.imageCopy.dstOffset = {defaultHalfSize, defaultHalfSize, 0};
7458 stencilRegions.push_back(stencilCopyRegion);
7459 }
7460 }
7461 else
7462 {
7463 // Copy the default region (full image)
7464 if (testParameters.copyAspect & VK_IMAGE_ASPECT_DEPTH_BIT)
7465 {
7466 depthRegions.push_back(depthCopyRegion);
7467 }
7468 if (testParameters.copyAspect & VK_IMAGE_ASPECT_STENCIL_BIT)
7469 {
7470 stencilRegions.push_back(stencilCopyRegion);
7471 }
7472 }
7473
7474 if (testParameters.copyAspect & VK_IMAGE_ASPECT_DEPTH_BIT)
7475 {
7476 m_regions.insert(m_regions.end(), depthRegions.begin(), depthRegions.end());
7477 }
7478
7479 if (testParameters.copyAspect & VK_IMAGE_ASPECT_STENCIL_BIT)
7480 {
7481 m_regions.insert(m_regions.end(), stencilRegions.begin(), stencilRegions.end());
7482 }
7483 }
7484
iterate(void)7485 tcu::TestStatus DepthStencilMSAA::iterate (void)
7486 {
7487 const DeviceInterface& vk = m_context.getDeviceInterface();
7488 const InstanceInterface& vki = m_context.getInstanceInterface();
7489 const VkDevice vkDevice = m_context.getDevice();
7490 const VkPhysicalDevice vkPhysDevice = m_context.getPhysicalDevice();
7491 const VkQueue queue = m_context.getUniversalQueue();
7492 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
7493 Allocator& memAlloc = m_context.getDefaultAllocator();
7494 Move<VkCommandPool> cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
7495 Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
7496
7497 const tcu::TextureFormat srcTcuFormat = mapVkFormat(m_srcImage.format);
7498 const tcu::TextureFormat dstTcuFormat = mapVkFormat(m_dstImage.format);
7499 VkImageAspectFlags aspectFlags = getUsedImageAspects();
7500 deUint32 sourceArraySize = getArraySize(m_srcImage);
7501
7502 Move<VkImage> srcImage;
7503 de::MovePtr<Allocation> srcImageAlloc;
7504 Move<VkImage> dstImage;
7505 de::MovePtr<Allocation> dstImageAlloc;
7506
7507 // 1. Create the images and draw a triangle to the source image.
7508 {
7509 const VkComponentMapping componentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
7510 Move<VkShaderModule> vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
7511 Move<VkShaderModule> fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
7512 std::vector<tcu::Vec4> vertices;
7513 Move<VkBuffer> vertexBuffer;
7514 de::MovePtr<Allocation> vertexBufferAlloc;
7515 Move<VkPipelineLayout> pipelineLayout;
7516 Move<VkPipeline> graphicsPipeline;
7517 Move<VkRenderPass> renderPass;
7518
7519 // Create multisampled depth/stencil image (srcImage) and the copy destination image (dstImage).
7520 {
7521 VkImageCreateInfo multiSampledImageParams =
7522 {
7523 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
7524 DE_NULL, // const void* pNext;
7525 getCreateFlags(m_srcImage), // VkImageCreateFlags flags;
7526 m_srcImage.imageType, // VkImageType imageType;
7527 m_srcImage.format, // VkFormat format;
7528 getExtent3D(m_srcImage), // VkExtent3D extent;
7529 1u, // deUint32 mipLevels;
7530 getArraySize(m_srcImage), // deUint32 arrayLayers;
7531 m_params.samples, // VkSampleCountFlagBits samples;
7532 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
7533 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT // VkImageUsageFlags usage;
7534 | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
7535 | VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
7536 | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
7537 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
7538 1u, // deUint32 queueFamilyIndexCount;
7539 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
7540 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
7541 };
7542
7543 srcImage = createImage(vk, vkDevice, &multiSampledImageParams);
7544
7545 VkMemoryRequirements req = getImageMemoryRequirements(vk, vkDevice, *srcImage);
7546 deUint32 offset = m_params.imageOffset ? static_cast<deUint32>(req.alignment) : 0;
7547
7548 srcImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, srcImage.get(), MemoryRequirement::Any, memAlloc,
7549 m_params.allocationKind, offset);
7550 VK_CHECK(vk.bindImageMemory(vkDevice, srcImage.get(), srcImageAlloc->getMemory(), srcImageAlloc->getOffset() + offset));
7551
7552 dstImage = createImage(vk, vkDevice, &multiSampledImageParams);
7553 dstImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, dstImage.get(), MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
7554 VK_CHECK(vk.bindImageMemory(vkDevice, dstImage.get(), dstImageAlloc->getMemory(), dstImageAlloc->getOffset()));
7555 }
7556
7557 // Create render pass.
7558 {
7559 const VkImageLayout initialLayout = m_params.copyOptions == COPY_ARRAY_TO_ARRAY ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED;
7560 const VkAttachmentDescription attachmentDescription =
7561 {
7562 0u, // VkAttachmentDescriptionFlags flags
7563 m_srcImage.format, // VkFormat format
7564 m_params.samples, // VkSampleCountFlagBits samples
7565 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp
7566 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp
7567 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp stencilLoadOp
7568 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp
7569 initialLayout, // VkImageLayout initialLayout
7570 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout
7571 };
7572
7573 const VkAttachmentReference attachmentReference =
7574 {
7575 0u, // deUint32 attachment
7576 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout layout
7577 };
7578
7579 const VkSubpassDescription subpassDescription =
7580 {
7581 0u, // VkSubpassDescriptionFlags flags
7582 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint
7583 0u, // deUint32 inputAttachmentCount
7584 DE_NULL, // const VkAttachmentReference* pInputAttachments
7585 0u, // deUint32 colorAttachmentCount
7586 DE_NULL, // const VkAttachmentReference* pColorAttachments
7587 DE_NULL, // const VkAttachmentReference* pResolveAttachments
7588 &attachmentReference, // const VkAttachmentReference* pDepthStencilAttachment
7589 0u, // deUint32 preserveAttachmentCount
7590 DE_NULL // const VkAttachmentReference* pPreserveAttachments
7591 };
7592
7593 const VkRenderPassCreateInfo renderPassParams =
7594 {
7595 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
7596 DE_NULL, // const void* pNext;
7597 0u, // VkRenderPassCreateFlags flags;
7598 1u, // deUint32 attachmentCount;
7599 &attachmentDescription, // const VkAttachmentDescription* pAttachments;
7600 1u, // deUint32 subpassCount;
7601 &subpassDescription, // const VkSubpassDescription* pSubpasses;
7602 0u, // deUint32 dependencyCount;
7603 DE_NULL // const VkSubpassDependency* pDependencies;
7604 };
7605
7606 renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
7607 }
7608
7609 // Create pipeline layout
7610 {
7611 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
7612 {
7613 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
7614 DE_NULL, // const void* pNext;
7615 0u, // VkPipelineLayoutCreateFlags flags;
7616 0u, // deUint32 setLayoutCount;
7617 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
7618 0u, // deUint32 pushConstantRangeCount;
7619 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
7620 };
7621
7622 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
7623 }
7624
7625 // Create upper half triangle.
7626 {
7627 // Add triangle.
7628 vertices.emplace_back(-1.0f, -1.0f, 0.0f, 1.0f);
7629 vertices.emplace_back(1.0f, -1.0f, 0.0f, 1.0f);
7630 vertices.emplace_back(1.0f, 1.0f, 0.0f, 1.0f);
7631 }
7632
7633 // Create vertex buffer.
7634 {
7635 const VkDeviceSize vertexDataSize = vertices.size() * sizeof(tcu::Vec4);
7636 const VkBufferCreateInfo vertexBufferParams =
7637 {
7638 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
7639 DE_NULL, // const void* pNext;
7640 0u, // VkBufferCreateFlags flags;
7641 vertexDataSize, // VkDeviceSize size;
7642 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
7643 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
7644 1u, // deUint32 queueFamilyIndexCount;
7645 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
7646 };
7647
7648 vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
7649 vertexBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *vertexBuffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
7650 VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset()));
7651
7652 // Load vertices into vertex buffer.
7653 deMemcpy(vertexBufferAlloc->getHostPtr(), vertices.data(), (size_t)vertexDataSize);
7654 flushAlloc(vk, vkDevice, *vertexBufferAlloc);
7655 }
7656
7657 {
7658 Move<VkFramebuffer> framebuffer;
7659 Move<VkImageView> sourceAttachmentView;
7660
7661 // Create depth/stencil attachment view.
7662 {
7663 const uint32_t arrayLayer = m_params.copyOptions == COPY_ARRAY_TO_ARRAY ? 2u : 0u;
7664 const VkImageViewCreateInfo depthStencilAttachmentViewParams =
7665 {
7666 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
7667 DE_NULL, // const void* pNext;
7668 0u, // VkImageViewCreateFlags flags;
7669 *srcImage, // VkImage image;
7670 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
7671 m_srcImage.format, // VkFormat format;
7672 componentMappingRGBA, // VkComponentMapping components;
7673 { aspectFlags, 0u, 1u, arrayLayer, 1u } // VkImageSubresourceRange subresourceRange;
7674 };
7675 sourceAttachmentView = createImageView(vk, vkDevice, &depthStencilAttachmentViewParams);
7676 }
7677
7678 // Create framebuffer
7679 {
7680 const VkFramebufferCreateInfo framebufferParams =
7681 {
7682 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
7683 DE_NULL, // const void* pNext;
7684 0u, // VkFramebufferCreateFlags flags;
7685 *renderPass, // VkRenderPass renderPass;
7686 1u, // deUint32 attachmentCount;
7687 &sourceAttachmentView.get(), // const VkImageView* pAttachments;
7688 m_srcImage.extent.width, // deUint32 width;
7689 m_srcImage.extent.height, // deUint32 height;
7690 1u // deUint32 layers;
7691 };
7692
7693 framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
7694 }
7695
7696 // Create pipeline
7697 {
7698 const std::vector<VkViewport> viewports (1, makeViewport(m_srcImage.extent));
7699 const std::vector<VkRect2D> scissors (1, makeRect2D(m_srcImage.extent));
7700
7701 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
7702 {
7703 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
7704 DE_NULL, // const void* pNext;
7705 0u, // VkPipelineMultisampleStateCreateFlags flags;
7706 m_params.samples, // VkSampleCountFlagBits rasterizationSamples;
7707 VK_FALSE, // VkBool32 sampleShadingEnable;
7708 0.0f, // float minSampleShading;
7709 DE_NULL, // const VkSampleMask* pSampleMask;
7710 VK_FALSE, // VkBool32 alphaToCoverageEnable;
7711 VK_FALSE // VkBool32 alphaToOneEnable;
7712 };
7713
7714 const VkStencilOpState stencilOpState =
7715 {
7716 VK_STENCIL_OP_KEEP, // VkStencilOp failOp
7717 VK_STENCIL_OP_REPLACE, // VkStencilOp passOp
7718 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp
7719 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp
7720 0, // deUint32 compareMask
7721 0xFF, // deUint32 writeMask
7722 0xFF // deUint32 reference
7723 };
7724
7725 const VkPipelineDepthStencilStateCreateInfo depthStencilStateCreateInfoDefault =
7726 {
7727 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType
7728 DE_NULL, // const void* pNext
7729 0u, // VkPipelineDepthStencilStateCreateFlags flags
7730 aspectFlags & VK_IMAGE_ASPECT_DEPTH_BIT ? VK_TRUE : VK_FALSE, // VkBool32 depthTestEnable
7731 aspectFlags & VK_IMAGE_ASPECT_DEPTH_BIT ? VK_TRUE : VK_FALSE, // VkBool32 depthWriteEnable
7732 VK_COMPARE_OP_ALWAYS, // VkCompareOp depthCompareOp
7733 VK_FALSE, // VkBool32 depthBoundsTestEnable
7734 aspectFlags & VK_IMAGE_ASPECT_STENCIL_BIT ? VK_TRUE : VK_FALSE, // VkBool32 stencilTestEnable
7735 stencilOpState, // VkStencilOpState front
7736 stencilOpState, // VkStencilOpState back
7737 0.0f, // float minDepthBounds
7738 1.0f, // float maxDepthBounds
7739 };
7740
7741 graphicsPipeline = makeGraphicsPipeline(vk, // const DeviceInterface& vk
7742 vkDevice, // const VkDevice device
7743 *pipelineLayout, // const VkPipelineLayout pipelineLayout
7744 *vertexShaderModule, // const VkShaderModule vertexShaderModule
7745 DE_NULL, // const VkShaderModule tessellationControlModule
7746 DE_NULL, // const VkShaderModule tessellationEvalModule
7747 DE_NULL, // const VkShaderModule geometryShaderModule
7748 *fragmentShaderModule, // const VkShaderModule fragmentShaderModule
7749 *renderPass, // const VkRenderPass renderPass
7750 viewports, // const std::vector<VkViewport>& viewports
7751 scissors, // const std::vector<VkRect2D>& scissors
7752 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
7753 0u, // const deUint32 subpass
7754 0u, // const deUint32 patchControlPoints
7755 DE_NULL, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
7756 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
7757 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
7758 &depthStencilStateCreateInfoDefault); // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
7759 }
7760
7761 // Create command buffer
7762 {
7763 beginCommandBuffer(vk, *cmdBuffer, 0u);
7764
7765 const VkClearValue srcImageClearValue = makeClearValueDepthStencil(0.1f, 0x10);
7766
7767 // Change the layout of each layer of the depth / stencil image to VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL and clear the images.
7768 const VkClearValue copiedImageClearValue = makeClearValueDepthStencil(m_clearValue, (uint32_t)m_clearValue);
7769 const auto subResourceRange = makeImageSubresourceRange( // VkImageSubresourceRange subresourceRange
7770 (getAspectFlags(m_srcImage.format)), // VkImageAspectFlags aspectMask
7771 0u, // uint32_t baseMipLevel
7772 1u, // uint32_t levelCount
7773 0u, // uint32_t baseArrayLayer
7774 getArraySize(m_srcImage));
7775
7776 const VkImageMemoryBarrier preClearBarrier = makeImageMemoryBarrier(
7777 0u, // VkAccessFlags srcAccessMask
7778 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask
7779 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
7780 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout
7781 srcImage.get(), // VkImage image
7782 subResourceRange); // VkImageSubresourceRange subresourceRange
7783 std::vector<VkImageMemoryBarrier> preClearBarriers(2u, preClearBarrier);
7784 preClearBarriers[1].image = dstImage.get();
7785 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
7786 (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 2, preClearBarriers.data());
7787
7788 vk.cmdClearDepthStencilImage(
7789 *cmdBuffer, // VkCommandBuffer commandBuffer
7790 srcImage.get(), // VkImage image
7791 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout imageLayout
7792 &srcImageClearValue.depthStencil, // const VkClearDepthStencilValue* pDepthStencil
7793 1u, // uint32_t rangeCount
7794 &subResourceRange); // const VkImageSubresourceRange* pRanges
7795
7796 vk.cmdClearDepthStencilImage(
7797 *cmdBuffer, // VkCommandBuffer commandBuffer
7798 dstImage.get(), // VkImage image
7799 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout imageLayout
7800 &copiedImageClearValue.depthStencil, // const VkClearDepthStencilValue* pDepthStencil
7801 1u, // uint32_t rangeCount
7802 &subResourceRange); // const VkImageSubresourceRange* pRanges
7803
7804 // Post clear barrier
7805 const VkImageMemoryBarrier postClearBarrier = makeImageMemoryBarrier(
7806 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask
7807 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
7808 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout
7809 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout
7810 srcImage.get(), // VkImage image
7811 subResourceRange); // VkImageSubresourceRange subresourceRange
7812
7813 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
7814 (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postClearBarrier);
7815
7816 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(0, 0, m_srcImage.extent.width, m_srcImage.extent.height), 1u, &srcImageClearValue);
7817
7818 const VkDeviceSize vertexBufferOffset = 0u;
7819
7820 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
7821 vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
7822 vk.cmdDraw(*cmdBuffer, (deUint32)vertices.size(), 1, 0, 0);
7823
7824 endRenderPass(vk, *cmdBuffer);
7825 endCommandBuffer(vk, *cmdBuffer);
7826 }
7827
7828 submitCommandsAndWait (vk, vkDevice, queue, *cmdBuffer);
7829 m_context.resetCommandPoolForVKSC(vkDevice, *cmdPool);
7830 }
7831 }
7832
7833 // 2. Record a command buffer that contains the copy operation(s).
7834 beginCommandBuffer(vk, *cmdBuffer);
7835 {
7836 // Change the image layouts and synchronize the memory access before copying
7837 {
7838 const VkImageMemoryBarrier imageBarriers[] =
7839 {
7840 // srcImage
7841 makeImageMemoryBarrier(
7842 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
7843 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask
7844 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout
7845 m_srcImage.operationLayout, // VkImageLayout newLayout
7846 srcImage.get(), // VkImage image
7847 makeImageSubresourceRange( // VkImageSubresourceRange subresourceRange
7848 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask
7849 0u, // deUint32 baseMipLevel
7850 1u, // deUint32 levelCount
7851 0u, // deUint32 baseArrayLayer
7852 sourceArraySize // deUint32 layerCount
7853 )),
7854 // dstImage
7855 makeImageMemoryBarrier(
7856 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask
7857 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask
7858 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout
7859 m_dstImage.operationLayout, // VkImageLayout newLayout
7860 dstImage.get(), // VkImage image
7861 makeImageSubresourceRange( // VkImageSubresourceRange subresourceRange
7862 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask
7863 0u, // deUint32 baseMipLevel
7864 1u, // deUint32 levelCount
7865 0u, // deUint32 baseArrayLayer
7866 sourceArraySize // deUint32 layerCount
7867 )),
7868 };
7869 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
7870 (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 2u, imageBarriers);
7871 }
7872
7873 std::vector<VkImageCopy> imageCopies;
7874 std::vector<VkImageCopy2KHR> imageCopies2KHR;
7875 for (const auto & region : m_regions)
7876 {
7877 if (m_params.extensionUse == EXTENSION_USE_NONE)
7878 {
7879 imageCopies.push_back(region.imageCopy);
7880 }
7881 else
7882 {
7883 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
7884 imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(region.imageCopy));
7885 }
7886 }
7887
7888 if (m_params.extensionUse == EXTENSION_USE_NONE)
7889 {
7890 vk.cmdCopyImage(*cmdBuffer, srcImage.get(), m_srcImage.operationLayout, dstImage.get(), m_dstImage.operationLayout, (deUint32)imageCopies.size(), imageCopies.data());
7891 }
7892 #ifndef CTS_USES_VULKANSC
7893 else
7894 {
7895 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
7896 const VkCopyImageInfo2KHR copyImageInfo2KHR =
7897 {
7898 VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR, // VkStructureType sType;
7899 DE_NULL, // const void* pNext;
7900 srcImage.get(), // VkImage srcImage;
7901 m_srcImage.operationLayout, // VkImageLayout srcImageLayout;
7902 dstImage.get(), // VkImage dstImage;
7903 m_dstImage.operationLayout, // VkImageLayout dstImageLayout;
7904 (deUint32)imageCopies2KHR.size(), // uint32_t regionCount;
7905 imageCopies2KHR.data() // const VkImageCopy2KHR* pRegions;
7906 };
7907
7908 vk.cmdCopyImage2(*cmdBuffer, ©ImageInfo2KHR);
7909 }
7910 #endif // CTS_USES_VULKANSC
7911 }
7912 endCommandBuffer(vk, *cmdBuffer);
7913 submitCommandsAndWait (vk, vkDevice, queue, *cmdBuffer);
7914 m_context.resetCommandPoolForVKSC(vkDevice, *cmdPool);
7915
7916 // Verify that all samples have been copied properly from all aspects.
7917 const auto usedImageAspects = getUsedImageAspects();
7918 if (usedImageAspects & VK_IMAGE_ASPECT_DEPTH_BIT)
7919 {
7920 auto copyResult = checkCopyResults(cmdBuffer.get(), VK_IMAGE_ASPECT_DEPTH_BIT, srcImage.get(), dstImage.get());
7921 if (copyResult.getCode() != QP_TEST_RESULT_PASS)
7922 return copyResult;
7923 }
7924 if (usedImageAspects & VK_IMAGE_ASPECT_STENCIL_BIT)
7925 {
7926 auto copyResult = checkCopyResults(cmdBuffer.get(), VK_IMAGE_ASPECT_STENCIL_BIT, srcImage.get(), dstImage.get());
7927 if (copyResult.getCode() != QP_TEST_RESULT_PASS)
7928 return copyResult;
7929 }
7930 return tcu::TestStatus::pass("pass");
7931 }
7932
checkCopyResults(VkCommandBuffer cmdBuffer,const VkImageAspectFlagBits & aspectToVerify,VkImage srcImage,VkImage dstImage)7933 tcu::TestStatus DepthStencilMSAA::checkCopyResults (VkCommandBuffer cmdBuffer, const VkImageAspectFlagBits& aspectToVerify, VkImage srcImage, VkImage dstImage)
7934 {
7935 DE_ASSERT((aspectToVerify & VK_IMAGE_ASPECT_DEPTH_BIT) || (aspectToVerify & VK_IMAGE_ASPECT_STENCIL_BIT));
7936
7937 const auto& vkd = m_context.getDeviceInterface();
7938 const auto device = m_context.getDevice();
7939 const auto queue = m_context.getUniversalQueue();
7940 auto& alloc = m_context.getDefaultAllocator();
7941 const auto layerCount = getArraySize(m_srcImage);
7942 const auto numInputAttachments = layerCount + 1u; // +1 for the source image.
7943 const auto numOutputBuffers = 2u; // 1 for the reference and 1 for the copied values.
7944 const auto numSets = 2u; // 1 for the output buffers, 1 for the input attachments.
7945 const auto fbWidth = m_srcImage.extent.width;
7946 const auto fbHeight = m_srcImage.extent.height;
7947 const auto aspectFlags = getUsedImageAspects();
7948
7949 // Shader modules.
7950 const auto vertexModule = createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
7951 const auto verificationModule = createShaderModule(vkd, device, m_context.getBinaryCollection().get(aspectToVerify & VK_IMAGE_ASPECT_DEPTH_BIT ? "verify_depth" : "verify_stencil"), 0u);
7952
7953 // Descriptor sets.
7954 DescriptorPoolBuilder poolBuilder;
7955 poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, numOutputBuffers);
7956 poolBuilder.addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, numInputAttachments);
7957 const auto descriptorPool = poolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, numSets);
7958
7959 DescriptorSetLayoutBuilder layoutBuilderBuffer;
7960 layoutBuilderBuffer.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
7961 layoutBuilderBuffer.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
7962 const auto outputBufferSetLayout = layoutBuilderBuffer.build(vkd, device);
7963
7964 DescriptorSetLayoutBuilder layoutBuilderAttachments;
7965 for (deUint32 i = 0u; i < numInputAttachments; ++i)
7966 layoutBuilderAttachments.addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT);
7967 const auto inputAttachmentsSetLayout = layoutBuilderAttachments.build(vkd, device);
7968
7969 const auto descriptorSetBuffer = makeDescriptorSet(vkd, device, descriptorPool.get(), outputBufferSetLayout.get());
7970 const auto descriptorSetAttachments = makeDescriptorSet(vkd, device, descriptorPool.get(), inputAttachmentsSetLayout.get());
7971
7972 // Array with raw descriptor sets.
7973 const std::array<VkDescriptorSet, numSets> descriptorSets =
7974 {{
7975 descriptorSetBuffer.get(),
7976 descriptorSetAttachments.get(),
7977 }};
7978
7979 // Pipeline layout.
7980 const std::array<VkDescriptorSetLayout, numSets> setLayouts =
7981 {{
7982 outputBufferSetLayout.get(),
7983 inputAttachmentsSetLayout.get(),
7984 }};
7985
7986 // Push constants.
7987 std::array<int, 3> pushConstantData =
7988 {{
7989 static_cast<int>(fbWidth),
7990 static_cast<int>(fbHeight),
7991 static_cast<int>(m_params.samples),
7992 }};
7993
7994 const auto pushConstantSize = static_cast<deUint32>(pushConstantData.size() * sizeof(decltype(pushConstantData)::value_type));
7995
7996 const VkPushConstantRange pushConstantRange =
7997 {
7998 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
7999 0u, // deUint32 offset;
8000 pushConstantSize, // deUint32 size;
8001 };
8002
8003 const VkPipelineLayoutCreateInfo pipelineLayoutInfo =
8004 {
8005 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
8006 nullptr, // const void* pNext;
8007 0u, // VkPipelineLayoutCreateFlags flags;
8008 static_cast<deUint32>(setLayouts.size()), // deUint32 setLayoutCount;
8009 setLayouts.data(), // const VkDescriptorSetLayout* pSetLayouts;
8010 1u, // deUint32 pushConstantRangeCount;
8011 &pushConstantRange, // const VkPushConstantRange* pPushConstantRanges;
8012 };
8013
8014 const auto pipelineLayout = createPipelineLayout(vkd, device, &pipelineLayoutInfo);
8015
8016 // Render pass.
8017 const VkAttachmentDescription commonAttachmentDescription =
8018 {
8019 0u, // VkAttachmentDescriptionFlags flags;
8020 m_srcImage.format, // VkFormat format;
8021 m_params.samples, // VkSampleCountFlagBits samples;
8022 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
8023 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
8024 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
8025 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
8026 m_dstImage.operationLayout, // VkImageLayout initialLayout;
8027 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout finalLayout;
8028 };
8029
8030 std::vector<VkAttachmentDescription> attachmentDescriptions(numInputAttachments, commonAttachmentDescription);
8031 // Set the first attachment's (m_srcImage) initial layout to match the layout it was left after copying.
8032 attachmentDescriptions[0].initialLayout = m_srcImage.operationLayout;
8033
8034 std::vector<VkAttachmentReference> inputAttachmentReferences;
8035 inputAttachmentReferences.reserve(numInputAttachments);
8036 for (deUint32 i = 0u; i < numInputAttachments; ++i)
8037 {
8038 const VkAttachmentReference reference = { i, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL };
8039 inputAttachmentReferences.push_back(reference);
8040 }
8041
8042 const VkSubpassDescription subpassDescription =
8043 {
8044 0u, // VkSubpassDescriptionFlags flags;
8045 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
8046 static_cast<deUint32>(inputAttachmentReferences.size()), // deUint32 inputAttachmentCount;
8047 inputAttachmentReferences.data(), // const VkAttachmentReference* pInputAttachments;
8048 0u, // deUint32 colorAttachmentCount;
8049 nullptr, // const VkAttachmentReference* pColorAttachments;
8050 nullptr, // const VkAttachmentReference* pResolveAttachments;
8051 nullptr, // const VkAttachmentReference* pDepthStencilAttachment;
8052 0u, // deUint32 preserveAttachmentCount;
8053 nullptr, // const deUint32* pPreserveAttachments;
8054 };
8055
8056 const VkRenderPassCreateInfo renderPassInfo =
8057 {
8058 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
8059 nullptr, // const void* pNext;
8060 0u, // VkRenderPassCreateFlags flags;
8061 static_cast<deUint32>(attachmentDescriptions.size()), // deUint32 attachmentCount;
8062 attachmentDescriptions.data(), // const VkAttachmentDescription* pAttachments;
8063 1u, // deUint32 subpassCount;
8064 &subpassDescription, // const VkSubpassDescription* pSubpasses;
8065 0u, // deUint32 dependencyCount;
8066 nullptr, // const VkSubpassDependency* pDependencies;
8067 };
8068
8069 const auto renderPass = createRenderPass(vkd, device, &renderPassInfo);
8070
8071 // Framebuffer.
8072 std::vector<Move<VkImageView>> imageViews;
8073 std::vector<VkImageView> imageViewsRaw;
8074
8075 const uint32_t srcArrayLayer = m_params.copyOptions == COPY_ARRAY_TO_ARRAY ? 2u : 0u;
8076 imageViews.push_back(makeImageView(vkd, device, srcImage, VK_IMAGE_VIEW_TYPE_2D, m_srcImage.format, makeImageSubresourceRange(aspectFlags, 0u, 1u, srcArrayLayer, 1u)));
8077 for (deUint32 i = 0u; i < layerCount; ++i)
8078 {
8079 const auto subresourceRange = makeImageSubresourceRange(aspectFlags, 0u, 1u, i, 1u);
8080 imageViews.push_back(makeImageView(vkd, device, dstImage, VK_IMAGE_VIEW_TYPE_2D, m_srcImage.format, subresourceRange));
8081 }
8082
8083 imageViewsRaw.reserve(imageViews.size());
8084 std::transform(begin(imageViews), end(imageViews), std::back_inserter(imageViewsRaw), [](const Move<VkImageView>& ptr) { return ptr.get(); });
8085
8086 const auto framebuffer = makeFramebuffer(vkd, device, renderPass.get(), static_cast<deUint32>(imageViewsRaw.size()), imageViewsRaw.data(), fbWidth, fbHeight);
8087
8088 // Create storage buffers for both original and copied multisampled depth/stencil images.
8089 const auto bufferCount = static_cast<size_t>(fbWidth * fbHeight * m_params.samples);
8090 const auto bufferSize = static_cast<VkDeviceSize>(bufferCount * sizeof(float));
8091 BufferWithMemory bufferOriginal (vkd, device, alloc, makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible);
8092 BufferWithMemory bufferCopied (vkd, device, alloc, makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible);
8093 auto& bufferOriginalAlloc = bufferOriginal.getAllocation();
8094 auto& bufferCopiedAlloc = bufferCopied.getAllocation();
8095
8096 // Update descriptor sets.
8097 DescriptorSetUpdateBuilder updater;
8098
8099 const auto bufferOriginalInfo = makeDescriptorBufferInfo(bufferOriginal.get(), 0ull, bufferSize);
8100 const auto bufferCopiedInfo = makeDescriptorBufferInfo(bufferCopied.get(), 0ull, bufferSize);
8101 updater.writeSingle(descriptorSetBuffer.get(), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferOriginalInfo);
8102 updater.writeSingle(descriptorSetBuffer.get(), DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferCopiedInfo);
8103
8104 std::vector<VkDescriptorImageInfo> imageInfos;
8105 imageInfos.reserve(imageViewsRaw.size());
8106 for (size_t i = 0; i < imageViewsRaw.size(); ++i)
8107 {
8108 imageInfos.push_back(makeDescriptorImageInfo(DE_NULL, imageViewsRaw[i], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL));
8109 updater.writeSingle(descriptorSetAttachments.get(), DescriptorSetUpdateBuilder::Location::binding(static_cast<deUint32>(i)), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &imageInfos[i]);
8110 }
8111
8112 updater.update(vkd, device);
8113
8114 // Vertex buffer.
8115 std::vector<tcu::Vec4> fullScreenQuad;
8116 {
8117 // Full screen quad so every framebuffer pixel and sample location is verified by the shader.
8118 const tcu::Vec4 topLeft (-1.0f, -1.0f, 0.0f, 1.0f);
8119 const tcu::Vec4 topRight ( 1.0f, -1.0f, 0.0f, 1.0f);
8120 const tcu::Vec4 bottomLeft (-1.0f, 1.0f, 0.0f, 1.0f);
8121 const tcu::Vec4 bottomRight ( 1.0f, 1.0f, 0.0f, 1.0f);
8122
8123 fullScreenQuad.reserve(6u);
8124 fullScreenQuad.push_back(topLeft);
8125 fullScreenQuad.push_back(topRight);
8126 fullScreenQuad.push_back(bottomRight);
8127 fullScreenQuad.push_back(topLeft);
8128 fullScreenQuad.push_back(bottomRight);
8129 fullScreenQuad.push_back(bottomLeft);
8130 }
8131
8132 const auto vertexBufferSize = static_cast<VkDeviceSize>(fullScreenQuad.size() * sizeof(decltype(fullScreenQuad)::value_type));
8133 const auto vertexBufferInfo = makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
8134 const BufferWithMemory vertexBuffer (vkd, device, alloc, vertexBufferInfo, MemoryRequirement::HostVisible);
8135 const VkDeviceSize vertexBufferOffset = 0ull;
8136
8137 deMemcpy(vertexBuffer.getAllocation().getHostPtr(), fullScreenQuad.data(), static_cast<size_t>(vertexBufferSize));
8138 flushAlloc(vkd, device, vertexBuffer.getAllocation());
8139
8140 // Graphics pipeline.
8141 const std::vector<VkViewport> viewports (1, makeViewport(m_srcImage.extent));
8142 const std::vector<VkRect2D> scissors (1, makeRect2D(m_srcImage.extent));
8143
8144 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
8145 {
8146 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
8147 nullptr, // const void* pNext;
8148 0u, // VkPipelineMultisampleStateCreateFlags flags;
8149 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
8150 VK_FALSE, // VkBool32 sampleShadingEnable;
8151 0.0f, // float minSampleShading;
8152 nullptr, // const VkSampleMask* pSampleMask;
8153 VK_FALSE, // VkBool32 alphaToCoverageEnable;
8154 VK_FALSE // VkBool32 alphaToOneEnable;
8155 };
8156
8157 const auto graphicsPipeline = makeGraphicsPipeline(
8158 vkd, // const DeviceInterface& vk
8159 device, // const VkDevice device
8160 pipelineLayout.get(), // const VkPipelineLayout pipelineLayout
8161 vertexModule.get(), // const VkShaderModule vertexShaderModule
8162 DE_NULL, // const VkShaderModule tessellationControlModule
8163 DE_NULL, // const VkShaderModule tessellationEvalModule
8164 DE_NULL, // const VkShaderModule geometryShaderModule
8165 verificationModule.get(), // const VkShaderModule fragmentShaderModule
8166 renderPass.get(), // const VkRenderPass renderPass
8167 viewports, // const std::vector<VkViewport>& viewports
8168 scissors, // const std::vector<VkRect2D>& scissors
8169 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
8170 0u, // const deUint32 subpass
8171 0u, // const deUint32 patchControlPoints
8172 nullptr, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
8173 nullptr, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
8174 &multisampleStateParams); // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
8175
8176 // Make sure multisample copy data is available to the fragment shader.
8177 const auto imagesBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT);
8178
8179 // Record and submit command buffer.
8180 beginCommandBuffer(vkd, cmdBuffer);
8181 vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 1u, &imagesBarrier, 0u, nullptr, 0u, nullptr);
8182 beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffer.get(), makeRect2D(m_srcImage.extent));
8183 vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline.get());
8184 vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
8185
8186 vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), VK_SHADER_STAGE_FRAGMENT_BIT, 0u, pushConstantSize, pushConstantData.data());
8187 vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u, static_cast<deUint32>(descriptorSets.size()), descriptorSets.data(), 0u, nullptr);
8188 vkd.cmdDraw(cmdBuffer, static_cast<deUint32>(fullScreenQuad.size()), 1u, 0u, 0u);
8189
8190 endRenderPass(vkd, cmdBuffer);
8191
8192 // Make sure verification buffer data is available on the host.
8193 const auto bufferBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
8194 vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &bufferBarrier, 0u, nullptr, 0u, nullptr);
8195 endCommandBuffer(vkd, cmdBuffer);
8196 submitCommandsAndWait(vkd, device, queue, cmdBuffer);
8197
8198 // Verify intermediate results.
8199 invalidateAlloc(vkd, device, bufferOriginalAlloc);
8200 invalidateAlloc(vkd, device, bufferCopiedAlloc);
8201 std::vector<float> outputOriginal (bufferCount, 0);
8202 std::vector<float> outputCopied (bufferCount, 0);
8203 deMemcpy(outputOriginal.data(), bufferOriginalAlloc.getHostPtr(), static_cast<size_t>(bufferSize));
8204 deMemcpy(outputCopied.data(), bufferCopiedAlloc.getHostPtr(), static_cast<size_t>(bufferSize));
8205
8206 auto& log = m_context.getTestContext().getLog();
8207 log << tcu::TestLog::Message << "Verifying intermediate multisample copy results" << tcu::TestLog::EndMessage;
8208
8209 const auto sampleCount = static_cast<deUint32>(m_params.samples);
8210
8211 // Verify copied region(s)
8212 for (const auto ®ion : m_regions)
8213 {
8214 for (uint32_t x = 0u; x < region.imageCopy.extent.width; ++x)
8215 for (uint32_t y = 0u; y < region.imageCopy.extent.height; ++y)
8216 for (uint32_t s = 0u; s < sampleCount; ++s)
8217 {
8218 tcu::UVec2 srcCoord(x + region.imageCopy.srcOffset.x, y + region.imageCopy.srcOffset.y);
8219 tcu::UVec2 dstCoord(x + region.imageCopy.dstOffset.x, y + region.imageCopy.dstOffset.y);
8220 const auto srcIndex = (srcCoord.y() * fbWidth + srcCoord.x()) * sampleCount + s;
8221 const auto dstIndex = (dstCoord.y() * fbWidth + dstCoord.x()) * sampleCount + s;
8222 if (outputOriginal[srcIndex] != outputCopied[dstIndex])
8223 {
8224 std::ostringstream msg;
8225 msg << "Intermediate verification failed for coordinates (" << x << ", " << y << ") sample " << s << ". "
8226 << "result: " << outputCopied[dstIndex] << " expected: " << outputOriginal[srcIndex];
8227 return tcu::TestStatus::fail(msg.str());
8228 }
8229 }
8230 }
8231
8232 if (m_params.copyOptions == COPY_PARTIAL)
8233 {
8234 // In the partial copy tests the destination image contains copied data only in the bottom half of the image.
8235 // Verify that the upper half of the image is left at it's clear value (0).
8236 for (uint32_t x = 0u; x < m_srcImage.extent.width; x++)
8237 for (uint32_t y = 0u; y < m_srcImage.extent.height / 2; y++)
8238 for (uint32_t s = 0u; s < sampleCount; ++s)
8239 {
8240 const auto bufferIndex = (y * fbWidth + x) * sampleCount + s;
8241 if (outputCopied[bufferIndex] != m_clearValue)
8242 {
8243 std::ostringstream msg;
8244 msg << "Intermediate verification failed for coordinates (" << x << ", " << y << ") sample " << s << ". "
8245 << "result: " << outputCopied[bufferIndex] << " expected: 0.0" ;
8246 return tcu::TestStatus::fail(msg.str());
8247 }
8248 }
8249 }
8250
8251 log << tcu::TestLog::Message << "Intermediate multisample copy verification passed" << tcu::TestLog::EndMessage;
8252 return tcu::TestStatus::pass("Pass");
8253 }
8254
8255 class DepthStencilMSAATestCase : public vkt::TestCase
8256 {
8257 public:
DepthStencilMSAATestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const DepthStencilMSAA::TestParameters testParams)8258 DepthStencilMSAATestCase (tcu::TestContext& testCtx,
8259 const std::string& name,
8260 const std::string& description,
8261 const DepthStencilMSAA::TestParameters testParams)
8262 : vkt::TestCase (testCtx, name, description)
8263 , m_params (testParams)
8264 {}
8265
8266 virtual void initPrograms (SourceCollections& programCollection) const;
8267
createInstance(Context & context) const8268 virtual TestInstance* createInstance (Context& context) const
8269 {
8270 return new DepthStencilMSAA(context, m_params);
8271 }
8272
checkSupport(Context & context) const8273 virtual void checkSupport (Context& context) const
8274 {
8275 const VkSampleCountFlagBits rasterizationSamples = m_params.samples;
8276
8277 if (!context.getDeviceFeatures().fragmentStoresAndAtomics)
8278 TCU_THROW(NotSupportedError, "fragmentStoresAndAtomics not supported");
8279
8280 if ((m_params.copyAspect & VK_IMAGE_ASPECT_DEPTH_BIT) && !(context.getDeviceProperties().limits.framebufferDepthSampleCounts & rasterizationSamples))
8281 TCU_THROW(NotSupportedError, "Unsupported number of depth samples");
8282
8283 if ((m_params.copyAspect & VK_IMAGE_ASPECT_STENCIL_BIT) && !(context.getDeviceProperties().limits.framebufferDepthSampleCounts & rasterizationSamples))
8284 TCU_THROW(NotSupportedError, "Unsupported number of stencil samples");
8285
8286 VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
8287 | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
8288 | VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
8289 | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
8290
8291 VkImageFormatProperties properties;
8292 if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
8293 m_params.imageFormat,
8294 VK_IMAGE_TYPE_2D,
8295 VK_IMAGE_TILING_OPTIMAL,
8296 usageFlags, 0,
8297 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
8298 {
8299 TCU_THROW(NotSupportedError, "Format not supported");
8300 }
8301
8302 if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
8303 (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
8304 {
8305 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
8306 }
8307 }
8308
8309 private:
8310
getArrayLayerCount() const8311 uint32_t getArrayLayerCount () const
8312 {
8313 return (m_params.copyOptions == DepthStencilMSAA::COPY_ARRAY_TO_ARRAY) ? 5u : 1u;
8314 }
8315
createVerificationShader(std::ostringstream & shaderCode,const VkImageAspectFlagBits attachmentAspect) const8316 void createVerificationShader (std::ostringstream& shaderCode, const VkImageAspectFlagBits attachmentAspect) const
8317 {
8318 DE_ASSERT(attachmentAspect & (VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT));
8319 // The shader copies the sample values from the source and destination image to output buffers OriginalValue and
8320 // CopiedValues, respectively. If the dst image contains multiple array layers, only one layer has the copied data
8321 // and the rest should be filled with the clear value (0). This is also verified in this shader.
8322 // Array layer cases need an image view per layer in the copied image.
8323 // Set 0 contains the output buffers.
8324 // Set 1 contains the input attachments.
8325
8326 std::string inputAttachmentPrefix = attachmentAspect == VK_IMAGE_ASPECT_STENCIL_BIT ? "u" : "";
8327
8328 shaderCode
8329 << "#version 450\n"
8330 << "\n"
8331 << "layout (push_constant, std430) uniform PushConstants {\n"
8332 << " int width;\n"
8333 << " int height;\n"
8334 << " int samples;\n"
8335 << "};\n"
8336 << "layout (set=0, binding=0) buffer OriginalValues {\n"
8337 << " float outputOriginal[];\n"
8338 << "};\n"
8339 << "layout (set=0, binding=1) buffer CopiedValues {\n"
8340 << " float outputCopied[];\n"
8341 << "};\n"
8342 << "layout (input_attachment_index=0, set=1, binding=0) uniform " << inputAttachmentPrefix << "subpassInputMS attachment0;\n"
8343 ;
8344
8345 const auto layerCount = getArrayLayerCount();
8346 for (deUint32 layerNdx = 0u; layerNdx < layerCount; ++layerNdx)
8347 {
8348 const auto i = layerNdx + 1u;
8349 shaderCode << "layout (input_attachment_index=" << i << ", set=1, binding=" << i << ") uniform " << inputAttachmentPrefix << "subpassInputMS attachment" << i << ";\n";
8350 }
8351
8352 // Using a loop to iterate over each sample avoids the need for the sampleRateShading feature. The pipeline needs to be
8353 // created with a single sample.
8354 shaderCode
8355 << "\n"
8356 << "void main() {\n"
8357 << " for (int sampleID = 0; sampleID < samples; ++sampleID) {\n"
8358 << " ivec3 coords = ivec3(int(gl_FragCoord.x), int(gl_FragCoord.y), sampleID);\n"
8359 << " int bufferPos = (coords.y * width + coords.x) * samples + coords.z;\n"
8360 << " " << inputAttachmentPrefix << "vec4 orig = subpassLoad(attachment0, sampleID);\n"
8361 << " outputOriginal[bufferPos] = orig.r;\n"
8362 ;
8363
8364 for (deUint32 layerNdx = 0u; layerNdx < layerCount; ++layerNdx)
8365 {
8366 const auto i = layerNdx + 1u;
8367 shaderCode << " " << inputAttachmentPrefix << "vec4 copy" << i << " = subpassLoad(attachment" << i << ", sampleID);\n";
8368 }
8369
8370 std::ostringstream testCondition;
8371 std::string layerToVerify = m_params.copyOptions == DepthStencilMSAA::COPY_ARRAY_TO_ARRAY ? "copy4" : "copy1";
8372 shaderCode
8373 << "\n"
8374 << " outputCopied[bufferPos] = " << layerToVerify << ".r; \n";
8375
8376 if (m_params.copyOptions == DepthStencilMSAA::COPY_ARRAY_TO_ARRAY)
8377 {
8378 // 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.
8379 // This verifies that all the samples in the other layers have proper values.
8380 shaderCode << " bool equalEmptyLayers = ";
8381 for (deUint32 layerNdx = 0u; layerNdx < layerCount; ++layerNdx)
8382 {
8383 if (layerNdx == 3)
8384 continue;
8385 const auto i = layerNdx + 1u;
8386 shaderCode << "copy" << i << ".r == " << (attachmentAspect == VK_IMAGE_ASPECT_STENCIL_BIT ? "0" : "0.0") << (layerNdx < 4u ? " && " : ";\n");
8387 }
8388 shaderCode
8389 << " if (!equalEmptyLayers)\n"
8390 << " outputCopied[bufferPos]--; \n";
8391 }
8392
8393 shaderCode
8394 << " }\n"
8395 << "}\n";
8396 }
8397
8398 DepthStencilMSAA::TestParameters m_params;
8399 };
8400
initPrograms(SourceCollections & programCollection) const8401 void DepthStencilMSAATestCase::initPrograms (SourceCollections& programCollection) const
8402 {
8403 programCollection.glslSources.add("vert") << glu::VertexSource(
8404 "#version 310 es\n"
8405 "layout (location = 0) in highp vec4 a_position;\n"
8406 "void main()\n"
8407 "{\n"
8408 " gl_Position = vec4(a_position.xy, 1.0, 1.0);\n"
8409 "}\n");
8410
8411 programCollection.glslSources.add("frag") << glu::FragmentSource(
8412 "#version 310 es\n"
8413 "void main()\n"
8414 "{}\n");
8415
8416 // Create the verifying shader for the depth aspect if the depth is used.
8417 if (m_params.copyAspect & VK_IMAGE_ASPECT_DEPTH_BIT)
8418 {
8419 std::ostringstream verificationShader;
8420 // All the depth formats are float types, so the input attachment prefix is not used.
8421 createVerificationShader(verificationShader, VK_IMAGE_ASPECT_DEPTH_BIT);
8422 programCollection.glslSources.add("verify_depth") << glu::FragmentSource(verificationShader.str());
8423 }
8424
8425 // Create the verifying shader for the stencil aspect if the stencil is used.
8426 if (m_params.copyAspect & VK_IMAGE_ASPECT_STENCIL_BIT)
8427 {
8428 std::ostringstream verificationShader;
8429 // All the stencil formats are uint types, so the input attachment prefix is "u".
8430 createVerificationShader(verificationShader, VK_IMAGE_ASPECT_STENCIL_BIT);
8431 programCollection.glslSources.add("verify_stencil") << glu::FragmentSource(verificationShader.str());
8432 }
8433 }
8434
8435 struct BufferOffsetParams
8436 {
8437 static constexpr deUint32 kMaxOffset = 8u;
8438
8439 deUint32 srcOffset;
8440 deUint32 dstOffset;
8441 };
8442
checkZerosAt(const std::vector<deUint8> & bufferData,deUint32 from,deUint32 count)8443 void checkZerosAt(const std::vector<deUint8>& bufferData, deUint32 from, deUint32 count)
8444 {
8445 constexpr deUint8 zero{0};
8446 for (deUint32 i = 0; i < count; ++i)
8447 {
8448 const auto& val = bufferData[from + i];
8449 if (val != zero)
8450 {
8451 std::ostringstream msg;
8452 msg << "Unexpected non-zero byte found at position " << (from + i) << ": " << static_cast<int>(val);
8453 TCU_FAIL(msg.str());
8454 }
8455 }
8456 }
8457
bufferOffsetTest(Context & ctx,BufferOffsetParams params)8458 tcu::TestStatus bufferOffsetTest (Context& ctx, BufferOffsetParams params)
8459 {
8460 // 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.
8461 constexpr auto kMaxOffset = BufferOffsetParams::kMaxOffset;
8462 constexpr auto kBlockSize = kMaxOffset * 2u;
8463 constexpr auto kBufferSize = kMaxOffset * kBlockSize;
8464
8465 DE_ASSERT(params.srcOffset < kMaxOffset);
8466 DE_ASSERT(params.dstOffset < kMaxOffset);
8467
8468 const auto& vkd = ctx.getDeviceInterface();
8469 const auto device = ctx.getDevice();
8470 auto& alloc = ctx.getDefaultAllocator();
8471 const auto qIndex = ctx.getUniversalQueueFamilyIndex();
8472 const auto queue = ctx.getUniversalQueue();
8473
8474 const auto srcBufferInfo = makeBufferCreateInfo(kBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
8475 const auto dstBufferInfo = makeBufferCreateInfo(kBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
8476
8477 BufferWithMemory srcBuffer (vkd, device, alloc, srcBufferInfo, MemoryRequirement::HostVisible);
8478 BufferWithMemory dstBuffer (vkd, device, alloc, dstBufferInfo, MemoryRequirement::HostVisible);
8479 auto& srcAlloc = srcBuffer.getAllocation();
8480 auto& dstAlloc = dstBuffer.getAllocation();
8481
8482 // Zero-out destination buffer.
8483 deMemset(dstAlloc.getHostPtr(), 0, kBufferSize);
8484 flushAlloc(vkd, device, dstAlloc);
8485
8486 // Fill source buffer with nonzero bytes.
8487 std::vector<deUint8> srcData;
8488 srcData.reserve(kBufferSize);
8489 for (deUint32 i = 0; i < kBufferSize; ++i)
8490 srcData.push_back(static_cast<deUint8>(100u + i));
8491 deMemcpy(srcAlloc.getHostPtr(), srcData.data(), de::dataSize(srcData));
8492 flushAlloc(vkd, device, srcAlloc);
8493
8494 // Copy regions.
8495 std::vector<VkBufferCopy> copies;
8496 copies.reserve(kMaxOffset);
8497 for (deUint32 i = 0; i < kMaxOffset; ++i)
8498 {
8499 const auto blockStart = kBlockSize * i;
8500 const auto copySize = i + 1u;
8501 const auto bufferCopy = makeBufferCopy(params.srcOffset + blockStart, params.dstOffset + blockStart, copySize);
8502 copies.push_back(bufferCopy);
8503 }
8504
8505 const auto cmdPool = makeCommandPool(vkd, device, qIndex);
8506 const auto cmdBufferPtr = allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
8507 const auto cmdBuffer = cmdBufferPtr.get();
8508
8509 beginCommandBuffer(vkd, cmdBuffer);
8510 vkd.cmdCopyBuffer(cmdBuffer, srcBuffer.get(), dstBuffer.get(), static_cast<deUint32>(copies.size()), copies.data());
8511 const auto barrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
8512 vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &barrier, 0u, nullptr, 0u, nullptr);
8513 endCommandBuffer(vkd, cmdBuffer);
8514 submitCommandsAndWait(vkd, device, queue, cmdBuffer);
8515 invalidateAlloc(vkd, device, dstAlloc);
8516
8517 // Verify destination buffer data.
8518 std::vector<deUint8> dstData(kBufferSize);
8519 deMemcpy(dstData.data(), dstAlloc.getHostPtr(), de::dataSize(dstData));
8520
8521 for (deUint32 blockIdx = 0; blockIdx < kMaxOffset; ++blockIdx)
8522 {
8523 const auto blockStart = kBlockSize * blockIdx;
8524 const auto copySize = blockIdx + 1u;
8525
8526 // Verify no data has been written before dstOffset.
8527 checkZerosAt(dstData, blockStart, params.dstOffset);
8528
8529 // Verify copied block.
8530 for (deUint32 i = 0; i < copySize; ++i)
8531 {
8532 const auto& dstVal = dstData[blockStart + params.dstOffset + i];
8533 const auto& srcVal = srcData[blockStart + params.srcOffset + i];
8534 if (dstVal != srcVal)
8535 {
8536 std::ostringstream msg;
8537 msg << "Unexpected value found at position " << (blockStart + params.dstOffset + i) << ": expected " << static_cast<int>(srcVal) << " but found " << static_cast<int>(dstVal);
8538 TCU_FAIL(msg.str());
8539 }
8540 }
8541
8542 // Verify no data has been written after copy block.
8543 checkZerosAt(dstData, blockStart + params.dstOffset + copySize, kBlockSize - (params.dstOffset + copySize));
8544 }
8545
8546 return tcu::TestStatus::pass("Pass");
8547 }
8548
getSampleCountCaseName(VkSampleCountFlagBits sampleFlag)8549 std::string getSampleCountCaseName (VkSampleCountFlagBits sampleFlag)
8550 {
8551 return de::toLower(de::toString(getSampleCountFlagsStr(sampleFlag)).substr(16));
8552 }
8553
getFormatCaseName(VkFormat format)8554 std::string getFormatCaseName (VkFormat format)
8555 {
8556 return de::toLower(de::toString(getFormatStr(format)).substr(10));
8557 }
8558
getImageLayoutCaseName(VkImageLayout layout)8559 std::string getImageLayoutCaseName (VkImageLayout layout)
8560 {
8561 switch (layout)
8562 {
8563 case VK_IMAGE_LAYOUT_GENERAL:
8564 return "general";
8565 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
8566 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
8567 return "optimal";
8568 default:
8569 DE_ASSERT(false);
8570 return "";
8571 }
8572 }
8573
addImageToImageSimpleTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)8574 void addImageToImageSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
8575 {
8576 tcu::TestContext& testCtx = group->getTestContext();
8577
8578 {
8579 TestParams params;
8580 params.src.image.imageType = VK_IMAGE_TYPE_2D;
8581 params.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
8582 params.src.image.extent = defaultExtent;
8583 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8584 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8585 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
8586 params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
8587 params.dst.image.extent = defaultExtent;
8588 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8589 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8590 params.allocationKind = allocationKind;
8591 params.extensionUse = extensionUse;
8592
8593 {
8594 const VkImageCopy testCopy =
8595 {
8596 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
8597 {0, 0, 0}, // VkOffset3D srcOffset;
8598 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
8599 {0, 0, 0}, // VkOffset3D dstOffset;
8600 defaultExtent, // VkExtent3D extent;
8601 };
8602
8603 CopyRegion imageCopy;
8604 imageCopy.imageCopy = testCopy;
8605 params.regions.push_back(imageCopy);
8606 }
8607
8608 group->addChild(new CopyImageToImageTestCase(testCtx, "whole_image", "Whole image", params));
8609 }
8610
8611 {
8612 TestParams params;
8613 params.src.image.imageType = VK_IMAGE_TYPE_2D;
8614 params.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
8615 params.src.image.extent = defaultExtent;
8616 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8617 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8618 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
8619 params.dst.image.format = VK_FORMAT_R32_UINT;
8620 params.dst.image.extent = defaultExtent;
8621 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8622 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8623 params.allocationKind = allocationKind;
8624 params.extensionUse = extensionUse;
8625
8626 {
8627 const VkImageCopy testCopy =
8628 {
8629 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
8630 {0, 0, 0}, // VkOffset3D srcOffset;
8631 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
8632 {0, 0, 0}, // VkOffset3D dstOffset;
8633 defaultExtent, // VkExtent3D extent;
8634 };
8635
8636 CopyRegion imageCopy;
8637 imageCopy.imageCopy = testCopy;
8638 params.regions.push_back(imageCopy);
8639 }
8640
8641 group->addChild(new CopyImageToImageTestCase(testCtx, "whole_image_diff_fromat", "Whole image with different format", params));
8642 }
8643
8644 {
8645 TestParams params;
8646 params.src.image.imageType = VK_IMAGE_TYPE_2D;
8647 params.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
8648 params.src.image.extent = defaultExtent;
8649 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8650 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8651 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
8652 params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
8653 params.dst.image.extent = defaultExtent;
8654 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8655 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8656 params.allocationKind = allocationKind;
8657 params.extensionUse = extensionUse;
8658
8659 {
8660 const VkImageCopy testCopy =
8661 {
8662 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
8663 {0, 0, 0}, // VkOffset3D srcOffset;
8664 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
8665 {defaultQuarterSize, defaultQuarterSize / 2, 0}, // VkOffset3D dstOffset;
8666 {defaultQuarterSize / 2, defaultQuarterSize / 2, 1}, // VkExtent3D extent;
8667 };
8668
8669 CopyRegion imageCopy;
8670 imageCopy.imageCopy = testCopy;
8671 params.regions.push_back(imageCopy);
8672 }
8673
8674 group->addChild(new CopyImageToImageTestCase(testCtx, "partial_image", "Partial image", params));
8675 }
8676
8677 static const struct
8678 {
8679 std::string name;
8680 vk::VkFormat format1;
8681 vk::VkFormat format2;
8682 } formats [] =
8683 {
8684 { "diff_format", vk::VK_FORMAT_R32_UINT, vk::VK_FORMAT_R8G8B8A8_UNORM },
8685 { "same_format", vk::VK_FORMAT_R8G8B8A8_UNORM, vk::VK_FORMAT_R8G8B8A8_UNORM }
8686 };
8687 static const struct
8688 {
8689 std::string name;
8690 vk::VkBool32 clear;
8691 } clears [] =
8692 {
8693 { "clear", VK_TRUE },
8694 { "noclear", VK_FALSE }
8695 };
8696 static const struct
8697 {
8698 std::string name;
8699 VkExtent3D extent;
8700 } extents [] =
8701 {
8702 { "npot", {65u, 63u, 1u} },
8703 { "pot", {64u, 64u, 1u} }
8704 };
8705
8706 for (const auto& format : formats)
8707 {
8708 for (const auto& clear : clears)
8709 {
8710 for (const auto& extent : extents)
8711 {
8712 TestParams params;
8713 params.src.image.imageType = VK_IMAGE_TYPE_2D;
8714 params.src.image.format = format.format1;
8715 params.src.image.extent = extent.extent;
8716 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8717 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8718 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
8719 params.dst.image.format = format.format2;
8720 params.dst.image.extent = extent.extent;
8721 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8722 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8723 params.allocationKind = allocationKind;
8724 params.extensionUse = extensionUse;
8725 params.clearDestination = clear.clear;
8726
8727 {
8728 VkImageCopy testCopy =
8729 {
8730 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
8731 {34, 34, 0}, // VkOffset3D srcOffset;
8732 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
8733 {0, 0, 0}, // VkOffset3D dstOffset;
8734 {31, 29, 1} // VkExtent3D extent;
8735 };
8736
8737 if (extent.name == "pot")
8738 {
8739 testCopy.srcOffset = { 16, 16, 0 };
8740 testCopy.extent = { 32, 32, 1 };
8741 }
8742
8743 CopyRegion imageCopy;
8744 imageCopy.imageCopy = testCopy;
8745 params.regions.push_back(imageCopy);
8746 }
8747
8748 // Example test case name: "partial_image_npot_diff_format_clear"
8749 const std::string testCaseName = "partial_image_" + extent.name + "_" + format.name + "_" + clear.name;
8750
8751 group->addChild(new CopyImageToImageTestCase(testCtx, testCaseName, "", params));
8752 }
8753 }
8754 }
8755
8756 {
8757 TestParams params;
8758 params.src.image.imageType = VK_IMAGE_TYPE_2D;
8759 params.src.image.format = VK_FORMAT_D32_SFLOAT;
8760 params.src.image.extent = defaultExtent;
8761 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8762 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8763 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
8764 params.dst.image.format = VK_FORMAT_D32_SFLOAT;
8765 params.dst.image.extent = defaultExtent;
8766 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8767 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8768 params.allocationKind = allocationKind;
8769 params.extensionUse = extensionUse;
8770
8771 {
8772 const VkImageSubresourceLayers sourceLayer =
8773 {
8774 VK_IMAGE_ASPECT_DEPTH_BIT, // VkImageAspectFlags aspectMask;
8775 0u, // deUint32 mipLevel;
8776 0u, // deUint32 baseArrayLayer;
8777 1u // deUint32 layerCount;
8778 };
8779 const VkImageCopy testCopy =
8780 {
8781 sourceLayer, // VkImageSubresourceLayers srcSubresource;
8782 {0, 0, 0}, // VkOffset3D srcOffset;
8783 sourceLayer, // VkImageSubresourceLayers dstSubresource;
8784 {defaultQuarterSize, defaultQuarterSize / 2, 0}, // VkOffset3D dstOffset;
8785 {defaultQuarterSize / 2, defaultQuarterSize / 2, 1}, // VkExtent3D extent;
8786 };
8787
8788 CopyRegion imageCopy;
8789 imageCopy.imageCopy = testCopy;
8790 params.regions.push_back(imageCopy);
8791 }
8792
8793 group->addChild(new CopyImageToImageTestCase(testCtx, "depth", "With depth", params));
8794 }
8795
8796 {
8797 TestParams params;
8798 params.src.image.imageType = VK_IMAGE_TYPE_2D;
8799 params.src.image.format = VK_FORMAT_S8_UINT;
8800 params.src.image.extent = defaultExtent;
8801 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8802 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8803 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
8804 params.dst.image.format = VK_FORMAT_S8_UINT;
8805 params.dst.image.extent = defaultExtent;
8806 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8807 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8808 params.allocationKind = allocationKind;
8809 params.extensionUse = extensionUse;
8810
8811 {
8812 const VkImageSubresourceLayers sourceLayer =
8813 {
8814 VK_IMAGE_ASPECT_STENCIL_BIT, // VkImageAspectFlags aspectMask;
8815 0u, // deUint32 mipLevel;
8816 0u, // deUint32 baseArrayLayer;
8817 1u // deUint32 layerCount;
8818 };
8819 const VkImageCopy testCopy =
8820 {
8821 sourceLayer, // VkImageSubresourceLayers srcSubresource;
8822 {0, 0, 0}, // VkOffset3D srcOffset;
8823 sourceLayer, // VkImageSubresourceLayers dstSubresource;
8824 {defaultQuarterSize, defaultQuarterSize / 2, 0}, // VkOffset3D dstOffset;
8825 {defaultQuarterSize / 2, defaultQuarterSize / 2, 1}, // VkExtent3D extent;
8826 };
8827
8828 CopyRegion imageCopy;
8829 imageCopy.imageCopy = testCopy;
8830 params.regions.push_back(imageCopy);
8831 }
8832
8833 group->addChild(new CopyImageToImageTestCase(testCtx, "stencil", "With stencil", params));
8834 }
8835 }
8836
8837 struct CopyColorTestParams
8838 {
8839 TestParams params;
8840 const VkFormat* compatibleFormats;
8841 };
8842
addImageToImageAllFormatsColorSrcFormatDstFormatTests(tcu::TestCaseGroup * group,TestParams params)8843 void addImageToImageAllFormatsColorSrcFormatDstFormatTests (tcu::TestCaseGroup* group, TestParams params)
8844 {
8845 const VkImageLayout copySrcLayouts[] =
8846 {
8847 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
8848 VK_IMAGE_LAYOUT_GENERAL
8849 };
8850 const VkImageLayout copyDstLayouts[] =
8851 {
8852 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
8853 VK_IMAGE_LAYOUT_GENERAL
8854 };
8855
8856 for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx)
8857 {
8858 params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
8859
8860 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx)
8861 {
8862 params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
8863
8864 const std::string testName = getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
8865 getImageLayoutCaseName(params.dst.image.operationLayout);
8866 const std::string description = "From layout " + getImageLayoutCaseName(params.src.image.operationLayout) +
8867 " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
8868 group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, description, params));
8869 }
8870 }
8871 }
8872
isAllowedImageToImageAllFormatsColorSrcFormatTests(const CopyColorTestParams & testParams)8873 bool isAllowedImageToImageAllFormatsColorSrcFormatTests(const CopyColorTestParams& testParams)
8874 {
8875 bool result = true;
8876
8877 if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED)
8878 {
8879 DE_ASSERT(!dedicatedAllocationImageToImageFormatsToTestSet.empty());
8880
8881 result =
8882 de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.dst.image.format) ||
8883 de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.src.image.format);
8884 }
8885
8886 return result;
8887 }
8888
addImageToImageAllFormatsColorSrcFormatTests(tcu::TestCaseGroup * group,CopyColorTestParams testParams)8889 void addImageToImageAllFormatsColorSrcFormatTests (tcu::TestCaseGroup* group, CopyColorTestParams testParams)
8890 {
8891 // If testParams.compatibleFormats is nullptr, the destination format will be copied from the source format.
8892 const VkFormat srcFormatOnly[2] = { testParams.params.src.image.format, VK_FORMAT_UNDEFINED };
8893 const VkFormat* formatList = (testParams.compatibleFormats ? testParams.compatibleFormats : srcFormatOnly);
8894
8895 for (int dstFormatIndex = 0; formatList[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex)
8896 {
8897 testParams.params.dst.image.format = formatList[dstFormatIndex];
8898
8899 const VkFormat srcFormat = testParams.params.src.image.format;
8900 const VkFormat dstFormat = testParams.params.dst.image.format;
8901
8902 if (!isSupportedByFramework(dstFormat) && !isCompressedFormat(dstFormat))
8903 continue;
8904
8905 if (!isAllowedImageToImageAllFormatsColorSrcFormatTests(testParams))
8906 continue;
8907
8908 if (isCompressedFormat(srcFormat) && isCompressedFormat(dstFormat))
8909 if ((getBlockWidth(srcFormat) != getBlockWidth(dstFormat)) || (getBlockHeight(srcFormat) != getBlockHeight(dstFormat)))
8910 continue;
8911
8912 const std::string description = "Copy to destination format " + getFormatCaseName(dstFormat);
8913 addTestGroup(group, getFormatCaseName(dstFormat), description, addImageToImageAllFormatsColorSrcFormatDstFormatTests, testParams.params);
8914 }
8915 }
8916
8917 const VkFormat compatibleFormats8Bit[] =
8918 {
8919 VK_FORMAT_R4G4_UNORM_PACK8,
8920 VK_FORMAT_R8_UNORM,
8921 VK_FORMAT_R8_SNORM,
8922 VK_FORMAT_R8_USCALED,
8923 VK_FORMAT_R8_SSCALED,
8924 VK_FORMAT_R8_UINT,
8925 VK_FORMAT_R8_SINT,
8926 VK_FORMAT_R8_SRGB,
8927
8928 VK_FORMAT_UNDEFINED
8929 };
8930 const VkFormat compatibleFormats16Bit[] =
8931 {
8932 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
8933 VK_FORMAT_B4G4R4A4_UNORM_PACK16,
8934 VK_FORMAT_R5G6B5_UNORM_PACK16,
8935 VK_FORMAT_B5G6R5_UNORM_PACK16,
8936 VK_FORMAT_R5G5B5A1_UNORM_PACK16,
8937 VK_FORMAT_B5G5R5A1_UNORM_PACK16,
8938 VK_FORMAT_A1R5G5B5_UNORM_PACK16,
8939 VK_FORMAT_R8G8_UNORM,
8940 VK_FORMAT_R8G8_SNORM,
8941 VK_FORMAT_R8G8_USCALED,
8942 VK_FORMAT_R8G8_SSCALED,
8943 VK_FORMAT_R8G8_UINT,
8944 VK_FORMAT_R8G8_SINT,
8945 VK_FORMAT_R8G8_SRGB,
8946 VK_FORMAT_R16_UNORM,
8947 VK_FORMAT_R16_SNORM,
8948 VK_FORMAT_R16_USCALED,
8949 VK_FORMAT_R16_SSCALED,
8950 VK_FORMAT_R16_UINT,
8951 VK_FORMAT_R16_SINT,
8952 VK_FORMAT_R16_SFLOAT,
8953 VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
8954 VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
8955
8956 VK_FORMAT_UNDEFINED
8957 };
8958 const VkFormat compatibleFormats24Bit[] =
8959 {
8960 VK_FORMAT_R8G8B8_UNORM,
8961 VK_FORMAT_R8G8B8_SNORM,
8962 VK_FORMAT_R8G8B8_USCALED,
8963 VK_FORMAT_R8G8B8_SSCALED,
8964 VK_FORMAT_R8G8B8_UINT,
8965 VK_FORMAT_R8G8B8_SINT,
8966 VK_FORMAT_R8G8B8_SRGB,
8967 VK_FORMAT_B8G8R8_UNORM,
8968 VK_FORMAT_B8G8R8_SNORM,
8969 VK_FORMAT_B8G8R8_USCALED,
8970 VK_FORMAT_B8G8R8_SSCALED,
8971 VK_FORMAT_B8G8R8_UINT,
8972 VK_FORMAT_B8G8R8_SINT,
8973 VK_FORMAT_B8G8R8_SRGB,
8974
8975 VK_FORMAT_UNDEFINED
8976 };
8977 const VkFormat compatibleFormats32Bit[] =
8978 {
8979 VK_FORMAT_R8G8B8A8_UNORM,
8980 VK_FORMAT_R8G8B8A8_SNORM,
8981 VK_FORMAT_R8G8B8A8_USCALED,
8982 VK_FORMAT_R8G8B8A8_SSCALED,
8983 VK_FORMAT_R8G8B8A8_UINT,
8984 VK_FORMAT_R8G8B8A8_SINT,
8985 VK_FORMAT_R8G8B8A8_SRGB,
8986 VK_FORMAT_B8G8R8A8_UNORM,
8987 VK_FORMAT_B8G8R8A8_SNORM,
8988 VK_FORMAT_B8G8R8A8_USCALED,
8989 VK_FORMAT_B8G8R8A8_SSCALED,
8990 VK_FORMAT_B8G8R8A8_UINT,
8991 VK_FORMAT_B8G8R8A8_SINT,
8992 VK_FORMAT_B8G8R8A8_SRGB,
8993 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
8994 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
8995 VK_FORMAT_A8B8G8R8_USCALED_PACK32,
8996 VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
8997 VK_FORMAT_A8B8G8R8_UINT_PACK32,
8998 VK_FORMAT_A8B8G8R8_SINT_PACK32,
8999 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
9000 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
9001 VK_FORMAT_A2R10G10B10_SNORM_PACK32,
9002 VK_FORMAT_A2R10G10B10_USCALED_PACK32,
9003 VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
9004 VK_FORMAT_A2R10G10B10_UINT_PACK32,
9005 VK_FORMAT_A2R10G10B10_SINT_PACK32,
9006 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
9007 VK_FORMAT_A2B10G10R10_SNORM_PACK32,
9008 VK_FORMAT_A2B10G10R10_USCALED_PACK32,
9009 VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
9010 VK_FORMAT_A2B10G10R10_UINT_PACK32,
9011 VK_FORMAT_A2B10G10R10_SINT_PACK32,
9012 VK_FORMAT_R16G16_UNORM,
9013 VK_FORMAT_R16G16_SNORM,
9014 VK_FORMAT_R16G16_USCALED,
9015 VK_FORMAT_R16G16_SSCALED,
9016 VK_FORMAT_R16G16_UINT,
9017 VK_FORMAT_R16G16_SINT,
9018 VK_FORMAT_R16G16_SFLOAT,
9019 VK_FORMAT_R32_UINT,
9020 VK_FORMAT_R32_SINT,
9021 VK_FORMAT_R32_SFLOAT,
9022
9023 VK_FORMAT_UNDEFINED
9024 };
9025 const VkFormat compatibleFormats48Bit[] =
9026 {
9027 VK_FORMAT_R16G16B16_UNORM,
9028 VK_FORMAT_R16G16B16_SNORM,
9029 VK_FORMAT_R16G16B16_USCALED,
9030 VK_FORMAT_R16G16B16_SSCALED,
9031 VK_FORMAT_R16G16B16_UINT,
9032 VK_FORMAT_R16G16B16_SINT,
9033 VK_FORMAT_R16G16B16_SFLOAT,
9034
9035 VK_FORMAT_UNDEFINED
9036 };
9037 const VkFormat compatibleFormats64Bit[] =
9038 {
9039 VK_FORMAT_R16G16B16A16_UNORM,
9040 VK_FORMAT_R16G16B16A16_SNORM,
9041 VK_FORMAT_R16G16B16A16_USCALED,
9042 VK_FORMAT_R16G16B16A16_SSCALED,
9043 VK_FORMAT_R16G16B16A16_UINT,
9044 VK_FORMAT_R16G16B16A16_SINT,
9045 VK_FORMAT_R16G16B16A16_SFLOAT,
9046 VK_FORMAT_R32G32_UINT,
9047 VK_FORMAT_R32G32_SINT,
9048 VK_FORMAT_R32G32_SFLOAT,
9049 VK_FORMAT_R64_UINT,
9050 VK_FORMAT_R64_SINT,
9051 VK_FORMAT_R64_SFLOAT,
9052
9053 VK_FORMAT_BC1_RGB_UNORM_BLOCK,
9054 VK_FORMAT_BC1_RGB_SRGB_BLOCK,
9055 VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
9056 VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
9057 VK_FORMAT_BC4_UNORM_BLOCK,
9058 VK_FORMAT_BC4_SNORM_BLOCK,
9059
9060 VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
9061 VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
9062 VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
9063 VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
9064
9065 VK_FORMAT_EAC_R11_UNORM_BLOCK,
9066 VK_FORMAT_EAC_R11_SNORM_BLOCK,
9067
9068 VK_FORMAT_UNDEFINED
9069 };
9070 const VkFormat compatibleFormats96Bit[] =
9071 {
9072 VK_FORMAT_R32G32B32_UINT,
9073 VK_FORMAT_R32G32B32_SINT,
9074 VK_FORMAT_R32G32B32_SFLOAT,
9075
9076 VK_FORMAT_UNDEFINED
9077 };
9078 const VkFormat compatibleFormats128Bit[] =
9079 {
9080 VK_FORMAT_R32G32B32A32_UINT,
9081 VK_FORMAT_R32G32B32A32_SINT,
9082 VK_FORMAT_R32G32B32A32_SFLOAT,
9083 VK_FORMAT_R64G64_UINT,
9084 VK_FORMAT_R64G64_SINT,
9085 VK_FORMAT_R64G64_SFLOAT,
9086
9087 VK_FORMAT_BC2_UNORM_BLOCK,
9088 VK_FORMAT_BC2_SRGB_BLOCK,
9089 VK_FORMAT_BC3_UNORM_BLOCK,
9090 VK_FORMAT_BC3_SRGB_BLOCK,
9091 VK_FORMAT_BC5_UNORM_BLOCK,
9092 VK_FORMAT_BC5_SNORM_BLOCK,
9093 VK_FORMAT_BC6H_UFLOAT_BLOCK,
9094 VK_FORMAT_BC6H_SFLOAT_BLOCK,
9095 VK_FORMAT_BC7_UNORM_BLOCK,
9096 VK_FORMAT_BC7_SRGB_BLOCK,
9097
9098 VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
9099 VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
9100
9101 VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
9102 VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
9103
9104 VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
9105 VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
9106 VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
9107 VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
9108 VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
9109 VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
9110 VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
9111 VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
9112 VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
9113 VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
9114 VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
9115 VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
9116 VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
9117 VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
9118 VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
9119 VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
9120 VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
9121 VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
9122 VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
9123 VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
9124 VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
9125 VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
9126 VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
9127 VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
9128 VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
9129 VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
9130 VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
9131 VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
9132
9133 VK_FORMAT_UNDEFINED
9134 };
9135 const VkFormat compatibleFormats192Bit[] =
9136 {
9137 VK_FORMAT_R64G64B64_UINT,
9138 VK_FORMAT_R64G64B64_SINT,
9139 VK_FORMAT_R64G64B64_SFLOAT,
9140
9141 VK_FORMAT_UNDEFINED
9142 };
9143 const VkFormat compatibleFormats256Bit[] =
9144 {
9145 VK_FORMAT_R64G64B64A64_UINT,
9146 VK_FORMAT_R64G64B64A64_SINT,
9147 VK_FORMAT_R64G64B64A64_SFLOAT,
9148
9149 VK_FORMAT_UNDEFINED
9150 };
9151
9152 const VkFormat* colorImageFormatsToTest[] =
9153 {
9154 compatibleFormats8Bit,
9155 compatibleFormats16Bit,
9156 compatibleFormats24Bit,
9157 compatibleFormats32Bit,
9158 compatibleFormats48Bit,
9159 compatibleFormats64Bit,
9160 compatibleFormats96Bit,
9161 compatibleFormats128Bit,
9162 compatibleFormats192Bit,
9163 compatibleFormats256Bit
9164 };
9165
9166 const VkFormat dedicatedAllocationImageToImageFormatsToTest[] =
9167 {
9168 // From compatibleFormats8Bit
9169 VK_FORMAT_R4G4_UNORM_PACK8,
9170 VK_FORMAT_R8_SRGB,
9171
9172 // From compatibleFormats16Bit
9173 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
9174 VK_FORMAT_R16_SFLOAT,
9175
9176 // From compatibleFormats24Bit
9177 VK_FORMAT_R8G8B8_UNORM,
9178 VK_FORMAT_B8G8R8_SRGB,
9179
9180 // From compatibleFormats32Bit
9181 VK_FORMAT_R8G8B8A8_UNORM,
9182 VK_FORMAT_R32_SFLOAT,
9183
9184 // From compatibleFormats48Bit
9185 VK_FORMAT_R16G16B16_UNORM,
9186 VK_FORMAT_R16G16B16_SFLOAT,
9187
9188 // From compatibleFormats64Bit
9189 VK_FORMAT_R16G16B16A16_UNORM,
9190 VK_FORMAT_R64_SFLOAT,
9191
9192 // From compatibleFormats96Bit
9193 VK_FORMAT_R32G32B32_UINT,
9194 VK_FORMAT_R32G32B32_SFLOAT,
9195
9196 // From compatibleFormats128Bit
9197 VK_FORMAT_R32G32B32A32_UINT,
9198 VK_FORMAT_R64G64_SFLOAT,
9199
9200 // From compatibleFormats192Bit
9201 VK_FORMAT_R64G64B64_UINT,
9202 VK_FORMAT_R64G64B64_SFLOAT,
9203
9204 // From compatibleFormats256Bit
9205 VK_FORMAT_R64G64B64A64_UINT,
9206 VK_FORMAT_R64G64B64A64_SFLOAT,
9207 };
9208
addImageToImageAllFormatsColorTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)9209 void addImageToImageAllFormatsColorTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9210 {
9211 if (allocationKind == ALLOCATION_KIND_DEDICATED)
9212 {
9213 const int numOfDedicatedAllocationImageToImageFormatsToTest = DE_LENGTH_OF_ARRAY(dedicatedAllocationImageToImageFormatsToTest);
9214 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfDedicatedAllocationImageToImageFormatsToTest; ++compatibleFormatsIndex)
9215 dedicatedAllocationImageToImageFormatsToTestSet.insert(dedicatedAllocationImageToImageFormatsToTest[compatibleFormatsIndex]);
9216 }
9217
9218 // 2D tests.
9219 {
9220 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D copies"));
9221
9222 TestParams params;
9223 params.src.image.imageType = VK_IMAGE_TYPE_2D;
9224 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
9225 params.src.image.extent = defaultExtent;
9226 params.dst.image.extent = defaultExtent;
9227 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9228 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9229 params.allocationKind = allocationKind;
9230 params.extensionUse = extensionUse;
9231
9232 for (deInt32 i = 0; i < defaultSize; i += defaultQuarterSize)
9233 {
9234 const VkImageCopy testCopy =
9235 {
9236 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
9237 {0, 0, 0}, // VkOffset3D srcOffset;
9238 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
9239 {i, defaultSize - i - defaultQuarterSize, 0}, // VkOffset3D dstOffset;
9240 {defaultQuarterSize, defaultQuarterSize, 1}, // VkExtent3D extent;
9241 };
9242
9243 CopyRegion imageCopy;
9244 imageCopy.imageCopy = testCopy;
9245
9246 params.regions.push_back(imageCopy);
9247 }
9248
9249 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
9250 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
9251 {
9252 const VkFormat* compatibleFormats = colorImageFormatsToTest[compatibleFormatsIndex];
9253 for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
9254 {
9255 params.src.image.format = compatibleFormats[srcFormatIndex];
9256 if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
9257 continue;
9258
9259 CopyColorTestParams testParams;
9260 testParams.params = params;
9261 testParams.compatibleFormats = compatibleFormats;
9262
9263 const std::string testName = getFormatCaseName(params.src.image.format);
9264 const std::string description = "Copy from source format " + getFormatCaseName(params.src.image.format);
9265 addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsColorSrcFormatTests, testParams);
9266 }
9267 }
9268
9269 group->addChild(subGroup.release());
9270 }
9271
9272 // 1D tests.
9273 {
9274 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D copies"));
9275
9276 TestParams params;
9277 params.src.image.imageType = VK_IMAGE_TYPE_1D;
9278 params.dst.image.imageType = VK_IMAGE_TYPE_1D;
9279 params.src.image.extent = default1dExtent;
9280 params.dst.image.extent = default1dExtent;
9281 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9282 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9283 params.allocationKind = allocationKind;
9284 params.extensionUse = extensionUse;
9285
9286 for (deInt32 i = defaultQuarterSize; i < defaultSize; i += defaultSize / 2)
9287 {
9288 const VkImageCopy testCopy =
9289 {
9290 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
9291 {0, 0, 0}, // VkOffset3D srcOffset;
9292 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
9293 {i, 0, 0}, // VkOffset3D dstOffset;
9294 {defaultQuarterSize, 1, 1}, // VkExtent3D extent;
9295 };
9296
9297 CopyRegion imageCopy;
9298 imageCopy.imageCopy = testCopy;
9299
9300 params.regions.push_back(imageCopy);
9301 }
9302
9303 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
9304 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
9305 {
9306 const VkFormat* compatibleFormats = colorImageFormatsToTest[compatibleFormatsIndex];
9307 for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
9308 {
9309 params.src.image.format = compatibleFormats[srcFormatIndex];
9310 if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
9311 continue;
9312
9313 CopyColorTestParams testParams;
9314 testParams.params = params;
9315 testParams.compatibleFormats = nullptr;
9316
9317 const std::string testName = getFormatCaseName(params.src.image.format);
9318 const std::string description = "Copy from source format " + getFormatCaseName(params.src.image.format);
9319 addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsColorSrcFormatTests, testParams);
9320 }
9321 }
9322
9323 group->addChild(subGroup.release());
9324 }
9325
9326 // 3D tests. Note we use smaller dimensions here for performance reasons.
9327 {
9328 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D copies"));
9329
9330 TestParams params;
9331 params.src.image.imageType = VK_IMAGE_TYPE_3D;
9332 params.dst.image.imageType = VK_IMAGE_TYPE_3D;
9333 params.src.image.extent = default3dExtent;
9334 params.dst.image.extent = default3dExtent;
9335 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9336 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9337 params.allocationKind = allocationKind;
9338 params.extensionUse = extensionUse;
9339
9340 for (deInt32 i = 0; i < defaultQuarterSize; i += defaultSixteenthSize)
9341 {
9342 const VkImageCopy testCopy =
9343 {
9344 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
9345 {0, 0, 0}, // VkOffset3D srcOffset;
9346 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
9347 {i, defaultQuarterSize - i - defaultSixteenthSize, i}, // VkOffset3D dstOffset;
9348 {defaultSixteenthSize, defaultSixteenthSize, defaultSixteenthSize}, // VkExtent3D extent;
9349 };
9350
9351 CopyRegion imageCopy;
9352 imageCopy.imageCopy = testCopy;
9353
9354 params.regions.push_back(imageCopy);
9355 }
9356
9357 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
9358 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
9359 {
9360 const VkFormat* compatibleFormats = colorImageFormatsToTest[compatibleFormatsIndex];
9361 for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
9362 {
9363 params.src.image.format = compatibleFormats[srcFormatIndex];
9364 if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
9365 continue;
9366
9367 CopyColorTestParams testParams;
9368 testParams.params = params;
9369 testParams.compatibleFormats = nullptr;
9370
9371 const std::string testName = getFormatCaseName(params.src.image.format);
9372 const std::string description = "Copy from source format " + getFormatCaseName(params.src.image.format);
9373 addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsColorSrcFormatTests, testParams);
9374 }
9375 }
9376
9377 group->addChild(subGroup.release());
9378 }
9379 }
9380
addImageToImageDimensionsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)9381 void addImageToImageDimensionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9382 {
9383 tcu::TestContext& testCtx = group->getTestContext();
9384
9385 const VkFormat testFormats[][2] =
9386 {
9387 // From compatibleFormats8Bit
9388 {
9389 VK_FORMAT_R4G4_UNORM_PACK8,
9390 VK_FORMAT_R8_SRGB
9391 },
9392 // From compatibleFormats16Bit
9393 {
9394 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
9395 VK_FORMAT_R16_SFLOAT,
9396 },
9397 // From compatibleFormats24Bit
9398 {
9399 VK_FORMAT_R8G8B8_UNORM,
9400 VK_FORMAT_B8G8R8_SRGB
9401 },
9402 // From compatibleFormats32Bit
9403 {
9404 VK_FORMAT_R8G8B8A8_UNORM,
9405 VK_FORMAT_R32_SFLOAT
9406 },
9407 // From compatibleFormats48Bit
9408 {
9409 VK_FORMAT_R16G16B16_UNORM,
9410 VK_FORMAT_R16G16B16_SFLOAT
9411 },
9412 // From compatibleFormats64Bit
9413 {
9414 VK_FORMAT_R16G16B16A16_UNORM,
9415 VK_FORMAT_R64_SFLOAT
9416 },
9417 // From compatibleFormats96Bit
9418 {
9419 VK_FORMAT_R32G32B32_UINT,
9420 VK_FORMAT_R32G32B32_SFLOAT
9421 },
9422 // From compatibleFormats128Bit
9423 {
9424 VK_FORMAT_R32G32B32A32_UINT,
9425 VK_FORMAT_R64G64_SFLOAT
9426 },
9427 // From compatibleFormats192Bit
9428 {
9429 VK_FORMAT_R64G64B64_UINT,
9430 VK_FORMAT_R64G64B64_SFLOAT,
9431 },
9432 // From compatibleFormats256Bit
9433 {
9434 VK_FORMAT_R64G64B64A64_UINT,
9435 VK_FORMAT_R64G64B64A64_SFLOAT
9436 }
9437 };
9438
9439 const tcu::UVec2 imageDimensions[] =
9440 {
9441 // large pot x small pot
9442 tcu::UVec2(4096, 4u),
9443 tcu::UVec2(8192, 4u),
9444 tcu::UVec2(16384, 4u),
9445 tcu::UVec2(32768, 4u),
9446
9447 // large pot x small npot
9448 tcu::UVec2(4096, 6u),
9449 tcu::UVec2(8192, 6u),
9450 tcu::UVec2(16384, 6u),
9451 tcu::UVec2(32768, 6u),
9452
9453 // small pot x large pot
9454 tcu::UVec2(4u, 4096),
9455 tcu::UVec2(4u, 8192),
9456 tcu::UVec2(4u, 16384),
9457 tcu::UVec2(4u, 32768),
9458
9459 // small npot x large pot
9460 tcu::UVec2(6u, 4096),
9461 tcu::UVec2(6u, 8192),
9462 tcu::UVec2(6u, 16384),
9463 tcu::UVec2(6u, 32768)
9464 };
9465
9466 const VkImageLayout copySrcLayouts[] =
9467 {
9468 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
9469 VK_IMAGE_LAYOUT_GENERAL
9470 };
9471
9472 const VkImageLayout copyDstLayouts[] =
9473 {
9474 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
9475 VK_IMAGE_LAYOUT_GENERAL
9476 };
9477
9478 if (allocationKind == ALLOCATION_KIND_DEDICATED)
9479 {
9480 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(dedicatedAllocationImageToImageFormatsToTest); compatibleFormatsIndex++)
9481 dedicatedAllocationImageToImageFormatsToTestSet.insert(dedicatedAllocationImageToImageFormatsToTest[compatibleFormatsIndex]);
9482 }
9483
9484 // Image dimensions
9485 for (size_t dimensionNdx = 0; dimensionNdx < DE_LENGTH_OF_ARRAY(imageDimensions); dimensionNdx++)
9486 {
9487 CopyRegion copyRegion;
9488 CopyColorTestParams testParams;
9489
9490 const VkExtent3D extent = { imageDimensions[dimensionNdx].x(), imageDimensions[dimensionNdx].y(), 1 };
9491
9492 const VkImageCopy testCopy =
9493 {
9494 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
9495 {0, 0, 0}, // VkOffset3D srcOffset;
9496 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
9497 {0, 0, 0}, // VkOffset3D dstOffset;
9498 extent, // VkExtent3D extent;
9499 };
9500
9501 testParams.params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9502 testParams.params.src.image.imageType = VK_IMAGE_TYPE_2D;
9503 testParams.params.src.image.extent = extent;
9504
9505 testParams.params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9506 testParams.params.dst.image.imageType = VK_IMAGE_TYPE_2D;
9507 testParams.params.dst.image.extent = extent;
9508
9509 copyRegion.imageCopy = testCopy;
9510 testParams.params.allocationKind = allocationKind;
9511 testParams.params.extensionUse = extensionUse;
9512
9513 testParams.params.regions.push_back(copyRegion);
9514
9515 const std::string dimensionStr = "src" + de::toString(testParams.params.src.image.extent.width) + "x" + de::toString(testParams.params.src.image.extent.height)
9516 + "_dst" + de::toString(testParams.params.dst.image.extent.width) + "x" + de::toString(testParams.params.dst.image.extent.height);
9517 tcu::TestCaseGroup* imageSizeGroup = new tcu::TestCaseGroup(testCtx, dimensionStr.c_str(), ("Image sizes " + dimensionStr).c_str());
9518
9519 // Compatible formats for copying
9520 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(testFormats); compatibleFormatsIndex++)
9521 {
9522 const VkFormat* compatibleFormats = testFormats[compatibleFormatsIndex];
9523
9524 testParams.compatibleFormats = compatibleFormats;
9525
9526 // Source image format
9527 for (int srcFormatIndex = 0; srcFormatIndex < DE_LENGTH_OF_ARRAY(testFormats[compatibleFormatsIndex]); srcFormatIndex++)
9528 {
9529 testParams.params.src.image.format = testParams.compatibleFormats[srcFormatIndex];
9530
9531 if (!isSupportedByFramework(testParams.params.src.image.format) && !isCompressedFormat(testParams.params.src.image.format))
9532 continue;
9533
9534 const std::string srcDescription = "Copy from source format " + getFormatCaseName(testParams.params.src.image.format);
9535 tcu::TestCaseGroup* srcFormatGroup = new tcu::TestCaseGroup(testCtx, getFormatCaseName(testParams.params.src.image.format).c_str(), srcDescription.c_str());
9536
9537 // Destination image format
9538 for (int dstFormatIndex = 0; dstFormatIndex < DE_LENGTH_OF_ARRAY(testFormats[compatibleFormatsIndex]); dstFormatIndex++)
9539 {
9540 testParams.params.dst.image.format = testParams.compatibleFormats[dstFormatIndex];
9541
9542 if (!isSupportedByFramework(testParams.params.dst.image.format) && !isCompressedFormat(testParams.params.dst.image.format))
9543 continue;
9544
9545 if (!isAllowedImageToImageAllFormatsColorSrcFormatTests(testParams))
9546 continue;
9547
9548 if (isCompressedFormat(testParams.params.src.image.format) && isCompressedFormat(testParams.params.dst.image.format))
9549 {
9550 if ((getBlockWidth(testParams.params.src.image.format) != getBlockWidth(testParams.params.dst.image.format))
9551 || (getBlockHeight(testParams.params.src.image.format) != getBlockHeight(testParams.params.dst.image.format)))
9552 continue;
9553 }
9554
9555 const std::string dstDescription = "Copy to destination format " + getFormatCaseName(testParams.params.dst.image.format);
9556 tcu::TestCaseGroup* dstFormatGroup = new tcu::TestCaseGroup(testCtx, getFormatCaseName(testParams.params.dst.image.format).c_str(), dstDescription.c_str());
9557
9558 // Source/destionation image layouts
9559 for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); srcLayoutNdx++)
9560 {
9561 testParams.params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
9562
9563 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); dstLayoutNdx++)
9564 {
9565 testParams.params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
9566
9567 const std::string testName = getImageLayoutCaseName(testParams.params.src.image.operationLayout) + "_" + getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
9568 const std::string description = "From layout " + getImageLayoutCaseName(testParams.params.src.image.operationLayout) + " to " + getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
9569 const TestParams params = testParams.params;
9570
9571 dstFormatGroup->addChild(new CopyImageToImageTestCase(testCtx, testName, description, params));
9572 }
9573 }
9574
9575 srcFormatGroup->addChild(dstFormatGroup);
9576 }
9577
9578 imageSizeGroup->addChild(srcFormatGroup);
9579 }
9580 }
9581
9582 group->addChild(imageSizeGroup);
9583 }
9584 }
9585
addImageToImageAllFormatsDepthStencilFormatsTests(tcu::TestCaseGroup * group,TestParams params)9586 void addImageToImageAllFormatsDepthStencilFormatsTests (tcu::TestCaseGroup* group, TestParams params)
9587 {
9588 const VkImageLayout copySrcLayouts[] =
9589 {
9590 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
9591 VK_IMAGE_LAYOUT_GENERAL
9592 };
9593 const VkImageLayout copyDstLayouts[] =
9594 {
9595 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
9596 VK_IMAGE_LAYOUT_GENERAL
9597 };
9598
9599 for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx)
9600 {
9601 params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
9602 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx)
9603 {
9604 params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
9605
9606 const std::string testName = getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
9607 getImageLayoutCaseName(params.dst.image.operationLayout);
9608 const std::string description = "From layout " + getImageLayoutCaseName(params.src.image.operationLayout) +
9609 " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
9610 group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, description, params));
9611 }
9612 }
9613 }
9614
addImageToImageAllFormatsDepthStencilTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)9615 void addImageToImageAllFormatsDepthStencilTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9616 {
9617 const VkFormat depthAndStencilFormats[] =
9618 {
9619 VK_FORMAT_D16_UNORM,
9620 VK_FORMAT_X8_D24_UNORM_PACK32,
9621 VK_FORMAT_D32_SFLOAT,
9622 VK_FORMAT_S8_UINT,
9623 VK_FORMAT_D16_UNORM_S8_UINT,
9624 VK_FORMAT_D24_UNORM_S8_UINT,
9625 VK_FORMAT_D32_SFLOAT_S8_UINT,
9626 };
9627
9628 // 2D tests.
9629 {
9630 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D copies"));
9631
9632 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
9633 {
9634 TestParams params;
9635 params.src.image.imageType = VK_IMAGE_TYPE_2D;
9636 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
9637 params.src.image.extent = defaultExtent;
9638 params.dst.image.extent = defaultExtent;
9639 params.src.image.format = depthAndStencilFormats[compatibleFormatsIndex];
9640 params.dst.image.format = params.src.image.format;
9641 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9642 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9643 params.allocationKind = allocationKind;
9644 params.extensionUse = extensionUse;
9645 params.separateDepthStencilLayouts = DE_FALSE;
9646
9647 bool hasDepth = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
9648 bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
9649
9650 const VkImageSubresourceLayers defaultDepthSourceLayer = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
9651 const VkImageSubresourceLayers defaultStencilSourceLayer = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
9652 const VkImageSubresourceLayers defaultDSSourceLayer = { VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
9653
9654 for (deInt32 i = 0; i < defaultSize; i += defaultQuarterSize)
9655 {
9656 CopyRegion copyRegion;
9657 const VkOffset3D srcOffset = {0, 0, 0};
9658 const VkOffset3D dstOffset = {i, defaultSize - i - defaultQuarterSize, 0};
9659 const VkExtent3D extent = {defaultQuarterSize, defaultQuarterSize, 1};
9660
9661 if (hasDepth)
9662 {
9663 const VkImageCopy testCopy =
9664 {
9665 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
9666 srcOffset, // VkOffset3D srcOffset;
9667 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
9668 dstOffset, // VkOffset3D dstOffset;
9669 extent, // VkExtent3D extent;
9670 };
9671
9672 copyRegion.imageCopy = testCopy;
9673 params.regions.push_back(copyRegion);
9674 }
9675 if (hasStencil)
9676 {
9677 const VkImageCopy testCopy =
9678 {
9679 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
9680 srcOffset, // VkOffset3D srcOffset;
9681 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
9682 dstOffset, // VkOffset3D dstOffset;
9683 extent, // VkExtent3D extent;
9684 };
9685
9686 copyRegion.imageCopy = testCopy;
9687 params.regions.push_back(copyRegion);
9688 }
9689 }
9690
9691 const std::string testName = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
9692 const std::string description = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
9693 addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params);
9694
9695 if (hasDepth && hasStencil)
9696 {
9697 params.separateDepthStencilLayouts = DE_TRUE;
9698 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_separate_layouts";
9699 const std::string description2 = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
9700 addTestGroup(subGroup.get(), testName2, description2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
9701
9702 // DS Image copy
9703 {
9704 params.separateDepthStencilLayouts = DE_FALSE;
9705 // Clear previous vkImageCopy elements
9706 params.regions.clear();
9707
9708 for (deInt32 i = 0; i < defaultSize; i += defaultQuarterSize)
9709 {
9710 CopyRegion copyRegion;
9711 const VkOffset3D srcOffset = {0, 0, 0};
9712 const VkOffset3D dstOffset = {i, defaultSize - i - defaultQuarterSize, 0};
9713 const VkExtent3D extent = {defaultQuarterSize, defaultQuarterSize, 1};
9714
9715 const VkImageCopy testCopy =
9716 {
9717 defaultDSSourceLayer, // VkImageSubresourceLayers srcSubresource;
9718 srcOffset, // VkOffset3D srcOffset;
9719 defaultDSSourceLayer, // VkImageSubresourceLayers dstSubresource;
9720 dstOffset, // VkOffset3D dstOffset;
9721 extent, // VkExtent3D extent;
9722 };
9723
9724 copyRegion.imageCopy = testCopy;
9725 params.regions.push_back(copyRegion);
9726 }
9727
9728 const std::string testName3 = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_depth_stencil_aspects";
9729 const std::string description3 = "Copy both depth and stencil aspects from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
9730 addTestGroup(subGroup.get(), testName3, description3, addImageToImageAllFormatsDepthStencilFormatsTests, params);
9731 }
9732 }
9733 }
9734
9735 group->addChild(subGroup.release());
9736 }
9737
9738 // 1D tests.
9739 {
9740 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D copies"));
9741
9742 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
9743 {
9744 TestParams params;
9745 params.src.image.imageType = VK_IMAGE_TYPE_1D;
9746 params.dst.image.imageType = VK_IMAGE_TYPE_1D;
9747 params.src.image.extent = default1dExtent;
9748 params.dst.image.extent = default1dExtent;
9749 params.src.image.format = depthAndStencilFormats[compatibleFormatsIndex];
9750 params.dst.image.format = params.src.image.format;
9751 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9752 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9753 params.allocationKind = allocationKind;
9754 params.extensionUse = extensionUse;
9755
9756 bool hasDepth = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
9757 bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
9758
9759 const VkImageSubresourceLayers defaultDepthSourceLayer = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
9760 const VkImageSubresourceLayers defaultStencilSourceLayer = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
9761
9762 for (deInt32 i = defaultQuarterSize; i < defaultSize; i += defaultSize / 2)
9763 {
9764 CopyRegion copyRegion;
9765 const VkOffset3D srcOffset = {0, 0, 0};
9766 const VkOffset3D dstOffset = {i, 0, 0};
9767 const VkExtent3D extent = {defaultQuarterSize, 1, 1};
9768
9769 if (hasDepth)
9770 {
9771 const VkImageCopy testCopy =
9772 {
9773 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
9774 srcOffset, // VkOffset3D srcOffset;
9775 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
9776 dstOffset, // VkOffset3D dstOffset;
9777 extent, // VkExtent3D extent;
9778 };
9779
9780 copyRegion.imageCopy = testCopy;
9781 params.regions.push_back(copyRegion);
9782 }
9783 if (hasStencil)
9784 {
9785 const VkImageCopy testCopy =
9786 {
9787 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
9788 srcOffset, // VkOffset3D srcOffset;
9789 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
9790 dstOffset, // VkOffset3D dstOffset;
9791 extent, // VkExtent3D extent;
9792 };
9793
9794 copyRegion.imageCopy = testCopy;
9795 params.regions.push_back(copyRegion);
9796 }
9797 }
9798
9799 const std::string testName = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
9800 const std::string description = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
9801 addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params);
9802
9803 if (hasDepth && hasStencil)
9804 {
9805 params.separateDepthStencilLayouts = DE_TRUE;
9806 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_separate_layouts";
9807 const std::string description2 = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
9808 addTestGroup(subGroup.get(), testName2, description2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
9809 }
9810 }
9811
9812 group->addChild(subGroup.release());
9813 }
9814
9815 // 3D tests. Note we use smaller dimensions here for performance reasons.
9816 {
9817 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D copies"));
9818
9819 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
9820 {
9821 TestParams params;
9822 params.src.image.imageType = VK_IMAGE_TYPE_3D;
9823 params.dst.image.imageType = VK_IMAGE_TYPE_3D;
9824 params.src.image.extent = default3dExtent;
9825 params.dst.image.extent = default3dExtent;
9826 params.src.image.format = depthAndStencilFormats[compatibleFormatsIndex];
9827 params.dst.image.format = params.src.image.format;
9828 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9829 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9830 params.allocationKind = allocationKind;
9831 params.extensionUse = extensionUse;
9832
9833 bool hasDepth = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
9834 bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
9835
9836 const VkImageSubresourceLayers defaultDepthSourceLayer = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
9837 const VkImageSubresourceLayers defaultStencilSourceLayer = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
9838
9839 for (deInt32 i = 0; i < defaultQuarterSize; i += defaultSixteenthSize)
9840 {
9841 CopyRegion copyRegion;
9842 const VkOffset3D srcOffset = {0, 0, 0};
9843 const VkOffset3D dstOffset = {i, defaultQuarterSize - i - defaultSixteenthSize, i};
9844 const VkExtent3D extent = {defaultSixteenthSize, defaultSixteenthSize, defaultSixteenthSize};
9845
9846 if (hasDepth)
9847 {
9848 const VkImageCopy testCopy =
9849 {
9850 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
9851 srcOffset, // VkOffset3D srcOffset;
9852 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
9853 dstOffset, // VkOffset3D dstOffset;
9854 extent, // VkExtent3D extent;
9855 };
9856
9857 copyRegion.imageCopy = testCopy;
9858 params.regions.push_back(copyRegion);
9859 }
9860 if (hasStencil)
9861 {
9862 const VkImageCopy testCopy =
9863 {
9864 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
9865 srcOffset, // VkOffset3D srcOffset;
9866 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
9867 dstOffset, // VkOffset3D dstOffset;
9868 extent, // VkExtent3D extent;
9869 };
9870
9871 copyRegion.imageCopy = testCopy;
9872 params.regions.push_back(copyRegion);
9873 }
9874 }
9875
9876 const std::string testName = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
9877 const std::string description = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
9878 addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params);
9879
9880 if (hasDepth && hasStencil)
9881 {
9882 params.separateDepthStencilLayouts = DE_TRUE;
9883 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_separate_layouts";
9884 const std::string description2 = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
9885 addTestGroup(subGroup.get(), testName2, description2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
9886 }
9887 }
9888
9889 group->addChild(subGroup.release());
9890 }
9891 }
9892
addImageToImageAllFormatsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)9893 void addImageToImageAllFormatsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9894 {
9895 addTestGroup(group, "color", "Copy image to image with color formats", addImageToImageAllFormatsColorTests, allocationKind, extensionUse);
9896 addTestGroup(group, "depth_stencil", "Copy image to image with depth/stencil formats", addImageToImageAllFormatsDepthStencilTests, allocationKind, extensionUse);
9897 }
9898
addImageToImage3dImagesTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)9899 void addImageToImage3dImagesTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9900 {
9901 tcu::TestContext& testCtx = group->getTestContext();
9902
9903 {
9904 TestParams params3DTo2D;
9905 const deUint32 slicesLayers = 16u;
9906 params3DTo2D.src.image.imageType = VK_IMAGE_TYPE_3D;
9907 params3DTo2D.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
9908 params3DTo2D.src.image.extent = defaultHalfExtent;
9909 params3DTo2D.src.image.extent.depth = slicesLayers;
9910 params3DTo2D.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9911 params3DTo2D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9912 params3DTo2D.dst.image.imageType = VK_IMAGE_TYPE_2D;
9913 params3DTo2D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
9914 params3DTo2D.dst.image.extent = defaultHalfExtent;
9915 params3DTo2D.dst.image.extent.depth = slicesLayers;
9916 params3DTo2D.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9917 params3DTo2D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9918 params3DTo2D.allocationKind = allocationKind;
9919 params3DTo2D.extensionUse = extensionUse;
9920
9921 for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
9922 {
9923 const VkImageSubresourceLayers sourceLayer =
9924 {
9925 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
9926 0u, // deUint32 mipLevel;
9927 0u, // deUint32 baseArrayLayer;
9928 1u // deUint32 layerCount;
9929 };
9930
9931 const VkImageSubresourceLayers destinationLayer =
9932 {
9933 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
9934 0u, // deUint32 mipLevel;
9935 slicesLayersNdx, // deUint32 baseArrayLayer;
9936 1u // deUint32 layerCount;
9937 };
9938
9939 const VkImageCopy testCopy =
9940 {
9941 sourceLayer, // VkImageSubresourceLayers srcSubresource;
9942 {0, 0, (deInt32)slicesLayersNdx}, // VkOffset3D srcOffset;
9943 destinationLayer, // VkImageSubresourceLayers dstSubresource;
9944 {0, 0, 0}, // VkOffset3D dstOffset;
9945 defaultHalfExtent, // VkExtent3D extent;
9946 };
9947
9948 CopyRegion imageCopy;
9949 imageCopy.imageCopy = testCopy;
9950
9951 params3DTo2D.regions.push_back(imageCopy);
9952 }
9953 group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_by_slices", "copy 2d layers to 3d slices one by one", params3DTo2D));
9954 }
9955
9956 {
9957 TestParams params2DTo3D;
9958 const deUint32 slicesLayers = 16u;
9959 params2DTo3D.src.image.imageType = VK_IMAGE_TYPE_2D;
9960 params2DTo3D.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
9961 params2DTo3D.src.image.extent = defaultHalfExtent;
9962 params2DTo3D.src.image.extent.depth = slicesLayers;
9963 params2DTo3D.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9964 params2DTo3D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9965 params2DTo3D.dst.image.imageType = VK_IMAGE_TYPE_3D;
9966 params2DTo3D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
9967 params2DTo3D.dst.image.extent = defaultHalfExtent;
9968 params2DTo3D.dst.image.extent.depth = slicesLayers;
9969 params2DTo3D.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9970 params2DTo3D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9971 params2DTo3D.allocationKind = allocationKind;
9972 params2DTo3D.extensionUse = extensionUse;
9973
9974 for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
9975 {
9976 const VkImageSubresourceLayers sourceLayer =
9977 {
9978 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
9979 0u, // deUint32 mipLevel;
9980 slicesLayersNdx, // deUint32 baseArrayLayer;
9981 1u // deUint32 layerCount;
9982 };
9983
9984 const VkImageSubresourceLayers destinationLayer =
9985 {
9986 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
9987 0u, // deUint32 mipLevel;
9988 0u, // deUint32 baseArrayLayer;
9989 1u // deUint32 layerCount;
9990 };
9991
9992 const VkImageCopy testCopy =
9993 {
9994 sourceLayer, // VkImageSubresourceLayers srcSubresource;
9995 {0, 0, 0}, // VkOffset3D srcOffset;
9996 destinationLayer, // VkImageSubresourceLayers dstSubresource;
9997 {0, 0, (deInt32)slicesLayersNdx}, // VkOffset3D dstOffset;
9998 defaultHalfExtent, // VkExtent3D extent;
9999 };
10000
10001 CopyRegion imageCopy;
10002 imageCopy.imageCopy = testCopy;
10003
10004 params2DTo3D.regions.push_back(imageCopy);
10005 }
10006
10007 group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_by_layers", "copy 3d slices to 2d layers one by one", params2DTo3D));
10008 }
10009
10010 {
10011 TestParams params3DTo2D;
10012 const deUint32 slicesLayers = 16u;
10013 params3DTo2D.src.image.imageType = VK_IMAGE_TYPE_3D;
10014 params3DTo2D.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
10015 params3DTo2D.src.image.extent = defaultHalfExtent;
10016 params3DTo2D.src.image.extent.depth = slicesLayers;
10017 params3DTo2D.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10018 params3DTo2D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10019 params3DTo2D.dst.image.imageType = VK_IMAGE_TYPE_2D;
10020 params3DTo2D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
10021 params3DTo2D.dst.image.extent = defaultHalfExtent;
10022 params3DTo2D.dst.image.extent.depth = slicesLayers;
10023 params3DTo2D.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10024 params3DTo2D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10025 params3DTo2D.allocationKind = allocationKind;
10026 params3DTo2D.extensionUse = extensionUse;
10027
10028 {
10029 const VkImageSubresourceLayers sourceLayer =
10030 {
10031 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10032 0u, // deUint32 mipLevel;
10033 0u, // deUint32 baseArrayLayer;
10034 1u // deUint32 layerCount;
10035 };
10036
10037 const VkImageSubresourceLayers destinationLayer =
10038 {
10039 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10040 0u, // deUint32 mipLevel;
10041 0, // deUint32 baseArrayLayer;
10042 slicesLayers // deUint32 layerCount;
10043 };
10044
10045 const VkImageCopy testCopy =
10046 {
10047 sourceLayer, // VkImageSubresourceLayers srcSubresource;
10048 {0, 0, 0}, // VkOffset3D srcOffset;
10049 destinationLayer, // VkImageSubresourceLayers dstSubresource;
10050 {0, 0, 0}, // VkOffset3D dstOffset;
10051 params3DTo2D.src.image.extent // VkExtent3D extent;
10052 };
10053
10054 CopyRegion imageCopy;
10055 imageCopy.imageCopy = testCopy;
10056
10057 params3DTo2D.regions.push_back(imageCopy);
10058 }
10059 group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_whole", "copy 3d slices to 2d layers all at once", params3DTo2D));
10060 }
10061
10062 {
10063 TestParams params2DTo3D;
10064 const deUint32 slicesLayers = 16u;
10065 params2DTo3D.src.image.imageType = VK_IMAGE_TYPE_2D;
10066 params2DTo3D.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
10067 params2DTo3D.src.image.extent = defaultHalfExtent;
10068 params2DTo3D.src.image.extent.depth = slicesLayers;
10069 params2DTo3D.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10070 params2DTo3D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10071 params2DTo3D.dst.image.imageType = VK_IMAGE_TYPE_3D;
10072 params2DTo3D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
10073 params2DTo3D.dst.image.extent = defaultHalfExtent;
10074 params2DTo3D.dst.image.extent.depth = slicesLayers;
10075 params2DTo3D.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10076 params2DTo3D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10077 params2DTo3D.allocationKind = allocationKind;
10078 params2DTo3D.extensionUse = extensionUse;
10079
10080 {
10081 const VkImageSubresourceLayers sourceLayer =
10082 {
10083 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10084 0u, // deUint32 mipLevel;
10085 0u, // deUint32 baseArrayLayer;
10086 slicesLayers // deUint32 layerCount;
10087 };
10088
10089 const VkImageSubresourceLayers destinationLayer =
10090 {
10091 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10092 0u, // deUint32 mipLevel;
10093 0u, // deUint32 baseArrayLayer;
10094 1u // deUint32 layerCount;
10095 };
10096
10097 const VkImageCopy testCopy =
10098 {
10099 sourceLayer, // VkImageSubresourceLayers srcSubresource;
10100 {0, 0, 0}, // VkOffset3D srcOffset;
10101 destinationLayer, // VkImageSubresourceLayers dstSubresource;
10102 {0, 0, 0}, // VkOffset3D dstOffset;
10103 params2DTo3D.src.image.extent, // VkExtent3D extent;
10104 };
10105
10106 CopyRegion imageCopy;
10107 imageCopy.imageCopy = testCopy;
10108
10109 params2DTo3D.regions.push_back(imageCopy);
10110 }
10111
10112 group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_whole", "copy 2d layers to 3d slices all at once", params2DTo3D));
10113 }
10114
10115 {
10116 TestParams params3DTo2D;
10117 const deUint32 slicesLayers = 16u;
10118 params3DTo2D.src.image.imageType = VK_IMAGE_TYPE_3D;
10119 params3DTo2D.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
10120 params3DTo2D.src.image.extent = defaultHalfExtent;
10121 params3DTo2D.src.image.extent.depth = slicesLayers;
10122 params3DTo2D.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10123 params3DTo2D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10124 params3DTo2D.dst.image.imageType = VK_IMAGE_TYPE_2D;
10125 params3DTo2D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
10126 params3DTo2D.dst.image.extent = defaultHalfExtent;
10127 params3DTo2D.dst.image.extent.depth = slicesLayers;
10128 params3DTo2D.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10129 params3DTo2D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10130 params3DTo2D.allocationKind = allocationKind;
10131 params3DTo2D.extensionUse = extensionUse;
10132
10133 const deUint32 regionWidth = defaultHalfExtent.width / slicesLayers -1;
10134 const deUint32 regionHeight = defaultHalfExtent.height / slicesLayers -1 ;
10135
10136 for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
10137 {
10138 const VkImageSubresourceLayers sourceLayer =
10139 {
10140 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10141 0u, // deUint32 mipLevel;
10142 0u, // deUint32 baseArrayLayer;
10143 1u // deUint32 layerCount;
10144 };
10145
10146 const VkImageSubresourceLayers destinationLayer =
10147 {
10148 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10149 0u, // deUint32 mipLevel;
10150 slicesLayersNdx, // deUint32 baseArrayLayer;
10151 1u // deUint32 layerCount;
10152 };
10153
10154
10155 const VkImageCopy testCopy =
10156 {
10157 sourceLayer, // VkImageSubresourceLayers srcSubresource;
10158 {0, (deInt32)(regionHeight*slicesLayersNdx), (deInt32)slicesLayersNdx}, // VkOffset3D srcOffset;
10159 destinationLayer, // VkImageSubresourceLayers dstSubresource;
10160 {(deInt32)(regionWidth*slicesLayersNdx), 0, 0}, // VkOffset3D dstOffset;
10161 {
10162 (defaultHalfExtent.width - regionWidth*slicesLayersNdx),
10163 (defaultHalfExtent.height - regionHeight*slicesLayersNdx),
10164 1
10165 } // VkExtent3D extent;
10166 };
10167
10168 CopyRegion imageCopy;
10169 imageCopy.imageCopy = testCopy;
10170 params3DTo2D.regions.push_back(imageCopy);
10171 }
10172 group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_regions", "copy 3d slices regions to 2d layers", params3DTo2D));
10173 }
10174
10175 {
10176 TestParams params2DTo3D;
10177 const deUint32 slicesLayers = 16u;
10178 params2DTo3D.src.image.imageType = VK_IMAGE_TYPE_2D;
10179 params2DTo3D.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
10180 params2DTo3D.src.image.extent = defaultHalfExtent;
10181 params2DTo3D.src.image.extent.depth = slicesLayers;
10182 params2DTo3D.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10183 params2DTo3D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10184 params2DTo3D.dst.image.imageType = VK_IMAGE_TYPE_3D;
10185 params2DTo3D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
10186 params2DTo3D.dst.image.extent = defaultHalfExtent;
10187 params2DTo3D.dst.image.extent.depth = slicesLayers;
10188 params2DTo3D.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10189 params2DTo3D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10190 params2DTo3D.allocationKind = allocationKind;
10191 params2DTo3D.extensionUse = extensionUse;
10192
10193 const deUint32 regionWidth = defaultHalfExtent.width / slicesLayers -1;
10194 const deUint32 regionHeight = defaultHalfExtent.height / slicesLayers -1 ;
10195
10196 for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
10197 {
10198 const VkImageSubresourceLayers sourceLayer =
10199 {
10200 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10201 0u, // deUint32 mipLevel;
10202 slicesLayersNdx, // deUint32 baseArrayLayer;
10203 1u // deUint32 layerCount;
10204 };
10205
10206 const VkImageSubresourceLayers destinationLayer =
10207 {
10208 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10209 0u, // deUint32 mipLevel;
10210 0u, // deUint32 baseArrayLayer;
10211 1u // deUint32 layerCount;
10212 };
10213
10214 const VkImageCopy testCopy =
10215 {
10216 sourceLayer, // VkImageSubresourceLayers srcSubresource;
10217 {(deInt32)(regionWidth*slicesLayersNdx), 0, 0}, // VkOffset3D srcOffset;
10218 destinationLayer, // VkImageSubresourceLayers dstSubresource;
10219 {0, (deInt32)(regionHeight*slicesLayersNdx), (deInt32)(slicesLayersNdx)}, // VkOffset3D dstOffset;
10220 {
10221 defaultHalfExtent.width - regionWidth*slicesLayersNdx,
10222 defaultHalfExtent.height - regionHeight*slicesLayersNdx,
10223 1
10224 } // VkExtent3D extent;
10225 };
10226
10227 CopyRegion imageCopy;
10228 imageCopy.imageCopy = testCopy;
10229
10230 params2DTo3D.regions.push_back(imageCopy);
10231 }
10232
10233 group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_regions", "copy 2d layers regions to 3d slices", params2DTo3D));
10234 }
10235 }
10236
addImageToImageCubeTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)10237 void addImageToImageCubeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10238 {
10239 tcu::TestContext& testCtx = group->getTestContext();
10240
10241 {
10242 TestParams paramsCubeToArray;
10243 const deUint32 arrayLayers = 6u;
10244 paramsCubeToArray.src.image.createFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
10245 paramsCubeToArray.src.image.imageType = VK_IMAGE_TYPE_2D;
10246 paramsCubeToArray.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
10247 paramsCubeToArray.src.image.extent = defaultHalfExtent;
10248 paramsCubeToArray.src.image.extent.depth = arrayLayers;
10249 paramsCubeToArray.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10250 paramsCubeToArray.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10251 paramsCubeToArray.dst.image.createFlags = 0;
10252 paramsCubeToArray.dst.image.imageType = VK_IMAGE_TYPE_2D;
10253 paramsCubeToArray.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
10254 paramsCubeToArray.dst.image.extent = defaultHalfExtent;
10255 paramsCubeToArray.dst.image.extent.depth = arrayLayers;
10256 paramsCubeToArray.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10257 paramsCubeToArray.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10258 paramsCubeToArray.allocationKind = allocationKind;
10259 paramsCubeToArray.extensionUse = extensionUse;
10260
10261 for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
10262 {
10263 const VkImageSubresourceLayers sourceLayer =
10264 {
10265 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10266 0u, // deUint32 mipLevel;
10267 arrayLayersNdx, // deUint32 baseArrayLayer;
10268 1u // deUint32 layerCount;
10269 };
10270
10271 const VkImageSubresourceLayers destinationLayer =
10272 {
10273 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10274 0u, // deUint32 mipLevel;
10275 arrayLayersNdx, // deUint32 baseArrayLayer;
10276 1u // deUint32 layerCount;
10277 };
10278
10279 const VkImageCopy testCopy =
10280 {
10281 sourceLayer, // VkImageSubresourceLayers srcSubresource;
10282 {0, 0, 0}, // VkOffset3D srcOffset;
10283 destinationLayer, // VkImageSubresourceLayers dstSubresource;
10284 {0, 0, 0}, // VkOffset3D dstOffset;
10285 defaultHalfExtent // VkExtent3D extent;
10286 };
10287
10288 CopyRegion imageCopy;
10289 imageCopy.imageCopy = testCopy;
10290
10291 paramsCubeToArray.regions.push_back(imageCopy);
10292 }
10293
10294 group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_array_layers", "copy cube compatible image to 2d layers layer by layer", paramsCubeToArray));
10295 }
10296
10297 {
10298 TestParams paramsCubeToArray;
10299 const deUint32 arrayLayers = 6u;
10300 paramsCubeToArray.src.image.createFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
10301 paramsCubeToArray.src.image.imageType = VK_IMAGE_TYPE_2D;
10302 paramsCubeToArray.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
10303 paramsCubeToArray.src.image.extent = defaultHalfExtent;
10304 paramsCubeToArray.src.image.extent.depth = arrayLayers;
10305 paramsCubeToArray.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10306 paramsCubeToArray.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10307 paramsCubeToArray.dst.image.createFlags = 0;
10308 paramsCubeToArray.dst.image.imageType = VK_IMAGE_TYPE_2D;
10309 paramsCubeToArray.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
10310 paramsCubeToArray.dst.image.extent = defaultHalfExtent;
10311 paramsCubeToArray.dst.image.extent.depth = arrayLayers;
10312 paramsCubeToArray.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10313 paramsCubeToArray.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10314 paramsCubeToArray.allocationKind = allocationKind;
10315 paramsCubeToArray.extensionUse = extensionUse;
10316
10317 {
10318 const VkImageSubresourceLayers sourceLayer =
10319 {
10320 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10321 0u, // deUint32 mipLevel;
10322 0u, // deUint32 baseArrayLayer;
10323 arrayLayers // deUint32 layerCount;
10324 };
10325
10326 const VkImageSubresourceLayers destinationLayer =
10327 {
10328 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10329 0u, // deUint32 mipLevel;
10330 0u, // deUint32 baseArrayLayer;
10331 arrayLayers // deUint32 layerCount;
10332 };
10333
10334 const VkImageCopy testCopy =
10335 {
10336 sourceLayer, // VkImageSubresourceLayers srcSubresource;
10337 {0, 0, 0}, // VkOffset3D srcOffset;
10338 destinationLayer, // VkImageSubresourceLayers dstSubresource;
10339 {0, 0, 0}, // VkOffset3D dstOffset;
10340 defaultHalfExtent // VkExtent3D extent;
10341 };
10342
10343 CopyRegion imageCopy;
10344 imageCopy.imageCopy = testCopy;
10345
10346 paramsCubeToArray.regions.push_back(imageCopy);
10347 }
10348
10349 group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_array_whole", "copy cube compatible image to 2d layers all at once", paramsCubeToArray));
10350 }
10351
10352 {
10353 TestParams paramsArrayToCube;
10354 const deUint32 arrayLayers = 6u;
10355 paramsArrayToCube.src.image.createFlags = 0;
10356 paramsArrayToCube.src.image.imageType = VK_IMAGE_TYPE_2D;
10357 paramsArrayToCube.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
10358 paramsArrayToCube.src.image.extent = defaultHalfExtent;
10359 paramsArrayToCube.src.image.extent.depth = arrayLayers;
10360 paramsArrayToCube.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10361 paramsArrayToCube.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10362 paramsArrayToCube.dst.image.createFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
10363 paramsArrayToCube.dst.image.imageType = VK_IMAGE_TYPE_2D;
10364 paramsArrayToCube.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
10365 paramsArrayToCube.dst.image.extent = defaultHalfExtent;
10366 paramsArrayToCube.dst.image.extent.depth = arrayLayers;
10367 paramsArrayToCube.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10368 paramsArrayToCube.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10369 paramsArrayToCube.allocationKind = allocationKind;
10370 paramsArrayToCube.extensionUse = extensionUse;
10371
10372 for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
10373 {
10374 const VkImageSubresourceLayers sourceLayer =
10375 {
10376 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10377 0u, // deUint32 mipLevel;
10378 arrayLayersNdx, // deUint32 baseArrayLayer;
10379 1u // deUint32 layerCount;
10380 };
10381
10382 const VkImageSubresourceLayers destinationLayer =
10383 {
10384 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10385 0u, // deUint32 mipLevel;
10386 arrayLayersNdx, // deUint32 baseArrayLayer;
10387 1u // deUint32 layerCount;
10388 };
10389
10390 const VkImageCopy testCopy =
10391 {
10392 sourceLayer, // VkImageSubresourceLayers srcSubresource;
10393 {0, 0, 0}, // VkOffset3D srcOffset;
10394 destinationLayer, // VkImageSubresourceLayers dstSubresource;
10395 {0, 0, 0}, // VkOffset3D dstOffset;
10396 defaultHalfExtent // VkExtent3D extent;
10397 };
10398
10399 CopyRegion imageCopy;
10400 imageCopy.imageCopy = testCopy;
10401
10402 paramsArrayToCube.regions.push_back(imageCopy);
10403 }
10404
10405 group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_cube_layers", "copy 2d layers to cube compatible image layer by layer", paramsArrayToCube));
10406 }
10407
10408 {
10409 TestParams paramsArrayToCube;
10410 const deUint32 arrayLayers = 6u;
10411 paramsArrayToCube.src.image.createFlags = 0;
10412 paramsArrayToCube.src.image.imageType = VK_IMAGE_TYPE_2D;
10413 paramsArrayToCube.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
10414 paramsArrayToCube.src.image.extent = defaultHalfExtent;
10415 paramsArrayToCube.src.image.extent.depth = arrayLayers;
10416 paramsArrayToCube.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10417 paramsArrayToCube.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10418 paramsArrayToCube.dst.image.createFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
10419 paramsArrayToCube.dst.image.imageType = VK_IMAGE_TYPE_2D;
10420 paramsArrayToCube.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
10421 paramsArrayToCube.dst.image.extent = defaultHalfExtent;
10422 paramsArrayToCube.dst.image.extent.depth = arrayLayers;
10423 paramsArrayToCube.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10424 paramsArrayToCube.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10425 paramsArrayToCube.allocationKind = allocationKind;
10426 paramsArrayToCube.extensionUse = extensionUse;
10427
10428 {
10429 const VkImageSubresourceLayers sourceLayer =
10430 {
10431 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10432 0u, // deUint32 mipLevel;
10433 0u, // deUint32 baseArrayLayer;
10434 arrayLayers // deUint32 layerCount;
10435 };
10436
10437 const VkImageSubresourceLayers destinationLayer =
10438 {
10439 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10440 0u, // deUint32 mipLevel;
10441 0u, // deUint32 baseArrayLayer;
10442 arrayLayers // deUint32 layerCount;
10443 };
10444
10445 const VkImageCopy testCopy =
10446 {
10447 sourceLayer, // VkImageSubresourceLayers srcSubresource;
10448 {0, 0, 0}, // VkOffset3D srcOffset;
10449 destinationLayer, // VkImageSubresourceLayers dstSubresource;
10450 {0, 0, 0}, // VkOffset3D dstOffset;
10451 defaultHalfExtent // VkExtent3D extent;
10452 };
10453
10454 CopyRegion imageCopy;
10455 imageCopy.imageCopy = testCopy;
10456
10457 paramsArrayToCube.regions.push_back(imageCopy);
10458 }
10459
10460 group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_cube_whole", "copy 2d layers to cube compatible image all at once", paramsArrayToCube));
10461 }
10462
10463 {
10464 TestParams paramsCubeToArray;
10465 const deUint32 arrayLayers = 6u;
10466 paramsCubeToArray.src.image.createFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
10467 paramsCubeToArray.src.image.imageType = VK_IMAGE_TYPE_2D;
10468 paramsCubeToArray.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
10469 paramsCubeToArray.src.image.extent = defaultHalfExtent;
10470 paramsCubeToArray.src.image.extent.depth = arrayLayers;
10471 paramsCubeToArray.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10472 paramsCubeToArray.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10473 paramsCubeToArray.dst.image.createFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
10474 paramsCubeToArray.dst.image.imageType = VK_IMAGE_TYPE_2D;
10475 paramsCubeToArray.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
10476 paramsCubeToArray.dst.image.extent = defaultHalfExtent;
10477 paramsCubeToArray.dst.image.extent.depth = arrayLayers;
10478 paramsCubeToArray.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10479 paramsCubeToArray.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10480 paramsCubeToArray.allocationKind = allocationKind;
10481 paramsCubeToArray.extensionUse = extensionUse;
10482
10483 for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
10484 {
10485 const VkImageSubresourceLayers sourceLayer =
10486 {
10487 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10488 0u, // deUint32 mipLevel;
10489 arrayLayersNdx, // deUint32 baseArrayLayer;
10490 1u // deUint32 layerCount;
10491 };
10492
10493 const VkImageSubresourceLayers destinationLayer =
10494 {
10495 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10496 0u, // deUint32 mipLevel;
10497 arrayLayersNdx, // deUint32 baseArrayLayer;
10498 1u // deUint32 layerCount;
10499 };
10500
10501 const VkImageCopy testCopy =
10502 {
10503 sourceLayer, // VkImageSubresourceLayers srcSubresource;
10504 {0, 0, 0}, // VkOffset3D srcOffset;
10505 destinationLayer, // VkImageSubresourceLayers dstSubresource;
10506 {0, 0, 0}, // VkOffset3D dstOffset;
10507 defaultHalfExtent // VkExtent3D extent;
10508 };
10509
10510 CopyRegion imageCopy;
10511 imageCopy.imageCopy = testCopy;
10512
10513 paramsCubeToArray.regions.push_back(imageCopy);
10514 }
10515
10516 group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_cube_layers", "copy cube compatible image to cube compatible image layer by layer", paramsCubeToArray));
10517 }
10518
10519 {
10520 TestParams paramsCubeToCube;
10521 const deUint32 arrayLayers = 6u;
10522 paramsCubeToCube.src.image.createFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
10523 paramsCubeToCube.src.image.imageType = VK_IMAGE_TYPE_2D;
10524 paramsCubeToCube.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
10525 paramsCubeToCube.src.image.extent = defaultHalfExtent;
10526 paramsCubeToCube.src.image.extent.depth = arrayLayers;
10527 paramsCubeToCube.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10528 paramsCubeToCube.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10529 paramsCubeToCube.dst.image.createFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
10530 paramsCubeToCube.dst.image.imageType = VK_IMAGE_TYPE_2D;
10531 paramsCubeToCube.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
10532 paramsCubeToCube.dst.image.extent = defaultHalfExtent;
10533 paramsCubeToCube.dst.image.extent.depth = arrayLayers;
10534 paramsCubeToCube.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10535 paramsCubeToCube.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10536 paramsCubeToCube.allocationKind = allocationKind;
10537 paramsCubeToCube.extensionUse = extensionUse;
10538
10539 {
10540 const VkImageSubresourceLayers sourceLayer =
10541 {
10542 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10543 0u, // deUint32 mipLevel;
10544 0u, // deUint32 baseArrayLayer;
10545 arrayLayers // deUint32 layerCount;
10546 };
10547
10548 const VkImageSubresourceLayers destinationLayer =
10549 {
10550 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10551 0u, // deUint32 mipLevel;
10552 0u, // deUint32 baseArrayLayer;
10553 arrayLayers // deUint32 layerCount;
10554 };
10555
10556 const VkImageCopy testCopy =
10557 {
10558 sourceLayer, // VkImageSubresourceLayers srcSubresource;
10559 {0, 0, 0}, // VkOffset3D srcOffset;
10560 destinationLayer, // VkImageSubresourceLayers dstSubresource;
10561 {0, 0, 0}, // VkOffset3D dstOffset;
10562 defaultHalfExtent // VkExtent3D extent;
10563 };
10564
10565 CopyRegion imageCopy;
10566 imageCopy.imageCopy = testCopy;
10567
10568 paramsCubeToCube.regions.push_back(imageCopy);
10569 }
10570
10571 group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_cube_whole", "copy cube compatible image to cube compatible image all at once", paramsCubeToCube));
10572 }
10573 }
10574
addImageToImageArrayTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)10575 void addImageToImageArrayTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10576 {
10577 tcu::TestContext& testCtx = group->getTestContext();
10578
10579 {
10580 TestParams paramsArrayToArray;
10581 const deUint32 arrayLayers = 16u;
10582 paramsArrayToArray.src.image.imageType = VK_IMAGE_TYPE_2D;
10583 paramsArrayToArray.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
10584 paramsArrayToArray.src.image.extent = defaultHalfExtent;
10585 paramsArrayToArray.src.image.extent.depth = arrayLayers;
10586 paramsArrayToArray.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10587 paramsArrayToArray.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10588 paramsArrayToArray.dst.image.imageType = VK_IMAGE_TYPE_2D;
10589 paramsArrayToArray.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
10590 paramsArrayToArray.dst.image.extent = defaultHalfExtent;
10591 paramsArrayToArray.dst.image.extent.depth = arrayLayers;
10592 paramsArrayToArray.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10593 paramsArrayToArray.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10594 paramsArrayToArray.allocationKind = allocationKind;
10595 paramsArrayToArray.extensionUse = extensionUse;
10596
10597 for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
10598 {
10599 const VkImageSubresourceLayers sourceLayer =
10600 {
10601 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10602 0u, // deUint32 mipLevel;
10603 arrayLayersNdx, // deUint32 baseArrayLayer;
10604 1u // deUint32 layerCount;
10605 };
10606
10607 const VkImageSubresourceLayers destinationLayer =
10608 {
10609 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10610 0u, // deUint32 mipLevel;
10611 arrayLayersNdx, // deUint32 baseArrayLayer;
10612 1u // deUint32 layerCount;
10613 };
10614
10615 const VkImageCopy testCopy =
10616 {
10617 sourceLayer, // VkImageSubresourceLayers srcSubresource;
10618 {0, 0, 0}, // VkOffset3D srcOffset;
10619 destinationLayer, // VkImageSubresourceLayers dstSubresource;
10620 {0, 0, 0}, // VkOffset3D dstOffset;
10621 defaultHalfExtent // VkExtent3D extent;
10622 };
10623
10624 CopyRegion imageCopy;
10625 imageCopy.imageCopy = testCopy;
10626
10627 paramsArrayToArray.regions.push_back(imageCopy);
10628 }
10629
10630 group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_array_layers", "copy 2d array image to 2d array image layer by layer", paramsArrayToArray));
10631 }
10632
10633 {
10634 TestParams paramsArrayToArray;
10635 const deUint32 arrayLayers = 16u;
10636 paramsArrayToArray.src.image.imageType = VK_IMAGE_TYPE_2D;
10637 paramsArrayToArray.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
10638 paramsArrayToArray.src.image.extent = defaultHalfExtent;
10639 paramsArrayToArray.src.image.extent.depth = arrayLayers;
10640 paramsArrayToArray.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10641 paramsArrayToArray.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10642 paramsArrayToArray.dst.image.imageType = VK_IMAGE_TYPE_2D;
10643 paramsArrayToArray.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
10644 paramsArrayToArray.dst.image.extent = defaultHalfExtent;
10645 paramsArrayToArray.dst.image.extent.depth = arrayLayers;
10646 paramsArrayToArray.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10647 paramsArrayToArray.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10648 paramsArrayToArray.allocationKind = allocationKind;
10649 paramsArrayToArray.extensionUse = extensionUse;
10650
10651 {
10652 const VkImageSubresourceLayers sourceLayer =
10653 {
10654 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10655 0u, // deUint32 mipLevel;
10656 0u, // deUint32 baseArrayLayer;
10657 arrayLayers // deUint32 layerCount;
10658 };
10659
10660 const VkImageSubresourceLayers destinationLayer =
10661 {
10662 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10663 0u, // deUint32 mipLevel;
10664 0u, // deUint32 baseArrayLayer;
10665 arrayLayers // deUint32 layerCount;
10666 };
10667
10668 const VkImageCopy testCopy =
10669 {
10670 sourceLayer, // VkImageSubresourceLayers srcSubresource;
10671 {0, 0, 0}, // VkOffset3D srcOffset;
10672 destinationLayer, // VkImageSubresourceLayers dstSubresource;
10673 {0, 0, 0}, // VkOffset3D dstOffset;
10674 defaultHalfExtent // VkExtent3D extent;
10675 };
10676
10677 CopyRegion imageCopy;
10678 imageCopy.imageCopy = testCopy;
10679
10680 paramsArrayToArray.regions.push_back(imageCopy);
10681 }
10682
10683 group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_array_whole", "copy 2d array image to 2d array image all at once", paramsArrayToArray));
10684 }
10685
10686 {
10687 TestParams paramsArrayToArray;
10688 const deUint32 arrayLayers = 16u;
10689 paramsArrayToArray.src.image.imageType = VK_IMAGE_TYPE_2D;
10690 paramsArrayToArray.src.image.extent = defaultHalfExtent;
10691 paramsArrayToArray.src.image.extent.depth = arrayLayers;
10692 paramsArrayToArray.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10693 paramsArrayToArray.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10694 paramsArrayToArray.dst.image.imageType = VK_IMAGE_TYPE_2D;
10695 paramsArrayToArray.dst.image.extent = defaultHalfExtent;
10696 paramsArrayToArray.dst.image.extent.depth = arrayLayers;
10697 paramsArrayToArray.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10698 paramsArrayToArray.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10699 paramsArrayToArray.allocationKind = allocationKind;
10700 paramsArrayToArray.extensionUse = extensionUse;
10701 paramsArrayToArray.mipLevels = deLog2Floor32(deMaxu32(defaultHalfExtent.width, defaultHalfExtent.height)) + 1u;
10702
10703 for (deUint32 mipLevelNdx = 0u; mipLevelNdx < paramsArrayToArray.mipLevels; mipLevelNdx++)
10704 {
10705 const VkImageSubresourceLayers sourceLayer =
10706 {
10707 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10708 mipLevelNdx, // deUint32 mipLevel;
10709 0u, // deUint32 baseArrayLayer;
10710 arrayLayers // deUint32 layerCount;
10711 };
10712
10713 const VkImageSubresourceLayers destinationLayer =
10714 {
10715 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10716 mipLevelNdx, // deUint32 mipLevel;
10717 0u, // deUint32 baseArrayLayer;
10718 arrayLayers // deUint32 layerCount;
10719 };
10720
10721 const VkExtent3D extent =
10722 {
10723 (deUint32)deMax(defaultHalfExtent.width >> mipLevelNdx, 1), // deUint32 width;
10724 (deUint32)deMax(defaultHalfExtent.height >> mipLevelNdx, 1), // deUint32 height;
10725 1u, // deUint32 depth;
10726 };
10727
10728 const VkImageCopy testCopy =
10729 {
10730 sourceLayer, // VkImageSubresourceLayers srcSubresource;
10731 {0, 0, 0}, // VkOffset3D srcOffset;
10732 destinationLayer, // VkImageSubresourceLayers dstSubresource;
10733 {0, 0, 0}, // VkOffset3D dstOffset;
10734 extent // VkExtent3D extent;
10735 };
10736
10737 CopyRegion imageCopy;
10738 imageCopy.imageCopy = testCopy;
10739
10740 paramsArrayToArray.regions.push_back(imageCopy);
10741 }
10742
10743 VkFormat imageFormats [] = { VK_FORMAT_R8G8B8A8_UINT, VK_FORMAT_D32_SFLOAT, VK_FORMAT_D16_UNORM, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_S8_UINT};
10744
10745 for (deUint32 imageFormatsNdx = 0; imageFormatsNdx < DE_LENGTH_OF_ARRAY(imageFormats); imageFormatsNdx++)
10746 {
10747 paramsArrayToArray.src.image.format = imageFormats[imageFormatsNdx];
10748 paramsArrayToArray.dst.image.format = imageFormats[imageFormatsNdx];
10749 for (deUint32 regionNdx = 0u; regionNdx < paramsArrayToArray.regions.size(); regionNdx++)
10750 {
10751 paramsArrayToArray.regions[regionNdx].imageCopy.srcSubresource.aspectMask = getImageAspectFlags(mapVkFormat(imageFormats[imageFormatsNdx]));
10752 paramsArrayToArray.regions[regionNdx].imageCopy.dstSubresource.aspectMask = getImageAspectFlags(mapVkFormat(imageFormats[imageFormatsNdx]));
10753 }
10754 std::ostringstream testName;
10755 const std::string formatName = getFormatName(imageFormats[imageFormatsNdx]);
10756 testName << "array_to_array_whole_mipmap_" << de::toLower(formatName.substr(10));
10757 group->addChild(new CopyImageToImageMipmapTestCase(testCtx, testName.str(), "copy 2d array mipmap image to 2d array mipmap image all at once", paramsArrayToArray));
10758 }
10759 }
10760 }
10761
addImageToImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)10762 void addImageToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10763 {
10764 addTestGroup(group, "simple_tests", "Copy from image to image simple tests", addImageToImageSimpleTests, allocationKind, extensionUse);
10765 addTestGroup(group, "all_formats", "Copy from image to image with all compatible formats", addImageToImageAllFormatsTests, allocationKind, extensionUse);
10766 addTestGroup(group, "3d_images", "Coping operations on 3d images", addImageToImage3dImagesTests, allocationKind, extensionUse);
10767 addTestGroup(group, "dimensions", "Copying operations on different image dimensions", addImageToImageDimensionsTests, allocationKind, extensionUse);
10768 addTestGroup(group, "cube", "Coping operations on cube compatible images", addImageToImageCubeTests, allocationKind, extensionUse);
10769 addTestGroup(group, "array", "Copying operations on array of images", addImageToImageArrayTests, allocationKind, extensionUse);
10770 }
10771
add1dImageToBufferTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)10772 void add1dImageToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10773 {
10774 tcu::TestContext& testCtx = group->getTestContext();
10775
10776 {
10777 TestParams params;
10778 params.src.image.imageType = VK_IMAGE_TYPE_1D;
10779 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
10780 params.src.image.extent = default1dExtent;
10781 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10782 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10783 params.dst.buffer.size = defaultSize;
10784 params.allocationKind = allocationKind;
10785 params.extensionUse = extensionUse;
10786
10787 const VkBufferImageCopy bufferImageCopy =
10788 {
10789 0u, // VkDeviceSize bufferOffset;
10790 0u, // deUint32 bufferRowLength;
10791 0u, // deUint32 bufferImageHeight;
10792 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
10793 {0, 0, 0}, // VkOffset3D imageOffset;
10794 default1dExtent // VkExtent3D imageExtent;
10795 };
10796 CopyRegion copyRegion;
10797 copyRegion.bufferImageCopy = bufferImageCopy;
10798
10799 params.regions.push_back(copyRegion);
10800
10801 group->addChild(new CopyImageToBufferTestCase(testCtx, "tightly_sized_buffer", "Copy from image to a buffer that is just large enough to contain the data", params));
10802 }
10803
10804 {
10805 TestParams params;
10806 deUint32 bufferImageHeight = defaultSize + 1u;
10807 params.src.image.imageType = VK_IMAGE_TYPE_1D;
10808 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
10809 params.src.image.extent = default1dExtent;
10810 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10811 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10812 params.dst.buffer.size = bufferImageHeight;
10813 params.allocationKind = allocationKind;
10814 params.extensionUse = extensionUse;
10815
10816 const VkBufferImageCopy bufferImageCopy =
10817 {
10818 0u, // VkDeviceSize bufferOffset;
10819 0u, // deUint32 bufferRowLength;
10820 bufferImageHeight, // deUint32 bufferImageHeight;
10821 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
10822 {0, 0, 0}, // VkOffset3D imageOffset;
10823 default1dExtent // VkExtent3D imageExtent;
10824 };
10825 CopyRegion copyRegion;
10826 copyRegion.bufferImageCopy = bufferImageCopy;
10827
10828 params.regions.push_back(copyRegion);
10829
10830 group->addChild(new CopyImageToBufferTestCase(testCtx, "larger_buffer", "Copy from image to a buffer that is larger than necessary", params));
10831 }
10832
10833 {
10834 TestParams params;
10835 deUint32 arrayLayers = 16u;
10836 params.src.image.imageType = VK_IMAGE_TYPE_1D;
10837 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
10838 params.src.image.extent = default1dExtent;
10839 params.src.image.extent.depth = arrayLayers;
10840 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10841 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10842 params.dst.buffer.size = defaultSize * arrayLayers;
10843 params.allocationKind = allocationKind;
10844 params.extensionUse = extensionUse;
10845
10846 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.src.image.format));
10847 for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
10848 {
10849 const VkDeviceSize offset = defaultSize * pixelSize * arrayLayerNdx;
10850 const VkBufferImageCopy bufferImageCopy =
10851 {
10852 offset, // VkDeviceSize bufferOffset;
10853 0u, // deUint32 bufferRowLength;
10854 defaultSize, // deUint32 bufferImageHeight;
10855 {
10856 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10857 0u, // deUint32 mipLevel;
10858 arrayLayerNdx, // deUint32 baseArrayLayer;
10859 1u, // deUint32 layerCount;
10860 }, // VkImageSubresourceLayers imageSubresource;
10861 {0, 0, 0}, // VkOffset3D imageOffset;
10862 default1dExtent // VkExtent3D imageExtent;
10863 };
10864 CopyRegion copyRegion;
10865 copyRegion.bufferImageCopy = bufferImageCopy;
10866
10867 params.regions.push_back(copyRegion);
10868 }
10869
10870 group->addChild(new CopyImageToBufferTestCase(testCtx, "array_tightly_sized_buffer", "Copy each layer from array to tightly sized buffer", params));
10871 }
10872
10873 {
10874 TestParams params;
10875 deUint32 arrayLayers = 16u;
10876 deUint32 bufferImageHeight = defaultSize + 1u;
10877 params.src.image.imageType = VK_IMAGE_TYPE_1D;
10878 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
10879 params.src.image.extent = default1dExtent;
10880 params.src.image.extent.depth = arrayLayers;
10881 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10882 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10883 params.dst.buffer.size = bufferImageHeight * arrayLayers;
10884 params.allocationKind = allocationKind;
10885 params.extensionUse = extensionUse;
10886
10887 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.src.image.format));
10888 for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
10889 {
10890 const VkDeviceSize offset = bufferImageHeight * pixelSize * arrayLayerNdx;
10891 const VkBufferImageCopy bufferImageCopy =
10892 {
10893 offset, // VkDeviceSize bufferOffset;
10894 0u, // deUint32 bufferRowLength;
10895 bufferImageHeight, // deUint32 bufferImageHeight;
10896 {
10897 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10898 0u, // deUint32 mipLevel;
10899 arrayLayerNdx, // deUint32 baseArrayLayer;
10900 1u, // deUint32 layerCount;
10901 }, // VkImageSubresourceLayers imageSubresource;
10902 {0, 0, 0}, // VkOffset3D imageOffset;
10903 default1dExtent // VkExtent3D imageExtent;
10904 };
10905 CopyRegion copyRegion;
10906 copyRegion.bufferImageCopy = bufferImageCopy;
10907
10908 params.regions.push_back(copyRegion);
10909 }
10910
10911 group->addChild(new CopyImageToBufferTestCase(testCtx, "array_larger_buffer", "Copy each layer from array to a buffer that is larger than necessary", params));
10912 }
10913 }
10914
add2dImageToBufferTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)10915 void add2dImageToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10916 {
10917 tcu::TestContext& testCtx = group->getTestContext();
10918
10919 {
10920 TestParams params;
10921 params.src.image.imageType = VK_IMAGE_TYPE_2D;
10922 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
10923 params.src.image.extent = defaultExtent;
10924 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10925 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10926 params.dst.buffer.size = defaultSize * defaultSize;
10927 params.allocationKind = allocationKind;
10928 params.extensionUse = extensionUse;
10929
10930 const VkBufferImageCopy bufferImageCopy =
10931 {
10932 0u, // VkDeviceSize bufferOffset;
10933 0u, // deUint32 bufferRowLength;
10934 0u, // deUint32 bufferImageHeight;
10935 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
10936 {0, 0, 0}, // VkOffset3D imageOffset;
10937 defaultExtent // VkExtent3D imageExtent;
10938 };
10939 CopyRegion copyRegion;
10940 copyRegion.bufferImageCopy = bufferImageCopy;
10941
10942 params.regions.push_back(copyRegion);
10943
10944 group->addChild(new CopyImageToBufferTestCase(testCtx, "whole", "Copy from image to buffer", params));
10945 }
10946
10947 {
10948 TestParams params;
10949 params.src.image.imageType = VK_IMAGE_TYPE_2D;
10950 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
10951 params.src.image.extent = defaultExtent;
10952 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10953 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10954 params.dst.buffer.size = defaultSize * defaultSize;
10955 params.allocationKind = allocationKind;
10956 params.extensionUse = extensionUse;
10957
10958 const VkBufferImageCopy bufferImageCopy =
10959 {
10960 defaultSize * defaultHalfSize, // VkDeviceSize bufferOffset;
10961 0u, // deUint32 bufferRowLength;
10962 0u, // deUint32 bufferImageHeight;
10963 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
10964 {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
10965 defaultHalfExtent // VkExtent3D imageExtent;
10966 };
10967 CopyRegion copyRegion;
10968 copyRegion.bufferImageCopy = bufferImageCopy;
10969
10970 params.regions.push_back(copyRegion);
10971
10972 group->addChild(new CopyImageToBufferTestCase(testCtx, "buffer_offset", "Copy from image to buffer with buffer offset", params));
10973 }
10974
10975 {
10976 TestParams params;
10977 params.src.image.imageType = VK_IMAGE_TYPE_2D;
10978 params.src.image.format = VK_FORMAT_R8_UNORM;
10979 params.src.image.extent = defaultExtent;
10980 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10981 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10982 params.dst.buffer.size = defaultSize * defaultSize;
10983 params.allocationKind = allocationKind;
10984 params.extensionUse = extensionUse;
10985
10986 const VkBufferImageCopy bufferImageCopy =
10987 {
10988 defaultSize * defaultHalfSize + 1u, // VkDeviceSize bufferOffset;
10989 0u, // deUint32 bufferRowLength;
10990 0u, // deUint32 bufferImageHeight;
10991 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
10992 {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
10993 defaultHalfExtent // VkExtent3D imageExtent;
10994 };
10995 CopyRegion copyRegion;
10996 copyRegion.bufferImageCopy = bufferImageCopy;
10997
10998 params.regions.push_back(copyRegion);
10999
11000 group->addChild(new CopyImageToBufferTestCase(testCtx, "buffer_offset_relaxed", "Copy from image to buffer with buffer offset not a multiple of 4", params));
11001 }
11002
11003 {
11004 TestParams params;
11005 params.src.image.imageType = VK_IMAGE_TYPE_2D;
11006 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
11007 params.src.image.extent = defaultExtent;
11008 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11009 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11010 params.dst.buffer.size = defaultSize * defaultSize;
11011 params.allocationKind = allocationKind;
11012 params.extensionUse = extensionUse;
11013
11014 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.src.image.format));
11015 const VkDeviceSize bufferSize = pixelSize * params.dst.buffer.size;
11016 const VkDeviceSize offsetSize = pixelSize * defaultQuarterSize * defaultQuarterSize;
11017 deUint32 divisor = 1;
11018 for (VkDeviceSize offset = 0; offset < bufferSize - offsetSize; offset += offsetSize, ++divisor)
11019 {
11020 const deUint32 bufferRowLength = defaultQuarterSize;
11021 const deUint32 bufferImageHeight = defaultQuarterSize;
11022 const VkExtent3D imageExtent = {defaultQuarterSize / divisor, defaultQuarterSize, 1};
11023 DE_ASSERT(!bufferRowLength || bufferRowLength >= imageExtent.width);
11024 DE_ASSERT(!bufferImageHeight || bufferImageHeight >= imageExtent.height);
11025 DE_ASSERT(imageExtent.width * imageExtent.height *imageExtent.depth <= offsetSize);
11026
11027 CopyRegion region;
11028 const VkBufferImageCopy bufferImageCopy =
11029 {
11030 offset, // VkDeviceSize bufferOffset;
11031 bufferRowLength, // deUint32 bufferRowLength;
11032 bufferImageHeight, // deUint32 bufferImageHeight;
11033 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
11034 {0, 0, 0}, // VkOffset3D imageOffset;
11035 imageExtent // VkExtent3D imageExtent;
11036 };
11037 region.bufferImageCopy = bufferImageCopy;
11038 params.regions.push_back(region);
11039 }
11040
11041 group->addChild(new CopyImageToBufferTestCase(testCtx, "regions", "Copy from image to buffer with multiple regions", params));
11042 }
11043
11044 {
11045 TestParams params;
11046 params.src.image.imageType = VK_IMAGE_TYPE_2D;
11047 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
11048 params.src.image.extent = defaultExtent;
11049 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11050 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11051 params.dst.buffer.size = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize;
11052 params.allocationKind = allocationKind;
11053 params.extensionUse = extensionUse;
11054
11055 const VkBufferImageCopy bufferImageCopy =
11056 {
11057 0u, // VkDeviceSize bufferOffset;
11058 defaultSize, // deUint32 bufferRowLength;
11059 defaultSize, // deUint32 bufferImageHeight;
11060 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
11061 {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
11062 defaultHalfExtent // VkExtent3D imageExtent;
11063 };
11064 CopyRegion copyRegion;
11065 copyRegion.bufferImageCopy = bufferImageCopy;
11066
11067 params.regions.push_back(copyRegion);
11068
11069 group->addChild(new CopyImageToBufferTestCase(testCtx, "tightly_sized_buffer", "Copy from image to a buffer that is just large enough to contain the data", params));
11070 }
11071
11072 {
11073 TestParams params;
11074 deUint32 bufferImageHeight = defaultSize + 1u;
11075 params.src.image.imageType = VK_IMAGE_TYPE_2D;
11076 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
11077 params.src.image.extent = defaultExtent;
11078 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11079 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11080 params.dst.buffer.size = bufferImageHeight * defaultSize;
11081 params.allocationKind = allocationKind;
11082 params.extensionUse = extensionUse;
11083
11084 const VkBufferImageCopy bufferImageCopy =
11085 {
11086 0u, // VkDeviceSize bufferOffset;
11087 defaultSize, // deUint32 bufferRowLength;
11088 bufferImageHeight, // deUint32 bufferImageHeight;
11089 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
11090 {0, 0, 0}, // VkOffset3D imageOffset;
11091 defaultExtent // VkExtent3D imageExtent;
11092 };
11093 CopyRegion copyRegion;
11094 copyRegion.bufferImageCopy = bufferImageCopy;
11095
11096 params.regions.push_back(copyRegion);
11097
11098 group->addChild(new CopyImageToBufferTestCase(testCtx, "larger_buffer", "Copy from image to a buffer that is larger than necessary", params));
11099 }
11100
11101 {
11102 TestParams params;
11103 params.src.image.imageType = VK_IMAGE_TYPE_2D;
11104 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
11105 params.src.image.extent = defaultExtent;
11106 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11107 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11108 params.dst.buffer.size = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultQuarterSize;
11109 params.allocationKind = allocationKind;
11110 params.extensionUse = extensionUse;
11111
11112 const VkBufferImageCopy bufferImageCopy =
11113 {
11114 defaultQuarterSize, // VkDeviceSize bufferOffset;
11115 defaultSize, // deUint32 bufferRowLength;
11116 defaultSize, // deUint32 bufferImageHeight;
11117 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
11118 {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
11119 defaultHalfExtent // VkExtent3D imageExtent;
11120 };
11121 CopyRegion copyRegion;
11122 copyRegion.bufferImageCopy = bufferImageCopy;
11123
11124 params.regions.push_back(copyRegion);
11125
11126 group->addChild(new CopyImageToBufferTestCase(testCtx, "tightly_sized_buffer_offset", "Copy from image to a buffer that is just large enough to contain the data", params));
11127 }
11128
11129 {
11130 TestParams params;
11131 deUint32 arrayLayers = 16u;
11132 params.src.image.imageType = VK_IMAGE_TYPE_2D;
11133 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
11134 params.src.image.extent = defaultHalfExtent;
11135 params.src.image.extent.depth = arrayLayers;
11136 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11137 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11138 params.dst.buffer.size = defaultHalfSize * defaultHalfSize * arrayLayers;
11139 params.allocationKind = allocationKind;
11140 params.extensionUse = extensionUse;
11141
11142 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.src.image.format));
11143 for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
11144 {
11145 const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
11146 const VkBufferImageCopy bufferImageCopy =
11147 {
11148 offset, // VkDeviceSize bufferOffset;
11149 0u, // deUint32 bufferRowLength;
11150 0u, // deUint32 bufferImageHeight;
11151 {
11152 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11153 0u, // deUint32 mipLevel;
11154 arrayLayerNdx, // deUint32 baseArrayLayer;
11155 1u, // deUint32 layerCount;
11156 }, // VkImageSubresourceLayers imageSubresource;
11157 {0, 0, 0}, // VkOffset3D imageOffset;
11158 defaultHalfExtent // VkExtent3D imageExtent;
11159 };
11160 CopyRegion copyRegion;
11161 copyRegion.bufferImageCopy = bufferImageCopy;
11162
11163 params.regions.push_back(copyRegion);
11164 }
11165 group->addChild(new CopyImageToBufferTestCase(testCtx, "array", "Copy each layer from array to buffer", params));
11166 }
11167
11168 {
11169 TestParams params;
11170 deUint32 arrayLayers = 16u;
11171 deUint32 imageBufferHeight = defaultHalfSize + 1u;
11172 params.src.image.imageType = VK_IMAGE_TYPE_2D;
11173 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
11174 params.src.image.extent = defaultHalfExtent;
11175 params.src.image.extent.depth = arrayLayers;
11176 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11177 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11178 params.dst.buffer.size = defaultHalfSize * imageBufferHeight * arrayLayers;
11179 params.allocationKind = allocationKind;
11180 params.extensionUse = extensionUse;
11181
11182 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.src.image.format));
11183 for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
11184 {
11185 const VkDeviceSize offset = defaultHalfSize * imageBufferHeight * pixelSize * arrayLayerNdx;
11186 const VkBufferImageCopy bufferImageCopy =
11187 {
11188 offset, // VkDeviceSize bufferOffset;
11189 0u, // deUint32 bufferRowLength;
11190 imageBufferHeight, // deUint32 bufferImageHeight;
11191 {
11192 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11193 0u, // deUint32 mipLevel;
11194 arrayLayerNdx, // deUint32 baseArrayLayer;
11195 1u, // deUint32 layerCount;
11196 }, // VkImageSubresourceLayers imageSubresource;
11197 {0, 0, 0}, // VkOffset3D imageOffset;
11198 defaultHalfExtent // VkExtent3D imageExtent;
11199 };
11200 CopyRegion copyRegion;
11201 copyRegion.bufferImageCopy = bufferImageCopy;
11202
11203 params.regions.push_back(copyRegion);
11204 }
11205 group->addChild(new CopyImageToBufferTestCase(testCtx, "array_larger_buffer", "Copy each layer from array to a buffer that is larger than necessary", params));
11206 }
11207
11208 {
11209 TestParams params;
11210 deUint32 arrayLayers = 16u;
11211 params.src.image.imageType = VK_IMAGE_TYPE_2D;
11212 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
11213 params.src.image.extent = defaultHalfExtent;
11214 params.src.image.extent.depth = arrayLayers;
11215 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11216 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11217 params.dst.buffer.size = defaultHalfSize * defaultHalfSize * arrayLayers;
11218 params.allocationKind = allocationKind;
11219 params.extensionUse = extensionUse;
11220
11221 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.src.image.format));
11222 for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
11223 {
11224 const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
11225 const VkBufferImageCopy bufferImageCopy =
11226 {
11227 offset, // VkDeviceSize bufferOffset;
11228 defaultHalfSize, // deUint32 bufferRowLength;
11229 defaultHalfSize, // deUint32 bufferImageHeight;
11230 {
11231 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11232 0u, // deUint32 mipLevel;
11233 arrayLayerNdx, // deUint32 baseArrayLayer;
11234 1u, // deUint32 layerCount;
11235 }, // VkImageSubresourceLayers imageSubresource;
11236 {0, 0, 0}, // VkOffset3D imageOffset;
11237 defaultHalfExtent // VkExtent3D imageExtent;
11238 };
11239 CopyRegion copyRegion;
11240 copyRegion.bufferImageCopy = bufferImageCopy;
11241
11242 params.regions.push_back(copyRegion);
11243 }
11244 group->addChild(new CopyImageToBufferTestCase(testCtx, "array_tightly_sized_buffer", "Copy each layer from array to tightly sized buffer", params));
11245 }
11246 }
11247
addImageToBufferTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)11248 void addImageToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11249 {
11250 addTestGroup(group, "1d_images", "Copying operations on 1d images", add1dImageToBufferTests, allocationKind, extensionUse);
11251 addTestGroup(group, "2d_images", "Copying operations on 2d images", add2dImageToBufferTests, allocationKind, extensionUse);
11252 }
11253
addBufferToDepthStencilTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)11254 void addBufferToDepthStencilTests(tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11255 {
11256 tcu::TestContext& testCtx = group->getTestContext();
11257
11258 const struct
11259 {
11260 const char* name;
11261 const VkFormat format;
11262 } depthAndStencilFormats[] =
11263 {
11264 { "d16_unorm", VK_FORMAT_D16_UNORM },
11265 { "x8_d24_unorm_pack32", VK_FORMAT_X8_D24_UNORM_PACK32 },
11266 { "d32_sfloat", VK_FORMAT_D32_SFLOAT },
11267 { "d16_unorm_s8_uint", VK_FORMAT_D16_UNORM_S8_UINT },
11268 { "d24_unorm_s8_uint", VK_FORMAT_D24_UNORM_S8_UINT },
11269 { "d32_sfloat_s8_uint", VK_FORMAT_D32_SFLOAT_S8_UINT }
11270 };
11271
11272 const VkImageSubresourceLayers depthSourceLayer =
11273 {
11274 VK_IMAGE_ASPECT_DEPTH_BIT, // VkImageAspectFlags aspectMask;
11275 0u, // deUint32 mipLevel;
11276 0u, // deUint32 baseArrayLayer;
11277 1u, // deUint32 layerCount;
11278 };
11279
11280 const VkBufferImageCopy bufferDepthCopy =
11281 {
11282 0u, // VkDeviceSize bufferOffset;
11283 0u, // deUint32 bufferRowLength;
11284 0u, // deUint32 bufferImageHeight;
11285 depthSourceLayer, // VkImageSubresourceLayers imageSubresource;
11286 {0, 0, 0}, // VkOffset3D imageOffset;
11287 defaultExtent // VkExtent3D imageExtent;
11288 };
11289
11290 const VkBufferImageCopy bufferDepthCopyOffset =
11291 {
11292 32, // VkDeviceSize bufferOffset;
11293 defaultHalfSize + defaultQuarterSize, // deUint32 bufferRowLength;
11294 defaultHalfSize + defaultQuarterSize, // deUint32 bufferImageHeight;
11295 depthSourceLayer, // VkImageSubresourceLayers imageSubresource;
11296 {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
11297 defaultHalfExtent // VkExtent3D imageExtent;
11298 };
11299
11300 const VkImageSubresourceLayers stencilSourceLayer =
11301 {
11302 VK_IMAGE_ASPECT_STENCIL_BIT, // VkImageAspectFlags aspectMask;
11303 0u, // deUint32 mipLevel;
11304 0u, // deUint32 baseArrayLayer;
11305 1u, // deUint32 layerCount;
11306 };
11307
11308 const VkBufferImageCopy bufferStencilCopy =
11309 {
11310 0u, // VkDeviceSize bufferOffset;
11311 0u, // deUint32 bufferRowLength;
11312 0u, // deUint32 bufferImageHeight;
11313 stencilSourceLayer, // VkImageSubresourceLayers imageSubresource;
11314 {0, 0, 0}, // VkOffset3D imageOffset;
11315 defaultExtent // VkExtent3D imageExtent;
11316 };
11317
11318 const VkBufferImageCopy bufferStencilCopyOffset =
11319 {
11320 32, // VkDeviceSize bufferOffset;
11321 defaultHalfSize + defaultQuarterSize, // deUint32 bufferRowLength;
11322 defaultHalfSize + defaultQuarterSize, // deUint32 bufferImageHeight;
11323 stencilSourceLayer, // VkImageSubresourceLayers imageSubresource;
11324 {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
11325 defaultHalfExtent // VkExtent3D imageExtent;
11326 };
11327
11328 const bool useOffset[] = {false, true};
11329
11330 // Note: Depth stencil tests I want to do
11331 // Formats: D16, D24S8, D32FS8
11332 // Test writing each component with separate CopyBufferToImage commands
11333 // Test writing both components in one CopyBufferToImage command
11334 // Swap order of writes of Depth & Stencil
11335 // whole surface, subimages?
11336 // Similar tests as BufferToImage?
11337 for (const auto config : depthAndStencilFormats)
11338 for (const auto offset : useOffset)
11339 {
11340 // TODO: Check that this format is supported before creating tests?
11341 //if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D24_UNORM_S8_UINT))
11342
11343 CopyRegion copyDepthRegion;
11344 CopyRegion copyStencilRegion;
11345 TestParams params;
11346 const tcu::TextureFormat format = mapVkFormat(config.format);
11347 const bool hasDepth = tcu::hasDepthComponent(format.order);
11348 const bool hasStencil = tcu::hasStencilComponent(format.order);
11349 std::string description = config.name;
11350
11351 if (offset)
11352 {
11353 copyDepthRegion.bufferImageCopy = bufferDepthCopyOffset;
11354 copyStencilRegion.bufferImageCopy = bufferStencilCopyOffset;
11355 description = "buffer_offset_" + description;
11356 params.src.buffer.size = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultQuarterSize;
11357 }
11358 else
11359 {
11360 copyDepthRegion.bufferImageCopy = bufferDepthCopy;
11361 copyStencilRegion.bufferImageCopy = bufferStencilCopy;
11362 params.src.buffer.size = defaultSize * defaultSize;
11363 }
11364
11365 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
11366 params.dst.image.format = config.format;
11367 params.dst.image.extent = defaultExtent;
11368 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11369 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11370 params.allocationKind = allocationKind;
11371 params.extensionUse = extensionUse;
11372
11373 if (hasDepth && hasStencil)
11374 {
11375 params.singleCommand = DE_TRUE;
11376
11377 params.regions.push_back(copyDepthRegion);
11378 params.regions.push_back(copyStencilRegion);
11379
11380 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_DS", "Copy from depth&stencil to image", params));
11381
11382 params.singleCommand = DE_FALSE;
11383
11384 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_D_S", "Copy from depth then stencil to image", params));
11385
11386 params.regions.clear();
11387 params.regions.push_back(copyStencilRegion);
11388 params.regions.push_back(copyDepthRegion);
11389
11390 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_S_D", "Copy from depth then stencil to image", params));
11391
11392 params.singleCommand = DE_TRUE;
11393 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_SD", "Copy from depth&stencil to image", params));
11394 }
11395
11396 if (hasStencil)
11397 {
11398 params.regions.clear();
11399 params.regions.push_back(copyStencilRegion);
11400
11401 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_S", "Copy from stencil to image", params));
11402 }
11403
11404 if (hasDepth)
11405 {
11406 params.regions.clear();
11407 params.regions.push_back(copyDepthRegion);
11408
11409 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_D", "Copy from depth to image", params));
11410 }
11411 }
11412 }
11413
add1dBufferToImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)11414 void add1dBufferToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11415 {
11416 tcu::TestContext& testCtx = group->getTestContext();
11417
11418 {
11419 TestParams params;
11420 params.src.buffer.size = defaultSize;
11421 params.dst.image.imageType = VK_IMAGE_TYPE_1D;
11422 params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
11423 params.dst.image.extent = default1dExtent;
11424 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11425 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11426 params.allocationKind = allocationKind;
11427 params.extensionUse = extensionUse;
11428
11429 const VkBufferImageCopy bufferImageCopy =
11430 {
11431 0u, // VkDeviceSize bufferOffset;
11432 0u, // deUint32 bufferRowLength;
11433 0u, // deUint32 bufferImageHeight;
11434 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
11435 {0, 0, 0}, // VkOffset3D imageOffset;
11436 default1dExtent // VkExtent3D imageExtent;
11437 };
11438 CopyRegion copyRegion;
11439 copyRegion.bufferImageCopy = bufferImageCopy;
11440
11441 params.regions.push_back(copyRegion);
11442
11443 group->addChild(new CopyBufferToImageTestCase(testCtx, "tightly_sized_buffer", "Copy from tightly packed buffer to image", params));
11444 }
11445
11446 {
11447 TestParams params;
11448 deUint32 bufferImageHeight = defaultSize + 1u;
11449 params.src.buffer.size = bufferImageHeight;
11450 params.dst.image.imageType = VK_IMAGE_TYPE_1D;
11451 params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
11452 params.dst.image.extent = default1dExtent;
11453 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11454 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11455 params.allocationKind = allocationKind;
11456 params.extensionUse = extensionUse;
11457
11458 const VkBufferImageCopy bufferImageCopy =
11459 {
11460 0u, // VkDeviceSize bufferOffset;
11461 0u, // deUint32 bufferRowLength;
11462 bufferImageHeight, // deUint32 bufferImageHeight;
11463 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
11464 {0, 0, 0}, // VkOffset3D imageOffset;
11465 default1dExtent // VkExtent3D imageExtent;
11466 };
11467 CopyRegion copyRegion;
11468 copyRegion.bufferImageCopy = bufferImageCopy;
11469
11470 params.regions.push_back(copyRegion);
11471
11472 group->addChild(new CopyBufferToImageTestCase(testCtx, "larger_buffer", "Copy from a buffer to image", params));
11473 }
11474
11475 {
11476 TestParams params;
11477 deUint32 arrayLayers = 16u;
11478 params.src.buffer.size = defaultSize * arrayLayers;
11479 params.dst.image.imageType = VK_IMAGE_TYPE_1D;
11480 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
11481 params.dst.image.extent = default1dExtent;
11482 params.dst.image.extent.depth = arrayLayers;
11483 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11484 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11485 params.allocationKind = allocationKind;
11486 params.extensionUse = extensionUse;
11487
11488 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.dst.image.format));
11489 for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
11490 {
11491 const VkDeviceSize offset = defaultSize * pixelSize * arrayLayerNdx;
11492 const VkBufferImageCopy bufferImageCopy =
11493 {
11494 offset, // VkDeviceSize bufferOffset;
11495 0u, // deUint32 bufferRowLength;
11496 0u, // deUint32 bufferImageHeight;
11497 {
11498 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11499 0u, // deUint32 mipLevel;
11500 arrayLayerNdx, // deUint32 baseArrayLayer;
11501 1u, // deUint32 layerCount;
11502 }, // VkImageSubresourceLayers imageSubresource;
11503 {0, 0, 0}, // VkOffset3D imageOffset;
11504 default1dExtent // VkExtent3D imageExtent;
11505 };
11506 CopyRegion copyRegion;
11507 copyRegion.bufferImageCopy = bufferImageCopy;
11508
11509 params.regions.push_back(copyRegion);
11510 }
11511
11512 group->addChild(new CopyBufferToImageTestCase(testCtx, "array_tightly_sized_buffer", "Copy from a different part of the tightly packed buffer to each layer", params));
11513 }
11514
11515 {
11516 TestParams params;
11517 deUint32 arrayLayers = 16u;
11518 deUint32 bufferImageHeight = defaultSize + 1u;
11519 params.src.buffer.size = defaultSize * arrayLayers;
11520 params.dst.image.imageType = VK_IMAGE_TYPE_1D;
11521 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
11522 params.dst.image.extent = default1dExtent;
11523 params.dst.image.extent.depth = arrayLayers;
11524 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11525 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11526 params.allocationKind = allocationKind;
11527 params.extensionUse = extensionUse;
11528
11529 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.dst.image.format));
11530 for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
11531 {
11532 const VkDeviceSize offset = defaultSize * pixelSize * arrayLayerNdx;
11533 const VkBufferImageCopy bufferImageCopy =
11534 {
11535 offset, // VkDeviceSize bufferOffset;
11536 0u, // deUint32 bufferRowLength;
11537 bufferImageHeight, // deUint32 bufferImageHeight;
11538 {
11539 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11540 0u, // deUint32 mipLevel;
11541 arrayLayerNdx, // deUint32 baseArrayLayer;
11542 1u, // deUint32 layerCount;
11543 }, // VkImageSubresourceLayers imageSubresource;
11544 {0, 0, 0}, // VkOffset3D imageOffset;
11545 default1dExtent // VkExtent3D imageExtent;
11546 };
11547 CopyRegion copyRegion;
11548 copyRegion.bufferImageCopy = bufferImageCopy;
11549
11550 params.regions.push_back(copyRegion);
11551 }
11552
11553 group->addChild(new CopyBufferToImageTestCase(testCtx, "array_larger_buffer", "Copy from a different part of the buffer to each layer", params));
11554 }
11555 }
11556
add2dBufferToImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)11557 void add2dBufferToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11558 {
11559 tcu::TestContext& testCtx = group->getTestContext();
11560
11561 {
11562 TestParams params;
11563 params.src.buffer.size = defaultSize * defaultSize;
11564 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
11565 params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
11566 params.dst.image.extent = defaultExtent;
11567 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11568 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11569 params.allocationKind = allocationKind;
11570 params.extensionUse = extensionUse;
11571
11572 const VkBufferImageCopy bufferImageCopy =
11573 {
11574 0u, // VkDeviceSize bufferOffset;
11575 0u, // deUint32 bufferRowLength;
11576 0u, // deUint32 bufferImageHeight;
11577 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
11578 {0, 0, 0}, // VkOffset3D imageOffset;
11579 defaultExtent // VkExtent3D imageExtent;
11580 };
11581 CopyRegion copyRegion;
11582 copyRegion.bufferImageCopy = bufferImageCopy;
11583
11584 params.regions.push_back(copyRegion);
11585
11586 group->addChild(new CopyBufferToImageTestCase(testCtx, "whole", "Copy from buffer to image", params));
11587 }
11588
11589 {
11590 TestParams params;
11591 params.src.buffer.size = defaultSize * defaultSize;
11592 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
11593 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
11594 params.dst.image.extent = defaultExtent;
11595 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11596 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11597 params.allocationKind = allocationKind;
11598 params.extensionUse = extensionUse;
11599
11600 CopyRegion region;
11601 deUint32 divisor = 1;
11602 for (int offset = 0; (offset + defaultQuarterSize / divisor < defaultSize) && (defaultQuarterSize > divisor); offset += defaultQuarterSize / divisor++)
11603 {
11604 const VkBufferImageCopy bufferImageCopy =
11605 {
11606 0u, // VkDeviceSize bufferOffset;
11607 0u, // deUint32 bufferRowLength;
11608 0u, // deUint32 bufferImageHeight;
11609 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
11610 {offset, defaultHalfSize, 0}, // VkOffset3D imageOffset;
11611 {defaultQuarterSize / divisor, defaultQuarterSize / divisor, 1} // VkExtent3D imageExtent;
11612 };
11613 region.bufferImageCopy = bufferImageCopy;
11614 params.regions.push_back(region);
11615 }
11616
11617 group->addChild(new CopyBufferToImageTestCase(testCtx, "regions", "Copy from buffer to image with multiple regions", params));
11618 }
11619
11620 {
11621 TestParams params;
11622 params.src.buffer.size = defaultSize * defaultSize;
11623 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
11624 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
11625 params.dst.image.extent = defaultExtent;
11626 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11627 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11628 params.allocationKind = allocationKind;
11629 params.extensionUse = extensionUse;
11630
11631 const VkBufferImageCopy bufferImageCopy =
11632 {
11633 defaultQuarterSize, // VkDeviceSize bufferOffset;
11634 defaultHalfSize + defaultQuarterSize, // deUint32 bufferRowLength;
11635 defaultHalfSize + defaultQuarterSize, // deUint32 bufferImageHeight;
11636 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
11637 {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
11638 defaultHalfExtent // VkExtent3D imageExtent;
11639 };
11640 CopyRegion copyRegion;
11641 copyRegion.bufferImageCopy = bufferImageCopy;
11642
11643 params.regions.push_back(copyRegion);
11644
11645 group->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_offset", "Copy from buffer to image with buffer offset", params));
11646 }
11647
11648 {
11649 TestParams params;
11650 params.src.buffer.size = defaultSize * defaultSize;
11651 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
11652 params.dst.image.format = VK_FORMAT_R8_UNORM;
11653 params.dst.image.extent = defaultExtent;
11654 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11655 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11656 params.allocationKind = allocationKind;
11657 params.extensionUse = extensionUse;
11658
11659 const VkBufferImageCopy bufferImageCopy =
11660 {
11661 defaultQuarterSize + 1u, // VkDeviceSize bufferOffset;
11662 defaultHalfSize + defaultQuarterSize, // deUint32 bufferRowLength;
11663 defaultHalfSize + defaultQuarterSize, // deUint32 bufferImageHeight;
11664 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
11665 {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
11666 defaultHalfExtent // VkExtent3D imageExtent;
11667 };
11668 CopyRegion copyRegion;
11669 copyRegion.bufferImageCopy = bufferImageCopy;
11670
11671 params.regions.push_back(copyRegion);
11672
11673 group->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_offset_relaxed", "Copy from buffer to image with buffer offset not a multiple of 4", params));
11674 }
11675
11676 {
11677 TestParams params;
11678 params.src.buffer.size = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize;
11679 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
11680 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
11681 params.dst.image.extent = defaultExtent;
11682 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11683 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11684 params.allocationKind = allocationKind;
11685 params.extensionUse = extensionUse;
11686
11687 const VkBufferImageCopy bufferImageCopy =
11688 {
11689 0u, // VkDeviceSize bufferOffset;
11690 defaultSize, // deUint32 bufferRowLength;
11691 defaultSize, // deUint32 bufferImageHeight;
11692 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
11693 {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
11694 defaultHalfExtent // VkExtent3D imageExtent;
11695 };
11696 CopyRegion copyRegion;
11697 copyRegion.bufferImageCopy = bufferImageCopy;
11698
11699 params.regions.push_back(copyRegion);
11700
11701 group->addChild(new CopyBufferToImageTestCase(testCtx, "tightly_sized_buffer", "Copy from buffer that is just large enough to contain the accessed elements", params));
11702 }
11703
11704 {
11705 TestParams params;
11706 deUint32 bufferImageHeight = defaultSize + 1u;
11707 params.src.buffer.size = defaultSize * bufferImageHeight;
11708 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
11709 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
11710 params.dst.image.extent = defaultExtent;
11711 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11712 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11713 params.allocationKind = allocationKind;
11714 params.extensionUse = extensionUse;
11715
11716 const VkBufferImageCopy bufferImageCopy =
11717 {
11718 0u, // VkDeviceSize bufferOffset;
11719 defaultSize, // deUint32 bufferRowLength;
11720 bufferImageHeight, // deUint32 bufferImageHeight;
11721 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
11722 {0, 0, 0}, // VkOffset3D imageOffset;
11723 defaultHalfExtent // VkExtent3D imageExtent;
11724 };
11725 CopyRegion copyRegion;
11726 copyRegion.bufferImageCopy = bufferImageCopy;
11727
11728 params.regions.push_back(copyRegion);
11729
11730 group->addChild(new CopyBufferToImageTestCase(testCtx, "larger_buffer", "Copy from buffer that is larger than necessary to image", params));
11731 }
11732
11733 {
11734 TestParams params;
11735 params.src.buffer.size = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultQuarterSize;
11736 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
11737 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
11738 params.dst.image.extent = defaultExtent;
11739 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11740 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11741 params.allocationKind = allocationKind;
11742 params.extensionUse = extensionUse;
11743
11744 const VkBufferImageCopy bufferImageCopy =
11745 {
11746 defaultQuarterSize, // VkDeviceSize bufferOffset;
11747 defaultSize, // deUint32 bufferRowLength;
11748 defaultSize, // deUint32 bufferImageHeight;
11749 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
11750 {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
11751 defaultHalfExtent // VkExtent3D imageExtent;
11752 };
11753 CopyRegion copyRegion;
11754 copyRegion.bufferImageCopy = bufferImageCopy;
11755
11756 params.regions.push_back(copyRegion);
11757
11758 group->addChild(new CopyBufferToImageTestCase(testCtx, "tightly_sized_buffer_offset", "Copy from buffer that is just large enough to contain the accessed elements", params));
11759 }
11760
11761 {
11762 TestParams params;
11763 deUint32 arrayLayers = 16u;
11764 params.src.buffer.size = defaultHalfSize * defaultHalfSize * arrayLayers;
11765 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
11766 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
11767 params.dst.image.extent = defaultHalfExtent;
11768 params.dst.image.extent.depth = arrayLayers;
11769 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11770 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11771 params.allocationKind = allocationKind;
11772 params.extensionUse = extensionUse;
11773
11774 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.dst.image.format));
11775 for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
11776 {
11777 const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
11778 const VkBufferImageCopy bufferImageCopy =
11779 {
11780 offset, // VkDeviceSize bufferOffset;
11781 0u, // deUint32 bufferRowLength;
11782 0u, // deUint32 bufferImageHeight;
11783 {
11784 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11785 0u, // deUint32 mipLevel;
11786 arrayLayerNdx, // deUint32 baseArrayLayer;
11787 1u, // deUint32 layerCount;
11788 }, // VkImageSubresourceLayers imageSubresource;
11789 {0, 0, 0}, // VkOffset3D imageOffset;
11790 defaultHalfExtent // VkExtent3D imageExtent;
11791 };
11792 CopyRegion copyRegion;
11793 copyRegion.bufferImageCopy = bufferImageCopy;
11794
11795 params.regions.push_back(copyRegion);
11796 }
11797 group->addChild(new CopyBufferToImageTestCase(testCtx, "array", "Copy from a different part of the buffer to each layer", params));
11798 }
11799
11800 {
11801 TestParams params;
11802 deUint32 arrayLayers = 16u;
11803 deUint32 bufferImageHeight = defaultHalfSize + 1u;
11804 params.src.buffer.size = defaultHalfSize * bufferImageHeight * arrayLayers;
11805 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
11806 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
11807 params.dst.image.extent = defaultHalfExtent;
11808 params.dst.image.extent.depth = arrayLayers;
11809 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11810 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11811 params.allocationKind = allocationKind;
11812 params.extensionUse = extensionUse;
11813
11814 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.dst.image.format));
11815 for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
11816 {
11817 const VkDeviceSize offset = defaultHalfSize * bufferImageHeight * pixelSize * arrayLayerNdx;
11818 const VkBufferImageCopy bufferImageCopy =
11819 {
11820 offset, // VkDeviceSize bufferOffset;
11821 defaultHalfSize, // deUint32 bufferRowLength;
11822 bufferImageHeight, // deUint32 bufferImageHeight;
11823 {
11824 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11825 0u, // deUint32 mipLevel;
11826 arrayLayerNdx, // deUint32 baseArrayLayer;
11827 1u, // deUint32 layerCount;
11828 }, // VkImageSubresourceLayers imageSubresource;
11829 {0, 0, 0}, // VkOffset3D imageOffset;
11830 defaultHalfExtent // VkExtent3D imageExtent;
11831 };
11832 CopyRegion copyRegion;
11833 copyRegion.bufferImageCopy = bufferImageCopy;
11834
11835 params.regions.push_back(copyRegion);
11836 }
11837 group->addChild(new CopyBufferToImageTestCase(testCtx, "array_larger_buffer", "Copy from different part of buffer to each layer", params));
11838 }
11839
11840 {
11841 TestParams params;
11842 deUint32 arrayLayers = 16u;
11843 params.src.buffer.size = defaultHalfSize * defaultHalfSize * arrayLayers;
11844 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
11845 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
11846 params.dst.image.extent = defaultHalfExtent;
11847 params.dst.image.extent.depth = arrayLayers;
11848 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11849 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11850 params.allocationKind = allocationKind;
11851 params.extensionUse = extensionUse;
11852
11853 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.dst.image.format));
11854 for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
11855 {
11856 const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
11857 const VkBufferImageCopy bufferImageCopy =
11858 {
11859 offset, // VkDeviceSize bufferOffset;
11860 defaultHalfSize, // deUint32 bufferRowLength;
11861 defaultHalfSize, // deUint32 bufferImageHeight;
11862 {
11863 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11864 0u, // deUint32 mipLevel;
11865 arrayLayerNdx, // deUint32 baseArrayLayer;
11866 1u, // deUint32 layerCount;
11867 }, // VkImageSubresourceLayers imageSubresource;
11868 {0, 0, 0}, // VkOffset3D imageOffset;
11869 defaultHalfExtent // VkExtent3D imageExtent;
11870 };
11871 CopyRegion copyRegion;
11872 copyRegion.bufferImageCopy = bufferImageCopy;
11873
11874 params.regions.push_back(copyRegion);
11875 }
11876 group->addChild(new CopyBufferToImageTestCase(testCtx, "array_tightly_sized_buffer", "Copy from different part of tightly sized buffer to each layer", params));
11877 }
11878 }
11879
addBufferToImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)11880 void addBufferToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11881 {
11882 addTestGroup(group, "1d_images", "Copying operations on 1d images", add1dBufferToImageTests, allocationKind, extensionUse);
11883 addTestGroup(group, "2d_images", "Copying operations on 2d images", add2dBufferToImageTests, allocationKind, extensionUse);
11884 }
11885
addBufferToBufferTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)11886 void addBufferToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11887 {
11888 tcu::TestContext& testCtx = group->getTestContext();
11889
11890 {
11891 TestParams params;
11892 params.src.buffer.size = defaultSize;
11893 params.dst.buffer.size = defaultSize;
11894 params.allocationKind = allocationKind;
11895 params.extensionUse = extensionUse;
11896
11897 const VkBufferCopy bufferCopy =
11898 {
11899 0u, // VkDeviceSize srcOffset;
11900 0u, // VkDeviceSize dstOffset;
11901 defaultSize, // VkDeviceSize size;
11902 };
11903
11904 CopyRegion copyRegion;
11905 copyRegion.bufferCopy = bufferCopy;
11906 params.regions.push_back(copyRegion);
11907
11908 group->addChild(new BufferToBufferTestCase(testCtx, "whole", "Whole buffer", params));
11909 }
11910
11911 // Filter is VK_FILTER_NEAREST.
11912 {
11913 TestParams params;
11914 params.src.buffer.size = defaultQuarterSize;
11915 params.dst.buffer.size = defaultQuarterSize;
11916 params.allocationKind = allocationKind;
11917 params.extensionUse = extensionUse;
11918
11919 const VkBufferCopy bufferCopy =
11920 {
11921 12u, // VkDeviceSize srcOffset;
11922 4u, // VkDeviceSize dstOffset;
11923 1u, // VkDeviceSize size;
11924 };
11925
11926 CopyRegion copyRegion;
11927 copyRegion.bufferCopy = bufferCopy;
11928 params.regions.push_back(copyRegion);
11929
11930 group->addChild(new BufferToBufferTestCase(testCtx, "partial", "Partial", params));
11931 }
11932
11933 {
11934 const deUint32 size = 16;
11935 TestParams params;
11936 params.src.buffer.size = size;
11937 params.dst.buffer.size = size * (size + 1);
11938 params.allocationKind = allocationKind;
11939 params.extensionUse = extensionUse;
11940
11941 // Copy region with size 1..size
11942 for (unsigned int i = 1; i <= size; i++)
11943 {
11944 const VkBufferCopy bufferCopy =
11945 {
11946 0, // VkDeviceSize srcOffset;
11947 i * size, // VkDeviceSize dstOffset;
11948 i, // VkDeviceSize size;
11949 };
11950
11951 CopyRegion copyRegion;
11952 copyRegion.bufferCopy = bufferCopy;
11953 params.regions.push_back(copyRegion);
11954 }
11955
11956 group->addChild(new BufferToBufferTestCase(testCtx, "regions", "Multiple regions", params));
11957 }
11958
11959 {
11960 TestParams params;
11961 params.src.buffer.size = 32;
11962 params.dst.buffer.size = 32;
11963 params.allocationKind = allocationKind;
11964 params.extensionUse = extensionUse;
11965
11966 // Copy four unaligned regions
11967 for (unsigned int i = 0; i < 4; i++)
11968 {
11969 const VkBufferCopy bufferCopy
11970 {
11971 3 + i * 3, // VkDeviceSize srcOffset; 3 6 9 12
11972 1 + i * 5, // VkDeviceSize dstOffset; 1 6 11 16
11973 2 + i, // VkDeviceSize size; 2 3 4 5
11974 };
11975
11976 CopyRegion copyRegion;
11977 copyRegion.bufferCopy = bufferCopy;
11978 params.regions.push_back(copyRegion);
11979 }
11980
11981 group->addChild(new BufferToBufferTestCase(testCtx, "unaligned_regions", "Multiple unaligned regions", params));
11982 }
11983 }
11984
addBlittingImageSimpleTests(tcu::TestCaseGroup * group,TestParams & params)11985 void addBlittingImageSimpleTests (tcu::TestCaseGroup* group, TestParams& params)
11986 {
11987 tcu::TestContext& testCtx = group->getTestContext();
11988
11989 // Filter is VK_FILTER_NEAREST.
11990 {
11991 params.filter = VK_FILTER_NEAREST;
11992 const std::string description = "Nearest filter";
11993
11994 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
11995 group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params));
11996
11997 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
11998 const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)");
11999 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
12000
12001 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
12002 const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
12003 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
12004 }
12005
12006 // Filter is VK_FILTER_LINEAR.
12007 {
12008 params.filter = VK_FILTER_LINEAR;
12009 const std::string description = "Linear filter";
12010
12011 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12012 group->addChild(new BlitImageTestCase(testCtx, "linear", description, params));
12013
12014 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
12015 const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)");
12016 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
12017
12018 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
12019 const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
12020 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
12021 }
12022
12023 // Filter is VK_FILTER_CUBIC_EXT.
12024 // Cubic filtering can only be used with 2D images.
12025 if (params.dst.image.imageType == VK_IMAGE_TYPE_2D)
12026 {
12027 params.filter = VK_FILTER_CUBIC_EXT;
12028 const std::string description = "Cubic filter";
12029
12030 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12031 group->addChild(new BlitImageTestCase(testCtx, "cubic", description, params));
12032
12033 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
12034 const std::string descriptionOfRGBAToR32(description + " and different formats (R8G8B8A8 -> R32)");
12035 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_cubic", descriptionOfRGBAToR32, params));
12036
12037 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
12038 const std::string descriptionOfRGBAToBGRA(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
12039 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_cubic", descriptionOfRGBAToBGRA, params));
12040 }
12041 }
12042
addBlittingImageSimpleWholeTests(tcu::TestCaseGroup * group,TestParams params)12043 void addBlittingImageSimpleWholeTests (tcu::TestCaseGroup* group, TestParams params)
12044 {
12045 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12046 const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
12047 params.src.image.extent = defaultExtent;
12048 params.dst.image.extent = defaultExtent;
12049 params.src.image.extent.depth = imageDepth;
12050 params.dst.image.extent.depth = imageDepth;
12051
12052 {
12053 const VkImageBlit imageBlit =
12054 {
12055 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
12056 {
12057 { 0, 0, 0 },
12058 { defaultSize, defaultSize, imageDepth }
12059 }, // VkOffset3D srcOffsets[2];
12060
12061 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
12062 {
12063 { 0, 0, 0 },
12064 { defaultSize, defaultSize, imageDepth }
12065 } // VkOffset3D dstOffset[2];
12066 };
12067
12068 CopyRegion region;
12069 region.imageBlit = imageBlit;
12070 params.regions.push_back(region);
12071 }
12072
12073 addBlittingImageSimpleTests(group, params);
12074 }
12075
addBlittingImageSimpleMirrorXYTests(tcu::TestCaseGroup * group,TestParams params)12076 void addBlittingImageSimpleMirrorXYTests (tcu::TestCaseGroup* group, TestParams params)
12077 {
12078 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12079 const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
12080 params.src.image.extent = defaultExtent;
12081 params.dst.image.extent = defaultExtent;
12082 params.src.image.extent.depth = imageDepth;
12083 params.dst.image.extent.depth = imageDepth;
12084
12085 {
12086 const VkImageBlit imageBlit =
12087 {
12088 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
12089 {
12090 {0, 0, 0},
12091 {defaultSize, defaultSize, imageDepth}
12092 }, // VkOffset3D srcOffsets[2];
12093
12094 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
12095 {
12096 {defaultSize, defaultSize, 0},
12097 {0, 0, imageDepth}
12098 } // VkOffset3D dstOffset[2];
12099 };
12100
12101 CopyRegion region;
12102 region.imageBlit = imageBlit;
12103 params.regions.push_back(region);
12104 }
12105
12106 addBlittingImageSimpleTests(group, params);
12107 }
12108
addBlittingImageSimpleMirrorXTests(tcu::TestCaseGroup * group,TestParams params)12109 void addBlittingImageSimpleMirrorXTests (tcu::TestCaseGroup* group, TestParams params)
12110 {
12111 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12112 const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
12113 params.src.image.extent = defaultExtent;
12114 params.dst.image.extent = defaultExtent;
12115 params.src.image.extent.depth = imageDepth;
12116 params.dst.image.extent.depth = imageDepth;
12117
12118 {
12119 const VkImageBlit imageBlit =
12120 {
12121 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
12122 {
12123 {0, 0, 0},
12124 {defaultSize, defaultSize, imageDepth}
12125 }, // VkOffset3D srcOffsets[2];
12126
12127 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
12128 {
12129 {defaultSize, 0, 0},
12130 {0, defaultSize, imageDepth}
12131 } // VkOffset3D dstOffset[2];
12132 };
12133
12134 CopyRegion region;
12135 region.imageBlit = imageBlit;
12136 params.regions.push_back(region);
12137 }
12138
12139 addBlittingImageSimpleTests(group, params);
12140 }
12141
addBlittingImageSimpleMirrorYTests(tcu::TestCaseGroup * group,TestParams params)12142 void addBlittingImageSimpleMirrorYTests (tcu::TestCaseGroup* group, TestParams params)
12143 {
12144 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12145 const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
12146 params.src.image.extent = defaultExtent;
12147 params.dst.image.extent = defaultExtent;
12148 params.src.image.extent.depth = imageDepth;
12149 params.dst.image.extent.depth = imageDepth;
12150
12151 {
12152 const VkImageBlit imageBlit =
12153 {
12154 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
12155 {
12156 {0, 0, 0},
12157 {defaultSize, defaultSize, imageDepth}
12158 }, // VkOffset3D srcOffsets[2];
12159
12160 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
12161 {
12162 {0, defaultSize, 0},
12163 {defaultSize, 0, imageDepth}
12164 } // VkOffset3D dstOffset[2];
12165 };
12166
12167 CopyRegion region;
12168 region.imageBlit = imageBlit;
12169 params.regions.push_back(region);
12170 }
12171
12172 addBlittingImageSimpleTests(group, params);
12173 }
12174
addBlittingImageSimpleMirrorZTests(tcu::TestCaseGroup * group,TestParams params)12175 void addBlittingImageSimpleMirrorZTests (tcu::TestCaseGroup* group, TestParams params)
12176 {
12177 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12178 DE_ASSERT(params.src.image.imageType == VK_IMAGE_TYPE_3D);
12179 params.src.image.extent = defaultExtent;
12180 params.dst.image.extent = defaultExtent;
12181 params.src.image.extent.depth = defaultSize;
12182 params.dst.image.extent.depth = defaultSize;
12183
12184 {
12185 const VkImageBlit imageBlit =
12186 {
12187 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
12188 {
12189 {0, 0, 0},
12190 {defaultSize, defaultSize, defaultSize}
12191 }, // VkOffset3D srcOffsets[2];
12192
12193 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
12194 {
12195 {0, 0, defaultSize},
12196 {defaultSize, defaultSize, 0}
12197 } // VkOffset3D dstOffset[2];
12198 };
12199
12200 CopyRegion region;
12201 region.imageBlit = imageBlit;
12202 params.regions.push_back(region);
12203 }
12204
12205 addBlittingImageSimpleTests(group, params);
12206 }
12207
addBlittingImageSimpleMirrorSubregionsTests(tcu::TestCaseGroup * group,TestParams params)12208 void addBlittingImageSimpleMirrorSubregionsTests (tcu::TestCaseGroup* group, TestParams params)
12209 {
12210 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12211 const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
12212 params.src.image.extent = defaultExtent;
12213 params.dst.image.extent = defaultExtent;
12214 params.src.image.extent.depth = imageDepth;
12215 params.dst.image.extent.depth = imageDepth;
12216
12217 // No mirroring.
12218 {
12219 const VkImageBlit imageBlit =
12220 {
12221 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
12222 {
12223 {0, 0, 0},
12224 {defaultHalfSize, defaultHalfSize, imageDepth}
12225 }, // VkOffset3D srcOffsets[2];
12226
12227 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
12228 {
12229 {0, 0, 0},
12230 {defaultHalfSize, defaultHalfSize, imageDepth}
12231 } // VkOffset3D dstOffset[2];
12232 };
12233
12234 CopyRegion region;
12235 region.imageBlit = imageBlit;
12236 params.regions.push_back(region);
12237 }
12238
12239 // Flipping y coordinates.
12240 {
12241 const VkImageBlit imageBlit =
12242 {
12243 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
12244 {
12245 {defaultHalfSize, 0, 0},
12246 {defaultSize, defaultHalfSize, imageDepth}
12247 }, // VkOffset3D srcOffsets[2];
12248
12249 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
12250 {
12251 {defaultHalfSize, defaultHalfSize, 0},
12252 {defaultSize, 0, imageDepth}
12253 } // VkOffset3D dstOffset[2];
12254 };
12255 CopyRegion region;
12256 region.imageBlit = imageBlit;
12257 params.regions.push_back(region);
12258 }
12259
12260 // Flipping x coordinates.
12261 {
12262 const VkImageBlit imageBlit =
12263 {
12264 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
12265 {
12266 {0, defaultHalfSize, 0},
12267 {defaultHalfSize, defaultSize, imageDepth}
12268 }, // VkOffset3D srcOffsets[2];
12269
12270 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
12271 {
12272 {defaultHalfSize, defaultHalfSize, 0},
12273 {0, defaultSize, imageDepth}
12274 } // VkOffset3D dstOffset[2];
12275 };
12276
12277 CopyRegion region;
12278 region.imageBlit = imageBlit;
12279 params.regions.push_back(region);
12280 }
12281
12282 // Flipping x and y coordinates.
12283 {
12284 const VkImageBlit imageBlit =
12285 {
12286 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
12287 {
12288 {defaultHalfSize, defaultHalfSize, 0},
12289 {defaultSize, defaultSize, imageDepth}
12290 }, // VkOffset3D srcOffsets[2];
12291
12292 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
12293 {
12294 {defaultSize, defaultSize, 0},
12295 {defaultHalfSize, defaultHalfSize, imageDepth}
12296 } // VkOffset3D dstOffset[2];
12297 };
12298
12299 CopyRegion region;
12300 region.imageBlit = imageBlit;
12301 params.regions.push_back(region);
12302 }
12303
12304 addBlittingImageSimpleTests(group, params);
12305 }
12306
addBlittingImageSimpleScalingWhole1Tests(tcu::TestCaseGroup * group,TestParams params)12307 void addBlittingImageSimpleScalingWhole1Tests (tcu::TestCaseGroup* group, TestParams params)
12308 {
12309 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12310 const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
12311 const deInt32 halfImageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultHalfSize : 1;
12312 params.src.image.extent = defaultExtent;
12313 params.dst.image.extent = defaultHalfExtent;
12314 params.src.image.extent.depth = imageDepth;
12315 params.dst.image.extent.depth = halfImageDepth;
12316
12317 {
12318 const VkImageBlit imageBlit =
12319 {
12320 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
12321 {
12322 {0, 0, 0},
12323 {defaultSize, defaultSize, imageDepth}
12324 }, // VkOffset3D srcOffsets[2];
12325
12326 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
12327 {
12328 {0, 0, 0},
12329 {defaultHalfSize, defaultHalfSize, halfImageDepth}
12330 } // VkOffset3D dstOffset[2];
12331 };
12332
12333 CopyRegion region;
12334 region.imageBlit = imageBlit;
12335 params.regions.push_back(region);
12336 }
12337
12338 addBlittingImageSimpleTests(group, params);
12339 }
12340
addBlittingImageSimpleScalingWhole2Tests(tcu::TestCaseGroup * group,TestParams params)12341 void addBlittingImageSimpleScalingWhole2Tests (tcu::TestCaseGroup* group, TestParams params)
12342 {
12343 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12344 const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
12345 const deInt32 halfImageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultHalfSize : 1;
12346 params.src.image.extent = defaultHalfExtent;
12347 params.dst.image.extent = defaultExtent;
12348 params.src.image.extent.depth = halfImageDepth;
12349 params.dst.image.extent.depth = imageDepth;
12350
12351 {
12352 const VkImageBlit imageBlit =
12353 {
12354 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
12355 {
12356 {0, 0, 0},
12357 {defaultHalfSize, defaultHalfSize, halfImageDepth}
12358 }, // VkOffset3D srcOffsets[2];
12359
12360 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
12361 {
12362 {0, 0, 0},
12363 {defaultSize, defaultSize, imageDepth}
12364 } // VkOffset3D dstOffset[2];
12365 };
12366
12367 CopyRegion region;
12368 region.imageBlit = imageBlit;
12369 params.regions.push_back(region);
12370 }
12371
12372 addBlittingImageSimpleTests(group, params);
12373 }
12374
addBlittingImageSimpleScalingAndOffsetTests(tcu::TestCaseGroup * group,TestParams params)12375 void addBlittingImageSimpleScalingAndOffsetTests (tcu::TestCaseGroup* group, TestParams params)
12376 {
12377 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12378 const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
12379 const deInt32 srcDepthOffset = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultQuarterSize : 0;
12380 const deInt32 srcDepthSize = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultQuarterSize * 3 : 1;
12381 params.src.image.extent = defaultExtent;
12382 params.dst.image.extent = defaultExtent;
12383 params.src.image.extent.depth = imageDepth;
12384 params.dst.image.extent.depth = imageDepth;
12385
12386 {
12387 const VkImageBlit imageBlit =
12388 {
12389 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
12390 {
12391 {defaultQuarterSize, defaultQuarterSize, srcDepthOffset},
12392 {defaultQuarterSize*3, defaultQuarterSize*3, srcDepthSize}
12393 }, // VkOffset3D srcOffsets[2];
12394
12395 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
12396 {
12397 {0, 0, 0},
12398 {defaultSize, defaultSize, imageDepth}
12399 } // VkOffset3D dstOffset[2];
12400 };
12401
12402 CopyRegion region;
12403 region.imageBlit = imageBlit;
12404 params.regions.push_back(region);
12405 }
12406
12407 addBlittingImageSimpleTests(group, params);
12408 }
12409
addBlittingImageSimpleWithoutScalingPartialTests(tcu::TestCaseGroup * group,TestParams params)12410 void addBlittingImageSimpleWithoutScalingPartialTests (tcu::TestCaseGroup* group, TestParams params)
12411 {
12412 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12413 const bool is3dBlit = params.src.image.imageType == VK_IMAGE_TYPE_3D;
12414 params.src.image.extent = defaultExtent;
12415 params.dst.image.extent = defaultExtent;
12416
12417 if (is3dBlit)
12418 {
12419 params.src.image.extent.depth = defaultSize;
12420 params.dst.image.extent.depth = defaultSize;
12421 }
12422
12423 {
12424 CopyRegion region;
12425 for (int i = 0; i < defaultSize; i += defaultQuarterSize)
12426 {
12427 const VkImageBlit imageBlit =
12428 {
12429 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
12430 {
12431 {defaultSize - defaultQuarterSize - i, defaultSize - defaultQuarterSize - i, is3dBlit ? defaultSize - defaultQuarterSize - i : 0},
12432 {defaultSize - i, defaultSize - i, is3dBlit ? defaultSize - i : 1}
12433 }, // VkOffset3D srcOffsets[2];
12434
12435 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
12436 {
12437 {i, i, is3dBlit ? i : 0},
12438 {i + defaultQuarterSize, i + defaultQuarterSize, is3dBlit ? i + defaultQuarterSize : 1}
12439 } // VkOffset3D dstOffset[2];
12440 };
12441 region.imageBlit = imageBlit;
12442 params.regions.push_back(region);
12443 }
12444 }
12445
12446 addBlittingImageSimpleTests(group, params);
12447 }
12448
addBlittingImageSimpleTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)12449 void addBlittingImageSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12450 {
12451 TestParams params;
12452 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12453 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12454 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12455 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12456 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12457 params.allocationKind = allocationKind;
12458 params.extensionUse = extensionUse;
12459 params.src.image.imageType = VK_IMAGE_TYPE_2D;
12460 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
12461 addTestGroup(group, "whole", "Blit without scaling (whole)", addBlittingImageSimpleWholeTests, params);
12462 addTestGroup(group, "mirror_xy", "Flipping x and y coordinates (whole)", addBlittingImageSimpleMirrorXYTests, params);
12463 addTestGroup(group, "mirror_x", "Flipping x coordinates (whole)", addBlittingImageSimpleMirrorXTests, params);
12464 addTestGroup(group, "mirror_y", "Flipping y coordinates (whole)", addBlittingImageSimpleMirrorYTests, params);
12465 addTestGroup(group, "mirror_subregions", "Mirroring subregions in image (no flip, y flip, x flip, xy flip)", addBlittingImageSimpleMirrorSubregionsTests, params);
12466 addTestGroup(group, "scaling_whole1", "Blit with scaling (whole, src extent bigger)", addBlittingImageSimpleScalingWhole1Tests, params);
12467 addTestGroup(group, "scaling_whole2", "Blit with scaling (whole, dst extent bigger)", addBlittingImageSimpleScalingWhole2Tests, params);
12468 addTestGroup(group, "scaling_and_offset", "Blit with scaling and offset (whole, dst extent bigger)", addBlittingImageSimpleScalingAndOffsetTests, params);
12469 addTestGroup(group, "without_scaling_partial", "Blit without scaling (partial)", addBlittingImageSimpleWithoutScalingPartialTests, params);
12470
12471 params.src.image.imageType = VK_IMAGE_TYPE_3D;
12472 params.dst.image.imageType = VK_IMAGE_TYPE_3D;
12473 addTestGroup(group, "whole_3d", "3D blit without scaling (whole)", addBlittingImageSimpleWholeTests, params);
12474 addTestGroup(group, "mirror_xy_3d", "Flipping x and y coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorXYTests, params);
12475 addTestGroup(group, "mirror_x_3d", "Flipping x coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorXTests, params);
12476 addTestGroup(group, "mirror_y_3d", "Flipping y coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorYTests, params);
12477 addTestGroup(group, "mirror_z_3d", "Flipping z coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorZTests, params);
12478 addTestGroup(group, "mirror_subregions_3d", "Mirroring subregions in a 3D image (no flip, y flip, x flip, xy flip)", addBlittingImageSimpleMirrorSubregionsTests, params);
12479 addTestGroup(group, "scaling_whole1_3d", "3D blit a with scaling (whole, src extent bigger)", addBlittingImageSimpleScalingWhole1Tests, params);
12480 addTestGroup(group, "scaling_whole2_3d", "3D blit with scaling (whole, dst extent bigger)", addBlittingImageSimpleScalingWhole2Tests, params);
12481 addTestGroup(group, "scaling_and_offset_3d", "3D blit with scaling and offset (whole, dst extent bigger)", addBlittingImageSimpleScalingAndOffsetTests, params);
12482 addTestGroup(group, "without_scaling_partial_3d", "3D blit without scaling (partial)", addBlittingImageSimpleWithoutScalingPartialTests, params);
12483 }
12484
12485 enum FilterMaskBits
12486 {
12487 FILTER_MASK_NEAREST = 0, // Always tested.
12488 FILTER_MASK_LINEAR = (1u << 0),
12489 FILTER_MASK_CUBIC = (1u << 1),
12490 };
12491
12492 using FilterMask = deUint32;
12493
makeFilterMask(bool onlyNearest,bool discardCubicFilter)12494 FilterMask makeFilterMask (bool onlyNearest, bool discardCubicFilter)
12495 {
12496 FilterMask mask = FILTER_MASK_NEAREST;
12497
12498 if (!onlyNearest)
12499 {
12500 mask |= FILTER_MASK_LINEAR;
12501 if (!discardCubicFilter)
12502 mask |= FILTER_MASK_CUBIC;
12503 }
12504
12505 return mask;
12506 }
12507
12508 struct BlitColorTestParams
12509 {
12510 TestParams params;
12511 const VkFormat* compatibleFormats;
12512 FilterMask testFilters;
12513 };
12514
isAllowedBlittingAllFormatsColorSrcFormatTests(const BlitColorTestParams & testParams)12515 bool isAllowedBlittingAllFormatsColorSrcFormatTests(const BlitColorTestParams& testParams)
12516 {
12517 bool result = true;
12518
12519 if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED)
12520 {
12521 DE_ASSERT(!dedicatedAllocationBlittingFormatsToTestSet.empty());
12522
12523 result =
12524 de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.dst.image.format) ||
12525 de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.src.image.format);
12526 }
12527
12528 return result;
12529 }
12530
12531 const VkFormat linearOtherImageFormatsToTest[] =
12532 {
12533 // From compatibleFormats8Bit
12534 VK_FORMAT_R4G4_UNORM_PACK8,
12535 VK_FORMAT_R8_SRGB,
12536
12537 // From compatibleFormats16Bit
12538 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
12539 VK_FORMAT_R16_SFLOAT,
12540
12541 // From compatibleFormats24Bit
12542 VK_FORMAT_R8G8B8_UNORM,
12543 VK_FORMAT_B8G8R8_SRGB,
12544
12545 // From compatibleFormats32Bit
12546 VK_FORMAT_R8G8B8A8_UNORM,
12547 VK_FORMAT_R32_SFLOAT,
12548
12549 // From compatibleFormats48Bit
12550 VK_FORMAT_R16G16B16_UNORM,
12551 VK_FORMAT_R16G16B16_SFLOAT,
12552
12553 // From compatibleFormats64Bit
12554 VK_FORMAT_R16G16B16A16_UNORM,
12555 VK_FORMAT_R64_SFLOAT,
12556
12557 // From compatibleFormats96Bit
12558 VK_FORMAT_R32G32B32_UINT,
12559 VK_FORMAT_R32G32B32_SFLOAT,
12560
12561 // From compatibleFormats128Bit
12562 VK_FORMAT_R32G32B32A32_UINT,
12563 VK_FORMAT_R64G64_SFLOAT,
12564
12565 // From compatibleFormats192Bit
12566 VK_FORMAT_R64G64B64_UINT,
12567 VK_FORMAT_R64G64B64_SFLOAT,
12568
12569 // From compatibleFormats256Bit
12570 VK_FORMAT_R64G64B64A64_UINT,
12571 VK_FORMAT_R64G64B64A64_SFLOAT,
12572 };
12573
getBlitImageTilingLayoutCaseName(VkImageTiling tiling,VkImageLayout layout)12574 std::string getBlitImageTilingLayoutCaseName (VkImageTiling tiling, VkImageLayout layout)
12575 {
12576 switch (tiling)
12577 {
12578 case VK_IMAGE_TILING_OPTIMAL:
12579 return getImageLayoutCaseName(layout);
12580 case VK_IMAGE_TILING_LINEAR:
12581 return "linear";
12582 default:
12583 DE_ASSERT(false);
12584 return "";
12585 }
12586 }
12587
addBlittingImageAllFormatsColorSrcFormatDstFormatTests(tcu::TestCaseGroup * group,BlitColorTestParams testParams)12588 void addBlittingImageAllFormatsColorSrcFormatDstFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
12589 {
12590 tcu::TestContext& testCtx = group->getTestContext();
12591
12592 FormatSet linearOtherImageFormatsToTestSet;
12593 const int numOfOtherImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(linearOtherImageFormatsToTest);
12594 for (int otherImageFormatsIndex = 0; otherImageFormatsIndex < numOfOtherImageFormatsToTestFilter; ++otherImageFormatsIndex)
12595 linearOtherImageFormatsToTestSet.insert(linearOtherImageFormatsToTest[otherImageFormatsIndex]);
12596
12597 const VkImageTiling blitSrcTilings[] =
12598 {
12599 VK_IMAGE_TILING_OPTIMAL,
12600 VK_IMAGE_TILING_LINEAR,
12601 };
12602 const VkImageLayout blitSrcLayouts[] =
12603 {
12604 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
12605 VK_IMAGE_LAYOUT_GENERAL
12606 };
12607 const VkImageTiling blitDstTilings[] =
12608 {
12609 VK_IMAGE_TILING_OPTIMAL,
12610 VK_IMAGE_TILING_LINEAR,
12611 };
12612 const VkImageLayout blitDstLayouts[] =
12613 {
12614 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
12615 VK_IMAGE_LAYOUT_GENERAL
12616 };
12617
12618 for (int srcTilingNdx = 0u; srcTilingNdx < DE_LENGTH_OF_ARRAY(blitSrcTilings); ++srcTilingNdx)
12619 {
12620 testParams.params.src.image.tiling = blitSrcTilings[srcTilingNdx];
12621
12622 for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
12623 {
12624 testParams.params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx];
12625
12626 // 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
12627 if (testParams.params.src.image.tiling == VK_IMAGE_TILING_LINEAR && testParams.params.src.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)
12628 continue;
12629
12630 for (int dstTilingNdx = 0u; dstTilingNdx < DE_LENGTH_OF_ARRAY(blitDstTilings); ++dstTilingNdx)
12631 {
12632 testParams.params.dst.image.tiling = blitDstTilings[dstTilingNdx];
12633
12634 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
12635 {
12636 testParams.params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx];
12637
12638 // 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
12639 if (testParams.params.dst.image.tiling == VK_IMAGE_TILING_LINEAR && testParams.params.dst.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
12640 continue;
12641
12642 if ((testParams.params.dst.image.tiling == VK_IMAGE_TILING_LINEAR && !de::contains(linearOtherImageFormatsToTestSet, testParams.params.src.image.format)) ||
12643 (testParams.params.src.image.tiling == VK_IMAGE_TILING_LINEAR && !de::contains(linearOtherImageFormatsToTestSet, testParams.params.dst.image.format)))
12644 continue;
12645
12646 testParams.params.filter = VK_FILTER_NEAREST;
12647 const std::string testName = getBlitImageTilingLayoutCaseName(testParams.params.src.image.tiling, testParams.params.src.image.operationLayout) + "_" +
12648 getBlitImageTilingLayoutCaseName(testParams.params.dst.image.tiling, testParams.params.dst.image.operationLayout);
12649 const std::string description = "Blit from layout " + getBlitImageTilingLayoutCaseName(testParams.params.src.image.tiling, testParams.params.src.image.operationLayout) +
12650 " to " + getBlitImageTilingLayoutCaseName(testParams.params.dst.image.tiling, testParams.params.dst.image.operationLayout);
12651 group->addChild(new BlitImageTestCase(testCtx, testName + "_nearest", description, testParams.params));
12652
12653 if (testParams.testFilters & FILTER_MASK_LINEAR)
12654 {
12655 testParams.params.filter = VK_FILTER_LINEAR;
12656 group->addChild(new BlitImageTestCase(testCtx, testName + "_linear", description, testParams.params));
12657 }
12658
12659 if (testParams.testFilters & FILTER_MASK_CUBIC)
12660 {
12661 testParams.params.filter = VK_FILTER_CUBIC_EXT;
12662 group->addChild(new BlitImageTestCase(testCtx, testName + "_cubic", description, testParams.params));
12663 }
12664
12665 if ((testParams.params.src.image.imageType == VK_IMAGE_TYPE_3D) && !isCompressedFormat(testParams.params.src.image.format))
12666 {
12667 const struct
12668 {
12669 FillMode mode;
12670 const char* name;
12671 } modeList[] =
12672 {
12673 { FILL_MODE_BLUE_RED_X, "x" },
12674 { FILL_MODE_BLUE_RED_Y, "y" },
12675 { FILL_MODE_BLUE_RED_Z, "z" },
12676 };
12677
12678 auto otherParams = testParams;
12679 otherParams.params.dst.image.fillMode = FILL_MODE_WHITE;
12680
12681 for (int i = 0; i < DE_LENGTH_OF_ARRAY(modeList); ++i)
12682 {
12683 otherParams.params.src.image.fillMode = modeList[i].mode;
12684
12685 otherParams.params.filter = VK_FILTER_LINEAR;
12686 group->addChild(new BlitImageTestCase(testCtx, testName + "_linear_stripes_" + modeList[i].name, description, otherParams.params));
12687
12688 otherParams.params.filter = VK_FILTER_NEAREST;
12689 group->addChild(new BlitImageTestCase(testCtx, testName + "_nearest_stripes_" + modeList[i].name, description, otherParams.params));
12690 }
12691 }
12692 }
12693 }
12694 }
12695 }
12696 }
12697
addBlittingImageAllFormatsColorSrcFormatTests(tcu::TestCaseGroup * group,BlitColorTestParams testParams)12698 void addBlittingImageAllFormatsColorSrcFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
12699 {
12700 VkFormat srcFormat = testParams.params.src.image.format;
12701
12702 if (testParams.compatibleFormats)
12703 {
12704 for (int dstFormatIndex = 0; testParams.compatibleFormats[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex)
12705 {
12706 testParams.params.dst.image.format = testParams.compatibleFormats[dstFormatIndex];
12707 if (!isSupportedByFramework(testParams.params.dst.image.format))
12708 continue;
12709
12710 if (!isAllowedBlittingAllFormatsColorSrcFormatTests(testParams))
12711 continue;
12712
12713 const std::string description = "Blit destination format " + getFormatCaseName(testParams.params.dst.image.format);
12714 addTestGroup(group, getFormatCaseName(testParams.params.dst.image.format), description, addBlittingImageAllFormatsColorSrcFormatDstFormatTests, testParams);
12715 }
12716 }
12717
12718 // If testParams.compatibleFormats is nullptr, the destination format will be copied from the source format
12719 // When testParams.compatibleFormats is not nullptr but format is compressed we also need to add that format
12720 // as it is not on compatibleFormats list
12721 if (!testParams.compatibleFormats || isCompressedFormat(srcFormat))
12722 {
12723 testParams.params.dst.image.format = srcFormat;
12724
12725 const std::string description = "Blit destination format " + getFormatCaseName(srcFormat);
12726 addTestGroup(group, getFormatCaseName(srcFormat), description, addBlittingImageAllFormatsColorSrcFormatDstFormatTests, testParams);
12727 }
12728 }
12729
12730 const VkFormat compatibleFormatsUInts[] =
12731 {
12732 VK_FORMAT_R8_UINT,
12733 VK_FORMAT_R8G8_UINT,
12734 VK_FORMAT_R8G8B8_UINT,
12735 VK_FORMAT_B8G8R8_UINT,
12736 VK_FORMAT_R8G8B8A8_UINT,
12737 VK_FORMAT_B8G8R8A8_UINT,
12738 VK_FORMAT_A8B8G8R8_UINT_PACK32,
12739 VK_FORMAT_A2R10G10B10_UINT_PACK32,
12740 VK_FORMAT_A2B10G10R10_UINT_PACK32,
12741 VK_FORMAT_R16_UINT,
12742 VK_FORMAT_R16G16_UINT,
12743 VK_FORMAT_R16G16B16_UINT,
12744 VK_FORMAT_R16G16B16A16_UINT,
12745 VK_FORMAT_R32_UINT,
12746 VK_FORMAT_R32G32_UINT,
12747 VK_FORMAT_R32G32B32_UINT,
12748 VK_FORMAT_R32G32B32A32_UINT,
12749 VK_FORMAT_R64_UINT,
12750 VK_FORMAT_R64G64_UINT,
12751 VK_FORMAT_R64G64B64_UINT,
12752 VK_FORMAT_R64G64B64A64_UINT,
12753
12754 VK_FORMAT_UNDEFINED
12755 };
12756 const VkFormat compatibleFormatsSInts[] =
12757 {
12758 VK_FORMAT_R8_SINT,
12759 VK_FORMAT_R8G8_SINT,
12760 VK_FORMAT_R8G8B8_SINT,
12761 VK_FORMAT_B8G8R8_SINT,
12762 VK_FORMAT_R8G8B8A8_SINT,
12763 VK_FORMAT_B8G8R8A8_SINT,
12764 VK_FORMAT_A8B8G8R8_SINT_PACK32,
12765 VK_FORMAT_A2R10G10B10_SINT_PACK32,
12766 VK_FORMAT_A2B10G10R10_SINT_PACK32,
12767 VK_FORMAT_R16_SINT,
12768 VK_FORMAT_R16G16_SINT,
12769 VK_FORMAT_R16G16B16_SINT,
12770 VK_FORMAT_R16G16B16A16_SINT,
12771 VK_FORMAT_R32_SINT,
12772 VK_FORMAT_R32G32_SINT,
12773 VK_FORMAT_R32G32B32_SINT,
12774 VK_FORMAT_R32G32B32A32_SINT,
12775 VK_FORMAT_R64_SINT,
12776 VK_FORMAT_R64G64_SINT,
12777 VK_FORMAT_R64G64B64_SINT,
12778 VK_FORMAT_R64G64B64A64_SINT,
12779
12780 VK_FORMAT_UNDEFINED
12781 };
12782 const VkFormat compatibleFormatsFloats[] =
12783 {
12784 VK_FORMAT_R4G4_UNORM_PACK8,
12785 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
12786 VK_FORMAT_B4G4R4A4_UNORM_PACK16,
12787 VK_FORMAT_R5G6B5_UNORM_PACK16,
12788 VK_FORMAT_B5G6R5_UNORM_PACK16,
12789 VK_FORMAT_R5G5B5A1_UNORM_PACK16,
12790 VK_FORMAT_B5G5R5A1_UNORM_PACK16,
12791 VK_FORMAT_A1R5G5B5_UNORM_PACK16,
12792 VK_FORMAT_R8_UNORM,
12793 VK_FORMAT_R8_SNORM,
12794 VK_FORMAT_R8_USCALED,
12795 VK_FORMAT_R8_SSCALED,
12796 VK_FORMAT_R8G8_UNORM,
12797 VK_FORMAT_R8G8_SNORM,
12798 VK_FORMAT_R8G8_USCALED,
12799 VK_FORMAT_R8G8_SSCALED,
12800 VK_FORMAT_R8G8B8_UNORM,
12801 VK_FORMAT_R8G8B8_SNORM,
12802 VK_FORMAT_R8G8B8_USCALED,
12803 VK_FORMAT_R8G8B8_SSCALED,
12804 VK_FORMAT_B8G8R8_UNORM,
12805 VK_FORMAT_B8G8R8_SNORM,
12806 VK_FORMAT_B8G8R8_USCALED,
12807 VK_FORMAT_B8G8R8_SSCALED,
12808 VK_FORMAT_R8G8B8A8_UNORM,
12809 VK_FORMAT_R8G8B8A8_SNORM,
12810 VK_FORMAT_R8G8B8A8_USCALED,
12811 VK_FORMAT_R8G8B8A8_SSCALED,
12812 VK_FORMAT_B8G8R8A8_UNORM,
12813 VK_FORMAT_B8G8R8A8_SNORM,
12814 VK_FORMAT_B8G8R8A8_USCALED,
12815 VK_FORMAT_B8G8R8A8_SSCALED,
12816 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
12817 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
12818 VK_FORMAT_A8B8G8R8_USCALED_PACK32,
12819 VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
12820 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
12821 VK_FORMAT_A2R10G10B10_SNORM_PACK32,
12822 VK_FORMAT_A2R10G10B10_USCALED_PACK32,
12823 VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
12824 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
12825 VK_FORMAT_A2B10G10R10_SNORM_PACK32,
12826 VK_FORMAT_A2B10G10R10_USCALED_PACK32,
12827 VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
12828 VK_FORMAT_R16_UNORM,
12829 VK_FORMAT_R16_SNORM,
12830 VK_FORMAT_R16_USCALED,
12831 VK_FORMAT_R16_SSCALED,
12832 VK_FORMAT_R16_SFLOAT,
12833 VK_FORMAT_R16G16_UNORM,
12834 VK_FORMAT_R16G16_SNORM,
12835 VK_FORMAT_R16G16_USCALED,
12836 VK_FORMAT_R16G16_SSCALED,
12837 VK_FORMAT_R16G16_SFLOAT,
12838 VK_FORMAT_R16G16B16_UNORM,
12839 VK_FORMAT_R16G16B16_SNORM,
12840 VK_FORMAT_R16G16B16_USCALED,
12841 VK_FORMAT_R16G16B16_SSCALED,
12842 VK_FORMAT_R16G16B16_SFLOAT,
12843 VK_FORMAT_R16G16B16A16_UNORM,
12844 VK_FORMAT_R16G16B16A16_SNORM,
12845 VK_FORMAT_R16G16B16A16_USCALED,
12846 VK_FORMAT_R16G16B16A16_SSCALED,
12847 VK_FORMAT_R16G16B16A16_SFLOAT,
12848 VK_FORMAT_R32_SFLOAT,
12849 VK_FORMAT_R32G32_SFLOAT,
12850 VK_FORMAT_R32G32B32_SFLOAT,
12851 VK_FORMAT_R32G32B32A32_SFLOAT,
12852 VK_FORMAT_R64_SFLOAT,
12853 VK_FORMAT_R64G64_SFLOAT,
12854 VK_FORMAT_R64G64B64_SFLOAT,
12855 VK_FORMAT_R64G64B64A64_SFLOAT,
12856 VK_FORMAT_B10G11R11_UFLOAT_PACK32,
12857 VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
12858
12859 VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
12860 VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
12861
12862 VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
12863
12864 VK_FORMAT_UNDEFINED
12865 };
12866
12867 const VkFormat compressedFormatsFloats[] =
12868 {
12869 VK_FORMAT_BC1_RGB_UNORM_BLOCK,
12870 VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
12871 VK_FORMAT_BC2_UNORM_BLOCK,
12872 VK_FORMAT_BC3_UNORM_BLOCK,
12873 VK_FORMAT_BC4_UNORM_BLOCK,
12874 VK_FORMAT_BC4_SNORM_BLOCK,
12875 VK_FORMAT_BC5_UNORM_BLOCK,
12876 VK_FORMAT_BC5_SNORM_BLOCK,
12877 VK_FORMAT_BC6H_UFLOAT_BLOCK,
12878 VK_FORMAT_BC6H_SFLOAT_BLOCK,
12879 VK_FORMAT_BC7_UNORM_BLOCK,
12880 VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
12881 VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
12882 VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
12883 VK_FORMAT_EAC_R11_UNORM_BLOCK,
12884 VK_FORMAT_EAC_R11_SNORM_BLOCK,
12885 VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
12886 VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
12887 VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
12888 VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
12889 VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
12890 VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
12891 VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
12892 VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
12893 VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
12894 VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
12895 VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
12896 VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
12897 VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
12898 VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
12899 VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
12900 VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
12901
12902 VK_FORMAT_UNDEFINED
12903 };
12904
12905 const VkFormat compatibleFormatsSrgb[] =
12906 {
12907 VK_FORMAT_R8_SRGB,
12908 VK_FORMAT_R8G8_SRGB,
12909 VK_FORMAT_R8G8B8_SRGB,
12910 VK_FORMAT_B8G8R8_SRGB,
12911 VK_FORMAT_R8G8B8A8_SRGB,
12912 VK_FORMAT_B8G8R8A8_SRGB,
12913 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
12914
12915 VK_FORMAT_UNDEFINED
12916 };
12917
12918 const VkFormat compressedFormatsSrgb[] =
12919 {
12920 VK_FORMAT_BC1_RGB_SRGB_BLOCK,
12921 VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
12922 VK_FORMAT_BC2_SRGB_BLOCK,
12923 VK_FORMAT_BC3_SRGB_BLOCK,
12924 VK_FORMAT_BC7_SRGB_BLOCK,
12925 VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
12926 VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
12927 VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
12928 VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
12929 VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
12930 VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
12931 VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
12932 VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
12933 VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
12934 VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
12935 VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
12936 VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
12937 VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
12938 VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
12939 VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
12940 VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
12941 VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
12942
12943 VK_FORMAT_UNDEFINED
12944 };
12945
12946 const VkFormat dedicatedAllocationBlittingFormatsToTest[] =
12947 {
12948 // compatibleFormatsUInts
12949 VK_FORMAT_R8_UINT,
12950 VK_FORMAT_R64G64B64A64_UINT,
12951
12952 // compatibleFormatsSInts
12953 VK_FORMAT_R8_SINT,
12954 VK_FORMAT_R64G64B64A64_SINT,
12955
12956 // compatibleFormatsFloats
12957 VK_FORMAT_R4G4_UNORM_PACK8,
12958 VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
12959
12960 // compatibleFormatsSrgb
12961 VK_FORMAT_R8_SRGB,
12962 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
12963 };
12964
12965 // skip cubic filtering test for the following data formats
12966 const FormatSet onlyNearestAndLinearFormatsToTest =
12967 {
12968 VK_FORMAT_A8B8G8R8_USCALED_PACK32,
12969 VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
12970 VK_FORMAT_A8B8G8R8_UINT_PACK32,
12971 VK_FORMAT_A8B8G8R8_SINT_PACK32
12972 };
12973
12974 // astc formats have diferent block sizes and thus require diferent resolutions for images
12975 enum class AstcImageSizeType
12976 {
12977 SIZE_64_64 = 0,
12978 SIZE_60_64,
12979 SIZE_64_60,
12980 SIZE_60_60,
12981 };
12982
12983 const std::map<VkFormat, AstcImageSizeType> astcSizes
12984 {
12985 { VK_FORMAT_ASTC_4x4_SRGB_BLOCK, AstcImageSizeType::SIZE_64_64 },
12986 { VK_FORMAT_ASTC_4x4_UNORM_BLOCK, AstcImageSizeType::SIZE_64_64 },
12987 { VK_FORMAT_ASTC_5x4_SRGB_BLOCK, AstcImageSizeType::SIZE_60_64 },
12988 { VK_FORMAT_ASTC_5x4_UNORM_BLOCK, AstcImageSizeType::SIZE_60_64 },
12989 { VK_FORMAT_ASTC_5x5_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60 },
12990 { VK_FORMAT_ASTC_5x5_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60 },
12991 { VK_FORMAT_ASTC_6x5_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60 },
12992 { VK_FORMAT_ASTC_6x5_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60 },
12993 { VK_FORMAT_ASTC_6x6_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60 },
12994 { VK_FORMAT_ASTC_6x6_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60 },
12995 { VK_FORMAT_ASTC_8x5_SRGB_BLOCK, AstcImageSizeType::SIZE_64_60 },
12996 { VK_FORMAT_ASTC_8x5_UNORM_BLOCK, AstcImageSizeType::SIZE_64_60 },
12997 { VK_FORMAT_ASTC_8x6_SRGB_BLOCK, AstcImageSizeType::SIZE_64_60 },
12998 { VK_FORMAT_ASTC_8x6_UNORM_BLOCK, AstcImageSizeType::SIZE_64_60 },
12999 { VK_FORMAT_ASTC_8x8_SRGB_BLOCK, AstcImageSizeType::SIZE_64_64 },
13000 { VK_FORMAT_ASTC_8x8_UNORM_BLOCK, AstcImageSizeType::SIZE_64_64 },
13001 { VK_FORMAT_ASTC_10x5_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60 },
13002 { VK_FORMAT_ASTC_10x5_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60 },
13003 { VK_FORMAT_ASTC_10x6_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60 },
13004 { VK_FORMAT_ASTC_10x6_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60 },
13005 { VK_FORMAT_ASTC_10x8_SRGB_BLOCK, AstcImageSizeType::SIZE_60_64 },
13006 { VK_FORMAT_ASTC_10x8_UNORM_BLOCK, AstcImageSizeType::SIZE_60_64 },
13007 { VK_FORMAT_ASTC_10x10_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60 },
13008 { VK_FORMAT_ASTC_10x10_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60 },
13009 { VK_FORMAT_ASTC_12x10_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60 },
13010 { VK_FORMAT_ASTC_12x10_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60 },
13011 { VK_FORMAT_ASTC_12x12_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60 },
13012 { VK_FORMAT_ASTC_12x12_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60 }
13013 };
13014
create2DCopyRegions(deInt32 srcWidth,deInt32 srcHeight,deInt32 dstWidth,deInt32 dstHeight)13015 std::vector<CopyRegion> create2DCopyRegions(deInt32 srcWidth, deInt32 srcHeight, deInt32 dstWidth, deInt32 dstHeight)
13016 {
13017 CopyRegion region;
13018 std::vector<CopyRegion> regionsVector;
13019
13020 deInt32 fourthOfSrcWidth = srcWidth / 4;
13021 deInt32 fourthOfSrcHeight = srcHeight / 4;
13022 deInt32 fourthOfDstWidth = dstWidth / 4;
13023 deInt32 fourthOfDstHeight = dstHeight / 4;
13024
13025 // to the top of resulting image copy whole source image but with increasingly smaller sizes
13026 for (int i = 0, j = 1; (i + fourthOfDstWidth / j < dstWidth) && (fourthOfDstWidth > j); i += fourthOfDstWidth / j++)
13027 {
13028 region.imageBlit =
13029 {
13030 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
13031 {
13032 {0, 0, 0},
13033 {srcWidth, srcHeight, 1}
13034 }, // VkOffset3D srcOffsets[2];
13035
13036 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
13037 {
13038 {i, 0, 0},
13039 {i + fourthOfDstWidth / j, fourthOfDstHeight / j, 1}
13040 } // VkOffset3D dstOffset[2];
13041 };
13042 regionsVector.push_back(region);
13043 }
13044
13045 // to the bottom of resulting image copy parts of source image;
13046 for (int i = 0; i < 4; ++i)
13047 {
13048 int srcX = i * fourthOfSrcWidth;
13049 int srcY = i * fourthOfSrcHeight;
13050 int dstX = i * fourthOfDstWidth;
13051
13052 region.imageBlit =
13053 {
13054 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
13055 {
13056 {srcX, srcY, 0},
13057 {srcX + fourthOfSrcWidth, srcY + fourthOfSrcHeight, 1}
13058 }, // VkOffset3D srcOffsets[2];
13059
13060 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
13061 {
13062 {dstX, 2 * fourthOfDstHeight, 0},
13063 {dstX + fourthOfDstWidth, 3 * fourthOfDstHeight, 1}
13064 } // VkOffset3D dstOffset[2];
13065 };
13066
13067 regionsVector.push_back(region);
13068 }
13069
13070 return regionsVector;
13071 }
13072
addBlittingImageAllFormatsColorTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)13073 void addBlittingImageAllFormatsColorTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
13074 {
13075 const struct {
13076 const VkFormat* sourceFormats;
13077 const VkFormat* destinationFormats;
13078 const bool onlyNearest;
13079 } colorImageFormatsToTestBlit[] =
13080 {
13081 { compatibleFormatsUInts, compatibleFormatsUInts, true },
13082 { compatibleFormatsSInts, compatibleFormatsSInts, true },
13083 { compatibleFormatsFloats, compatibleFormatsFloats, false },
13084 { compressedFormatsFloats, compatibleFormatsFloats, false },
13085 { compatibleFormatsSrgb, compatibleFormatsSrgb, false },
13086 { compressedFormatsSrgb, compatibleFormatsSrgb, false },
13087 };
13088
13089 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
13090
13091 if (allocationKind == ALLOCATION_KIND_DEDICATED)
13092 {
13093 const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
13094 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
13095 dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
13096 }
13097
13098 // 2D tests.
13099 {
13100 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D blitting tests"));
13101
13102 TestParams params;
13103 params.src.image.imageType = VK_IMAGE_TYPE_2D;
13104 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
13105 params.src.image.extent = defaultExtent;
13106 params.dst.image.extent = defaultExtent;
13107 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13108 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13109 params.allocationKind = allocationKind;
13110 params.extensionUse = extensionUse;
13111
13112 // create all required copy regions
13113 const std::map<AstcImageSizeType, std::vector<CopyRegion> > imageRegions
13114 {
13115 { AstcImageSizeType::SIZE_64_64, create2DCopyRegions(64, 64, 64, 64) },
13116 { AstcImageSizeType::SIZE_60_64, create2DCopyRegions(60, 64, 60, 64) },
13117 { AstcImageSizeType::SIZE_64_60, create2DCopyRegions(64, 60, 64, 60) },
13118 { AstcImageSizeType::SIZE_60_60, create2DCopyRegions(60, 60, 60, 60) },
13119 };
13120
13121 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
13122 {
13123 const VkFormat* sourceFormats = colorImageFormatsToTestBlit[compatibleFormatsIndex].sourceFormats;
13124 const VkFormat* destinationFormats = colorImageFormatsToTestBlit[compatibleFormatsIndex].destinationFormats;
13125 const bool onlyNearest = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
13126 for (int srcFormatIndex = 0; sourceFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
13127 {
13128 VkFormat srcFormat = sourceFormats[srcFormatIndex];
13129 params.src.image.format = srcFormat;
13130
13131 const bool onlyNearestAndLinear = de::contains(onlyNearestAndLinearFormatsToTest, params.src.image.format);
13132
13133 // most of tests are using regions caluculated for 64x64 size but astc formats require custom regions
13134 params.regions = imageRegions.at(AstcImageSizeType::SIZE_64_64);
13135 if (isCompressedFormat(srcFormat) && isAstcFormat(mapVkCompressedFormat(srcFormat)))
13136 params.regions = imageRegions.at(astcSizes.at(srcFormat));
13137
13138 // use the fact that first region contains the size of full source image
13139 // and make source and destination the same size - this is needed for astc formats
13140 const VkOffset3D& srcImageSize = params.regions[0].imageBlit.srcOffsets[1];
13141 VkExtent3D& srcImageExtent = params.src.image.extent;
13142 VkExtent3D& dstImageExtent = params.dst.image.extent;
13143 srcImageExtent.width = srcImageSize.x;
13144 srcImageExtent.height = srcImageSize.y;
13145 dstImageExtent.width = srcImageSize.x;
13146 dstImageExtent.height = srcImageSize.y;
13147
13148 BlitColorTestParams testParams
13149 {
13150 params,
13151 destinationFormats,
13152 makeFilterMask(onlyNearest, onlyNearestAndLinear)
13153 };
13154
13155 const std::string description = "Blit source format " + getFormatCaseName(params.src.image.format);
13156 addTestGroup(subGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams);
13157 }
13158 }
13159
13160 group->addChild(subGroup.release());
13161 }
13162
13163 // 1D tests.
13164 {
13165 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D blitting tests"));
13166
13167 TestParams params;
13168 params.src.image.imageType = VK_IMAGE_TYPE_1D;
13169 params.dst.image.imageType = VK_IMAGE_TYPE_1D;
13170 params.src.image.extent = default1dExtent;
13171 params.dst.image.extent = default1dExtent;
13172 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13173 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13174 params.allocationKind = allocationKind;
13175 params.extensionUse = extensionUse;
13176
13177 CopyRegion region;
13178 for (int i = 0; i < defaultSize; i += defaultSize / 2)
13179 {
13180 const VkImageBlit imageBlit =
13181 {
13182 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
13183 {
13184 {0, 0, 0},
13185 {defaultSize, 1, 1}
13186 }, // VkOffset3D srcOffsets[2];
13187
13188 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
13189 {
13190 {i, 0, 0},
13191 {i + defaultQuarterSize, 1, 1}
13192 } // VkOffset3D dstOffset[2];
13193 };
13194 region.imageBlit = imageBlit;
13195 params.regions.push_back(region);
13196 }
13197
13198 {
13199 const VkImageBlit imageBlit =
13200 {
13201 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
13202 {
13203 {0, 0, 0},
13204 {defaultQuarterSize, 1, 1}
13205 }, // VkOffset3D srcOffsets[2];
13206
13207 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
13208 {
13209 {defaultQuarterSize, 0, 0},
13210 {2 * defaultQuarterSize, 1, 1}
13211 } // VkOffset3D dstOffset[2];
13212 };
13213 region.imageBlit = imageBlit;
13214 params.regions.push_back(region);
13215 }
13216
13217 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
13218 {
13219 const VkFormat* sourceFormats = colorImageFormatsToTestBlit[compatibleFormatsIndex].sourceFormats;
13220 const bool onlyNearest = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
13221 for (int srcFormatIndex = 0; sourceFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
13222 {
13223 params.src.image.format = sourceFormats[srcFormatIndex];
13224 if (!isSupportedByFramework(params.src.image.format))
13225 continue;
13226
13227 // Cubic filtering can only be used with 2D images.
13228 const bool onlyNearestAndLinear = true;
13229
13230 BlitColorTestParams testParams
13231 {
13232 params,
13233 nullptr,
13234 makeFilterMask(onlyNearest, onlyNearestAndLinear)
13235 };
13236
13237 const std::string description = "Blit source format " + getFormatCaseName(params.src.image.format);
13238 addTestGroup(subGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams);
13239 }
13240 }
13241
13242 group->addChild(subGroup.release());
13243 }
13244
13245 // 3D tests. Note we use smaller dimensions here for performance reasons.
13246 {
13247 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D blitting tests"));
13248
13249 TestParams params;
13250 params.src.image.imageType = VK_IMAGE_TYPE_3D;
13251 params.dst.image.imageType = VK_IMAGE_TYPE_3D;
13252 params.src.image.extent = default3dExtent;
13253 params.dst.image.extent = default3dExtent;
13254 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13255 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13256 params.allocationKind = allocationKind;
13257 params.extensionUse = extensionUse;
13258
13259 CopyRegion region;
13260 for (int i = 0, j = 1; (i + defaultSixteenthSize / j < defaultQuarterSize) && (defaultSixteenthSize > j); i += defaultSixteenthSize / j++)
13261 {
13262 const VkImageBlit imageBlit =
13263 {
13264 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
13265 {
13266 {0, 0, 0},
13267 {defaultQuarterSize, defaultQuarterSize, defaultQuarterSize}
13268 }, // VkOffset3D srcOffsets[2];
13269
13270 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
13271 {
13272 {i, 0, i},
13273 {i + defaultSixteenthSize / j, defaultSixteenthSize / j, i + defaultSixteenthSize / j}
13274 } // VkOffset3D dstOffset[2];
13275 };
13276 region.imageBlit = imageBlit;
13277 params.regions.push_back(region);
13278 }
13279 for (int i = 0; i < defaultQuarterSize; i += defaultSixteenthSize)
13280 {
13281 const VkImageBlit imageBlit =
13282 {
13283 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
13284 {
13285 {i, i, i},
13286 {i + defaultSixteenthSize, i + defaultSixteenthSize, i + defaultSixteenthSize}
13287 }, // VkOffset3D srcOffsets[2];
13288
13289 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
13290 {
13291 {i, defaultQuarterSize / 2, i},
13292 {i + defaultSixteenthSize, defaultQuarterSize / 2 + defaultSixteenthSize, i + defaultSixteenthSize}
13293 } // VkOffset3D dstOffset[2];
13294 };
13295 region.imageBlit = imageBlit;
13296 params.regions.push_back(region);
13297 }
13298
13299 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
13300 {
13301 const VkFormat* sourceFormats = colorImageFormatsToTestBlit[compatibleFormatsIndex].sourceFormats;
13302 const bool onlyNearest = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
13303 for (int srcFormatIndex = 0; sourceFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
13304 {
13305 params.src.image.format = sourceFormats[srcFormatIndex];
13306 if (!isSupportedByFramework(params.src.image.format))
13307 continue;
13308
13309 // Cubic filtering can only be used with 2D images.
13310 const bool onlyNearestAndLinear = true;
13311
13312 BlitColorTestParams testParams
13313 {
13314 params,
13315 nullptr,
13316 makeFilterMask(onlyNearest, onlyNearestAndLinear)
13317 };
13318
13319 const std::string description = "Blit source format " + getFormatCaseName(params.src.image.format);
13320 addTestGroup(subGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams);
13321 }
13322 }
13323
13324 group->addChild(subGroup.release());
13325 }
13326 }
13327
addBlittingImageAllFormatsDepthStencilFormatsTests(tcu::TestCaseGroup * group,TestParams params)13328 void addBlittingImageAllFormatsDepthStencilFormatsTests (tcu::TestCaseGroup* group, TestParams params)
13329 {
13330 const VkImageLayout blitSrcLayouts[] =
13331 {
13332 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
13333 VK_IMAGE_LAYOUT_GENERAL
13334 };
13335 const VkImageLayout blitDstLayouts[] =
13336 {
13337 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
13338 VK_IMAGE_LAYOUT_GENERAL
13339 };
13340
13341 for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
13342 {
13343 params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx];
13344
13345 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
13346 {
13347 params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx];
13348 params.filter = VK_FILTER_NEAREST;
13349
13350 const std::string testName = getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
13351 getImageLayoutCaseName(params.dst.image.operationLayout);
13352 const std::string description = "Blit from " + getImageLayoutCaseName(params.src.image.operationLayout) +
13353 " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
13354
13355 group->addChild(new BlitImageTestCase(group->getTestContext(), testName + "_nearest", description, params));
13356 }
13357 }
13358 }
13359
addBlittingImageAllFormatsDepthStencilTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)13360 void addBlittingImageAllFormatsDepthStencilTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
13361 {
13362 const VkFormat depthAndStencilFormats[] =
13363 {
13364 VK_FORMAT_D16_UNORM,
13365 VK_FORMAT_X8_D24_UNORM_PACK32,
13366 VK_FORMAT_D32_SFLOAT,
13367 VK_FORMAT_S8_UINT,
13368 VK_FORMAT_D16_UNORM_S8_UINT,
13369 VK_FORMAT_D24_UNORM_S8_UINT,
13370 VK_FORMAT_D32_SFLOAT_S8_UINT,
13371 };
13372
13373 const VkImageSubresourceLayers defaultDepthSourceLayer = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
13374 const VkImageSubresourceLayers defaultStencilSourceLayer = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
13375 const VkImageSubresourceLayers defaultDSSourceLayer = { VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
13376
13377 // 2D tests
13378 {
13379 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D blitting tests"));
13380
13381 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
13382 {
13383 TestParams params;
13384 params.src.image.imageType = VK_IMAGE_TYPE_2D;
13385 params.src.image.extent = defaultExtent;
13386 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13387 params.src.image.format = depthAndStencilFormats[compatibleFormatsIndex];
13388 params.dst.image.extent = defaultExtent;
13389 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
13390 params.dst.image.format = params.src.image.format;
13391 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13392 params.allocationKind = allocationKind;
13393 params.extensionUse = extensionUse;
13394 params.separateDepthStencilLayouts = DE_FALSE;
13395
13396 bool hasDepth = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
13397 bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
13398
13399 CopyRegion region;
13400 for (int i = 0, j = 1; (i + defaultQuarterSize / j < defaultSize) && (defaultQuarterSize > j); i += defaultQuarterSize / j++)
13401 {
13402 const VkOffset3D srcOffset0 = {0, 0, 0};
13403 const VkOffset3D srcOffset1 = {defaultSize, defaultSize, 1};
13404 const VkOffset3D dstOffset0 = {i, 0, 0};
13405 const VkOffset3D dstOffset1 = {i + defaultQuarterSize / j, defaultQuarterSize / j, 1};
13406
13407 if (hasDepth)
13408 {
13409 const VkImageBlit imageBlit =
13410 {
13411 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
13412 { srcOffset0 , srcOffset1 }, // VkOffset3D srcOffsets[2];
13413 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
13414 { dstOffset0 , dstOffset1 }, // VkOffset3D dstOffset[2];
13415 };
13416 region.imageBlit = imageBlit;
13417 params.regions.push_back(region);
13418 }
13419 if (hasStencil)
13420 {
13421 const VkImageBlit imageBlit =
13422 {
13423 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
13424 { srcOffset0 , srcOffset1 }, // VkOffset3D srcOffsets[2];
13425 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
13426 { dstOffset0 , dstOffset1 }, // VkOffset3D dstOffset[2];
13427 };
13428 region.imageBlit = imageBlit;
13429 params.regions.push_back(region);
13430 }
13431 }
13432 for (int i = 0; i < defaultSize; i += defaultQuarterSize)
13433 {
13434 const VkOffset3D srcOffset0 = {i, i, 0};
13435 const VkOffset3D srcOffset1 = {i + defaultQuarterSize, i + defaultQuarterSize, 1};
13436 const VkOffset3D dstOffset0 = {i, defaultSize / 2, 0};
13437 const VkOffset3D dstOffset1 = {i + defaultQuarterSize, defaultSize / 2 + defaultQuarterSize, 1};
13438
13439 if (hasDepth)
13440 {
13441 const VkImageBlit imageBlit =
13442 {
13443 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
13444 { srcOffset0, srcOffset1 }, // VkOffset3D srcOffsets[2];
13445 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
13446 { dstOffset0, dstOffset1 } // VkOffset3D dstOffset[2];
13447 };
13448 region.imageBlit = imageBlit;
13449 params.regions.push_back(region);
13450 }
13451 if (hasStencil)
13452 {
13453 const VkImageBlit imageBlit =
13454 {
13455 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
13456 { srcOffset0, srcOffset1 }, // VkOffset3D srcOffsets[2];
13457 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
13458 { dstOffset0, dstOffset1 } // VkOffset3D dstOffset[2];
13459 };
13460 region.imageBlit = imageBlit;
13461 params.regions.push_back(region);
13462 }
13463 if (hasDepth && hasStencil)
13464 {
13465 const VkOffset3D dstDSOffset0 = {i, 3 * defaultQuarterSize, 0};
13466 const VkOffset3D dstDSOffset1 = {i + defaultQuarterSize, defaultSize, 1};
13467 const VkImageBlit imageBlit =
13468 {
13469 defaultDSSourceLayer, // VkImageSubresourceLayers srcSubresource;
13470 { srcOffset0, srcOffset1 }, // VkOffset3D srcOffsets[2];
13471 defaultDSSourceLayer, // VkImageSubresourceLayers dstSubresource;
13472 { dstDSOffset0, dstDSOffset1 } // VkOffset3D dstOffset[2];
13473 };
13474 region.imageBlit = imageBlit;
13475 params.regions.push_back(region);
13476 }
13477 }
13478
13479 const std::string testName = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
13480 const std::string description = "Blit from " + getFormatCaseName(params.src.image.format) +
13481 " to " + getFormatCaseName(params.dst.image.format);
13482 addTestGroup(subGroup.get(), testName, description, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
13483
13484 if (hasDepth && hasStencil)
13485 {
13486 params.separateDepthStencilLayouts = DE_TRUE;
13487 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" +
13488 getFormatCaseName(params.dst.image.format) + "_separate_layouts";
13489 const std::string description2 = "Blit from " + getFormatCaseName(params.src.image.format) +
13490 " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
13491 addTestGroup(subGroup.get(), testName2, description2, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
13492 }
13493 }
13494
13495 group->addChild(subGroup.release());
13496 }
13497
13498 // 1D tests
13499 {
13500 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D blitting tests"));
13501
13502 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
13503 {
13504 TestParams params;
13505 params.src.image.imageType = VK_IMAGE_TYPE_1D;
13506 params.dst.image.imageType = VK_IMAGE_TYPE_1D;
13507 params.src.image.extent = default1dExtent;
13508 params.dst.image.extent = default1dExtent;
13509 params.src.image.format = depthAndStencilFormats[compatibleFormatsIndex];
13510 params.dst.image.format = params.src.image.format;
13511 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13512 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13513 params.allocationKind = allocationKind;
13514 params.extensionUse = extensionUse;
13515
13516 bool hasDepth = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
13517 bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
13518
13519 CopyRegion region;
13520 for (int i = 0; i < defaultSize; i += defaultSize / 2)
13521 {
13522 const VkOffset3D srcOffset0 = {0, 0, 0};
13523 const VkOffset3D srcOffset1 = {defaultSize, 1, 1};
13524 const VkOffset3D dstOffset0 = {i, 0, 0};
13525 const VkOffset3D dstOffset1 = {i + defaultQuarterSize, 1, 1};
13526
13527 if (hasDepth)
13528 {
13529 const VkImageBlit imageBlit =
13530 {
13531 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
13532 { srcOffset0 , srcOffset1 }, // VkOffset3D srcOffsets[2];
13533 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
13534 { dstOffset0 , dstOffset1 }, // VkOffset3D dstOffset[2];
13535 };
13536 region.imageBlit = imageBlit;
13537 params.regions.push_back(region);
13538 }
13539 if (hasStencil)
13540 {
13541 const VkImageBlit imageBlit =
13542 {
13543 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
13544 { srcOffset0 , srcOffset1 }, // VkOffset3D srcOffsets[2];
13545 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
13546 { dstOffset0 , dstOffset1 }, // VkOffset3D dstOffset[2];
13547 };
13548 region.imageBlit = imageBlit;
13549 params.regions.push_back(region);
13550 }
13551 }
13552
13553 {
13554 const VkOffset3D srcOffset0 = {0, 0, 0};
13555 const VkOffset3D srcOffset1 = {defaultQuarterSize, 1, 1};
13556 const VkOffset3D dstOffset0 = {defaultQuarterSize, 0, 0};
13557 const VkOffset3D dstOffset1 = {2 * defaultQuarterSize, 1, 1};
13558
13559 if (hasDepth)
13560 {
13561 const VkImageBlit imageBlit =
13562 {
13563 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
13564 { srcOffset0, srcOffset1 }, // VkOffset3D srcOffsets[2];
13565 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
13566 { dstOffset0, dstOffset1 } // VkOffset3D dstOffset[2];
13567 };
13568 region.imageBlit = imageBlit;
13569 params.regions.push_back(region);
13570 }
13571 if (hasStencil)
13572 {
13573 const VkImageBlit imageBlit =
13574 {
13575 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
13576 { srcOffset0, srcOffset1 }, // VkOffset3D srcOffsets[2];
13577 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
13578 { dstOffset0, dstOffset1 } // VkOffset3D dstOffset[2];
13579 };
13580 region.imageBlit = imageBlit;
13581 params.regions.push_back(region);
13582 }
13583 if (hasDepth && hasStencil)
13584 {
13585 const VkOffset3D dstDSOffset0 = {3 * defaultQuarterSize, 0, 0};
13586 const VkOffset3D dstDSOffset1 = {3 * defaultQuarterSize + defaultQuarterSize / 2, 1, 1};
13587 const VkImageBlit imageBlit =
13588 {
13589 defaultDSSourceLayer, // VkImageSubresourceLayers srcSubresource;
13590 { srcOffset0, srcOffset1 }, // VkOffset3D srcOffsets[2];
13591 defaultDSSourceLayer, // VkImageSubresourceLayers dstSubresource;
13592 { dstDSOffset0, dstDSOffset1 } // VkOffset3D dstOffset[2];
13593 };
13594 region.imageBlit = imageBlit;
13595 params.regions.push_back(region);
13596 }
13597 }
13598
13599 const std::string testName = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
13600 const std::string description = "Blit from " + getFormatCaseName(params.src.image.format) +
13601 " to " + getFormatCaseName(params.dst.image.format);
13602 addTestGroup(subGroup.get(), testName, description, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
13603
13604 if (hasDepth && hasStencil)
13605 {
13606 params.separateDepthStencilLayouts = DE_TRUE;
13607 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" +
13608 getFormatCaseName(params.dst.image.format) + "_separate_layouts";
13609 const std::string description2 = "Blit from " + getFormatCaseName(params.src.image.format) +
13610 " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
13611 addTestGroup(subGroup.get(), testName2, description2, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
13612 }
13613 }
13614
13615 group->addChild(subGroup.release());
13616 }
13617
13618 // 3D tests. Note we use smaller dimensions here for performance reasons.
13619 {
13620 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D blitting tests"));
13621
13622 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
13623 {
13624 TestParams params;
13625 params.src.image.imageType = VK_IMAGE_TYPE_3D;
13626 params.dst.image.imageType = VK_IMAGE_TYPE_3D;
13627 params.src.image.extent = default3dExtent;
13628 params.dst.image.extent = default3dExtent;
13629 params.src.image.format = depthAndStencilFormats[compatibleFormatsIndex];
13630 params.dst.image.format = params.src.image.format;
13631 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13632 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13633 params.allocationKind = allocationKind;
13634 params.extensionUse = extensionUse;
13635
13636 bool hasDepth = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
13637 bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
13638
13639 CopyRegion region;
13640 for (int i = 0, j = 1; (i + defaultSixteenthSize / j < defaultQuarterSize) && (defaultSixteenthSize > j); i += defaultSixteenthSize / j++)
13641 {
13642 const VkOffset3D srcOffset0 = {0, 0, 0};
13643 const VkOffset3D srcOffset1 = {defaultQuarterSize, defaultQuarterSize, defaultQuarterSize};
13644 const VkOffset3D dstOffset0 = {i, 0, i};
13645 const VkOffset3D dstOffset1 = {i + defaultSixteenthSize / j, defaultSixteenthSize / j, i + defaultSixteenthSize / j};
13646
13647 if (hasDepth)
13648 {
13649 const VkImageBlit imageBlit =
13650 {
13651 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
13652 { srcOffset0 , srcOffset1 }, // VkOffset3D srcOffsets[2];
13653 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
13654 { dstOffset0 , dstOffset1 }, // VkOffset3D dstOffset[2];
13655 };
13656 region.imageBlit = imageBlit;
13657 params.regions.push_back(region);
13658 }
13659 if (hasStencil)
13660 {
13661 const VkImageBlit imageBlit =
13662 {
13663 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
13664 { srcOffset0 , srcOffset1 }, // VkOffset3D srcOffsets[2];
13665 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
13666 { dstOffset0 , dstOffset1 }, // VkOffset3D dstOffset[2];
13667 };
13668 region.imageBlit = imageBlit;
13669 params.regions.push_back(region);
13670 }
13671 }
13672 for (int i = 0; i < defaultQuarterSize; i += defaultSixteenthSize)
13673 {
13674 const VkOffset3D srcOffset0 = {i, i, i};
13675 const VkOffset3D srcOffset1 = {i + defaultSixteenthSize, i + defaultSixteenthSize, i + defaultSixteenthSize};
13676 const VkOffset3D dstOffset0 = {i, defaultQuarterSize / 2, i};
13677 const VkOffset3D dstOffset1 = {i + defaultSixteenthSize, defaultQuarterSize / 2 + defaultSixteenthSize, i + defaultSixteenthSize};
13678
13679 if (hasDepth)
13680 {
13681 const VkImageBlit imageBlit =
13682 {
13683 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
13684 { srcOffset0, srcOffset1 }, // VkOffset3D srcOffsets[2];
13685 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
13686 { dstOffset0, dstOffset1 } // VkOffset3D dstOffset[2];
13687 };
13688 region.imageBlit = imageBlit;
13689 params.regions.push_back(region);
13690 }
13691 if (hasStencil)
13692 {
13693 const VkImageBlit imageBlit =
13694 {
13695 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
13696 { srcOffset0, srcOffset1 }, // VkOffset3D srcOffsets[2];
13697 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
13698 { dstOffset0, dstOffset1 } // VkOffset3D dstOffset[2];
13699 };
13700 region.imageBlit = imageBlit;
13701 params.regions.push_back(region);
13702 }
13703 if (hasDepth && hasStencil)
13704 {
13705 const VkOffset3D dstDSOffset0 = {i, 3 * defaultSixteenthSize, i};
13706 const VkOffset3D dstDSOffset1 = {i + defaultSixteenthSize, defaultQuarterSize, i + defaultSixteenthSize};
13707 const VkImageBlit imageBlit =
13708 {
13709 defaultDSSourceLayer, // VkImageSubresourceLayers srcSubresource;
13710 { srcOffset0, srcOffset1 }, // VkOffset3D srcOffsets[2];
13711 defaultDSSourceLayer, // VkImageSubresourceLayers dstSubresource;
13712 { dstDSOffset0, dstDSOffset1 } // VkOffset3D dstOffset[2];
13713 };
13714 region.imageBlit = imageBlit;
13715 params.regions.push_back(region);
13716 }
13717 }
13718
13719 const std::string testName = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
13720 const std::string description = "Blit from " + getFormatCaseName(params.src.image.format) +
13721 " to " + getFormatCaseName(params.dst.image.format);
13722 addTestGroup(subGroup.get(), testName, description, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
13723
13724 if (hasDepth && hasStencil)
13725 {
13726 params.separateDepthStencilLayouts = DE_TRUE;
13727 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" +
13728 getFormatCaseName(params.dst.image.format) + "_separate_layouts";
13729 const std::string description2 = "Blit from " + getFormatCaseName(params.src.image.format) +
13730 " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
13731 addTestGroup(subGroup.get(), testName2, description2, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
13732 }
13733 }
13734
13735 group->addChild(subGroup.release());
13736 }
13737 }
13738
addBlittingImageAllFormatsMipmapFormatTests(tcu::TestCaseGroup * group,BlitColorTestParams testParams)13739 void addBlittingImageAllFormatsMipmapFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
13740 {
13741 tcu::TestContext& testCtx = group->getTestContext();
13742
13743 const VkImageLayout blitSrcLayouts[] =
13744 {
13745 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
13746 VK_IMAGE_LAYOUT_GENERAL
13747 };
13748 const VkImageLayout blitDstLayouts[] =
13749 {
13750 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
13751 VK_IMAGE_LAYOUT_GENERAL
13752 };
13753
13754 for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
13755 {
13756 testParams.params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx];
13757 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
13758 {
13759 testParams.params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx];
13760
13761 testParams.params.filter = VK_FILTER_NEAREST;
13762 const std::string testName = getImageLayoutCaseName(testParams.params.src.image.operationLayout) + "_" +
13763 getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
13764 const std::string description = "Blit from layout " + getImageLayoutCaseName(testParams.params.src.image.operationLayout) +
13765 " to " + getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
13766 group->addChild(new BlitMipmapTestCase(testCtx, testName + "_nearest", description, testParams.params));
13767
13768 if (testParams.testFilters & FILTER_MASK_LINEAR)
13769 {
13770 testParams.params.filter = VK_FILTER_LINEAR;
13771 group->addChild(new BlitMipmapTestCase(testCtx, testName + "_linear", description, testParams.params));
13772 }
13773
13774 if (testParams.testFilters & FILTER_MASK_CUBIC)
13775 {
13776 testParams.params.filter = VK_FILTER_CUBIC_EXT;
13777 group->addChild(new BlitMipmapTestCase(testCtx, testName + "_cubic", description, testParams.params));
13778 }
13779 }
13780 }
13781 }
13782
addBlittingImageAllFormatsBaseLevelMipmapTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)13783 void addBlittingImageAllFormatsBaseLevelMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
13784 {
13785 const struct
13786 {
13787 const VkFormat* const compatibleFormats;
13788 const bool onlyNearest;
13789 } colorImageFormatsToTestBlit[] =
13790 {
13791 { compatibleFormatsUInts, true },
13792 { compatibleFormatsSInts, true },
13793 { compatibleFormatsFloats, false },
13794 { compatibleFormatsSrgb, false },
13795 };
13796
13797 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
13798
13799 const int layerCountsToTest[] =
13800 {
13801 1,
13802 6
13803 };
13804
13805 TestParams params;
13806 params.src.image.imageType = VK_IMAGE_TYPE_2D;
13807 params.src.image.extent = defaultExtent;
13808 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13809 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
13810 params.dst.image.extent = defaultExtent;
13811 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13812 params.allocationKind = allocationKind;
13813 params.extensionUse = extensionUse;
13814 params.mipLevels = deLog2Floor32(deMaxu32(defaultExtent.width, defaultExtent.height)) + 1u;
13815 params.singleCommand = DE_TRUE;
13816
13817 CopyRegion region;
13818 for (deUint32 mipLevelNdx = 0u; mipLevelNdx < params.mipLevels; mipLevelNdx++)
13819 {
13820 VkImageSubresourceLayers destLayer = defaultSourceLayer;
13821 destLayer.mipLevel = mipLevelNdx;
13822
13823 const VkImageBlit imageBlit =
13824 {
13825 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
13826 {
13827 {0, 0, 0},
13828 {defaultSize, defaultSize, 1}
13829 }, // VkOffset3D srcOffsets[2];
13830
13831 destLayer, // VkImageSubresourceLayers dstSubresource;
13832 {
13833 {0, 0, 0},
13834 {defaultSize >> mipLevelNdx, defaultSize >> mipLevelNdx, 1}
13835 } // VkOffset3D dstOffset[2];
13836 };
13837 region.imageBlit = imageBlit;
13838 params.regions.push_back(region);
13839 }
13840
13841 if (allocationKind == ALLOCATION_KIND_DEDICATED)
13842 {
13843 const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
13844 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
13845 dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
13846 }
13847
13848 for (int layerCountIndex = 0; layerCountIndex < DE_LENGTH_OF_ARRAY(layerCountsToTest); layerCountIndex++)
13849 {
13850 const int layerCount = layerCountsToTest[layerCountIndex];
13851 const std::string layerGroupName = "layercount_" + de::toString(layerCount);
13852 const std::string layerGroupDesc = "Blit mipmaps with layerCount = " + de::toString(layerCount);
13853
13854 de::MovePtr<tcu::TestCaseGroup> layerCountGroup (new tcu::TestCaseGroup(group->getTestContext(), layerGroupName.c_str(), layerGroupDesc.c_str()));
13855
13856 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
13857 {
13858 const VkFormat* compatibleFormats = colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
13859 const bool onlyNearest = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
13860
13861 for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
13862 {
13863 params.src.image.format = compatibleFormats[srcFormatIndex];
13864 params.dst.image.format = compatibleFormats[srcFormatIndex];
13865
13866 if (!isSupportedByFramework(params.src.image.format))
13867 continue;
13868
13869 const bool onlyNearestAndLinear = de::contains(onlyNearestAndLinearFormatsToTest, params.src.image.format);
13870
13871 const std::string description = "Blit source format " + getFormatCaseName(params.src.image.format);
13872
13873 BlitColorTestParams testParams;
13874 testParams.params = params;
13875 testParams.compatibleFormats = compatibleFormats;
13876 testParams.testFilters = makeFilterMask(onlyNearest, onlyNearestAndLinear);
13877
13878 testParams.params.src.image.extent.depth = layerCount;
13879 testParams.params.dst.image.extent.depth = layerCount;
13880
13881 for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
13882 {
13883 testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
13884 testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
13885 }
13886
13887 addTestGroup(layerCountGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams);
13888 }
13889 }
13890 group->addChild(layerCountGroup.release());
13891 }
13892 }
13893
addBlittingImageAllFormatsPreviousLevelMipmapTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)13894 void addBlittingImageAllFormatsPreviousLevelMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
13895 {
13896 const struct
13897 {
13898 const VkFormat* const compatibleFormats;
13899 const bool onlyNearest;
13900 } colorImageFormatsToTestBlit[] =
13901 {
13902 { compatibleFormatsUInts, true },
13903 { compatibleFormatsSInts, true },
13904 { compatibleFormatsFloats, false },
13905 { compatibleFormatsSrgb, false },
13906 };
13907
13908 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
13909
13910 const int layerCountsToTest[] =
13911 {
13912 1,
13913 6
13914 };
13915
13916 TestParams params;
13917 params.src.image.imageType = VK_IMAGE_TYPE_2D;
13918 params.src.image.extent = defaultExtent;
13919 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13920 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
13921 params.dst.image.extent = defaultExtent;
13922 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13923 params.allocationKind = allocationKind;
13924 params.extensionUse = extensionUse;
13925 params.mipLevels = deLog2Floor32(deMaxu32(defaultExtent.width, defaultExtent.height)) + 1u;
13926 params.singleCommand = DE_FALSE;
13927
13928 CopyRegion region;
13929 for (deUint32 mipLevelNdx = 1u; mipLevelNdx < params.mipLevels; mipLevelNdx++)
13930 {
13931 VkImageSubresourceLayers srcLayer = defaultSourceLayer;
13932 VkImageSubresourceLayers destLayer = defaultSourceLayer;
13933
13934 srcLayer.mipLevel = mipLevelNdx - 1u;
13935 destLayer.mipLevel = mipLevelNdx;
13936
13937 const VkImageBlit imageBlit =
13938 {
13939 srcLayer, // VkImageSubresourceLayers srcSubresource;
13940 {
13941 {0, 0, 0},
13942 {defaultSize >> (mipLevelNdx - 1u), defaultSize >> (mipLevelNdx - 1u), 1}
13943 }, // VkOffset3D srcOffsets[2];
13944
13945 destLayer, // VkImageSubresourceLayers dstSubresource;
13946 {
13947 {0, 0, 0},
13948 {defaultSize >> mipLevelNdx, defaultSize >> mipLevelNdx, 1}
13949 } // VkOffset3D dstOffset[2];
13950 };
13951 region.imageBlit = imageBlit;
13952 params.regions.push_back(region);
13953 }
13954
13955 if (allocationKind == ALLOCATION_KIND_DEDICATED)
13956 {
13957 const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
13958 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
13959 dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
13960 }
13961
13962 for (int layerCountIndex = 0; layerCountIndex < DE_LENGTH_OF_ARRAY(layerCountsToTest); layerCountIndex++)
13963 {
13964 const int layerCount = layerCountsToTest[layerCountIndex];
13965 const std::string layerGroupName = "layercount_" + de::toString(layerCount);
13966 const std::string layerGroupDesc = "Blit mipmaps with layerCount = " + de::toString(layerCount);
13967
13968 de::MovePtr<tcu::TestCaseGroup> layerCountGroup (new tcu::TestCaseGroup(group->getTestContext(), layerGroupName.c_str(), layerGroupDesc.c_str()));
13969
13970 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
13971 {
13972 const VkFormat* compatibleFormats = colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
13973 const bool onlyNearest = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
13974
13975 for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
13976 {
13977 params.src.image.format = compatibleFormats[srcFormatIndex];
13978 params.dst.image.format = compatibleFormats[srcFormatIndex];
13979
13980 if (!isSupportedByFramework(params.src.image.format))
13981 continue;
13982
13983 const bool onlyNearestAndLinear = de::contains(onlyNearestAndLinearFormatsToTest, params.src.image.format);
13984
13985 const std::string description = "Blit source format " + getFormatCaseName(params.src.image.format);
13986
13987 BlitColorTestParams testParams;
13988 testParams.params = params;
13989 testParams.compatibleFormats = compatibleFormats;
13990 testParams.testFilters = makeFilterMask(onlyNearest, onlyNearestAndLinear);
13991
13992 testParams.params.src.image.extent.depth = layerCount;
13993 testParams.params.dst.image.extent.depth = layerCount;
13994
13995 for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
13996 {
13997 testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
13998 testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
13999 }
14000
14001 addTestGroup(layerCountGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams);
14002 }
14003 }
14004 group->addChild(layerCountGroup.release());
14005 }
14006
14007 for (int multiLayer = 0; multiLayer < 2; multiLayer++)
14008 {
14009 const int layerCount = multiLayer ? 6 : 1;
14010
14011 for (int barrierCount = 1; barrierCount < 4; barrierCount++)
14012 {
14013 if (layerCount != 1 || barrierCount != 1)
14014 {
14015 const std::string barrierGroupName = (multiLayer ? "layerbarriercount_" : "mipbarriercount_") + de::toString(barrierCount);
14016 const std::string barrierGroupDesc = "Use " + de::toString(barrierCount) + " image barriers";
14017
14018 de::MovePtr<tcu::TestCaseGroup> barrierCountGroup(new tcu::TestCaseGroup(group->getTestContext(), barrierGroupName.c_str(), barrierGroupDesc.c_str()));
14019
14020 params.barrierCount = barrierCount;
14021
14022 // Only go through a few common formats
14023 for (int srcFormatIndex = 2; srcFormatIndex < 6; ++srcFormatIndex)
14024 {
14025 params.src.image.format = compatibleFormatsUInts[srcFormatIndex];
14026 params.dst.image.format = compatibleFormatsUInts[srcFormatIndex];
14027
14028 if (!isSupportedByFramework(params.src.image.format))
14029 continue;
14030
14031 const std::string description = "Blit source format " + getFormatCaseName(params.src.image.format);
14032
14033 BlitColorTestParams testParams;
14034 testParams.params = params;
14035 testParams.compatibleFormats = compatibleFormatsUInts;
14036 testParams.testFilters = FILTER_MASK_NEAREST;
14037
14038 testParams.params.src.image.extent.depth = layerCount;
14039 testParams.params.dst.image.extent.depth = layerCount;
14040
14041 for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
14042 {
14043 testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
14044 testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
14045 }
14046
14047 addTestGroup(barrierCountGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams);
14048 }
14049 group->addChild(barrierCountGroup.release());
14050 }
14051 }
14052 }
14053 }
14054
addBlittingImageAllFormatsMipmapTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14055 void addBlittingImageAllFormatsMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14056 {
14057 addTestGroup(group, "from_base_level", "Generate all mipmap levels from base level", addBlittingImageAllFormatsBaseLevelMipmapTests, allocationKind, extensionUse);
14058 addTestGroup(group, "from_previous_level", "Generate next mipmap level from previous level", addBlittingImageAllFormatsPreviousLevelMipmapTests, allocationKind, extensionUse);
14059 }
14060
addBlittingImageAllFormatsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14061 void addBlittingImageAllFormatsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14062 {
14063 addTestGroup(group, "color", "Blitting image with color formats", addBlittingImageAllFormatsColorTests, allocationKind, extensionUse);
14064 addTestGroup(group, "depth_stencil", "Blitting image with depth/stencil formats", addBlittingImageAllFormatsDepthStencilTests, allocationKind, extensionUse);
14065 addTestGroup(group, "generate_mipmaps", "Generating mipmaps with vkCmdBlitImage()", addBlittingImageAllFormatsMipmapTests, allocationKind, extensionUse);
14066 }
14067
addBlittingImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14068 void addBlittingImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14069 {
14070 addTestGroup(group, "simple_tests", "Blitting image simple tests", addBlittingImageSimpleTests, allocationKind, extensionUse);
14071 addTestGroup(group, "all_formats", "Blitting image with all compatible formats", addBlittingImageAllFormatsTests, allocationKind, extensionUse);
14072 }
14073
14074 const VkSampleCountFlagBits samples[] =
14075 {
14076 VK_SAMPLE_COUNT_2_BIT,
14077 VK_SAMPLE_COUNT_4_BIT,
14078 VK_SAMPLE_COUNT_8_BIT,
14079 VK_SAMPLE_COUNT_16_BIT,
14080 VK_SAMPLE_COUNT_32_BIT,
14081 VK_SAMPLE_COUNT_64_BIT
14082 };
14083 const VkExtent3D resolveExtent = {256u, 256u, 1};
14084
addResolveImageWholeTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14085 void addResolveImageWholeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14086 {
14087 TestParams params;
14088 params.src.image.imageType = VK_IMAGE_TYPE_2D;
14089 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14090 params.src.image.extent = resolveExtent;
14091 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14092 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14093 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
14094 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14095 params.dst.image.extent = resolveExtent;
14096 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14097 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14098 params.allocationKind = allocationKind;
14099 params.extensionUse = extensionUse;
14100
14101 {
14102 const VkImageSubresourceLayers sourceLayer =
14103 {
14104 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
14105 0u, // deUint32 mipLevel;
14106 0u, // deUint32 baseArrayLayer;
14107 1u // deUint32 layerCount;
14108 };
14109 const VkImageResolve testResolve =
14110 {
14111 sourceLayer, // VkImageSubresourceLayers srcSubresource;
14112 {0, 0, 0}, // VkOffset3D srcOffset;
14113 sourceLayer, // VkImageSubresourceLayers dstSubresource;
14114 {0, 0, 0}, // VkOffset3D dstOffset;
14115 resolveExtent, // VkExtent3D extent;
14116 };
14117
14118 CopyRegion imageResolve;
14119 imageResolve.imageResolve = testResolve;
14120 params.regions.push_back(imageResolve);
14121 }
14122
14123 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14124 {
14125 params.imageOffset = false;
14126 params.samples = samples[samplesIndex];
14127 const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]);
14128 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
14129 params.imageOffset = true;
14130 if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14131 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", description, params));
14132 }
14133 }
14134 }
14135
addResolveImagePartialTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14136 void addResolveImagePartialTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14137 {
14138 TestParams params;
14139 params.src.image.imageType = VK_IMAGE_TYPE_2D;
14140 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14141 params.src.image.extent = resolveExtent;
14142 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14143 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14144 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
14145 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14146 params.dst.image.extent = resolveExtent;
14147 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14148 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14149 params.allocationKind = allocationKind;
14150 params.extensionUse = extensionUse;
14151
14152 {
14153 const VkImageSubresourceLayers sourceLayer =
14154 {
14155 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
14156 0u, // deUint32 mipLevel;
14157 0u, // deUint32 baseArrayLayer;
14158 1u // deUint32 layerCount;
14159 };
14160 const VkImageResolve testResolve =
14161 {
14162 sourceLayer, // VkImageSubresourceLayers srcSubresource;
14163 {0, 0, 0}, // VkOffset3D srcOffset;
14164 sourceLayer, // VkImageSubresourceLayers dstSubresource;
14165 {64u, 64u, 0}, // VkOffset3D dstOffset;
14166 {128u, 128u, 1u}, // VkExtent3D extent;
14167 };
14168
14169 CopyRegion imageResolve;
14170 imageResolve.imageResolve = testResolve;
14171 params.regions.push_back(imageResolve);
14172 }
14173
14174 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14175 {
14176 params.samples = samples[samplesIndex];
14177 const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]);
14178 params.imageOffset = false;
14179 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
14180 params.imageOffset = true;
14181 if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14182 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", description, params));
14183 }
14184 }
14185 }
14186
addResolveImageWithRegionsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14187 void addResolveImageWithRegionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14188 {
14189 TestParams params;
14190 params.src.image.imageType = VK_IMAGE_TYPE_2D;
14191 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14192 params.src.image.extent = resolveExtent;
14193 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14194 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14195 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
14196 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14197 params.dst.image.extent = resolveExtent;
14198 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14199 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14200 params.allocationKind = allocationKind;
14201 params.extensionUse = extensionUse;
14202 params.imageOffset = allocationKind != ALLOCATION_KIND_DEDICATED;
14203
14204 {
14205 const VkImageSubresourceLayers sourceLayer =
14206 {
14207 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
14208 0u, // deUint32 mipLevel;
14209 0u, // deUint32 baseArrayLayer;
14210 1u // deUint32 layerCount;
14211 };
14212
14213 for (int i = 0; i < 256; i += 64)
14214 {
14215 const VkImageResolve testResolve =
14216 {
14217 sourceLayer, // VkImageSubresourceLayers srcSubresource;
14218 {i, i, 0}, // VkOffset3D srcOffset;
14219 sourceLayer, // VkImageSubresourceLayers dstSubresource;
14220 {i, 0, 0}, // VkOffset3D dstOffset;
14221 {64u, 64u, 1u}, // VkExtent3D extent;
14222 };
14223
14224 CopyRegion imageResolve;
14225 imageResolve.imageResolve = testResolve;
14226 params.regions.push_back(imageResolve);
14227 }
14228 }
14229
14230 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14231 {
14232 params.samples = samples[samplesIndex];
14233 const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]);
14234 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
14235 }
14236 }
14237
addResolveImageWholeCopyBeforeResolvingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14238 void addResolveImageWholeCopyBeforeResolvingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14239 {
14240 TestParams params;
14241 params.src.image.imageType = VK_IMAGE_TYPE_2D;
14242 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14243 params.src.image.extent = defaultExtent;
14244 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14245 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14246 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
14247 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14248 params.dst.image.extent = defaultExtent;
14249 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14250 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14251 params.allocationKind = allocationKind;
14252 params.extensionUse = extensionUse;
14253
14254 {
14255 const VkImageSubresourceLayers sourceLayer =
14256 {
14257 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
14258 0u, // deUint32 mipLevel;
14259 0u, // deUint32 baseArrayLayer;
14260 1u // deUint32 layerCount;
14261 };
14262
14263 const VkImageResolve testResolve =
14264 {
14265 sourceLayer, // VkImageSubresourceLayers srcSubresource;
14266 {0, 0, 0}, // VkOffset3D srcOffset;
14267 sourceLayer, // VkImageSubresourceLayers dstSubresource;
14268 {0, 0, 0}, // VkOffset3D dstOffset;
14269 defaultExtent, // VkExtent3D extent;
14270 };
14271
14272 CopyRegion imageResolve;
14273 imageResolve.imageResolve = testResolve;
14274 params.regions.push_back(imageResolve);
14275 }
14276
14277 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14278 {
14279 params.samples = samples[samplesIndex];
14280 const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]);
14281 params.imageOffset = false;
14282 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_MS_IMAGE));
14283 params.imageOffset = true;
14284 if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14285 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", description, params, COPY_MS_IMAGE_TO_MS_IMAGE));
14286 }
14287 }
14288 }
14289
addComputeAndTransferQueueTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14290 void addComputeAndTransferQueueTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14291 {
14292 de::MovePtr<tcu::TestCaseGroup> computeGroup (new tcu::TestCaseGroup(group->getTestContext(), "whole_copy_before_resolving_compute", "Resolve from image to image using compute queue (whole copy before resolving)"));
14293 de::MovePtr<tcu::TestCaseGroup> transferGroup (new tcu::TestCaseGroup(group->getTestContext(), "whole_copy_before_resolving_transfer", "Resolve from image to image using compute queue (whole copy before resolving)"));
14294
14295 TestParams params;
14296 params.src.image.imageType = VK_IMAGE_TYPE_2D;
14297 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14298 params.src.image.extent = defaultExtent;
14299 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14300 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14301 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
14302 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14303 params.dst.image.extent = defaultExtent;
14304 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14305 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14306 params.allocationKind = allocationKind;
14307 params.extensionUse = extensionUse;
14308
14309 {
14310 const VkImageSubresourceLayers sourceLayer =
14311 {
14312 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
14313 0u, // deUint32 mipLevel;
14314 0u, // deUint32 baseArrayLayer;
14315 1u // deUint32 layerCount;
14316 };
14317
14318 const VkImageResolve testResolve =
14319 {
14320 sourceLayer, // VkImageSubresourceLayers srcSubresource;
14321 {0, 0, 0}, // VkOffset3D srcOffset;
14322 sourceLayer, // VkImageSubresourceLayers dstSubresource;
14323 {0, 0, 0}, // VkOffset3D dstOffset;
14324 defaultExtent, // VkExtent3D extent;
14325 };
14326
14327 CopyRegion imageResolve;
14328 imageResolve.imageResolve = testResolve;
14329 params.regions.push_back(imageResolve);
14330 }
14331
14332 for (const auto& sample : samples)
14333 {
14334 params.samples = sample;
14335 const std::string description = "With " + getSampleCountCaseName(sample);
14336 computeGroup->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(sample), description, params, COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE));
14337 transferGroup->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(sample), description, params, COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER));
14338 }
14339
14340 group->addChild(computeGroup.release());
14341 group->addChild(transferGroup.release());
14342 }
14343
addResolveImageWholeCopyWithoutCabBeforeResolvingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14344 void addResolveImageWholeCopyWithoutCabBeforeResolvingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14345 {
14346 TestParams params;
14347 params.src.image.imageType = VK_IMAGE_TYPE_2D;
14348 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14349 params.src.image.extent = defaultExtent;
14350 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14351 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14352 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
14353 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14354 params.dst.image.extent = defaultExtent;
14355 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14356 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14357 params.allocationKind = allocationKind;
14358 params.extensionUse = extensionUse;
14359
14360 {
14361 const VkImageSubresourceLayers sourceLayer =
14362 {
14363 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
14364 0u, // deUint32 mipLevel;
14365 0u, // deUint32 baseArrayLayer;
14366 1u // deUint32 layerCount;
14367 };
14368
14369 const VkImageResolve testResolve =
14370 {
14371 sourceLayer, // VkImageSubresourceLayers srcSubresource;
14372 {0, 0, 0}, // VkOffset3D srcOffset;
14373 sourceLayer, // VkImageSubresourceLayers dstSubresource;
14374 {0, 0, 0}, // VkOffset3D dstOffset;
14375 defaultExtent, // VkExtent3D extent;
14376 };
14377
14378 CopyRegion imageResolve;
14379 imageResolve.imageResolve = testResolve;
14380 params.regions.push_back(imageResolve);
14381 }
14382
14383 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14384 {
14385 params.samples = samples[samplesIndex];
14386 const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]);
14387 params.imageOffset = false;
14388 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB));
14389 params.imageOffset = true;
14390 if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14391 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", description, params, COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB));
14392 }
14393 }
14394 }
14395
addResolveImageWholeCopyDiffLayoutsBeforeResolvingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14396 void addResolveImageWholeCopyDiffLayoutsBeforeResolvingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14397 {
14398 TestParams params;
14399 params.src.image.imageType = VK_IMAGE_TYPE_2D;
14400 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14401 params.src.image.extent = defaultExtent;
14402 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14403 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14404 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
14405 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14406 params.dst.image.extent = defaultExtent;
14407 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14408 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14409 params.allocationKind = allocationKind;
14410 params.extensionUse = extensionUse;
14411
14412 {
14413 const VkImageSubresourceLayers sourceLayer =
14414 {
14415 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
14416 0u, // deUint32 mipLevel;
14417 0u, // deUint32 baseArrayLayer;
14418 1u // deUint32 layerCount;
14419 };
14420
14421 const VkImageResolve testResolve =
14422 {
14423 sourceLayer, // VkImageSubresourceLayers srcSubresource;
14424 {0, 0, 0}, // VkOffset3D srcOffset;
14425 sourceLayer, // VkImageSubresourceLayers dstSubresource;
14426 {0, 0, 0}, // VkOffset3D dstOffset;
14427 defaultExtent, // VkExtent3D extent;
14428 };
14429
14430 CopyRegion imageResolve;
14431 imageResolve.imageResolve = testResolve;
14432 params.regions.push_back(imageResolve);
14433 }
14434
14435 const struct
14436 {
14437 VkImageLayout layout;
14438 std::string name;
14439 } imageLayouts[] =
14440 {
14441 { VK_IMAGE_LAYOUT_GENERAL, "general" },
14442 { VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, "transfer_src_optimal" },
14443 { VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, "transfer_dst_optimal" }
14444 };
14445
14446 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14447 for (int srcLayoutIndex = 0; srcLayoutIndex < DE_LENGTH_OF_ARRAY(imageLayouts); ++srcLayoutIndex)
14448 for (int dstLayoutIndex = 0; dstLayoutIndex < DE_LENGTH_OF_ARRAY(imageLayouts); ++dstLayoutIndex)
14449 {
14450 params.src.image.operationLayout = imageLayouts[srcLayoutIndex].layout;
14451 params.dst.image.operationLayout = imageLayouts[dstLayoutIndex].layout;
14452 if (params.src.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ||
14453 params.dst.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)
14454 continue;
14455 params.samples = samples[samplesIndex];
14456 const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]);
14457 std::string testName = getSampleCountCaseName(samples[samplesIndex]) + "_" + imageLayouts[srcLayoutIndex].name + "_" + imageLayouts[dstLayoutIndex].name;
14458 params.imageOffset = false;
14459 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), testName, description, params, COPY_MS_IMAGE_TO_MS_IMAGE));
14460 params.imageOffset = true;
14461 if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14462 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), testName + "_bind_offset", description, params, COPY_MS_IMAGE_TO_MS_IMAGE));
14463 }
14464 }
14465 }
14466
addResolveImageLayerCopyBeforeResolvingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14467 void addResolveImageLayerCopyBeforeResolvingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14468 {
14469 TestParams params;
14470 params.src.image.imageType = VK_IMAGE_TYPE_2D;
14471 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14472 params.src.image.extent = defaultExtent;
14473 params.src.image.extent.depth = 5u;
14474 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14475 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14476 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
14477 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14478 params.dst.image.extent = defaultExtent;
14479 params.dst.image.extent.depth = 5u;
14480 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14481 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14482 params.allocationKind = allocationKind;
14483 params.extensionUse = extensionUse;
14484
14485 for (deUint32 layerNdx=0; layerNdx < params.src.image.extent.depth; ++layerNdx)
14486 {
14487 const VkImageSubresourceLayers sourceLayer =
14488 {
14489 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
14490 0u, // deUint32 mipLevel;
14491 layerNdx, // deUint32 baseArrayLayer;
14492 1u // deUint32 layerCount;
14493 };
14494
14495 const VkImageResolve testResolve =
14496 {
14497 sourceLayer, // VkImageSubresourceLayers srcSubresource;
14498 {0, 0, 0}, // VkOffset3D srcOffset;
14499 sourceLayer, // VkImageSubresourceLayers dstSubresource;
14500 {0, 0, 0}, // VkOffset3D dstOffset;
14501 defaultExtent, // VkExtent3D extent;
14502 };
14503
14504 CopyRegion imageResolve;
14505 imageResolve.imageResolve = testResolve;
14506 params.regions.push_back(imageResolve);
14507 }
14508
14509 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14510 {
14511 params.samples = samples[samplesIndex];
14512 const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]);
14513 params.imageOffset = false;
14514 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_LAYER_TO_MS_IMAGE));
14515 params.imageOffset = true;
14516 if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14517 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", description, params, COPY_MS_IMAGE_LAYER_TO_MS_IMAGE));
14518 }
14519 }
14520 }
14521
addResolveCopyImageWithRegionsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14522 void addResolveCopyImageWithRegionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14523 {
14524 TestParams params;
14525 params.src.image.imageType = VK_IMAGE_TYPE_2D;
14526 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14527 params.src.image.extent = resolveExtent;
14528 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14529 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14530 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
14531 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14532 params.dst.image.extent = resolveExtent;
14533 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14534 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14535 params.allocationKind = allocationKind;
14536 params.extensionUse = extensionUse;
14537
14538 int32_t imageHalfWidth = getExtent3D(params.src.image).width / 2;
14539 int32_t imageHalfHeight = getExtent3D(params.src.image).height / 2;
14540 VkExtent3D halfImageExtent = {resolveExtent.width / 2, resolveExtent.height / 2, 1u};
14541
14542 // Lower right corner to lower left corner.
14543 {
14544 const VkImageSubresourceLayers sourceLayer =
14545 {
14546 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
14547 0u, // deUint32 mipLevel;
14548 0u, // deUint32 baseArrayLayer;
14549 1u // deUint32 layerCount;
14550 };
14551
14552 const VkImageResolve testResolve =
14553 {
14554 sourceLayer, // VkImageSubresourceLayers srcSubresource;
14555 {imageHalfWidth, imageHalfHeight, 0}, // VkOffset3D srcOffset;
14556 sourceLayer, // VkImageSubresourceLayers dstSubresource;
14557 {0, imageHalfHeight, 0}, // VkOffset3D dstOffset;
14558 halfImageExtent, // VkExtent3D extent;
14559 };
14560
14561 CopyRegion imageResolve;
14562 imageResolve.imageResolve = testResolve;
14563 params.regions.push_back(imageResolve);
14564 }
14565
14566 // Upper right corner to lower right corner.
14567 {
14568 const VkImageSubresourceLayers sourceLayer =
14569 {
14570 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
14571 0u, // deUint32 mipLevel;
14572 0u, // deUint32 baseArrayLayer;
14573 1u // deUint32 layerCount;
14574 };
14575
14576 const VkImageResolve testResolve =
14577 {
14578 sourceLayer, // VkImageSubresourceLayers srcSubresource;
14579 {imageHalfWidth, 0, 0}, // VkOffset3D srcOffset;
14580 sourceLayer, // VkImageSubresourceLayers dstSubresource;
14581 {imageHalfWidth, imageHalfHeight, 0}, // VkOffset3D dstOffset;
14582 halfImageExtent, // VkExtent3D extent;
14583 };
14584
14585 CopyRegion imageResolve;
14586 imageResolve.imageResolve = testResolve;
14587 params.regions.push_back(imageResolve);
14588 }
14589
14590 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14591 {
14592 params.samples = samples[samplesIndex];
14593 const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]);
14594 params.imageOffset = false;
14595 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION));
14596 params.imageOffset = true;
14597 if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14598 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", description, params, COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION));
14599 }
14600 }
14601 }
14602
addResolveImageWholeArrayImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14603 void addResolveImageWholeArrayImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14604 {
14605 TestParams params;
14606 params.src.image.imageType = VK_IMAGE_TYPE_2D;
14607 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14608 params.src.image.extent = defaultExtent;
14609 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14610 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14611 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
14612 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14613 params.dst.image.extent = defaultExtent;
14614 params.dst.image.extent.depth = 5u;
14615 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14616 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14617 params.allocationKind = allocationKind;
14618 params.extensionUse = extensionUse;
14619
14620 for (deUint32 layerNdx=0; layerNdx < params.dst.image.extent.depth; ++layerNdx)
14621 {
14622 const VkImageSubresourceLayers sourceLayer =
14623 {
14624 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
14625 0u, // deUint32 mipLevel;
14626 layerNdx, // deUint32 baseArrayLayer;
14627 1u // deUint32 layerCount;
14628 };
14629
14630 const VkImageResolve testResolve =
14631 {
14632 sourceLayer, // VkImageSubresourceLayers srcSubresource;
14633 {0, 0, 0}, // VkOffset3D srcOffset;
14634 sourceLayer, // VkImageSubresourceLayers dstSubresource;
14635 {0, 0, 0}, // VkOffset3D dstOffset;
14636 defaultExtent, // VkExtent3D extent;
14637 };
14638
14639 CopyRegion imageResolve;
14640 imageResolve.imageResolve = testResolve;
14641 params.regions.push_back(imageResolve);
14642 }
14643
14644 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14645 {
14646 params.samples = samples[samplesIndex];
14647 const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]);
14648 params.imageOffset = false;
14649 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
14650 params.imageOffset = true;
14651 if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14652 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
14653 }
14654 }
14655 }
14656
addResolveImageWholeArrayImageSingleRegionTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14657 void addResolveImageWholeArrayImageSingleRegionTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14658 {
14659 TestParams params;
14660 params.src.image.imageType = VK_IMAGE_TYPE_2D;
14661 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14662 params.src.image.extent = defaultExtent;
14663 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14664 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
14665 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14666 params.dst.image.extent = defaultExtent;
14667 params.dst.image.extent.depth = 5u;
14668 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14669 params.allocationKind = allocationKind;
14670 params.extensionUse = extensionUse;
14671
14672 const VkImageSubresourceLayers sourceLayer =
14673 {
14674 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
14675 0u, // uint32_t mipLevel;
14676 0, // uint32_t baseArrayLayer;
14677 params.dst.image.extent.depth // uint32_t layerCount;
14678 };
14679
14680 const VkImageResolve testResolve =
14681 {
14682 sourceLayer, // VkImageSubresourceLayers srcSubresource;
14683 {0, 0, 0}, // VkOffset3D srcOffset;
14684 sourceLayer, // VkImageSubresourceLayers dstSubresource;
14685 {0, 0, 0}, // VkOffset3D dstOffset;
14686 defaultExtent, // VkExtent3D extent;
14687 };
14688
14689 CopyRegion imageResolve;
14690 imageResolve.imageResolve = testResolve;
14691 params.regions.push_back(imageResolve);
14692
14693 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14694 {
14695 params.samples = samples[samplesIndex];
14696 const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]);
14697 params.imageOffset = false;
14698 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
14699 params.imageOffset = true;
14700 if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14701 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
14702 }
14703 }
14704 }
14705
addResolveImageDiffImageSizeTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14706 void addResolveImageDiffImageSizeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14707 {
14708 tcu::TestContext& testCtx = group->getTestContext();
14709 TestParams params;
14710 params.src.image.imageType = VK_IMAGE_TYPE_2D;
14711 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14712 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14713 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14714 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
14715 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14716 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14717 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14718 params.allocationKind = allocationKind;
14719 params.extensionUse = extensionUse;
14720
14721 {
14722 const VkImageSubresourceLayers sourceLayer =
14723 {
14724 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
14725 0u, // deUint32 mipLevel;
14726 0u, // deUint32 baseArrayLayer;
14727 1u // deUint32 layerCount;
14728 };
14729 const VkImageResolve testResolve =
14730 {
14731 sourceLayer, // VkImageSubresourceLayers srcSubresource;
14732 {0, 0, 0}, // VkOffset3D srcOffset;
14733 sourceLayer, // VkImageSubresourceLayers dstSubresource;
14734 {0, 0, 0}, // VkOffset3D dstOffset;
14735 resolveExtent, // VkExtent3D extent;
14736 };
14737 CopyRegion imageResolve;
14738 imageResolve.imageResolve = testResolve;
14739 params.regions.push_back(imageResolve);
14740 }
14741
14742 const VkExtent3D imageExtents[] =
14743 {
14744 { resolveExtent.width + 10, resolveExtent.height, resolveExtent.depth },
14745 { resolveExtent.width, resolveExtent.height * 2, resolveExtent.depth },
14746 { resolveExtent.width, resolveExtent.height, resolveExtent.depth + 10 }
14747 };
14748
14749 for (int srcImageExtentIndex = 0; srcImageExtentIndex < DE_LENGTH_OF_ARRAY(imageExtents); ++srcImageExtentIndex)
14750 {
14751 const VkExtent3D& srcImageSize = imageExtents[srcImageExtentIndex];
14752 params.src.image.extent = srcImageSize;
14753 params.dst.image.extent = resolveExtent;
14754 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14755 {
14756 params.samples = samples[samplesIndex];
14757 std::ostringstream testName;
14758 testName << "src_" << srcImageSize.width << "_" << srcImageSize.height << "_" << srcImageSize.depth << "_" << getSampleCountCaseName(samples[samplesIndex]);
14759 std::ostringstream description;
14760 description << "With " << getSampleCountCaseName(samples[samplesIndex]) << " and source image size ("
14761 << srcImageSize.width << ", " << srcImageSize.height << ", " << srcImageSize.depth << ")";
14762 group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str(), description.str(), params));
14763 }
14764 }
14765 for (int dstImageExtentIndex = 0; dstImageExtentIndex < DE_LENGTH_OF_ARRAY(imageExtents); ++dstImageExtentIndex)
14766 {
14767 const VkExtent3D& dstImageSize = imageExtents[dstImageExtentIndex];
14768 params.src.image.extent = resolveExtent;
14769 params.dst.image.extent = dstImageSize;
14770 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14771 {
14772 params.samples = samples[samplesIndex];
14773 std::ostringstream testName;
14774 testName << "dst_" << dstImageSize.width << "_" << dstImageSize.height << "_" << dstImageSize.depth << "_" << getSampleCountCaseName(samples[samplesIndex]);
14775 std::ostringstream description;
14776 description << "With " << getSampleCountCaseName(samples[samplesIndex]) << " and destination image size ("
14777 << dstImageSize.width << ", " << dstImageSize.height << ", " << dstImageSize.depth << ")";
14778 params.imageOffset = false;
14779 group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str(), description.str(), params));
14780 params.imageOffset = true;
14781 if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14782 group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str() + "_bind_offset", description.str(), params));
14783 }
14784 }
14785 }
14786 }
14787
addDepthStencilCopyMSAATest(tcu::TestCaseGroup * group,DepthStencilMSAA::TestParameters testCreateParams)14788 void addDepthStencilCopyMSAATest (tcu::TestCaseGroup* group, DepthStencilMSAA::TestParameters testCreateParams)
14789 {
14790 // Run all the tests with one of the bare depth format and one bare stencil format + mandatory combined formats.
14791 const struct
14792 {
14793 const std::string name;
14794 const VkFormat vkFormat;
14795 } depthAndStencilFormats[] =
14796 {
14797 { "d32_sfloat", VK_FORMAT_D32_SFLOAT },
14798 { "s8_uint", VK_FORMAT_S8_UINT },
14799 { "d16_unorm_s8_uint", VK_FORMAT_D16_UNORM_S8_UINT },
14800 { "d24_unorm_s8_uint", VK_FORMAT_D24_UNORM_S8_UINT },
14801 };
14802
14803 // Both image layouts will be tested only with full image copy tests to limit the number of tests.
14804 const VkImageLayout srcImageLayouts[] =
14805 {
14806 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
14807 VK_IMAGE_LAYOUT_GENERAL
14808 };
14809 const VkImageLayout dstImageLayouts[] =
14810 {
14811 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
14812 VK_IMAGE_LAYOUT_GENERAL
14813 };
14814
14815 for (const auto &srcLayout : srcImageLayouts)
14816 {
14817 for (const auto &dstLayout : dstImageLayouts)
14818 {
14819 testCreateParams.srcImageLayout = srcLayout;
14820 testCreateParams.dstImageLayout = dstLayout;
14821 for (const auto &format : depthAndStencilFormats)
14822 {
14823 testCreateParams.imageFormat = format.vkFormat;
14824 const auto textureFormat = mapVkFormat(format.vkFormat);
14825 bool hasDepth = tcu::hasDepthComponent(textureFormat.order);
14826 bool hasStencil = tcu::hasStencilComponent(textureFormat.order);
14827 std::string testNameBase = format.name + "_" + (testCreateParams.copyOptions == DepthStencilMSAA::COPY_WHOLE_IMAGE ? getImageLayoutCaseName(srcLayout) + "_" + getImageLayoutCaseName(dstLayout) + "_": "");
14828
14829 if (hasDepth)
14830 {
14831 testCreateParams.copyAspect = VK_IMAGE_ASPECT_DEPTH_BIT;
14832 for (auto sample : samples)
14833 {
14834 testCreateParams.samples = sample;
14835 std::string description = "Copy depth component with sample count: " + getSampleCountCaseName(sample);
14836 testCreateParams.imageOffset = false;
14837 group->addChild(new DepthStencilMSAATestCase(group->getTestContext(), testNameBase + "D_" + getSampleCountCaseName(sample), description, testCreateParams));
14838 testCreateParams.imageOffset = true;
14839 if (testCreateParams.allocationKind != ALLOCATION_KIND_DEDICATED) {
14840 group->addChild(new DepthStencilMSAATestCase(group->getTestContext(), testNameBase + "D_" + getSampleCountCaseName(sample) + "_bind_offset", description, testCreateParams));
14841 }
14842 }
14843 }
14844
14845 if (hasStencil)
14846 {
14847 testCreateParams.copyAspect = VK_IMAGE_ASPECT_STENCIL_BIT;
14848 for (auto sample : samples)
14849 {
14850 testCreateParams.samples = sample;
14851 std::string description = "Copy stencil component with sample count: " + getSampleCountCaseName(sample);
14852 testCreateParams.imageOffset = false;
14853 group->addChild(new DepthStencilMSAATestCase(group->getTestContext(), testNameBase + "S_" + getSampleCountCaseName(sample), description, testCreateParams));
14854 testCreateParams.imageOffset = true;
14855 if (testCreateParams.allocationKind != ALLOCATION_KIND_DEDICATED) {
14856 group->addChild(new DepthStencilMSAATestCase(group->getTestContext(), testNameBase + "S_" + getSampleCountCaseName(sample) + "_bind_offset", description, testCreateParams));
14857 }
14858 }
14859 }
14860 }
14861 if (testCreateParams.copyOptions != DepthStencilMSAA::COPY_WHOLE_IMAGE)
14862 break;
14863 }
14864 if (testCreateParams.copyOptions != DepthStencilMSAA::COPY_WHOLE_IMAGE)
14865 break;
14866 }
14867 }
14868
addDepthStencilCopyMSAATestGroup(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14869 void addDepthStencilCopyMSAATestGroup (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14870 {
14871 // Allocation kind, extension use copy option parameters are defined here. Rest of the parameters are defined in `addDepthStencilCopyMSAATest` function.
14872 DepthStencilMSAA::TestParameters testParams = {};
14873 testParams.allocationKind = allocationKind;
14874 testParams.extensionUse = extensionUse;
14875
14876 testParams.copyOptions = DepthStencilMSAA::COPY_WHOLE_IMAGE;
14877 addTestGroup(group, "whole", "Copy from depth stencil to depth stencil with multi sample tests", addDepthStencilCopyMSAATest, testParams);
14878
14879 testParams.copyOptions = DepthStencilMSAA::COPY_PARTIAL;
14880 addTestGroup(group, "partial", "Copy from depth stencil to depth stencil with multi sample tests", addDepthStencilCopyMSAATest, testParams);
14881
14882 testParams.copyOptions = DepthStencilMSAA::COPY_ARRAY_TO_ARRAY;
14883 addTestGroup(group, "array_to_array", "Copy from array layer to array layer", addDepthStencilCopyMSAATest, testParams);
14884 }
14885
addBufferCopyOffsetTests(tcu::TestCaseGroup * group)14886 void addBufferCopyOffsetTests (tcu::TestCaseGroup* group)
14887 {
14888 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "buffer_to_buffer_with_offset", "Copy from buffer to buffer using different offsets in the source and destination buffers"));
14889
14890 for (deUint32 srcOffset = 0u; srcOffset < BufferOffsetParams::kMaxOffset; ++srcOffset)
14891 for (deUint32 dstOffset = 0u; dstOffset < BufferOffsetParams::kMaxOffset; ++dstOffset)
14892 {
14893 BufferOffsetParams params{srcOffset, dstOffset};
14894 addFunctionCase(subGroup.get(), de::toString(srcOffset) + "_" + de::toString(dstOffset), "", bufferOffsetTest, params);
14895 }
14896
14897 group->addChild(subGroup.release());
14898 }
14899
addResolveImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14900 void addResolveImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14901 {
14902 addTestGroup(group, "whole", "Resolve from image to image (whole)", addResolveImageWholeTests, allocationKind, extensionUse);
14903 addTestGroup(group, "partial", "Resolve from image to image (partial)", addResolveImagePartialTests, allocationKind, extensionUse);
14904 addTestGroup(group, "with_regions", "Resolve from image to image (with regions)", addResolveImageWithRegionsTests, allocationKind, extensionUse);
14905 addTestGroup(group, "whole_copy_before_resolving", "Resolve from image to image (whole copy before resolving)", addResolveImageWholeCopyBeforeResolvingTests, allocationKind, extensionUse);
14906 addTestGroup(group, "whole_copy_before_resolving_no_cab", "Resolve from image to image without using USAGE_COLOR_ATTACHMENT_BIT (whole copy before resolving)", addResolveImageWholeCopyWithoutCabBeforeResolvingTests, allocationKind, extensionUse);
14907 addComputeAndTransferQueueTests(group, allocationKind, extensionUse);
14908 addTestGroup(group, "diff_layout_copy_before_resolving", "Resolve from image to image (whole copy before resolving with different layouts)", addResolveImageWholeCopyDiffLayoutsBeforeResolvingTests, allocationKind, extensionUse);
14909 addTestGroup(group, "layer_copy_before_resolving", "Resolve from image to image (layer copy before resolving)", addResolveImageLayerCopyBeforeResolvingTests, allocationKind, extensionUse);
14910 addTestGroup(group, "copy_with_regions_before_resolving", "Resolve from image to image (region copy before resolving)", addResolveCopyImageWithRegionsTests, allocationKind, extensionUse);
14911 addTestGroup(group, "whole_array_image", "Resolve from image to image (whole array image)", addResolveImageWholeArrayImageTests, allocationKind, extensionUse);
14912 addTestGroup(group, "whole_array_image_one_region", "Resolve from image to image (whole array image with single region)", addResolveImageWholeArrayImageSingleRegionTests, allocationKind, extensionUse);
14913 addTestGroup(group, "diff_image_size", "Resolve from image to image of different size", addResolveImageDiffImageSizeTests, allocationKind, extensionUse);
14914 }
14915
addCopiesAndBlittingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14916 void addCopiesAndBlittingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14917 {
14918 addTestGroup(group, "image_to_image", "Copy from image to image", addImageToImageTests, allocationKind, extensionUse);
14919 addTestGroup(group, "image_to_buffer", "Copy from image to buffer", addImageToBufferTests, allocationKind, extensionUse);
14920 addTestGroup(group, "buffer_to_image", "Copy from buffer to image", addBufferToImageTests, allocationKind, extensionUse);
14921 addTestGroup(group, "buffer_to_depthstencil", "Copy from buffer to depth/Stencil", addBufferToDepthStencilTests, allocationKind, extensionUse);
14922 addTestGroup(group, "buffer_to_buffer", "Copy from buffer to buffer", addBufferToBufferTests, allocationKind, extensionUse);
14923 addTestGroup(group, "blit_image", "Blitting image", addBlittingImageTests, allocationKind, extensionUse);
14924 addTestGroup(group, "resolve_image", "Resolve image", addResolveImageTests, allocationKind, extensionUse);
14925 addTestGroup(group, "depth_stencil_msaa_copy", "Copy depth/stencil with MSAA", addDepthStencilCopyMSAATestGroup, allocationKind, extensionUse);
14926 }
14927
addCoreCopiesAndBlittingTests(tcu::TestCaseGroup * group)14928 void addCoreCopiesAndBlittingTests(tcu::TestCaseGroup* group)
14929 {
14930 addCopiesAndBlittingTests(group, ALLOCATION_KIND_SUBALLOCATED, EXTENSION_USE_NONE);
14931 addBufferCopyOffsetTests(group);
14932 }
14933
14934
addDedicatedAllocationCopiesAndBlittingTests(tcu::TestCaseGroup * group)14935 void addDedicatedAllocationCopiesAndBlittingTests (tcu::TestCaseGroup* group)
14936 {
14937 addCopiesAndBlittingTests(group, ALLOCATION_KIND_DEDICATED, EXTENSION_USE_NONE);
14938 }
14939
14940 #ifndef CTS_USES_VULKANSC
addExtensionCopiesAndBlittingTests(tcu::TestCaseGroup * group)14941 void addExtensionCopiesAndBlittingTests(tcu::TestCaseGroup* group)
14942 {
14943 addCopiesAndBlittingTests(group, ALLOCATION_KIND_DEDICATED, EXTENSION_USE_COPY_COMMANDS2);
14944 }
14945 #endif // CTS_USES_VULKANSC
14946
14947 } // anonymous
14948
createCopiesAndBlittingTests(tcu::TestContext & testCtx)14949 tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx)
14950 {
14951 de::MovePtr<tcu::TestCaseGroup> copiesAndBlittingTests(new tcu::TestCaseGroup(testCtx, "copy_and_blit", "Copies And Blitting Tests"));
14952
14953 copiesAndBlittingTests->addChild(createTestGroup(testCtx, "core", "Core Copies And Blitting Tests", addCoreCopiesAndBlittingTests));
14954 copiesAndBlittingTests->addChild(createTestGroup(testCtx, "dedicated_allocation", "Copies And Blitting Tests For Dedicated Memory Allocation", addDedicatedAllocationCopiesAndBlittingTests));
14955 #ifndef CTS_USES_VULKANSC
14956 copiesAndBlittingTests->addChild(createTestGroup(testCtx, "copy_commands2", "Copies And Blitting Tests using KHR_copy_commands2", addExtensionCopiesAndBlittingTests));
14957 #endif // CTS_USES_VULKANSC
14958
14959 return copiesAndBlittingTests.release();
14960 }
14961
14962 } // api
14963 } // vkt
14964