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 <limits>
66 #include <sstream>
67
68 namespace vkt
69 {
70
71 namespace api
72 {
73
74 namespace
75 {
76
77 enum FillMode
78 {
79 FILL_MODE_GRADIENT = 0,
80 FILL_MODE_WHITE,
81 FILL_MODE_BLACK,
82 FILL_MODE_RED,
83 FILL_MODE_MULTISAMPLE,
84 FILL_MODE_BLUE_RED_X,
85 FILL_MODE_BLUE_RED_Y,
86 FILL_MODE_BLUE_RED_Z,
87
88 FILL_MODE_LAST
89 };
90
91 enum MirrorModeBits
92 {
93 MIRROR_MODE_X = (1<<0),
94 MIRROR_MODE_Y = (1<<1),
95 MIRROR_MODE_Z = (1<<2),
96 MIRROR_MODE_LAST = (1<<3),
97 };
98
99 using MirrorMode = deUint32;
100
101 enum AllocationKind
102 {
103 ALLOCATION_KIND_SUBALLOCATED,
104 ALLOCATION_KIND_DEDICATED,
105 };
106
107 enum ExtensionUse
108 {
109 EXTENSION_USE_NONE,
110 EXTENSION_USE_COPY_COMMANDS2,
111 };
112
113 template <typename Type>
114 class BinaryCompare
115 {
116 public:
operator ()(const Type & a,const Type & b) const117 bool operator() (const Type& a, const Type& b) const
118 {
119 return deMemCmp(&a, &b, sizeof(Type)) < 0;
120 }
121 };
122
123 typedef std::set<vk::VkFormat, BinaryCompare<vk::VkFormat> > FormatSet;
124
125 FormatSet dedicatedAllocationImageToImageFormatsToTestSet;
126 FormatSet dedicatedAllocationBlittingFormatsToTestSet;
127
128 using namespace vk;
129
130 const deInt32 defaultSize = 64;
131 const deInt32 defaultHalfSize = defaultSize / 2;
132 const deInt32 defaultQuarterSize = defaultSize / 4;
133 const deInt32 defaultSixteenthSize = defaultSize / 16;
134 const VkExtent3D defaultExtent = {defaultSize, defaultSize, 1};
135 const VkExtent3D defaultHalfExtent = {defaultHalfSize, defaultHalfSize, 1};
136 const VkExtent3D default1dExtent = {defaultSize, 1, 1};
137 const VkExtent3D default3dExtent = {defaultQuarterSize, defaultQuarterSize, defaultQuarterSize};
138
139 const VkImageSubresourceLayers defaultSourceLayer =
140 {
141 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
142 0u, // deUint32 mipLevel;
143 0u, // deUint32 baseArrayLayer;
144 1u, // deUint32 layerCount;
145 };
146
convertvkImageCopyTovkImageCopy2KHR(VkImageCopy imageCopy)147 VkImageCopy2KHR convertvkImageCopyTovkImageCopy2KHR(VkImageCopy imageCopy)
148 {
149 const VkImageCopy2KHR imageCopy2 =
150 {
151 VK_STRUCTURE_TYPE_IMAGE_COPY_2_KHR, // VkStructureType sType;
152 DE_NULL, // const void* pNext;
153 imageCopy.srcSubresource, // VkImageSubresourceLayers srcSubresource;
154 imageCopy.srcOffset, // VkOffset3D srcOffset;
155 imageCopy.dstSubresource, // VkImageSubresourceLayers dstSubresource;
156 imageCopy.dstOffset, // VkOffset3D dstOffset;
157 imageCopy.extent // VkExtent3D extent;
158 };
159 return imageCopy2;
160 }
convertvkBufferCopyTovkBufferCopy2KHR(VkBufferCopy bufferCopy)161 VkBufferCopy2KHR convertvkBufferCopyTovkBufferCopy2KHR(VkBufferCopy bufferCopy)
162 {
163 const VkBufferCopy2KHR bufferCopy2 =
164 {
165 VK_STRUCTURE_TYPE_BUFFER_COPY_2_KHR, // VkStructureType sType;
166 DE_NULL, // const void* pNext;
167 bufferCopy.srcOffset, // VkDeviceSize srcOffset;
168 bufferCopy.dstOffset, // VkDeviceSize dstOffset;
169 bufferCopy.size, // VkDeviceSize size;
170 };
171 return bufferCopy2;
172 }
173
convertvkBufferImageCopyTovkBufferImageCopy2KHR(VkBufferImageCopy bufferImageCopy)174 VkBufferImageCopy2KHR convertvkBufferImageCopyTovkBufferImageCopy2KHR(VkBufferImageCopy bufferImageCopy)
175 {
176 const VkBufferImageCopy2KHR bufferImageCopy2 =
177 {
178 VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2_KHR, // VkStructureType sType;
179 DE_NULL, // const void* pNext;
180 bufferImageCopy.bufferOffset, // VkDeviceSize bufferOffset;
181 bufferImageCopy.bufferRowLength, // uint32_t bufferRowLength;
182 bufferImageCopy.bufferImageHeight, // uint32_t bufferImageHeight;
183 bufferImageCopy.imageSubresource, // VkImageSubresourceLayers imageSubresource;
184 bufferImageCopy.imageOffset, // VkOffset3D imageOffset;
185 bufferImageCopy.imageExtent // VkExtent3D imageExtent;
186 };
187 return bufferImageCopy2;
188 }
189
convertvkImageBlitTovkImageBlit2KHR(VkImageBlit imageBlit)190 VkImageBlit2KHR convertvkImageBlitTovkImageBlit2KHR(VkImageBlit imageBlit)
191 {
192 const VkImageBlit2KHR imageBlit2 =
193 {
194 VK_STRUCTURE_TYPE_IMAGE_BLIT_2_KHR, // VkStructureType sType;
195 DE_NULL, // const void* pNext;
196 imageBlit.srcSubresource, // VkImageSubresourceLayers srcSubresource;
197 { // VkOffset3D srcOffsets[2];
198 {
199 imageBlit.srcOffsets[0].x, // VkOffset3D srcOffsets[0].x;
200 imageBlit.srcOffsets[0].y, // VkOffset3D srcOffsets[0].y;
201 imageBlit.srcOffsets[0].z // VkOffset3D srcOffsets[0].z;
202 },
203 {
204 imageBlit.srcOffsets[1].x, // VkOffset3D srcOffsets[1].x;
205 imageBlit.srcOffsets[1].y, // VkOffset3D srcOffsets[1].y;
206 imageBlit.srcOffsets[1].z // VkOffset3D srcOffsets[1].z;
207 }
208 },
209 imageBlit.dstSubresource, // VkImageSubresourceLayers dstSubresource;
210 { // VkOffset3D srcOffsets[2];
211 {
212 imageBlit.dstOffsets[0].x, // VkOffset3D dstOffsets[0].x;
213 imageBlit.dstOffsets[0].y, // VkOffset3D dstOffsets[0].y;
214 imageBlit.dstOffsets[0].z // VkOffset3D dstOffsets[0].z;
215 },
216 {
217 imageBlit.dstOffsets[1].x, // VkOffset3D dstOffsets[1].x;
218 imageBlit.dstOffsets[1].y, // VkOffset3D dstOffsets[1].y;
219 imageBlit.dstOffsets[1].z // VkOffset3D dstOffsets[1].z;
220 }
221 }
222 };
223 return imageBlit2;
224 }
225
convertvkImageResolveTovkImageResolve2KHR(VkImageResolve imageResolve)226 VkImageResolve2KHR convertvkImageResolveTovkImageResolve2KHR(VkImageResolve imageResolve)
227 {
228 const VkImageResolve2KHR imageResolve2 =
229 {
230 VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR, // VkStructureType sType;
231 DE_NULL, // const void* pNext;
232 imageResolve.srcSubresource, // VkImageSubresourceLayers srcSubresource;
233 imageResolve.srcOffset, // VkOffset3D srcOffset;
234 imageResolve.dstSubresource, // VkImageSubresourceLayers dstSubresource;
235 imageResolve.dstOffset, // VkOffset3D dstOffset;
236 imageResolve.extent // VkExtent3D extent;
237 };
238 return imageResolve2;
239 }
240
getAspectFlags(tcu::TextureFormat format)241 VkImageAspectFlags getAspectFlags (tcu::TextureFormat format)
242 {
243 VkImageAspectFlags aspectFlag = 0;
244 aspectFlag |= (tcu::hasDepthComponent(format.order)? VK_IMAGE_ASPECT_DEPTH_BIT : 0);
245 aspectFlag |= (tcu::hasStencilComponent(format.order)? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
246
247 if (!aspectFlag)
248 aspectFlag = VK_IMAGE_ASPECT_COLOR_BIT;
249
250 return aspectFlag;
251 }
252
getAspectFlags(VkFormat format)253 VkImageAspectFlags getAspectFlags (VkFormat format)
254 {
255 if (isCompressedFormat(format))
256 return VK_IMAGE_ASPECT_COLOR_BIT;
257 else
258 return getAspectFlags(mapVkFormat(format));
259 }
260
getSizeCompatibleTcuTextureFormat(VkFormat format)261 tcu::TextureFormat getSizeCompatibleTcuTextureFormat (VkFormat format)
262 {
263 if (isCompressedFormat(format))
264 return (getBlockSizeInBytes(format) == 8) ? mapVkFormat(VK_FORMAT_R16G16B16A16_UINT) : mapVkFormat(VK_FORMAT_R32G32B32A32_UINT);
265 else
266 return mapVkFormat(format);
267 }
268
269 // This is effectively same as vk::isFloatFormat(mapTextureFormat(format))
270 // except that it supports some formats that are not mappable to VkFormat.
271 // When we are checking combined depth and stencil formats, each aspect is
272 // checked separately, and in some cases we construct PBA with a format that
273 // is not mappable to VkFormat.
isFloatFormat(tcu::TextureFormat format)274 bool isFloatFormat (tcu::TextureFormat format)
275 {
276 return tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
277 }
278
279 union CopyRegion
280 {
281 VkBufferCopy bufferCopy;
282 VkImageCopy imageCopy;
283 VkBufferImageCopy bufferImageCopy;
284 VkImageBlit imageBlit;
285 VkImageResolve imageResolve;
286 };
287
288 struct ImageParms
289 {
290 VkImageType imageType;
291 VkFormat format;
292 VkExtent3D extent;
293 VkImageTiling tiling;
294 VkImageLayout operationLayout;
295 VkImageCreateFlags createFlags;
296 FillMode fillMode;
297 };
298
299 struct TestParams
300 {
301 union Data
302 {
303 struct Buffer
304 {
305 VkDeviceSize size;
306 } buffer;
307
308 ImageParms image;
309 } src, dst;
310
311 std::vector<CopyRegion> regions;
312
313 union
314 {
315 VkFilter filter;
316 VkSampleCountFlagBits samples;
317 };
318
319 AllocationKind allocationKind;
320 ExtensionUse extensionUse;
321 deUint32 mipLevels;
322 deBool singleCommand;
323 deUint32 barrierCount;
324 deBool separateDepthStencilLayouts;
325 deBool clearDestination;
326 deBool imageOffset;
327
TestParamsvkt::api::__anon4493ca420111::TestParams328 TestParams (void)
329 {
330 allocationKind = ALLOCATION_KIND_DEDICATED;
331 extensionUse = EXTENSION_USE_NONE;
332 mipLevels = 1u;
333 singleCommand = DE_TRUE;
334 barrierCount = 1u;
335 separateDepthStencilLayouts = DE_FALSE;
336 src.image.createFlags = VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM;
337 dst.image.createFlags = VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM;
338 src.image.fillMode = FILL_MODE_GRADIENT;
339 dst.image.fillMode = FILL_MODE_WHITE;
340 clearDestination = DE_FALSE;
341 samples = VK_SAMPLE_COUNT_1_BIT;
342 imageOffset = false;
343 }
344 };
345
allocateBuffer(const InstanceInterface & vki,const DeviceInterface & vkd,const VkPhysicalDevice & physDevice,const VkDevice device,const VkBuffer & buffer,const MemoryRequirement requirement,Allocator & allocator,AllocationKind allocationKind)346 de::MovePtr<Allocation> allocateBuffer (const InstanceInterface& vki,
347 const DeviceInterface& vkd,
348 const VkPhysicalDevice& physDevice,
349 const VkDevice device,
350 const VkBuffer& buffer,
351 const MemoryRequirement requirement,
352 Allocator& allocator,
353 AllocationKind allocationKind)
354 {
355 switch (allocationKind)
356 {
357 case ALLOCATION_KIND_SUBALLOCATED:
358 {
359 const VkMemoryRequirements memoryRequirements = getBufferMemoryRequirements(vkd, device, buffer);
360
361 return allocator.allocate(memoryRequirements, requirement);
362 }
363
364 case ALLOCATION_KIND_DEDICATED:
365 {
366 return allocateDedicated(vki, vkd, physDevice, device, buffer, requirement);
367 }
368
369 default:
370 {
371 TCU_THROW(InternalError, "Invalid allocation kind");
372 }
373 }
374 }
375
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)376 de::MovePtr<Allocation> allocateImage (const InstanceInterface& vki,
377 const DeviceInterface& vkd,
378 const VkPhysicalDevice& physDevice,
379 const VkDevice device,
380 const VkImage& image,
381 const MemoryRequirement requirement,
382 Allocator& allocator,
383 AllocationKind allocationKind,
384 const deUint32 offset)
385 {
386 switch (allocationKind)
387 {
388 case ALLOCATION_KIND_SUBALLOCATED:
389 {
390 VkMemoryRequirements memoryRequirements = getImageMemoryRequirements(vkd, device, image);
391 memoryRequirements.size += offset;
392
393 return allocator.allocate(memoryRequirements, requirement);
394 }
395
396 case ALLOCATION_KIND_DEDICATED:
397 {
398 VkMemoryRequirements memoryRequirements = getImageMemoryRequirements(vkd, device, image);
399 memoryRequirements.size += offset;
400
401 const VkMemoryDedicatedAllocateInfo dedicatedAllocationInfo =
402 {
403 VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, // VkStructureType sType
404 DE_NULL, // const void* pNext
405 image, // VkImage image
406 DE_NULL // VkBuffer buffer
407 };
408
409 return allocateExtended(vki, vkd, physDevice, device, memoryRequirements, requirement, &dedicatedAllocationInfo);
410 }
411
412 default:
413 {
414 TCU_THROW(InternalError, "Invalid allocation kind");
415 }
416 }
417 }
418
419
getArraySize(const ImageParms & parms)420 inline deUint32 getArraySize(const ImageParms& parms)
421 {
422 return (parms.imageType != VK_IMAGE_TYPE_3D) ? parms.extent.depth : 1u;
423 }
424
getCreateFlags(const ImageParms & parms)425 inline VkImageCreateFlags getCreateFlags(const ImageParms& parms)
426 {
427 if (parms.createFlags == VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM)
428 return parms.imageType == VK_IMAGE_TYPE_2D && parms.extent.depth % 6 == 0 ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0;
429 else
430 return parms.createFlags;
431 }
432
getExtent3D(const ImageParms & parms,deUint32 mipLevel=0u)433 inline VkExtent3D getExtent3D(const ImageParms& parms, deUint32 mipLevel = 0u)
434 {
435 const bool isCompressed = isCompressedFormat(parms.format);
436 const deUint32 blockWidth = (isCompressed) ? getBlockWidth(parms.format) : 1u;
437 const deUint32 blockHeight = (isCompressed) ? getBlockHeight(parms.format) : 1u;
438
439 if (isCompressed && mipLevel != 0u)
440 DE_FATAL("Not implemented");
441
442 const VkExtent3D extent =
443 {
444 (parms.extent.width >> mipLevel) * blockWidth,
445 (parms.imageType != VK_IMAGE_TYPE_1D) ? ((parms.extent.height >> mipLevel) * blockHeight) : 1u,
446 (parms.imageType == VK_IMAGE_TYPE_3D) ? parms.extent.depth : 1u,
447 };
448 return extent;
449 }
450
mapCombinedToDepthTransferFormat(const tcu::TextureFormat & combinedFormat)451 const tcu::TextureFormat mapCombinedToDepthTransferFormat (const tcu::TextureFormat& combinedFormat)
452 {
453 tcu::TextureFormat format;
454 switch (combinedFormat.type)
455 {
456 case tcu::TextureFormat::UNORM_INT16:
457 case tcu::TextureFormat::UNSIGNED_INT_16_8_8:
458 format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
459 break;
460 case tcu::TextureFormat::UNSIGNED_INT_24_8_REV:
461 format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNSIGNED_INT_24_8_REV);
462 break;
463 case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
464 case tcu::TextureFormat::FLOAT:
465 format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT);
466 break;
467 default:
468 DE_ASSERT(false);
469 break;
470 }
471 return format;
472 }
473
474 class CopiesAndBlittingTestInstance : public vkt::TestInstance
475 {
476 public:
477 CopiesAndBlittingTestInstance (Context& context,
478 TestParams testParams);
479 virtual tcu::TestStatus iterate (void) = 0;
480
481 protected:
482 const TestParams m_params;
483
484 VkDevice m_device;
485 VkQueue m_queue;
486 Allocator* m_allocator;
487 Move<VkCommandPool> m_cmdPool;
488 Move<VkCommandBuffer> m_cmdBuffer;
489 de::MovePtr<tcu::TextureLevel> m_sourceTextureLevel;
490 de::MovePtr<tcu::TextureLevel> m_destinationTextureLevel;
491 de::MovePtr<tcu::TextureLevel> m_expectedTextureLevel[16];
492
493 void generateBuffer (tcu::PixelBufferAccess buffer, int width, int height, int depth = 1, FillMode = FILL_MODE_GRADIENT);
494 virtual void generateExpectedResult (void);
495 void uploadBuffer (const tcu::ConstPixelBufferAccess& bufferAccess, const Allocation& bufferAlloc);
496 void uploadImage (const tcu::ConstPixelBufferAccess& src, VkImage dst, const ImageParms& parms, const deUint32 mipLevels = 1u);
497 virtual tcu::TestStatus checkTestResult (tcu::ConstPixelBufferAccess result);
498 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u) = 0;
calculateSize(tcu::ConstPixelBufferAccess src) const499 deUint32 calculateSize (tcu::ConstPixelBufferAccess src) const
500 {
501 return src.getWidth() * src.getHeight() * src.getDepth() * tcu::getPixelSize(src.getFormat());
502 }
503
504 de::MovePtr<tcu::TextureLevel> readImage (vk::VkImage image,
505 const ImageParms& imageParms,
506 const deUint32 mipLevel = 0u);
507
508 private:
509 void uploadImageAspect (const tcu::ConstPixelBufferAccess& src,
510 const VkImage& dst,
511 const ImageParms& parms,
512 const deUint32 mipLevels = 1u);
513 void readImageAspect (vk::VkImage src,
514 const tcu::PixelBufferAccess& dst,
515 const ImageParms& parms,
516 const deUint32 mipLevel = 0u);
517 };
518
CopiesAndBlittingTestInstance(Context & context,TestParams testParams)519 CopiesAndBlittingTestInstance::CopiesAndBlittingTestInstance (Context& context, TestParams testParams)
520 : vkt::TestInstance (context)
521 , m_params (testParams)
522 {
523 // Store default device, queue and allocator. Some tests override these with custom device and queue.
524 m_device = context.getDevice();
525 m_queue = context.getUniversalQueue();
526 m_allocator = &context.getDefaultAllocator();
527 const DeviceInterface& vk = context.getDeviceInterface();
528 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
529
530 // Create command pool
531 m_cmdPool = createCommandPool(vk, m_device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
532
533 // Create command buffer
534 m_cmdBuffer = allocateCommandBuffer(vk, m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
535 }
536
generateBuffer(tcu::PixelBufferAccess buffer,int width,int height,int depth,FillMode mode)537 void CopiesAndBlittingTestInstance::generateBuffer (tcu::PixelBufferAccess buffer, int width, int height, int depth, FillMode mode)
538 {
539 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(buffer.getFormat().type);
540 tcu::Vec4 maxValue (1.0f);
541
542 if (buffer.getFormat().order == tcu::TextureFormat::S)
543 {
544 // Stencil-only is stored in the first component. Stencil is always 8 bits.
545 maxValue.x() = 1 << 8;
546 }
547 else if (buffer.getFormat().order == tcu::TextureFormat::DS)
548 {
549 // In a combined format, fillWithComponentGradients expects stencil in the fourth component.
550 maxValue.w() = 1 << 8;
551 }
552 else if (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
553 {
554 // The tcu::Vectors we use as pixels are 32-bit, so clamp to that.
555 const tcu::IVec4 bits = tcu::min(tcu::getTextureFormatBitDepth(buffer.getFormat()), tcu::IVec4(32));
556 const int signBit = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? 1 : 0);
557
558 for (int i = 0; i < 4; ++i)
559 {
560 if (bits[i] != 0)
561 maxValue[i] = static_cast<float>((deUint64(1) << (bits[i] - signBit)) - 1);
562 }
563 }
564
565 if (mode == FILL_MODE_GRADIENT)
566 {
567 tcu::fillWithComponentGradients2(buffer, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), maxValue);
568 return;
569 }
570
571 const tcu::Vec4 redColor (maxValue.x(), 0.0, 0.0, maxValue.w());
572 const tcu::Vec4 greenColor (0.0, maxValue.y(), 0.0, maxValue.w());
573 const tcu::Vec4 blueColor (0.0, 0.0, maxValue.z(), maxValue.w());
574 const tcu::Vec4 whiteColor (maxValue.x(), maxValue.y(), maxValue.z(), maxValue.w());
575 const tcu::Vec4 blackColor (0.0f, 0.0f, 0.0f, 0.0f);
576
577 for (int z = 0; z < depth; ++z)
578 for (int y = 0; y < height; ++y)
579 for (int x = 0; x < width; ++x)
580 {
581 switch (mode)
582 {
583 case FILL_MODE_WHITE:
584 if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
585 {
586 buffer.setPixDepth(1.0f, x, y, z);
587 if (tcu::hasStencilComponent(buffer.getFormat().order))
588 buffer.setPixStencil(255, x, y, z);
589 }
590 else
591 buffer.setPixel(whiteColor, x, y, z);
592 break;
593
594 case FILL_MODE_BLACK:
595 if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
596 {
597 buffer.setPixDepth(0.0f, x, y, z);
598 if (tcu::hasStencilComponent(buffer.getFormat().order))
599 buffer.setPixStencil(0, x, y, z);
600 }
601 else
602 buffer.setPixel(blackColor, x, y, z);
603 break;
604
605 case FILL_MODE_RED:
606 if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
607 {
608 buffer.setPixDepth(redColor[0], x, y, z);
609 if (tcu::hasStencilComponent(buffer.getFormat().order))
610 buffer.setPixStencil((int)redColor[3], x, y, z);
611 }
612 else
613 buffer.setPixel(redColor, x, y, z);
614 break;
615
616 case FILL_MODE_BLUE_RED_X:
617 case FILL_MODE_BLUE_RED_Y:
618 case FILL_MODE_BLUE_RED_Z:
619 bool useBlue;
620 switch (mode)
621 {
622 case FILL_MODE_BLUE_RED_X: useBlue = (x & 1); break;
623 case FILL_MODE_BLUE_RED_Y: useBlue = (y & 1); break;
624 case FILL_MODE_BLUE_RED_Z: useBlue = (z & 1); break;
625 default: DE_ASSERT(false); break;
626 }
627 if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
628 {
629 buffer.setPixDepth((useBlue ? blueColor[0] : redColor[0]), x, y, z);
630 if (tcu::hasStencilComponent(buffer.getFormat().order))
631 buffer.setPixStencil((useBlue ? (int) blueColor[3] : (int)redColor[3]), x, y, z);
632 }
633 else
634 buffer.setPixel((useBlue ? blueColor : redColor), x, y, z);
635 break;
636
637 case FILL_MODE_MULTISAMPLE:
638 {
639 float xScaled = static_cast<float>(x) / static_cast<float>(width);
640 float yScaled = static_cast<float>(y) / static_cast<float>(height);
641 buffer.setPixel((xScaled == yScaled) ? tcu::Vec4(0.0, 0.5, 0.5, 1.0) : ((xScaled > yScaled) ? greenColor : blueColor), x, y, z);
642 break;
643 }
644
645 default:
646 break;
647 }
648 }
649 }
650
uploadBuffer(const tcu::ConstPixelBufferAccess & bufferAccess,const Allocation & bufferAlloc)651 void CopiesAndBlittingTestInstance::uploadBuffer (const tcu::ConstPixelBufferAccess& bufferAccess, const Allocation& bufferAlloc)
652 {
653 const DeviceInterface& vk = m_context.getDeviceInterface();
654 const deUint32 bufferSize = calculateSize(bufferAccess);
655
656 // Write buffer data
657 deMemcpy(bufferAlloc.getHostPtr(), bufferAccess.getDataPtr(), bufferSize);
658 flushAlloc(vk, m_device, bufferAlloc);
659 }
660
uploadImageAspect(const tcu::ConstPixelBufferAccess & imageAccess,const VkImage & image,const ImageParms & parms,const deUint32 mipLevels)661 void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBufferAccess& imageAccess, const VkImage& image, const ImageParms& parms, const deUint32 mipLevels)
662 {
663 const InstanceInterface& vki = m_context.getInstanceInterface();
664 const DeviceInterface& vk = m_context.getDeviceInterface();
665 const VkPhysicalDevice vkPhysDevice = m_context.getPhysicalDevice();
666 const VkDevice vkDevice = m_device;
667 const VkQueue queue = m_queue;
668 Allocator& memAlloc = *m_allocator;
669 Move<VkBuffer> buffer;
670 const deUint32 bufferSize = calculateSize(imageAccess);
671 de::MovePtr<Allocation> bufferAlloc;
672 const deUint32 arraySize = getArraySize(parms);
673 const VkExtent3D imageExtent = getExtent3D(parms);
674 std::vector <VkBufferImageCopy> copyRegions;
675
676 // Create source buffer
677 {
678 const VkBufferCreateInfo bufferParams =
679 {
680 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
681 DE_NULL, // const void* pNext;
682 0u, // VkBufferCreateFlags flags;
683 bufferSize, // VkDeviceSize size;
684 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage;
685 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
686 0u, // deUint32 queueFamilyIndexCount;
687 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
688 };
689
690 buffer = createBuffer(vk, vkDevice, &bufferParams);
691 bufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *buffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
692 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
693 }
694
695 // Barriers for copying buffer to image
696 const VkBufferMemoryBarrier preBufferBarrier =
697 {
698 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
699 DE_NULL, // const void* pNext;
700 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask;
701 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
702 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
703 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
704 *buffer, // VkBuffer buffer;
705 0u, // VkDeviceSize offset;
706 bufferSize // VkDeviceSize size;
707 };
708
709 const VkImageAspectFlags formatAspect = (m_params.separateDepthStencilLayouts) ? getAspectFlags(imageAccess.getFormat()) : getAspectFlags(parms.format);
710 const bool skipPreImageBarrier = (m_params.separateDepthStencilLayouts) ? false : ((formatAspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) &&
711 getAspectFlags(imageAccess.getFormat()) == VK_IMAGE_ASPECT_STENCIL_BIT));
712
713 const VkImageMemoryBarrier preImageBarrier =
714 {
715 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
716 DE_NULL, // const void* pNext;
717 0u, // VkAccessFlags srcAccessMask;
718 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
719 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
720 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
721 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
722 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
723 image, // VkImage image;
724 { // VkImageSubresourceRange subresourceRange;
725 formatAspect, // VkImageAspectFlags aspect;
726 0u, // deUint32 baseMipLevel;
727 mipLevels, // deUint32 mipLevels;
728 0u, // deUint32 baseArraySlice;
729 arraySize, // deUint32 arraySize;
730 }
731 };
732
733 const VkImageMemoryBarrier postImageBarrier =
734 {
735 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
736 DE_NULL, // const void* pNext;
737 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
738 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
739 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
740 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
741 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
742 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
743 image, // VkImage image;
744 { // VkImageSubresourceRange subresourceRange;
745 formatAspect, // VkImageAspectFlags aspect;
746 0u, // deUint32 baseMipLevel;
747 mipLevels, // deUint32 mipLevels;
748 0u, // deUint32 baseArraySlice;
749 arraySize, // deUint32 arraySize;
750 }
751 };
752
753 for (deUint32 mipLevelNdx = 0; mipLevelNdx < mipLevels; mipLevelNdx++)
754 {
755 const VkExtent3D copyExtent =
756 {
757 imageExtent.width >> mipLevelNdx,
758 imageExtent.height >> mipLevelNdx,
759 imageExtent.depth
760 };
761
762 const bool isCompressed = isCompressedFormat(parms.format);
763 const deUint32 blockWidth = (isCompressed) ? getBlockWidth(parms.format) : 1u;
764 const deUint32 blockHeight = (isCompressed) ? getBlockHeight(parms.format) : 1u;
765 deUint32 rowLength = ((copyExtent.width + blockWidth-1) / blockWidth) * blockWidth;
766 deUint32 imageHeight = ((copyExtent.height + blockHeight-1) / blockHeight) * blockHeight;
767
768 const VkBufferImageCopy copyRegion =
769 {
770 0u, // VkDeviceSize bufferOffset;
771 rowLength, // deUint32 bufferRowLength;
772 imageHeight, // deUint32 bufferImageHeight;
773 {
774 getAspectFlags(imageAccess.getFormat()), // VkImageAspectFlags aspect;
775 mipLevelNdx, // deUint32 mipLevel;
776 0u, // deUint32 baseArrayLayer;
777 arraySize, // deUint32 layerCount;
778 }, // VkImageSubresourceLayers imageSubresource;
779 { 0, 0, 0 }, // VkOffset3D imageOffset;
780 copyExtent // VkExtent3D imageExtent;
781 };
782
783 copyRegions.push_back(copyRegion);
784 }
785
786 // Write buffer data
787 deMemcpy(bufferAlloc->getHostPtr(), imageAccess.getDataPtr(), bufferSize);
788 flushAlloc(vk, vkDevice, *bufferAlloc);
789
790 // Copy buffer to image
791 beginCommandBuffer(vk, *m_cmdBuffer);
792 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL,
793 1, &preBufferBarrier, (skipPreImageBarrier ? 0 : 1), (skipPreImageBarrier ? DE_NULL : &preImageBarrier));
794 vk.cmdCopyBufferToImage(*m_cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegions.size(), ©Regions[0]);
795 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);
796 endCommandBuffer(vk, *m_cmdBuffer);
797
798 submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
799 m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
800 }
801
uploadImage(const tcu::ConstPixelBufferAccess & src,VkImage dst,const ImageParms & parms,const deUint32 mipLevels)802 void CopiesAndBlittingTestInstance::uploadImage (const tcu::ConstPixelBufferAccess& src, VkImage dst, const ImageParms& parms, const deUint32 mipLevels)
803 {
804 if (tcu::isCombinedDepthStencilType(src.getFormat().type))
805 {
806 if (tcu::hasDepthComponent(src.getFormat().order))
807 {
808 tcu::TextureLevel depthTexture (mapCombinedToDepthTransferFormat(src.getFormat()), src.getWidth(), src.getHeight(), src.getDepth());
809 tcu::copy(depthTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH));
810 uploadImageAspect(depthTexture.getAccess(), dst, parms, mipLevels);
811 }
812
813 if (tcu::hasStencilComponent(src.getFormat().order))
814 {
815 tcu::TextureLevel stencilTexture (tcu::getEffectiveDepthStencilTextureFormat(src.getFormat(), tcu::Sampler::MODE_STENCIL), src.getWidth(), src.getHeight(), src.getDepth());
816 tcu::copy(stencilTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL));
817 uploadImageAspect(stencilTexture.getAccess(), dst, parms, mipLevels);
818 }
819 }
820 else
821 uploadImageAspect(src, dst, parms, mipLevels);
822 }
823
checkTestResult(tcu::ConstPixelBufferAccess result)824 tcu::TestStatus CopiesAndBlittingTestInstance::checkTestResult (tcu::ConstPixelBufferAccess result)
825 {
826 const tcu::ConstPixelBufferAccess expected = m_expectedTextureLevel[0]->getAccess();
827
828 if (isFloatFormat(result.getFormat()))
829 {
830 const tcu::Vec4 threshold (0.0f);
831 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
832 return tcu::TestStatus::fail("CopiesAndBlitting test");
833 }
834 else
835 {
836 const tcu::UVec4 threshold (0u);
837 if (tcu::hasDepthComponent(result.getFormat().order) || tcu::hasStencilComponent(result.getFormat().order))
838 {
839 if (!tcu::dsThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, 0.1f, tcu::COMPARE_LOG_RESULT))
840 return tcu::TestStatus::fail("CopiesAndBlitting test");
841 }
842 else
843 {
844 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
845 return tcu::TestStatus::fail("CopiesAndBlitting test");
846 }
847 }
848
849 return tcu::TestStatus::pass("CopiesAndBlitting test");
850 }
851
generateExpectedResult(void)852 void CopiesAndBlittingTestInstance::generateExpectedResult (void)
853 {
854 const tcu::ConstPixelBufferAccess src = m_sourceTextureLevel->getAccess();
855 const tcu::ConstPixelBufferAccess dst = m_destinationTextureLevel->getAccess();
856
857 m_expectedTextureLevel[0] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
858 tcu::copy(m_expectedTextureLevel[0]->getAccess(), dst);
859
860 for (deUint32 i = 0; i < m_params.regions.size(); i++)
861 copyRegionToTextureLevel(src, m_expectedTextureLevel[0]->getAccess(), m_params.regions[i]);
862 }
863
readImageAspect(vk::VkImage image,const tcu::PixelBufferAccess & dst,const ImageParms & imageParms,const deUint32 mipLevel)864 void CopiesAndBlittingTestInstance::readImageAspect (vk::VkImage image,
865 const tcu::PixelBufferAccess& dst,
866 const ImageParms& imageParms,
867 const deUint32 mipLevel)
868 {
869 const InstanceInterface& vki = m_context.getInstanceInterface();
870 const DeviceInterface& vk = m_context.getDeviceInterface();
871 const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
872 const VkDevice device = m_device;
873 const VkQueue queue = m_queue;
874 Allocator& allocator = *m_allocator;
875
876 Move<VkBuffer> buffer;
877 de::MovePtr<Allocation> bufferAlloc;
878 const VkDeviceSize pixelDataSize = calculateSize(dst);
879 const VkExtent3D imageExtent = getExtent3D(imageParms, mipLevel);
880
881 // Create destination buffer
882 {
883 const VkBufferCreateInfo bufferParams =
884 {
885 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
886 DE_NULL, // const void* pNext;
887 0u, // VkBufferCreateFlags flags;
888 pixelDataSize, // VkDeviceSize size;
889 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
890 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
891 0u, // deUint32 queueFamilyIndexCount;
892 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
893 };
894
895 buffer = createBuffer(vk, device, &bufferParams);
896 bufferAlloc = allocateBuffer(vki, vk, physDevice, device, *buffer, MemoryRequirement::HostVisible, allocator, m_params.allocationKind);
897 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
898
899 deMemset(bufferAlloc->getHostPtr(), 0, static_cast<size_t>(pixelDataSize));
900 flushAlloc(vk, device, *bufferAlloc);
901 }
902
903 // Barriers for copying image to buffer
904 const VkImageAspectFlags formatAspect = getAspectFlags(imageParms.format);
905 const VkImageMemoryBarrier imageBarrier =
906 {
907 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
908 DE_NULL, // const void* pNext;
909 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
910 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
911 imageParms.operationLayout, // VkImageLayout oldLayout;
912 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout;
913 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
914 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
915 image, // VkImage image;
916 { // VkImageSubresourceRange subresourceRange;
917 formatAspect, // VkImageAspectFlags aspectMask;
918 mipLevel, // deUint32 baseMipLevel;
919 1u, // deUint32 mipLevels;
920 0u, // deUint32 baseArraySlice;
921 getArraySize(imageParms)// deUint32 arraySize;
922 }
923 };
924
925 const VkBufferMemoryBarrier bufferBarrier =
926 {
927 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
928 DE_NULL, // const void* pNext;
929 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
930 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
931 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
932 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
933 *buffer, // VkBuffer buffer;
934 0u, // VkDeviceSize offset;
935 pixelDataSize // VkDeviceSize size;
936 };
937
938 const VkImageMemoryBarrier postImageBarrier =
939 {
940 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
941 DE_NULL, // const void* pNext;
942 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags srcAccessMask;
943 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
944 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout oldLayout;
945 imageParms.operationLayout, // VkImageLayout newLayout;
946 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
947 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
948 image, // VkImage image;
949 {
950 formatAspect, // VkImageAspectFlags aspectMask;
951 mipLevel, // deUint32 baseMipLevel;
952 1u, // deUint32 mipLevels;
953 0u, // deUint32 baseArraySlice;
954 getArraySize(imageParms) // deUint32 arraySize;
955 } // VkImageSubresourceRange subresourceRange;
956 };
957
958 // Copy image to buffer
959 const bool isCompressed = isCompressedFormat(imageParms.format);
960 const deUint32 blockWidth = (isCompressed) ? getBlockWidth(imageParms.format) : 1u;
961 const deUint32 blockHeight = (isCompressed) ? getBlockHeight(imageParms.format) : 1u;
962 deUint32 rowLength = ((imageExtent.width + blockWidth-1) / blockWidth) * blockWidth;
963 deUint32 imageHeight = ((imageExtent.height + blockHeight-1) / blockHeight) * blockHeight;
964
965 // Copy image to buffer - note that there are cases where m_params.dst.image.format is not the same as dst.getFormat()
966 const VkImageAspectFlags aspect = isCompressedFormat(m_params.dst.image.format) ?
967 static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_COLOR_BIT) : getAspectFlags(dst.getFormat());
968 const VkBufferImageCopy copyRegion =
969 {
970 0u, // VkDeviceSize bufferOffset;
971 rowLength, // deUint32 bufferRowLength;
972 imageHeight, // deUint32 bufferImageHeight;
973 {
974 aspect, // VkImageAspectFlags aspect;
975 mipLevel, // deUint32 mipLevel;
976 0u, // deUint32 baseArrayLayer;
977 getArraySize(imageParms), // deUint32 layerCount;
978 }, // VkImageSubresourceLayers imageSubresource;
979 { 0, 0, 0 }, // VkOffset3D imageOffset;
980 imageExtent // VkExtent3D imageExtent;
981 };
982
983 beginCommandBuffer(vk, *m_cmdBuffer);
984 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);
985 vk.cmdCopyImageToBuffer(*m_cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, ©Region);
986 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);
987 endCommandBuffer(vk, *m_cmdBuffer);
988
989 submitCommandsAndWait(vk, device, queue, *m_cmdBuffer);
990 m_context.resetCommandPoolForVKSC(device, *m_cmdPool);
991
992 // Read buffer data
993 invalidateAlloc(vk, device, *bufferAlloc);
994 tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferAlloc->getHostPtr()));
995 }
996
readImage(vk::VkImage image,const ImageParms & parms,const deUint32 mipLevel)997 de::MovePtr<tcu::TextureLevel> CopiesAndBlittingTestInstance::readImage (vk::VkImage image,
998 const ImageParms& parms,
999 const deUint32 mipLevel)
1000 {
1001 const tcu::TextureFormat imageFormat = getSizeCompatibleTcuTextureFormat(parms.format);
1002 de::MovePtr<tcu::TextureLevel> resultLevel (new tcu::TextureLevel(imageFormat, parms.extent.width >> mipLevel, parms.extent.height >> mipLevel, parms.extent.depth));
1003
1004 if (tcu::isCombinedDepthStencilType(imageFormat.type))
1005 {
1006 if (tcu::hasDepthComponent(imageFormat.order))
1007 {
1008 tcu::TextureLevel depthTexture (mapCombinedToDepthTransferFormat(imageFormat), parms.extent.width >> mipLevel, parms.extent.height >> mipLevel, parms.extent.depth);
1009 readImageAspect(image, depthTexture.getAccess(), parms, mipLevel);
1010 tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_DEPTH), depthTexture.getAccess());
1011 }
1012
1013 if (tcu::hasStencilComponent(imageFormat.order))
1014 {
1015 tcu::TextureLevel stencilTexture (tcu::getEffectiveDepthStencilTextureFormat(imageFormat, tcu::Sampler::MODE_STENCIL), parms.extent.width >> mipLevel, parms.extent.height >> mipLevel, parms.extent.depth);
1016 readImageAspect(image, stencilTexture.getAccess(), parms, mipLevel);
1017 tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_STENCIL), stencilTexture.getAccess());
1018 }
1019 }
1020 else
1021 readImageAspect(image, resultLevel->getAccess(), parms, mipLevel);
1022
1023 return resultLevel;
1024 }
1025
1026 // Copy from image to image.
1027
1028 class CopyImageToImage : public CopiesAndBlittingTestInstance
1029 {
1030 public:
1031 CopyImageToImage (Context& context,
1032 TestParams params);
1033 virtual tcu::TestStatus iterate (void);
1034
1035 protected:
1036 virtual tcu::TestStatus checkTestResult (tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess());
1037
1038 private:
1039 Move<VkImage> m_source;
1040 de::MovePtr<Allocation> m_sourceImageAlloc;
1041 Move<VkImage> m_destination;
1042 de::MovePtr<Allocation> m_destinationImageAlloc;
1043
1044 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
1045 };
1046
CopyImageToImage(Context & context,TestParams params)1047 CopyImageToImage::CopyImageToImage (Context& context, TestParams params)
1048 : CopiesAndBlittingTestInstance(context, params)
1049 {
1050 const InstanceInterface& vki = context.getInstanceInterface();
1051 const DeviceInterface& vk = context.getDeviceInterface();
1052 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
1053 const VkDevice vkDevice = m_device;
1054 Allocator& memAlloc = context.getDefaultAllocator();
1055
1056 // Create source image
1057 {
1058 const VkImageCreateInfo sourceImageParams =
1059 {
1060 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1061 DE_NULL, // const void* pNext;
1062 getCreateFlags(m_params.src.image), // VkImageCreateFlags flags;
1063 m_params.src.image.imageType, // VkImageType imageType;
1064 m_params.src.image.format, // VkFormat format;
1065 getExtent3D(m_params.src.image), // VkExtent3D extent;
1066 1u, // deUint32 mipLevels;
1067 getArraySize(m_params.src.image), // deUint32 arraySize;
1068 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
1069 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1070 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1071 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
1072 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1073 0u, // deUint32 queueFamilyIndexCount;
1074 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
1075 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
1076 };
1077
1078 m_source = createImage(vk, vkDevice, &sourceImageParams);
1079 m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
1080 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
1081 }
1082
1083 // Create destination image
1084 {
1085 const VkImageCreateInfo destinationImageParams =
1086 {
1087 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1088 DE_NULL, // const void* pNext;
1089 getCreateFlags(m_params.dst.image), // VkImageCreateFlags flags;
1090 m_params.dst.image.imageType, // VkImageType imageType;
1091 m_params.dst.image.format, // VkFormat format;
1092 getExtent3D(m_params.dst.image), // VkExtent3D extent;
1093 1u, // deUint32 mipLevels;
1094 getArraySize(m_params.dst.image), // deUint32 arraySize;
1095 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
1096 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1097 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1098 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
1099 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1100 0u, // deUint32 queueFamilyIndexCount;
1101 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
1102 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
1103 };
1104
1105 m_destination = createImage(vk, vkDevice, &destinationImageParams);
1106 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
1107 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
1108 }
1109 }
1110
iterate(void)1111 tcu::TestStatus CopyImageToImage::iterate (void)
1112 {
1113 const bool srcCompressed = isCompressedFormat(m_params.src.image.format);
1114 const bool dstCompressed = isCompressedFormat(m_params.dst.image.format);
1115
1116 const tcu::TextureFormat srcTcuFormat = getSizeCompatibleTcuTextureFormat(m_params.src.image.format);
1117 const tcu::TextureFormat dstTcuFormat = getSizeCompatibleTcuTextureFormat(m_params.dst.image.format);
1118
1119 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
1120 (int)m_params.src.image.extent.width,
1121 (int)m_params.src.image.extent.height,
1122 (int)m_params.src.image.extent.depth));
1123 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);
1124 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
1125 (int)m_params.dst.image.extent.width,
1126 (int)m_params.dst.image.extent.height,
1127 (int)m_params.dst.image.extent.depth));
1128 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);
1129 generateExpectedResult();
1130
1131 uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
1132 uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
1133
1134 const DeviceInterface& vk = m_context.getDeviceInterface();
1135 const VkDevice vkDevice = m_device;
1136 const VkQueue queue = m_queue;
1137
1138 std::vector<VkImageCopy> imageCopies;
1139 std::vector<VkImageCopy2KHR> imageCopies2KHR;
1140 for (deUint32 i = 0; i < m_params.regions.size(); i++)
1141 {
1142 VkImageCopy imageCopy = m_params.regions[i].imageCopy;
1143
1144 // When copying between compressed and uncompressed formats the extent
1145 // members represent the texel dimensions of the source image.
1146 if (srcCompressed)
1147 {
1148 const deUint32 blockWidth = getBlockWidth(m_params.src.image.format);
1149 const deUint32 blockHeight = getBlockHeight(m_params.src.image.format);
1150
1151 imageCopy.srcOffset.x *= blockWidth;
1152 imageCopy.extent.width *= blockWidth;
1153
1154 // VUID-vkCmdCopyImage-srcImage-00146
1155 if (m_params.src.image.imageType != vk::VK_IMAGE_TYPE_1D)
1156 {
1157 imageCopy.srcOffset.y *= blockHeight;
1158 imageCopy.extent.height *= blockHeight;
1159 }
1160 }
1161
1162 if (dstCompressed)
1163 {
1164 const deUint32 blockWidth = getBlockWidth(m_params.dst.image.format);
1165 const deUint32 blockHeight = getBlockHeight(m_params.dst.image.format);
1166
1167 imageCopy.dstOffset.x *= blockWidth;
1168
1169 // VUID-vkCmdCopyImage-dstImage-00152
1170 if (m_params.dst.image.imageType != vk::VK_IMAGE_TYPE_1D)
1171 {
1172 imageCopy.dstOffset.y *= blockHeight;
1173 }
1174 }
1175
1176 if (m_params.extensionUse == EXTENSION_USE_NONE)
1177 {
1178 imageCopies.push_back(imageCopy);
1179 }
1180 else
1181 {
1182 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1183 imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
1184 }
1185 }
1186
1187 VkImageMemoryBarrier imageBarriers[] =
1188 {
1189 // source image
1190 {
1191 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1192 DE_NULL, // const void* pNext;
1193 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1194 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
1195 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1196 m_params.src.image.operationLayout, // VkImageLayout newLayout;
1197 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1198 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
1199 m_source.get(), // VkImage image;
1200 { // VkImageSubresourceRange subresourceRange;
1201 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
1202 0u, // deUint32 baseMipLevel;
1203 1u, // deUint32 mipLevels;
1204 0u, // deUint32 baseArraySlice;
1205 getArraySize(m_params.src.image)// deUint32 arraySize;
1206 }
1207 },
1208 // destination image
1209 {
1210 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1211 DE_NULL, // const void* pNext;
1212 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1213 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1214 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1215 m_params.dst.image.operationLayout, // VkImageLayout newLayout;
1216 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1217 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
1218 m_destination.get(), // VkImage image;
1219 { // VkImageSubresourceRange subresourceRange;
1220 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
1221 0u, // deUint32 baseMipLevel;
1222 1u, // deUint32 mipLevels;
1223 0u, // deUint32 baseArraySlice;
1224 getArraySize(m_params.dst.image)// deUint32 arraySize;
1225 }
1226 },
1227 };
1228
1229 beginCommandBuffer(vk, *m_cmdBuffer);
1230 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);
1231
1232 if (m_params.clearDestination)
1233 {
1234 VkImageSubresourceRange range = { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u };
1235 VkClearColorValue clearColor;
1236
1237 clearColor.float32[0] = 1.0f;
1238 clearColor.float32[1] = 1.0f;
1239 clearColor.float32[2] = 1.0f;
1240 clearColor.float32[3] = 1.0f;
1241 vk.cmdClearColorImage(*m_cmdBuffer, m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1u, &range);
1242 imageBarriers[0].oldLayout = imageBarriers[0].newLayout;
1243 imageBarriers[1].oldLayout = imageBarriers[1].newLayout;
1244 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);
1245 }
1246
1247 if (m_params.extensionUse == EXTENSION_USE_NONE)
1248 {
1249 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());
1250 }
1251 #ifndef CTS_USES_VULKANSC
1252 else
1253 {
1254 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1255 const VkCopyImageInfo2KHR copyImageInfo2KHR =
1256 {
1257 VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR, // VkStructureType sType;
1258 DE_NULL, // const void* pNext;
1259 m_source.get(), // VkImage srcImage;
1260 m_params.src.image.operationLayout, // VkImageLayout srcImageLayout;
1261 m_destination.get(), // VkImage dstImage;
1262 m_params.dst.image.operationLayout, // VkImageLayout dstImageLayout;
1263 (deUint32)imageCopies2KHR.size(), // uint32_t regionCount;
1264 imageCopies2KHR.data() // const VkImageCopy2KHR* pRegions;
1265 };
1266
1267 vk.cmdCopyImage2(*m_cmdBuffer, ©ImageInfo2KHR);
1268 }
1269 #endif // CTS_USES_VULKANSC
1270
1271 endCommandBuffer(vk, *m_cmdBuffer);
1272
1273 submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
1274 m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
1275
1276 de::MovePtr<tcu::TextureLevel> resultTextureLevel = readImage(*m_destination, m_params.dst.image);
1277
1278 return checkTestResult(resultTextureLevel->getAccess());
1279 }
1280
checkTestResult(tcu::ConstPixelBufferAccess result)1281 tcu::TestStatus CopyImageToImage::checkTestResult (tcu::ConstPixelBufferAccess result)
1282 {
1283 const tcu::Vec4 fThreshold (0.0f);
1284 const tcu::UVec4 uThreshold (0u);
1285
1286 if (tcu::isCombinedDepthStencilType(result.getFormat().type))
1287 {
1288 if (tcu::hasDepthComponent(result.getFormat().order))
1289 {
1290 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_DEPTH;
1291 const tcu::ConstPixelBufferAccess depthResult = tcu::getEffectiveDepthStencilAccess(result, mode);
1292 const tcu::ConstPixelBufferAccess expectedResult = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
1293
1294 if (isFloatFormat(result.getFormat()))
1295 {
1296 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1297 return tcu::TestStatus::fail("CopiesAndBlitting test");
1298 }
1299 else
1300 {
1301 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1302 return tcu::TestStatus::fail("CopiesAndBlitting test");
1303 }
1304 }
1305
1306 if (tcu::hasStencilComponent(result.getFormat().order))
1307 {
1308 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_STENCIL;
1309 const tcu::ConstPixelBufferAccess stencilResult = tcu::getEffectiveDepthStencilAccess(result, mode);
1310 const tcu::ConstPixelBufferAccess expectedResult = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
1311
1312 if (isFloatFormat(result.getFormat()))
1313 {
1314 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1315 return tcu::TestStatus::fail("CopiesAndBlitting test");
1316 }
1317 else
1318 {
1319 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1320 return tcu::TestStatus::fail("CopiesAndBlitting test");
1321 }
1322 }
1323 }
1324 else
1325 {
1326 if (isFloatFormat(result.getFormat()))
1327 {
1328 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", m_expectedTextureLevel[0]->getAccess(), result, fThreshold, tcu::COMPARE_LOG_RESULT))
1329 return tcu::TestStatus::fail("CopiesAndBlitting test");
1330 }
1331 else
1332 {
1333 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", m_expectedTextureLevel[0]->getAccess(), result, uThreshold, tcu::COMPARE_LOG_RESULT))
1334 return tcu::TestStatus::fail("CopiesAndBlitting test");
1335 }
1336 }
1337
1338 return tcu::TestStatus::pass("CopiesAndBlitting test");
1339 }
1340
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)1341 void CopyImageToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
1342 {
1343 DE_UNREF(mipLevel);
1344
1345 VkOffset3D srcOffset = region.imageCopy.srcOffset;
1346 VkOffset3D dstOffset = region.imageCopy.dstOffset;
1347 VkExtent3D extent = region.imageCopy.extent;
1348
1349 if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && m_params.dst.image.imageType == VK_IMAGE_TYPE_2D)
1350 {
1351 dstOffset.z = srcOffset.z;
1352 extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.dstSubresource.layerCount);
1353 }
1354 if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && m_params.dst.image.imageType == VK_IMAGE_TYPE_3D)
1355 {
1356 srcOffset.z = dstOffset.z;
1357 extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.srcSubresource.layerCount);
1358 }
1359
1360
1361 if (tcu::isCombinedDepthStencilType(src.getFormat().type))
1362 {
1363 DE_ASSERT(src.getFormat() == dst.getFormat());
1364
1365 // Copy depth.
1366 if (tcu::hasDepthComponent(src.getFormat().order))
1367 {
1368 const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1369 const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1370 tcu::copy(dstSubRegion, srcSubRegion);
1371 }
1372
1373 // Copy stencil.
1374 if (tcu::hasStencilComponent(src.getFormat().order))
1375 {
1376 const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1377 const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1378 tcu::copy(dstSubRegion, srcSubRegion);
1379 }
1380 }
1381 else
1382 {
1383 const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
1384 // CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
1385 const tcu::PixelBufferAccess dstWithSrcFormat (srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
1386 const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
1387
1388 tcu::copy(dstSubRegion, srcSubRegion);
1389 }
1390 }
1391
1392 class CopyImageToImageTestCase : public vkt::TestCase
1393 {
1394 public:
CopyImageToImageTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)1395 CopyImageToImageTestCase (tcu::TestContext& testCtx,
1396 const std::string& name,
1397 const std::string& description,
1398 const TestParams params)
1399 : vkt::TestCase (testCtx, name, description)
1400 , m_params (params)
1401 {}
1402
createInstance(Context & context) const1403 virtual TestInstance* createInstance (Context& context) const
1404 {
1405 return new CopyImageToImage(context, m_params);
1406 }
1407
checkSupport(Context & context) const1408 virtual void checkSupport (Context& context) const
1409 {
1410 if (m_params.allocationKind == ALLOCATION_KIND_DEDICATED)
1411 {
1412 if (!context.isDeviceFunctionalitySupported("VK_KHR_dedicated_allocation"))
1413 TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported");
1414 }
1415
1416 if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
1417 {
1418 if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
1419 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
1420 }
1421
1422 if (m_params.separateDepthStencilLayouts)
1423 if (!context.isDeviceFunctionalitySupported("VK_KHR_separate_depth_stencil_layouts"))
1424 TCU_THROW(NotSupportedError, "VK_KHR_separate_depth_stencil_layouts is not supported");
1425
1426 if ((m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && m_params.src.image.imageType == VK_IMAGE_TYPE_2D) ||
1427 (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && m_params.src.image.imageType == VK_IMAGE_TYPE_3D))
1428 {
1429 if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance1"))
1430 TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported");
1431 }
1432
1433 const VkPhysicalDeviceLimits limits = context.getDeviceProperties().limits;
1434 VkImageFormatProperties properties;
1435
1436 if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1437 m_params.src.image.format,
1438 m_params.src.image.imageType,
1439 VK_IMAGE_TILING_OPTIMAL,
1440 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1441 0,
1442 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
1443 (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1444 m_params.dst.image.format,
1445 m_params.dst.image.imageType,
1446 VK_IMAGE_TILING_OPTIMAL,
1447 VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1448 0,
1449 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
1450 {
1451 TCU_THROW(NotSupportedError, "Format not supported");
1452 }
1453
1454 // Check maxImageDimension1D
1455 {
1456 if (m_params.src.image.imageType == VK_IMAGE_TYPE_1D && m_params.src.image.extent.width > limits.maxImageDimension1D)
1457 TCU_THROW(NotSupportedError, "Requested 1D src image dimensions not supported");
1458
1459 if (m_params.dst.image.imageType == VK_IMAGE_TYPE_1D && m_params.dst.image.extent.width > limits.maxImageDimension1D)
1460 TCU_THROW(NotSupportedError, "Requested 1D dst image dimensions not supported");
1461 }
1462
1463 // Check maxImageDimension2D
1464 {
1465 if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && (m_params.src.image.extent.width > limits.maxImageDimension2D
1466 || m_params.src.image.extent.height > limits.maxImageDimension2D))
1467 {
1468 TCU_THROW(NotSupportedError, "Requested 2D src image dimensions not supported");
1469 }
1470
1471 if (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && (m_params.dst.image.extent.width > limits.maxImageDimension2D
1472 || m_params.dst.image.extent.height > limits.maxImageDimension2D))
1473 {
1474 TCU_THROW(NotSupportedError, "Requested 2D dst image dimensions not supported");
1475 }
1476 }
1477
1478 // Check maxImageDimension3D
1479 {
1480 if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && (m_params.src.image.extent.width > limits.maxImageDimension3D
1481 || m_params.src.image.extent.height > limits.maxImageDimension3D
1482 || m_params.src.image.extent.depth > limits.maxImageDimension3D))
1483 {
1484 TCU_THROW(NotSupportedError, "Requested 3D src image dimensions not supported");
1485 }
1486
1487 if (m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && (m_params.dst.image.extent.width > limits.maxImageDimension3D
1488 || m_params.dst.image.extent.height > limits.maxImageDimension3D
1489 || m_params.src.image.extent.depth > limits.maxImageDimension3D))
1490 {
1491 TCU_THROW(NotSupportedError, "Requested 3D dst image dimensions not supported");
1492 }
1493 }
1494 }
1495
1496 private:
1497 TestParams m_params;
1498 };
1499
1500 class CopyImageToImageMipmap : public CopiesAndBlittingTestInstance
1501 {
1502 public:
1503 CopyImageToImageMipmap (Context& context,
1504 TestParams params);
1505 virtual tcu::TestStatus iterate (void);
1506
1507 protected:
1508 tcu::TestStatus checkResult (tcu::ConstPixelBufferAccess result, tcu::ConstPixelBufferAccess expected);
1509
1510 private:
1511 Move<VkImage> m_source;
1512 de::MovePtr<Allocation> m_sourceImageAlloc;
1513 Move<VkImage> m_destination;
1514 de::MovePtr<Allocation> m_destinationImageAlloc;
1515
1516 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
1517
1518 };
1519
CopyImageToImageMipmap(Context & context,TestParams params)1520 CopyImageToImageMipmap::CopyImageToImageMipmap (Context& context, TestParams params)
1521 : CopiesAndBlittingTestInstance(context, params)
1522 {
1523 const InstanceInterface& vki = context.getInstanceInterface();
1524 const DeviceInterface& vk = context.getDeviceInterface();
1525 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
1526 const VkDevice vkDevice = m_device;
1527 Allocator& memAlloc = context.getDefaultAllocator();
1528
1529 // Create source image
1530 {
1531 const VkImageCreateInfo sourceImageParams =
1532 {
1533 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1534 DE_NULL, // const void* pNext;
1535 getCreateFlags(m_params.src.image), // VkImageCreateFlags flags;
1536 m_params.src.image.imageType, // VkImageType imageType;
1537 m_params.src.image.format, // VkFormat format;
1538 getExtent3D(m_params.src.image), // VkExtent3D extent;
1539 params.mipLevels, // deUint32 mipLevels;
1540 getArraySize(m_params.src.image), // deUint32 arraySize;
1541 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
1542 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1543 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1544 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
1545 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1546 0u, // deUint32 queueFamilyIndexCount;
1547 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
1548 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
1549 };
1550
1551 m_source = createImage(vk, vkDevice, &sourceImageParams);
1552 m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
1553 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
1554 }
1555
1556 // Create destination image
1557 {
1558 const VkImageCreateInfo destinationImageParams =
1559 {
1560 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1561 DE_NULL, // const void* pNext;
1562 getCreateFlags(m_params.dst.image), // VkImageCreateFlags flags;
1563 m_params.dst.image.imageType, // VkImageType imageType;
1564 m_params.dst.image.format, // VkFormat format;
1565 getExtent3D(m_params.dst.image), // VkExtent3D extent;
1566 params.mipLevels, // deUint32 mipLevels;
1567 getArraySize(m_params.dst.image), // deUint32 arraySize;
1568 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
1569 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1570 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1571 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
1572 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1573 0u, // deUint32 queueFamilyIndexCount;
1574 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
1575 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
1576 };
1577
1578 m_destination = createImage(vk, vkDevice, &destinationImageParams);
1579 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
1580 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
1581 }
1582 }
1583
iterate(void)1584 tcu::TestStatus CopyImageToImageMipmap::iterate (void)
1585 {
1586 const bool srcCompressed = isCompressedFormat(m_params.src.image.format);
1587 const bool dstCompressed = isCompressedFormat(m_params.dst.image.format);
1588
1589 const tcu::TextureFormat srcTcuFormat = getSizeCompatibleTcuTextureFormat(m_params.src.image.format);
1590 const tcu::TextureFormat dstTcuFormat = getSizeCompatibleTcuTextureFormat(m_params.dst.image.format);
1591
1592 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
1593 (int)m_params.src.image.extent.width,
1594 (int)m_params.src.image.extent.height,
1595 (int)m_params.src.image.extent.depth));
1596 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);
1597 uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image, m_params.mipLevels);
1598
1599 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
1600 (int)m_params.dst.image.extent.width,
1601 (int)m_params.dst.image.extent.height,
1602 (int)m_params.dst.image.extent.depth));
1603 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);
1604 uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, m_params.mipLevels);
1605
1606 const DeviceInterface& vk = m_context.getDeviceInterface();
1607 const VkDevice vkDevice = m_device;
1608 const VkQueue queue = m_queue;
1609
1610 std::vector<VkImageCopy> imageCopies;
1611 std::vector<VkImageCopy2KHR> imageCopies2KHR;
1612 for (deUint32 i = 0; i < m_params.regions.size(); i++)
1613 {
1614 VkImageCopy imageCopy = m_params.regions[i].imageCopy;
1615
1616 // When copying between compressed and uncompressed formats the extent
1617 // members represent the texel dimensions of the source image.
1618 if (srcCompressed)
1619 {
1620 const deUint32 blockWidth = getBlockWidth(m_params.src.image.format);
1621 const deUint32 blockHeight = getBlockHeight(m_params.src.image.format);
1622
1623 imageCopy.srcOffset.x *= blockWidth;
1624 imageCopy.srcOffset.y *= blockHeight;
1625 imageCopy.extent.width *= blockWidth;
1626 imageCopy.extent.height *= blockHeight;
1627 }
1628
1629 if (dstCompressed)
1630 {
1631 const deUint32 blockWidth = getBlockWidth(m_params.dst.image.format);
1632 const deUint32 blockHeight = getBlockHeight(m_params.dst.image.format);
1633
1634 imageCopy.dstOffset.x *= blockWidth;
1635 imageCopy.dstOffset.y *= blockHeight;
1636 }
1637
1638 if (m_params.extensionUse == EXTENSION_USE_NONE)
1639 {
1640 imageCopies.push_back(imageCopy);
1641 }
1642 else
1643 {
1644 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1645 imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
1646 }
1647 }
1648
1649 VkImageMemoryBarrier imageBarriers[] =
1650 {
1651 // source image
1652 {
1653 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1654 DE_NULL, // const void* pNext;
1655 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1656 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
1657 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1658 m_params.src.image.operationLayout, // VkImageLayout newLayout;
1659 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1660 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
1661 m_source.get(), // VkImage image;
1662 { // VkImageSubresourceRange subresourceRange;
1663 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
1664 0u, // deUint32 baseMipLevel;
1665 m_params.mipLevels, // deUint32 mipLevels;
1666 0u, // deUint32 baseArraySlice;
1667 getArraySize(m_params.src.image)// deUint32 arraySize;
1668 }
1669 },
1670 // destination image
1671 {
1672 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1673 DE_NULL, // const void* pNext;
1674 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1675 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1676 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1677 m_params.dst.image.operationLayout, // VkImageLayout newLayout;
1678 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1679 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
1680 m_destination.get(), // VkImage image;
1681 { // VkImageSubresourceRange subresourceRange;
1682 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
1683 0u, // deUint32 baseMipLevel;
1684 m_params.mipLevels, // deUint32 mipLevels;
1685 0u, // deUint32 baseArraySlice;
1686 getArraySize(m_params.dst.image)// deUint32 arraySize;
1687 }
1688 },
1689 };
1690
1691 beginCommandBuffer(vk, *m_cmdBuffer);
1692 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);
1693
1694 if (m_params.extensionUse == EXTENSION_USE_NONE)
1695 {
1696 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());
1697 }
1698 #ifndef CTS_USES_VULKANSC
1699 else
1700 {
1701 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1702 const VkCopyImageInfo2KHR copyImageInfo2KHR =
1703 {
1704 VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR, // VkStructureType sType;
1705 DE_NULL, // const void* pNext;
1706 m_source.get(), // VkImage srcImage;
1707 m_params.src.image.operationLayout, // VkImageLayout srcImageLayout;
1708 m_destination.get(), // VkImage dstImage;
1709 m_params.dst.image.operationLayout, // VkImageLayout dstImageLayout;
1710 (deUint32)imageCopies2KHR.size(), // uint32_t regionCount;
1711 imageCopies2KHR.data() // const VkImageCopy2KHR* pRegions;
1712 };
1713
1714 vk.cmdCopyImage2(*m_cmdBuffer, ©ImageInfo2KHR);
1715 }
1716 #endif // CTS_USES_VULKANSC
1717
1718 endCommandBuffer(vk, *m_cmdBuffer);
1719
1720 submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
1721 m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
1722
1723 for (deUint32 miplevel = 0; miplevel < m_params.mipLevels; miplevel++)
1724 {
1725 de::MovePtr<tcu::TextureLevel> resultTextureLevel = readImage(*m_destination, m_params.dst.image, miplevel);
1726 de::MovePtr<tcu::TextureLevel> expectedTextureLevel = readImage(*m_source, m_params.src.image, miplevel);
1727
1728 tcu::TestStatus result = checkResult(resultTextureLevel->getAccess(), expectedTextureLevel->getAccess());
1729 if (result.getCode() != QP_TEST_RESULT_PASS)
1730 return result;
1731 }
1732 return tcu::TestStatus::pass("Pass");
1733 }
1734
checkResult(tcu::ConstPixelBufferAccess result,tcu::ConstPixelBufferAccess expected)1735 tcu::TestStatus CopyImageToImageMipmap::checkResult (tcu::ConstPixelBufferAccess result, tcu::ConstPixelBufferAccess expected)
1736 {
1737 const tcu::Vec4 fThreshold (0.0f);
1738 const tcu::UVec4 uThreshold (0u);
1739
1740 if (tcu::isCombinedDepthStencilType(result.getFormat().type))
1741 {
1742 if (tcu::hasDepthComponent(result.getFormat().order))
1743 {
1744 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_DEPTH;
1745 const tcu::ConstPixelBufferAccess depthResult = tcu::getEffectiveDepthStencilAccess(result, mode);
1746 const tcu::ConstPixelBufferAccess expectedResult = tcu::getEffectiveDepthStencilAccess(expected, mode);
1747
1748 if (isFloatFormat(result.getFormat()))
1749 {
1750 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1751 return tcu::TestStatus::fail("CopiesAndBlitting test");
1752 }
1753 else
1754 {
1755 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1756 return tcu::TestStatus::fail("CopiesAndBlitting test");
1757 }
1758 }
1759
1760 if (tcu::hasStencilComponent(result.getFormat().order))
1761 {
1762 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_STENCIL;
1763 const tcu::ConstPixelBufferAccess stencilResult = tcu::getEffectiveDepthStencilAccess(result, mode);
1764 const tcu::ConstPixelBufferAccess expectedResult = tcu::getEffectiveDepthStencilAccess(expected, mode);
1765
1766 if (isFloatFormat(result.getFormat()))
1767 {
1768 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1769 return tcu::TestStatus::fail("CopiesAndBlitting test");
1770 }
1771 else
1772 {
1773 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1774 return tcu::TestStatus::fail("CopiesAndBlitting test");
1775 }
1776 }
1777 }
1778 else
1779 {
1780 if (isFloatFormat(result.getFormat()))
1781 {
1782 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, fThreshold, tcu::COMPARE_LOG_RESULT))
1783 return tcu::TestStatus::fail("CopiesAndBlitting test");
1784 }
1785 else if (isSnormFormat(mapTextureFormat(result.getFormat())))
1786 {
1787 // There may be an ambiguity between two possible binary representations of 1.0.
1788 // Get rid of that by expanding the data to floats and re-normalizing again.
1789
1790 tcu::TextureLevel resultSnorm (result.getFormat(), result.getWidth(), result.getHeight(), result.getDepth());
1791 {
1792 tcu::TextureLevel resultFloat (tcu::TextureFormat(resultSnorm.getFormat().order, tcu::TextureFormat::FLOAT), resultSnorm.getWidth(), resultSnorm.getHeight(), resultSnorm.getDepth());
1793
1794 tcu::copy(resultFloat.getAccess(), result);
1795 tcu::copy(resultSnorm, resultFloat.getAccess());
1796 }
1797
1798 tcu::TextureLevel expectedSnorm (expected.getFormat(), expected.getWidth(), expected.getHeight(), expected.getDepth());
1799
1800 {
1801 tcu::TextureLevel expectedFloat (tcu::TextureFormat(expectedSnorm.getFormat().order, tcu::TextureFormat::FLOAT), expectedSnorm.getWidth(), expectedSnorm.getHeight(), expectedSnorm.getDepth());
1802
1803 tcu::copy(expectedFloat.getAccess(), m_expectedTextureLevel[0]->getAccess());
1804 tcu::copy(expectedSnorm, expectedFloat.getAccess());
1805 }
1806
1807 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedSnorm.getAccess(), resultSnorm.getAccess(), uThreshold, tcu::COMPARE_LOG_RESULT))
1808 return tcu::TestStatus::fail("CopiesAndBlitting test");
1809 }
1810 else
1811 {
1812 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, uThreshold, tcu::COMPARE_LOG_RESULT))
1813 return tcu::TestStatus::fail("CopiesAndBlitting test");
1814 }
1815 }
1816
1817 return tcu::TestStatus::pass("CopiesAndBlitting test");
1818 }
1819
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)1820 void CopyImageToImageMipmap::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
1821 {
1822 DE_UNREF(mipLevel);
1823
1824 VkOffset3D srcOffset = region.imageCopy.srcOffset;
1825 VkOffset3D dstOffset = region.imageCopy.dstOffset;
1826 VkExtent3D extent = region.imageCopy.extent;
1827
1828 if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && m_params.dst.image.imageType == VK_IMAGE_TYPE_2D)
1829 {
1830 dstOffset.z = srcOffset.z;
1831 extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.dstSubresource.layerCount);
1832 }
1833 if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && m_params.dst.image.imageType == VK_IMAGE_TYPE_3D)
1834 {
1835 srcOffset.z = dstOffset.z;
1836 extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.srcSubresource.layerCount);
1837 }
1838
1839
1840 if (tcu::isCombinedDepthStencilType(src.getFormat().type))
1841 {
1842 DE_ASSERT(src.getFormat() == dst.getFormat());
1843
1844 // Copy depth.
1845 if (tcu::hasDepthComponent(src.getFormat().order))
1846 {
1847 const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1848 const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1849 tcu::copy(dstSubRegion, srcSubRegion);
1850 }
1851
1852 // Copy stencil.
1853 if (tcu::hasStencilComponent(src.getFormat().order))
1854 {
1855 const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1856 const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1857 tcu::copy(dstSubRegion, srcSubRegion);
1858 }
1859 }
1860 else
1861 {
1862 const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
1863 // CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
1864 const tcu::PixelBufferAccess dstWithSrcFormat (srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
1865 const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
1866
1867 tcu::copy(dstSubRegion, srcSubRegion);
1868 }
1869 }
1870
1871 class CopyImageToImageMipmapTestCase : public vkt::TestCase
1872 {
1873 public:
CopyImageToImageMipmapTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)1874 CopyImageToImageMipmapTestCase (tcu::TestContext& testCtx,
1875 const std::string& name,
1876 const std::string& description,
1877 const TestParams params)
1878 : vkt::TestCase (testCtx, name, description)
1879 , m_params (params)
1880 {}
1881
createInstance(Context & context) const1882 virtual TestInstance* createInstance (Context& context) const
1883 {
1884 return new CopyImageToImageMipmap(context, m_params);
1885 }
1886
checkSupport(Context & context) const1887 virtual void checkSupport (Context& context) const
1888 {
1889 if (m_params.allocationKind == ALLOCATION_KIND_DEDICATED)
1890 {
1891 if (!context.isDeviceFunctionalitySupported("VK_KHR_dedicated_allocation"))
1892 TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported");
1893 }
1894
1895 if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
1896 {
1897 if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
1898 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
1899 }
1900
1901 if (m_params.separateDepthStencilLayouts)
1902 if (!context.isDeviceFunctionalitySupported("VK_KHR_separate_depth_stencil_layouts"))
1903 TCU_THROW(NotSupportedError, "VK_KHR_separate_depth_stencil_layouts is not supported");
1904
1905 if ((m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && m_params.src.image.imageType == VK_IMAGE_TYPE_2D) ||
1906 (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && m_params.src.image.imageType == VK_IMAGE_TYPE_3D))
1907 {
1908 if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance1"))
1909 TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported");
1910 }
1911
1912 const VkPhysicalDeviceLimits limits = context.getDeviceProperties().limits;
1913 VkImageFormatProperties properties;
1914
1915 if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1916 m_params.src.image.format,
1917 m_params.src.image.imageType,
1918 VK_IMAGE_TILING_OPTIMAL,
1919 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1920 0,
1921 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
1922 (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1923 m_params.dst.image.format,
1924 m_params.dst.image.imageType,
1925 VK_IMAGE_TILING_OPTIMAL,
1926 VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1927 0,
1928 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
1929 {
1930 TCU_THROW(NotSupportedError, "Format not supported");
1931 }
1932
1933 // Check maxImageDimension1D
1934 {
1935 if (m_params.src.image.imageType == VK_IMAGE_TYPE_1D && m_params.src.image.extent.width > limits.maxImageDimension1D)
1936 TCU_THROW(NotSupportedError, "Requested 1D src image dimensions not supported");
1937
1938 if (m_params.dst.image.imageType == VK_IMAGE_TYPE_1D && m_params.dst.image.extent.width > limits.maxImageDimension1D)
1939 TCU_THROW(NotSupportedError, "Requested 1D dst image dimensions not supported");
1940 }
1941
1942 // Check maxImageDimension2D
1943 {
1944 if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && (m_params.src.image.extent.width > limits.maxImageDimension2D
1945 || m_params.src.image.extent.height > limits.maxImageDimension2D))
1946 {
1947 TCU_THROW(NotSupportedError, "Requested 2D src image dimensions not supported");
1948 }
1949
1950 if (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && (m_params.dst.image.extent.width > limits.maxImageDimension2D
1951 || m_params.dst.image.extent.height > limits.maxImageDimension2D))
1952 {
1953 TCU_THROW(NotSupportedError, "Requested 2D dst image dimensions not supported");
1954 }
1955 }
1956
1957 // Check maxImageDimension3D
1958 {
1959 if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && (m_params.src.image.extent.width > limits.maxImageDimension3D
1960 || m_params.src.image.extent.height > limits.maxImageDimension3D
1961 || m_params.src.image.extent.depth > limits.maxImageDimension3D))
1962 {
1963 TCU_THROW(NotSupportedError, "Requested 3D src image dimensions not supported");
1964 }
1965
1966 if (m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && (m_params.dst.image.extent.width > limits.maxImageDimension3D
1967 || m_params.dst.image.extent.height > limits.maxImageDimension3D
1968 || m_params.src.image.extent.depth > limits.maxImageDimension3D))
1969 {
1970 TCU_THROW(NotSupportedError, "Requested 3D dst image dimensions not supported");
1971 }
1972 }
1973 }
1974
1975 private:
1976 TestParams m_params;
1977 };
1978
1979 // Copy from buffer to buffer.
1980
1981 class CopyBufferToBuffer : public CopiesAndBlittingTestInstance
1982 {
1983 public:
1984 CopyBufferToBuffer (Context& context, TestParams params);
1985 virtual tcu::TestStatus iterate (void);
1986 private:
1987 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess, tcu::PixelBufferAccess, CopyRegion, deUint32 mipLevel = 0u);
1988 Move<VkBuffer> m_source;
1989 de::MovePtr<Allocation> m_sourceBufferAlloc;
1990 Move<VkBuffer> m_destination;
1991 de::MovePtr<Allocation> m_destinationBufferAlloc;
1992 };
1993
CopyBufferToBuffer(Context & context,TestParams params)1994 CopyBufferToBuffer::CopyBufferToBuffer (Context& context, TestParams params)
1995 : CopiesAndBlittingTestInstance (context, params)
1996 {
1997 const InstanceInterface& vki = context.getInstanceInterface();
1998 const DeviceInterface& vk = context.getDeviceInterface();
1999 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
2000 const VkDevice vkDevice = m_device;
2001 Allocator& memAlloc = context.getDefaultAllocator();
2002
2003 // Create source buffer
2004 {
2005 const VkBufferCreateInfo sourceBufferParams =
2006 {
2007 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2008 DE_NULL, // const void* pNext;
2009 0u, // VkBufferCreateFlags flags;
2010 m_params.src.buffer.size, // VkDeviceSize size;
2011 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage;
2012 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2013 0u, // deUint32 queueFamilyIndexCount;
2014 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
2015 };
2016
2017 m_source = createBuffer(vk, vkDevice, &sourceBufferParams);
2018 m_sourceBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
2019 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
2020 }
2021
2022 // Create destination buffer
2023 {
2024 const VkBufferCreateInfo destinationBufferParams =
2025 {
2026 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2027 DE_NULL, // const void* pNext;
2028 0u, // VkBufferCreateFlags flags;
2029 m_params.dst.buffer.size, // VkDeviceSize size;
2030 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
2031 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2032 0u, // deUint32 queueFamilyIndexCount;
2033 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
2034 };
2035
2036 m_destination = createBuffer(vk, vkDevice, &destinationBufferParams);
2037 m_destinationBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
2038 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
2039 }
2040 }
2041
iterate(void)2042 tcu::TestStatus CopyBufferToBuffer::iterate (void)
2043 {
2044 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
2045 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), srcLevelWidth, 1));
2046 generateBuffer(m_sourceTextureLevel->getAccess(), srcLevelWidth, 1, 1, FILL_MODE_RED);
2047
2048 const int dstLevelWidth = (int)(m_params.dst.buffer.size/4);
2049 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
2050 generateBuffer(m_destinationTextureLevel->getAccess(), dstLevelWidth, 1, 1, FILL_MODE_BLACK);
2051
2052 generateExpectedResult();
2053
2054 uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
2055 uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
2056
2057 const DeviceInterface& vk = m_context.getDeviceInterface();
2058 const VkDevice vkDevice = m_device;
2059 const VkQueue queue = m_queue;
2060
2061 const VkBufferMemoryBarrier srcBufferBarrier =
2062 {
2063 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
2064 DE_NULL, // const void* pNext;
2065 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask;
2066 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
2067 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
2068 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
2069 *m_source, // VkBuffer buffer;
2070 0u, // VkDeviceSize offset;
2071 m_params.src.buffer.size // VkDeviceSize size;
2072 };
2073
2074 const VkBufferMemoryBarrier dstBufferBarrier =
2075 {
2076 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
2077 DE_NULL, // const void* pNext;
2078 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
2079 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
2080 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
2081 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
2082 *m_destination, // VkBuffer buffer;
2083 0u, // VkDeviceSize offset;
2084 m_params.dst.buffer.size // VkDeviceSize size;
2085 };
2086
2087 std::vector<VkBufferCopy> bufferCopies;
2088 std::vector<VkBufferCopy2KHR> bufferCopies2KHR;
2089 for (deUint32 i = 0; i < m_params.regions.size(); i++)
2090 {
2091 if (m_params.extensionUse == EXTENSION_USE_NONE)
2092 {
2093 bufferCopies.push_back(m_params.regions[i].bufferCopy);
2094 }
2095 else
2096 {
2097 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2098 bufferCopies2KHR.push_back(convertvkBufferCopyTovkBufferCopy2KHR(m_params.regions[i].bufferCopy));
2099 }
2100 }
2101
2102 beginCommandBuffer(vk, *m_cmdBuffer);
2103 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);
2104
2105 if (m_params.extensionUse == EXTENSION_USE_NONE)
2106 {
2107 vk.cmdCopyBuffer(*m_cmdBuffer, m_source.get(), m_destination.get(), (deUint32)m_params.regions.size(), &bufferCopies[0]);
2108 }
2109 #ifndef CTS_USES_VULKANSC
2110 else
2111 {
2112 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2113 const VkCopyBufferInfo2KHR copyBufferInfo2KHR =
2114 {
2115 VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2_KHR, // VkStructureType sType;
2116 DE_NULL, // const void* pNext;
2117 m_source.get(), // VkBuffer srcBuffer;
2118 m_destination.get(), // VkBuffer dstBuffer;
2119 (deUint32)m_params.regions.size(), // uint32_t regionCount;
2120 &bufferCopies2KHR[0] // const VkBufferCopy2KHR* pRegions;
2121 };
2122
2123 vk.cmdCopyBuffer2(*m_cmdBuffer, ©BufferInfo2KHR);
2124 }
2125 #endif // CTS_USES_VULKANSC
2126
2127 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);
2128 endCommandBuffer(vk, *m_cmdBuffer);
2129 submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
2130 m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
2131
2132 // Read buffer data
2133 de::MovePtr<tcu::TextureLevel> resultLevel (new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
2134 invalidateAlloc(vk, vkDevice, *m_destinationBufferAlloc);
2135 tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr()));
2136
2137 return checkTestResult(resultLevel->getAccess());
2138 }
2139
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)2140 void CopyBufferToBuffer::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
2141 {
2142 DE_UNREF(mipLevel);
2143
2144 deMemcpy((deUint8*) dst.getDataPtr() + region.bufferCopy.dstOffset,
2145 (deUint8*) src.getDataPtr() + region.bufferCopy.srcOffset,
2146 (size_t)region.bufferCopy.size);
2147 }
2148
2149 class BufferToBufferTestCase : public vkt::TestCase
2150 {
2151 public:
BufferToBufferTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)2152 BufferToBufferTestCase (tcu::TestContext& testCtx,
2153 const std::string& name,
2154 const std::string& description,
2155 const TestParams params)
2156 : vkt::TestCase (testCtx, name, description)
2157 , m_params (params)
2158 {}
2159
createInstance(Context & context) const2160 virtual TestInstance* createInstance (Context& context) const
2161 {
2162 return new CopyBufferToBuffer(context, m_params);
2163 }
2164
checkSupport(Context & context) const2165 virtual void checkSupport(Context& context) const
2166 {
2167 if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
2168 {
2169 if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
2170 {
2171 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
2172 }
2173 }
2174 }
2175
2176 private:
2177 TestParams m_params;
2178 };
2179
2180 // Copy from image to buffer.
2181
2182 class CopyImageToBuffer : public CopiesAndBlittingTestInstance
2183 {
2184 public:
2185 CopyImageToBuffer (Context& context,
2186 TestParams testParams);
2187 virtual tcu::TestStatus iterate (void);
2188 private:
2189 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
2190
2191 tcu::TextureFormat m_textureFormat;
2192 VkDeviceSize m_bufferSize;
2193
2194 Move<VkImage> m_source;
2195 de::MovePtr<Allocation> m_sourceImageAlloc;
2196 Move<VkBuffer> m_destination;
2197 de::MovePtr<Allocation> m_destinationBufferAlloc;
2198 };
2199
CopyImageToBuffer(Context & context,TestParams testParams)2200 CopyImageToBuffer::CopyImageToBuffer (Context& context, TestParams testParams)
2201 : CopiesAndBlittingTestInstance(context, testParams)
2202 , m_textureFormat(mapVkFormat(testParams.src.image.format))
2203 , m_bufferSize(m_params.dst.buffer.size * tcu::getPixelSize(m_textureFormat))
2204 {
2205 const InstanceInterface& vki = context.getInstanceInterface();
2206 const DeviceInterface& vk = context.getDeviceInterface();
2207 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
2208 const VkDevice vkDevice = m_device;
2209 Allocator& memAlloc = context.getDefaultAllocator();
2210
2211 // Create source image
2212 {
2213 const VkImageCreateInfo sourceImageParams =
2214 {
2215 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
2216 DE_NULL, // const void* pNext;
2217 getCreateFlags(m_params.src.image), // VkImageCreateFlags flags;
2218 m_params.src.image.imageType, // VkImageType imageType;
2219 m_params.src.image.format, // VkFormat format;
2220 getExtent3D(m_params.src.image), // VkExtent3D extent;
2221 1u, // deUint32 mipLevels;
2222 getArraySize(m_params.src.image), // deUint32 arraySize;
2223 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
2224 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
2225 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2226 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
2227 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2228 0u, // deUint32 queueFamilyIndexCount;
2229 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
2230 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
2231 };
2232
2233 m_source = createImage(vk, vkDevice, &sourceImageParams);
2234 m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
2235 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
2236 }
2237
2238 // Create destination buffer
2239 {
2240 const VkBufferCreateInfo destinationBufferParams =
2241 {
2242 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2243 DE_NULL, // const void* pNext;
2244 0u, // VkBufferCreateFlags flags;
2245 m_bufferSize, // VkDeviceSize size;
2246 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
2247 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2248 0u, // deUint32 queueFamilyIndexCount;
2249 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
2250 };
2251
2252 m_destination = createBuffer(vk, vkDevice, &destinationBufferParams);
2253 m_destinationBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
2254 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
2255 }
2256 }
2257
iterate(void)2258 tcu::TestStatus CopyImageToBuffer::iterate (void)
2259 {
2260 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
2261 m_params.src.image.extent.width,
2262 m_params.src.image.extent.height,
2263 m_params.src.image.extent.depth));
2264 generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth);
2265 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
2266 generateBuffer(m_destinationTextureLevel->getAccess(), (int)m_params.dst.buffer.size, 1, 1);
2267
2268 generateExpectedResult();
2269
2270 uploadImage(m_sourceTextureLevel->getAccess(), *m_source, m_params.src.image);
2271 uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
2272
2273 const DeviceInterface& vk = m_context.getDeviceInterface();
2274 const VkDevice vkDevice = m_device;
2275 const VkQueue queue = m_queue;
2276
2277 // Barriers for copying image to buffer
2278 const VkImageMemoryBarrier imageBarrier =
2279 {
2280 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
2281 DE_NULL, // const void* pNext;
2282 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
2283 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
2284 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
2285 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout;
2286 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
2287 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
2288 *m_source, // VkImage image;
2289 { // VkImageSubresourceRange subresourceRange;
2290 getAspectFlags(m_textureFormat), // VkImageAspectFlags aspectMask;
2291 0u, // deUint32 baseMipLevel;
2292 1u, // deUint32 mipLevels;
2293 0u, // deUint32 baseArraySlice;
2294 getArraySize(m_params.src.image) // deUint32 arraySize;
2295 }
2296 };
2297
2298 const VkBufferMemoryBarrier bufferBarrier =
2299 {
2300 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
2301 DE_NULL, // const void* pNext;
2302 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
2303 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
2304 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
2305 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
2306 *m_destination, // VkBuffer buffer;
2307 0u, // VkDeviceSize offset;
2308 m_bufferSize // VkDeviceSize size;
2309 };
2310
2311 // Copy from image to buffer
2312 std::vector<VkBufferImageCopy> bufferImageCopies;
2313 std::vector<VkBufferImageCopy2KHR> bufferImageCopies2KHR;
2314 for (deUint32 i = 0; i < m_params.regions.size(); i++)
2315 {
2316 if (m_params.extensionUse == EXTENSION_USE_NONE)
2317 {
2318 bufferImageCopies.push_back(m_params.regions[i].bufferImageCopy);
2319 }
2320 else
2321 {
2322 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2323 bufferImageCopies2KHR.push_back(convertvkBufferImageCopyTovkBufferImageCopy2KHR(m_params.regions[i].bufferImageCopy));
2324 }
2325 }
2326
2327 beginCommandBuffer(vk, *m_cmdBuffer);
2328 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);
2329
2330 if (m_params.extensionUse == EXTENSION_USE_NONE)
2331 {
2332 vk.cmdCopyImageToBuffer(*m_cmdBuffer, m_source.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_destination.get(), (deUint32)m_params.regions.size(), &bufferImageCopies[0]);
2333 }
2334 #ifndef CTS_USES_VULKANSC
2335 else
2336 {
2337 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2338 const VkCopyImageToBufferInfo2KHR copyImageToBufferInfo2KHR =
2339 {
2340 VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2_KHR, // VkStructureType sType;
2341 DE_NULL, // const void* pNext;
2342 m_source.get(), // VkImage srcImage;
2343 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout srcImageLayout;
2344 m_destination.get(), // VkBuffer dstBuffer;
2345 (deUint32)m_params.regions.size(), // uint32_t regionCount;
2346 &bufferImageCopies2KHR[0] // const VkBufferImageCopy2KHR* pRegions;
2347 };
2348
2349 vk.cmdCopyImageToBuffer2(*m_cmdBuffer, ©ImageToBufferInfo2KHR);
2350 }
2351 #endif // CTS_USES_VULKANSC
2352
2353 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);
2354 endCommandBuffer(vk, *m_cmdBuffer);
2355
2356 submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
2357 m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
2358
2359 // Read buffer data
2360 de::MovePtr<tcu::TextureLevel> resultLevel (new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
2361 invalidateAlloc(vk, vkDevice, *m_destinationBufferAlloc);
2362 tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr()));
2363
2364 return checkTestResult(resultLevel->getAccess());
2365 }
2366
2367 class CopyImageToBufferTestCase : public vkt::TestCase
2368 {
2369 public:
CopyImageToBufferTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)2370 CopyImageToBufferTestCase (tcu::TestContext& testCtx,
2371 const std::string& name,
2372 const std::string& description,
2373 const TestParams params)
2374 : vkt::TestCase (testCtx, name, description)
2375 , m_params (params)
2376 {}
2377
createInstance(Context & context) const2378 virtual TestInstance* createInstance (Context& context) const
2379 {
2380 return new CopyImageToBuffer(context, m_params);
2381 }
2382
checkSupport(Context & context) const2383 virtual void checkSupport (Context& context) const
2384 {
2385 if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
2386 (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
2387 {
2388 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
2389 }
2390 }
2391
2392 private:
2393 TestParams m_params;
2394 };
2395
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)2396 void CopyImageToBuffer::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
2397 {
2398 DE_UNREF(mipLevel);
2399
2400 deUint32 rowLength = region.bufferImageCopy.bufferRowLength;
2401 if (!rowLength)
2402 rowLength = region.bufferImageCopy.imageExtent.width;
2403
2404 deUint32 imageHeight = region.bufferImageCopy.bufferImageHeight;
2405 if (!imageHeight)
2406 imageHeight = region.bufferImageCopy.imageExtent.height;
2407
2408 const int texelSize = src.getFormat().getPixelSize();
2409 const VkExtent3D extent = region.bufferImageCopy.imageExtent;
2410 const VkOffset3D srcOffset = region.bufferImageCopy.imageOffset;
2411 const int texelOffset = (int) region.bufferImageCopy.bufferOffset / texelSize;
2412 const deUint32 baseArrayLayer = region.bufferImageCopy.imageSubresource.baseArrayLayer;
2413
2414 for (deUint32 z = 0; z < extent.depth; z++)
2415 {
2416 for (deUint32 y = 0; y < extent.height; y++)
2417 {
2418 int texelIndex = texelOffset + (z * imageHeight + y) * rowLength;
2419 const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, srcOffset.x, srcOffset.y + y, srcOffset.z + z + baseArrayLayer,
2420 region.bufferImageCopy.imageExtent.width, 1, 1);
2421 const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dst, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
2422 tcu::copy(dstSubRegion, srcSubRegion);
2423 }
2424 }
2425 }
2426
2427 // Copy from buffer to image.
2428
2429 class CopyBufferToImage : public CopiesAndBlittingTestInstance
2430 {
2431 public:
2432 CopyBufferToImage (Context& context,
2433 TestParams testParams);
2434 virtual tcu::TestStatus iterate (void);
2435
2436 private:
2437 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
2438
2439 tcu::TextureFormat m_textureFormat;
2440 VkDeviceSize m_bufferSize;
2441
2442 Move<VkBuffer> m_source;
2443 de::MovePtr<Allocation> m_sourceBufferAlloc;
2444 Move<VkImage> m_destination;
2445 de::MovePtr<Allocation> m_destinationImageAlloc;
2446 };
2447
CopyBufferToImage(Context & context,TestParams testParams)2448 CopyBufferToImage::CopyBufferToImage (Context& context, TestParams testParams)
2449 : CopiesAndBlittingTestInstance(context, testParams)
2450 , m_textureFormat(mapVkFormat(testParams.dst.image.format))
2451 , m_bufferSize(m_params.src.buffer.size * tcu::getPixelSize(m_textureFormat))
2452 {
2453 const InstanceInterface& vki = context.getInstanceInterface();
2454 const DeviceInterface& vk = context.getDeviceInterface();
2455 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
2456 const VkDevice vkDevice = m_device;
2457 Allocator& memAlloc = context.getDefaultAllocator();
2458
2459 // Create source buffer
2460 {
2461 const VkBufferCreateInfo sourceBufferParams =
2462 {
2463 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2464 DE_NULL, // const void* pNext;
2465 0u, // VkBufferCreateFlags flags;
2466 m_bufferSize, // VkDeviceSize size;
2467 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage;
2468 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2469 0u, // deUint32 queueFamilyIndexCount;
2470 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
2471 };
2472
2473 m_source = createBuffer(vk, vkDevice, &sourceBufferParams);
2474 m_sourceBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
2475 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
2476 }
2477
2478 // Create destination image
2479 {
2480 const VkImageCreateInfo destinationImageParams =
2481 {
2482 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
2483 DE_NULL, // const void* pNext;
2484 getCreateFlags(m_params.dst.image), // VkImageCreateFlags flags;
2485 m_params.dst.image.imageType, // VkImageType imageType;
2486 m_params.dst.image.format, // VkFormat format;
2487 getExtent3D(m_params.dst.image), // VkExtent3D extent;
2488 1u, // deUint32 mipLevels;
2489 getArraySize(m_params.dst.image), // deUint32 arraySize;
2490 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
2491 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
2492 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2493 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
2494 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2495 0u, // deUint32 queueFamilyIndexCount;
2496 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
2497 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
2498 };
2499
2500 m_destination = createImage(vk, vkDevice, &destinationImageParams);
2501 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
2502 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
2503 }
2504 }
2505
iterate(void)2506 tcu::TestStatus CopyBufferToImage::iterate (void)
2507 {
2508 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.src.buffer.size, 1));
2509 generateBuffer(m_sourceTextureLevel->getAccess(), (int)m_params.src.buffer.size, 1, 1);
2510 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
2511 m_params.dst.image.extent.width,
2512 m_params.dst.image.extent.height,
2513 m_params.dst.image.extent.depth));
2514
2515 generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
2516
2517 generateExpectedResult();
2518
2519 uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
2520 uploadImage(m_destinationTextureLevel->getAccess(), *m_destination, m_params.dst.image);
2521
2522 const DeviceInterface& vk = m_context.getDeviceInterface();
2523 const VkDevice vkDevice = m_device;
2524 const VkQueue queue = m_queue;
2525
2526 const VkImageMemoryBarrier imageBarrier =
2527 {
2528 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
2529 DE_NULL, // const void* pNext;
2530 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
2531 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
2532 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
2533 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
2534 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
2535 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
2536 *m_destination, // VkImage image;
2537 { // VkImageSubresourceRange subresourceRange;
2538 getAspectFlags(m_textureFormat), // VkImageAspectFlags aspectMask;
2539 0u, // deUint32 baseMipLevel;
2540 1u, // deUint32 mipLevels;
2541 0u, // deUint32 baseArraySlice;
2542 getArraySize(m_params.dst.image) // deUint32 arraySize;
2543 }
2544 };
2545
2546 // Copy from buffer to image
2547 std::vector<VkBufferImageCopy> bufferImageCopies;
2548 std::vector<VkBufferImageCopy2KHR> bufferImageCopies2KHR;
2549 for (deUint32 i = 0; i < m_params.regions.size(); i++)
2550 {
2551 if (m_params.extensionUse == EXTENSION_USE_NONE)
2552 {
2553 bufferImageCopies.push_back(m_params.regions[i].bufferImageCopy);
2554 }
2555 else
2556 {
2557 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2558 bufferImageCopies2KHR.push_back(convertvkBufferImageCopyTovkBufferImageCopy2KHR(m_params.regions[i].bufferImageCopy));
2559 }
2560 }
2561
2562 beginCommandBuffer(vk, *m_cmdBuffer);
2563 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);
2564
2565 if (m_params.extensionUse == EXTENSION_USE_NONE)
2566 {
2567 vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), bufferImageCopies.data());
2568 }
2569 #ifndef CTS_USES_VULKANSC
2570 else
2571 {
2572 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2573 const VkCopyBufferToImageInfo2KHR copyBufferToImageInfo2KHR =
2574 {
2575 VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR, // VkStructureType sType;
2576 DE_NULL, // const void* pNext;
2577 m_source.get(), // VkBuffer srcBuffer;
2578 m_destination.get(), // VkImage dstImage;
2579 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout dstImageLayout;
2580 (deUint32)m_params.regions.size(), // uint32_t regionCount;
2581 bufferImageCopies2KHR.data() // const VkBufferImageCopy2KHR* pRegions;
2582 };
2583
2584 vk.cmdCopyBufferToImage2(*m_cmdBuffer, ©BufferToImageInfo2KHR);
2585 }
2586 #endif // CTS_USES_VULKANSC
2587
2588 endCommandBuffer(vk, *m_cmdBuffer);
2589
2590 submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
2591 m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
2592
2593 de::MovePtr<tcu::TextureLevel> resultLevel = readImage(*m_destination, m_params.dst.image);
2594
2595 return checkTestResult(resultLevel->getAccess());
2596 }
2597
2598 class CopyBufferToImageTestCase : public vkt::TestCase
2599 {
2600 public:
CopyBufferToImageTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)2601 CopyBufferToImageTestCase (tcu::TestContext& testCtx,
2602 const std::string& name,
2603 const std::string& description,
2604 const TestParams params)
2605 : vkt::TestCase (testCtx, name, description)
2606 , m_params (params)
2607 {}
2608
~CopyBufferToImageTestCase(void)2609 virtual ~CopyBufferToImageTestCase (void) {}
2610
createInstance(Context & context) const2611 virtual TestInstance* createInstance (Context& context) const
2612 {
2613 return new CopyBufferToImage(context, m_params);
2614 }
2615
checkSupport(Context & context) const2616 virtual void checkSupport (Context& context) const
2617 {
2618 if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
2619 (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
2620 {
2621 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
2622 }
2623 }
2624
2625
2626 private:
2627 TestParams m_params;
2628 };
2629
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)2630 void CopyBufferToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
2631 {
2632 DE_UNREF(mipLevel);
2633
2634 deUint32 rowLength = region.bufferImageCopy.bufferRowLength;
2635 if (!rowLength)
2636 rowLength = region.bufferImageCopy.imageExtent.width;
2637
2638 deUint32 imageHeight = region.bufferImageCopy.bufferImageHeight;
2639 if (!imageHeight)
2640 imageHeight = region.bufferImageCopy.imageExtent.height;
2641
2642 const int texelSize = dst.getFormat().getPixelSize();
2643 const VkExtent3D extent = region.bufferImageCopy.imageExtent;
2644 const VkOffset3D dstOffset = region.bufferImageCopy.imageOffset;
2645 const int texelOffset = (int) region.bufferImageCopy.bufferOffset / texelSize;
2646 const deUint32 baseArrayLayer = region.bufferImageCopy.imageSubresource.baseArrayLayer;
2647
2648 for (deUint32 z = 0; z < extent.depth; z++)
2649 {
2650 for (deUint32 y = 0; y < extent.height; y++)
2651 {
2652 int texelIndex = texelOffset + (z * imageHeight + y) * rowLength;
2653 const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
2654 const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dst, dstOffset.x, dstOffset.y + y, dstOffset.z + z + baseArrayLayer,
2655 region.bufferImageCopy.imageExtent.width, 1, 1);
2656 tcu::copy(dstSubRegion, srcSubRegion);
2657 }
2658 }
2659 }
2660
2661 class CopyBufferToDepthStencil : public CopiesAndBlittingTestInstance
2662 {
2663 public:
2664 CopyBufferToDepthStencil (Context& context,
2665 TestParams testParams);
2666 virtual tcu::TestStatus iterate (void);
2667 private:
2668 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
2669
2670 tcu::TextureFormat m_textureFormat;
2671 VkDeviceSize m_bufferSize;
2672
2673 Move<VkBuffer> m_source;
2674 de::MovePtr<Allocation> m_sourceBufferAlloc;
2675 Move<VkImage> m_destination;
2676 de::MovePtr<Allocation> m_destinationImageAlloc;
2677 };
2678
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)2679 void CopyBufferToDepthStencil::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
2680 {
2681 DE_UNREF(mipLevel);
2682
2683 deUint32 rowLength = region.bufferImageCopy.bufferRowLength;
2684 if (!rowLength)
2685 rowLength = region.bufferImageCopy.imageExtent.width;
2686
2687 deUint32 imageHeight = region.bufferImageCopy.bufferImageHeight;
2688 if (!imageHeight)
2689 imageHeight = region.bufferImageCopy.imageExtent.height;
2690
2691 const int texelSize = dst.getFormat().getPixelSize();
2692 const VkExtent3D extent = region.bufferImageCopy.imageExtent;
2693 const VkOffset3D dstOffset = region.bufferImageCopy.imageOffset;
2694 const int texelOffset = (int)region.bufferImageCopy.bufferOffset / texelSize;
2695
2696 for (deUint32 z = 0; z < extent.depth; z++)
2697 {
2698 for (deUint32 y = 0; y < extent.height; y++)
2699 {
2700 int texelIndex = texelOffset + (z * imageHeight + y) * rowLength;
2701 const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
2702 const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dst, dstOffset.x, dstOffset.y + y, dstOffset.z + z,
2703 region.bufferImageCopy.imageExtent.width, 1, 1);
2704
2705 if (region.bufferImageCopy.imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)
2706 {
2707 tcu::copy(dstSubRegion, tcu::getEffectiveDepthStencilAccess(srcSubRegion, tcu::Sampler::MODE_DEPTH), DE_FALSE);
2708 }
2709 else
2710 {
2711 tcu::copy(dstSubRegion, tcu::getEffectiveDepthStencilAccess(srcSubRegion, tcu::Sampler::MODE_STENCIL), DE_FALSE);
2712 }
2713 }
2714 }
2715 }
2716
isSupportedDepthStencilFormat(const InstanceInterface & vki,const VkPhysicalDevice physDevice,const VkFormat format)2717 bool isSupportedDepthStencilFormat(const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format)
2718 {
2719 VkFormatProperties formatProps;
2720 vki.getPhysicalDeviceFormatProperties(physDevice, format, &formatProps);
2721 return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0;
2722 }
2723
CopyBufferToDepthStencil(Context & context,TestParams testParams)2724 CopyBufferToDepthStencil::CopyBufferToDepthStencil(Context& context, TestParams testParams)
2725 : CopiesAndBlittingTestInstance(context, testParams)
2726 , m_textureFormat(mapVkFormat(testParams.dst.image.format))
2727 , m_bufferSize(0)
2728 {
2729 const InstanceInterface& vki = context.getInstanceInterface();
2730 const DeviceInterface& vk = context.getDeviceInterface();
2731 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
2732 const VkDevice vkDevice = m_device;
2733 Allocator& memAlloc = context.getDefaultAllocator();
2734 const bool hasDepth = tcu::hasDepthComponent(mapVkFormat(m_params.dst.image.format).order);
2735 const bool hasStencil = tcu::hasStencilComponent(mapVkFormat(m_params.dst.image.format).order);
2736
2737 if (!isSupportedDepthStencilFormat(vki, vkPhysDevice, testParams.dst.image.format))
2738 {
2739 TCU_THROW(NotSupportedError, "Image format not supported.");
2740 }
2741
2742 if (hasDepth)
2743 {
2744 glw::GLuint texelSize = m_textureFormat.getPixelSize();
2745 if (texelSize > sizeof(float))
2746 {
2747 // We must have D32F_S8 format, depth must be packed so we only need
2748 // to allocate space for the D32F part. Stencil will be separate
2749 texelSize = sizeof(float);
2750 }
2751 m_bufferSize += static_cast<VkDeviceSize>(m_params.dst.image.extent.width) * static_cast<VkDeviceSize>(m_params.dst.image.extent.height) * static_cast<VkDeviceSize>(texelSize);
2752 }
2753 if (hasStencil)
2754 {
2755 // Stencil is always 8bits and packed.
2756 m_bufferSize += static_cast<VkDeviceSize>(m_params.dst.image.extent.width) * static_cast<VkDeviceSize>(m_params.dst.image.extent.height);
2757 }
2758
2759 // Create source buffer, this is where the depth & stencil data will go that's used by test's regions.
2760 {
2761 const VkBufferCreateInfo sourceBufferParams =
2762 {
2763 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2764 DE_NULL, // const void* pNext;
2765 0u, // VkBufferCreateFlags flags;
2766 m_bufferSize, // VkDeviceSize size;
2767 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage;
2768 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2769 0u, // deUint32 queueFamilyIndexCount;
2770 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
2771 };
2772
2773 m_source = createBuffer(vk, vkDevice, &sourceBufferParams);
2774 m_sourceBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
2775 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
2776 }
2777
2778 // Create destination image
2779 {
2780 const VkImageCreateInfo destinationImageParams =
2781 {
2782 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
2783 DE_NULL, // const void* pNext;
2784 getCreateFlags(m_params.dst.image), // VkImageCreateFlags flags;
2785 m_params.dst.image.imageType, // VkImageType imageType;
2786 m_params.dst.image.format, // VkFormat format;
2787 getExtent3D(m_params.dst.image), // VkExtent3D extent;
2788 1u, // deUint32 mipLevels;
2789 getArraySize(m_params.dst.image), // deUint32 arraySize;
2790 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
2791 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
2792 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2793 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
2794 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2795 0u, // deUint32 queueFamilyIndexCount;
2796 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
2797 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
2798 };
2799
2800 m_destination = createImage(vk, vkDevice, &destinationImageParams);
2801 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
2802 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
2803 }
2804 }
2805
iterate(void)2806 tcu::TestStatus CopyBufferToDepthStencil::iterate(void)
2807 {
2808 // Create source depth/stencil content. Treat as 1D texture to get different pattern
2809 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.src.buffer.size, 1));
2810 // Fill buffer with linear gradiant
2811 generateBuffer(m_sourceTextureLevel->getAccess(), (int)m_params.src.buffer.size, 1, 1);
2812
2813 // Create image layer for depth/stencil
2814 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
2815 m_params.dst.image.extent.width,
2816 m_params.dst.image.extent.height,
2817 m_params.dst.image.extent.depth));
2818
2819 // Fill image layer with 2D gradiant
2820 generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
2821
2822 // Fill m_extendedTextureLevel with copy of m_destinationTextureLevel
2823 // Then iterate over each of the regions given in m_params.regions and copy m_sourceTextureLevel content to m_extendedTextureLevel
2824 // This emulates what the HW will be doing.
2825 generateExpectedResult();
2826
2827 // Upload our source depth/stencil content to the source buffer
2828 // This is the buffer that will be used by region commands
2829 std::vector<VkBufferImageCopy> bufferImageCopies;
2830 std::vector<VkBufferImageCopy2KHR> bufferImageCopies2KHR;
2831 VkDeviceSize bufferOffset = 0;
2832 const VkDevice vkDevice = m_device;
2833 const DeviceInterface& vk = m_context.getDeviceInterface();
2834 const VkQueue queue = m_queue;
2835 char* dstPtr = reinterpret_cast<char*>(m_sourceBufferAlloc->getHostPtr());
2836 bool depthLoaded = DE_FALSE;
2837 bool stencilLoaded = DE_FALSE;
2838 VkDeviceSize depthOffset = 0;
2839 VkDeviceSize stencilOffset = 0;
2840
2841 // To be able to test ordering depth & stencil differently
2842 // we take the given copy regions and use that as the desired order
2843 // and copy the appropriate data into place and compute the appropriate
2844 // data offsets to be used in the copy command.
2845 for (deUint32 i = 0; i < m_params.regions.size(); i++)
2846 {
2847 tcu::ConstPixelBufferAccess bufferAccess = m_sourceTextureLevel->getAccess();
2848 deUint32 bufferSize = bufferAccess.getWidth() * bufferAccess.getHeight() * bufferAccess.getDepth();
2849 VkBufferImageCopy copyData = m_params.regions[i].bufferImageCopy;
2850 char* srcPtr;
2851
2852 if (copyData.imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT && !depthLoaded)
2853 {
2854 // Create level that is same component as depth buffer (e.g. D16, D24, D32F)
2855 tcu::TextureLevel depthTexture(mapCombinedToDepthTransferFormat(bufferAccess.getFormat()), bufferAccess.getWidth(), bufferAccess.getHeight(), bufferAccess.getDepth());
2856 bufferSize *= tcu::getPixelSize(depthTexture.getFormat());
2857 // Copy depth component only from source data. This gives us packed depth-only data.
2858 tcu::copy(depthTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(bufferAccess, tcu::Sampler::MODE_DEPTH));
2859 srcPtr = (char*)depthTexture.getAccess().getDataPtr();
2860 // Copy packed depth-only data to output buffer
2861 deMemcpy(dstPtr, srcPtr, bufferSize);
2862 depthLoaded = DE_TRUE;
2863 depthOffset = bufferOffset;
2864 dstPtr += bufferSize;
2865 bufferOffset += bufferSize;
2866 copyData.bufferOffset += depthOffset;
2867 }
2868 else if (!stencilLoaded)
2869 {
2870 // Create level that is same component as stencil buffer (always 8-bits)
2871 tcu::TextureLevel stencilTexture(tcu::getEffectiveDepthStencilTextureFormat(bufferAccess.getFormat(), tcu::Sampler::MODE_STENCIL), bufferAccess.getWidth(), bufferAccess.getHeight(), bufferAccess.getDepth());
2872 // Copy stencil component only from source data. This gives us packed stencil-only data.
2873 tcu::copy(stencilTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(bufferAccess, tcu::Sampler::MODE_STENCIL));
2874 srcPtr = (char*)stencilTexture.getAccess().getDataPtr();
2875 // Copy packed stencil-only data to output buffer
2876 deMemcpy(dstPtr, srcPtr, bufferSize);
2877 stencilLoaded = DE_TRUE;
2878 stencilOffset = bufferOffset;
2879 dstPtr += bufferSize;
2880 bufferOffset += bufferSize;
2881
2882 // Reference image generation uses pixel offsets based on buffer offset.
2883 // We need to adjust the offset now that the stencil data is not interleaved.
2884 copyData.bufferOffset /= tcu::getPixelSize(m_textureFormat);
2885
2886 copyData.bufferOffset += stencilOffset;
2887 }
2888
2889 if (m_params.extensionUse == EXTENSION_USE_NONE)
2890 {
2891 bufferImageCopies.push_back(copyData);
2892 }
2893 else
2894 {
2895 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2896 bufferImageCopies2KHR.push_back(convertvkBufferImageCopyTovkBufferImageCopy2KHR(copyData));
2897 }
2898 }
2899
2900 flushAlloc(vk, vkDevice, *m_sourceBufferAlloc);
2901
2902 // Upload the depth/stencil data from m_destinationTextureLevel to initialize
2903 // depth and stencil to known values.
2904 // Uses uploadImageAspect so makes its own buffers for depth and stencil
2905 // aspects (as needed) and copies them with independent vkCmdCopyBufferToImage commands.
2906 uploadImage(m_destinationTextureLevel->getAccess(), *m_destination, m_params.dst.image);
2907
2908 const VkImageMemoryBarrier imageBarrier =
2909 {
2910 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
2911 DE_NULL, // const void* pNext;
2912 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
2913 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
2914 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
2915 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
2916 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
2917 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
2918 *m_destination, // VkImage image;
2919 { // VkImageSubresourceRange subresourceRange;
2920 getAspectFlags(m_textureFormat), // VkImageAspectFlags aspectMask;
2921 0u, // deUint32 baseMipLevel;
2922 1u, // deUint32 mipLevels;
2923 0u, // deUint32 baseArraySlice;
2924 1u // deUint32 arraySize;
2925 }
2926 };
2927
2928 // Copy from buffer to depth/stencil image
2929
2930 beginCommandBuffer(vk, *m_cmdBuffer);
2931 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);
2932
2933 if (m_params.extensionUse == EXTENSION_USE_NONE)
2934 {
2935 if (m_params.singleCommand)
2936 {
2937 // Issue a single copy command with regions defined by the test.
2938 vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), bufferImageCopies.data());
2939 }
2940 else
2941 {
2942 // Issue a a copy command per region defined by the test.
2943 for (deUint32 i = 0; i < bufferImageCopies.size(); i++)
2944 {
2945 vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferImageCopies[i]);
2946 }
2947 }
2948 }
2949 #ifndef CTS_USES_VULKANSC
2950 else
2951 {
2952 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2953
2954 if (m_params.singleCommand)
2955 {
2956 // Issue a single copy command with regions defined by the test.
2957 const VkCopyBufferToImageInfo2KHR copyBufferToImageInfo2KHR =
2958 {
2959 VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR, // VkStructureType sType;
2960 DE_NULL, // const void* pNext;
2961 m_source.get(), // VkBuffer srcBuffer;
2962 m_destination.get(), // VkImage dstImage;
2963 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout dstImageLayout;
2964 (deUint32)m_params.regions.size(), // uint32_t regionCount;
2965 bufferImageCopies2KHR.data() // const VkBufferImageCopy2KHR* pRegions;
2966 };
2967 vk.cmdCopyBufferToImage2(*m_cmdBuffer, ©BufferToImageInfo2KHR);
2968 }
2969 else
2970 {
2971 // Issue a a copy command per region defined by the test.
2972 for (deUint32 i = 0; i < bufferImageCopies2KHR.size(); i++)
2973 {
2974 const VkCopyBufferToImageInfo2KHR copyBufferToImageInfo2KHR =
2975 {
2976 VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR, // VkStructureType sType;
2977 DE_NULL, // const void* pNext;
2978 m_source.get(), // VkBuffer srcBuffer;
2979 m_destination.get(), // VkImage dstImage;
2980 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout dstImageLayout;
2981 1, // uint32_t regionCount;
2982 &bufferImageCopies2KHR[i] // const VkBufferImageCopy2KHR* pRegions;
2983 };
2984 // Issue a single copy command with regions defined by the test.
2985 vk.cmdCopyBufferToImage2(*m_cmdBuffer, ©BufferToImageInfo2KHR);
2986 }
2987 }
2988 }
2989 #endif // CTS_USES_VULKANSC
2990
2991 endCommandBuffer(vk, *m_cmdBuffer);
2992
2993 submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
2994 m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
2995
2996 de::MovePtr<tcu::TextureLevel> resultLevel = readImage(*m_destination, m_params.dst.image);
2997
2998 // For combined depth/stencil formats both aspects are checked even when the test only
2999 // copies one. Clear such aspects here for both the result and the reference.
3000 if (tcu::hasDepthComponent(m_textureFormat.order) && !depthLoaded)
3001 {
3002 tcu::clearDepth(m_expectedTextureLevel[0]->getAccess(), 0.0f);
3003 tcu::clearDepth(resultLevel->getAccess(), 0.0f);
3004 }
3005 if (tcu::hasStencilComponent(m_textureFormat.order) && !stencilLoaded)
3006 {
3007 tcu::clearStencil(m_expectedTextureLevel[0]->getAccess(), 0);
3008 tcu::clearStencil(resultLevel->getAccess(), 0);
3009 }
3010
3011 return checkTestResult(resultLevel->getAccess());
3012 }
3013
3014 class CopyBufferToDepthStencilTestCase : public vkt::TestCase
3015 {
3016 public:
CopyBufferToDepthStencilTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)3017 CopyBufferToDepthStencilTestCase (tcu::TestContext& testCtx,
3018 const std::string& name,
3019 const std::string& description,
3020 const TestParams params)
3021 : vkt::TestCase(testCtx, name, description)
3022 , m_params(params)
3023 {}
3024
~CopyBufferToDepthStencilTestCase(void)3025 virtual ~CopyBufferToDepthStencilTestCase (void) {}
3026
createInstance(Context & context) const3027 virtual TestInstance* createInstance (Context& context) const
3028 {
3029 return new CopyBufferToDepthStencil(context, m_params);
3030 }
3031
checkSupport(Context & context) const3032 virtual void checkSupport (Context& context) const
3033 {
3034 if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
3035 (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
3036 {
3037 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
3038 }
3039 }
3040
3041 private:
3042 TestParams m_params;
3043 };
3044
3045 // CompressedTextureForBlit is a helper class that stores compressed texture data.
3046 // Implementation is based on pipeline::TestTexture2D but it allocates only one level
3047 // and has special cases needed for blits to some formats.
3048
3049 class CompressedTextureForBlit
3050 {
3051 public:
3052 CompressedTextureForBlit(const tcu::CompressedTexFormat& srcFormat, int width, int height, int depth);
3053
3054 tcu::PixelBufferAccess getDecompressedAccess() const;
3055 const tcu::CompressedTexture& getCompressedTexture() const;
3056
3057 protected:
3058
3059 tcu::CompressedTexture m_compressedTexture;
3060 de::ArrayBuffer<deUint8> m_decompressedData;
3061 tcu::PixelBufferAccess m_decompressedAccess;
3062 };
3063
CompressedTextureForBlit(const tcu::CompressedTexFormat & srcFormat,int width,int height,int depth)3064 CompressedTextureForBlit::CompressedTextureForBlit(const tcu::CompressedTexFormat& srcFormat, int width, int height, int depth)
3065 : m_compressedTexture(srcFormat, width, height, depth)
3066 {
3067 de::Random random (123);
3068
3069 const int compressedDataSize (m_compressedTexture.getDataSize());
3070 deUint8* compressedData ((deUint8*)m_compressedTexture.getData());
3071
3072 tcu::TextureFormat decompressedSrcFormat (tcu::getUncompressedFormat(srcFormat));
3073 const int decompressedDataSize (tcu::getPixelSize(decompressedSrcFormat) * width * height * depth);
3074
3075 // generate random data for compresed textre
3076 if (tcu::isAstcFormat(srcFormat))
3077 {
3078 // comparison doesn't currently handle invalid blocks correctly so we use only valid blocks
3079 tcu::astc::generateRandomValidBlocks(compressedData, compressedDataSize / tcu::astc::BLOCK_SIZE_BYTES,
3080 srcFormat, tcu::TexDecompressionParams::ASTCMODE_LDR, random.getUint32());
3081 }
3082 else if ((srcFormat == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK) ||
3083 (srcFormat == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK))
3084 {
3085 // special case - when we are blitting compressed floating-point image we can't have both big and small values
3086 // in compressed image; to resolve this we are constructing source texture out of set of predefined compressed
3087 // blocks that after decompression will have components in proper range
3088
3089 struct BC6HBlock
3090 {
3091 deUint32 data[4];
3092 };
3093 std::vector<BC6HBlock> validBlocks;
3094
3095 if (srcFormat == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK)
3096 {
3097 // define set of few valid blocks that contain values from <0; 1> range
3098 validBlocks =
3099 {
3100 { { 1686671500, 3957317723, 3010132342, 2420137890 } },
3101 { { 3538027716, 298848033, 1925786021, 2022072301 } },
3102 { { 2614043466, 1636155440, 1023731774, 1894349986 } },
3103 { { 3433039318, 1294346072, 1587319645, 1738449906 } },
3104 { { 1386298160, 1639492154, 1273285776, 361562050 } },
3105 { { 1310110688, 526460754, 3630858047, 537617591 } },
3106 { { 3270356556, 2432993217, 2415924417, 1792488857 } },
3107 { { 1204947583, 353249154, 3739153467, 2068076443 } },
3108 };
3109 }
3110 else
3111 {
3112 // define set of few valid blocks that contain values from <-1; 1> range
3113 validBlocks =
3114 {
3115 { { 2120678840, 3264271120, 4065378848, 3479743703 } },
3116 { { 1479697556, 3480872527, 3369382558, 568252340 } },
3117 { { 1301480032, 1607738094, 3055221704, 3663953681 } },
3118 { { 3531657186, 2285472028, 1429601507, 1969308187 } },
3119 { { 73229044, 650504649, 1120954865, 2626631975 } },
3120 { { 3872486086, 15326178, 2565171269, 2857722432 } },
3121 { { 1301480032, 1607738094, 3055221704, 3663953681 } },
3122 { { 73229044, 650504649, 1120954865, 2626631975 } },
3123 };
3124 }
3125
3126 deUint32* compressedDataUint32 = reinterpret_cast<deUint32*>(compressedData);
3127 const int blocksCount = compressedDataSize / static_cast<int>(sizeof(BC6HBlock));
3128
3129 // fill data using randomly selected valid blocks
3130 for (int blockNdx = 0; blockNdx < blocksCount; blockNdx++)
3131 {
3132 deUint32 selectedBlock = random.getUint32() % static_cast<deUint32>(validBlocks.size());
3133 deMemcpy(compressedDataUint32, validBlocks[selectedBlock].data, sizeof(BC6HBlock));
3134 compressedDataUint32 += 4;
3135 }
3136 }
3137 else if (srcFormat != tcu::COMPRESSEDTEXFORMAT_ETC1_RGB8)
3138 {
3139 // random initial values cause assertion during the decompression in case of COMPRESSEDTEXFORMAT_ETC1_RGB8 format
3140 for (int byteNdx = 0; byteNdx < compressedDataSize; byteNdx++)
3141 compressedData[byteNdx] = 0xFF & random.getUint32();
3142 }
3143
3144 // alocate space for decompressed texture
3145 m_decompressedData.setStorage(decompressedDataSize);
3146 m_decompressedAccess = tcu::PixelBufferAccess(decompressedSrcFormat, width, height, depth, m_decompressedData.getPtr());
3147
3148 // store decompressed data
3149 m_compressedTexture.decompress(m_decompressedAccess, tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR));
3150 }
3151
getDecompressedAccess() const3152 tcu::PixelBufferAccess CompressedTextureForBlit::getDecompressedAccess() const
3153 {
3154 return m_decompressedAccess;
3155 }
3156
getCompressedTexture() const3157 const tcu::CompressedTexture& CompressedTextureForBlit::getCompressedTexture() const
3158 {
3159 return m_compressedTexture;
3160 }
3161
3162 // Copy from image to image with scaling.
3163
3164 class BlittingImages : public CopiesAndBlittingTestInstance
3165 {
3166 public:
3167 BlittingImages (Context& context,
3168 TestParams params);
3169 virtual tcu::TestStatus iterate (void);
3170 protected:
3171 virtual tcu::TestStatus checkTestResult (tcu::ConstPixelBufferAccess result);
3172 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src,
3173 tcu::PixelBufferAccess dst,
3174 CopyRegion region,
3175 deUint32 mipLevel = 0u);
3176 virtual void generateExpectedResult (void);
3177 void uploadCompressedImage (const VkImage& image, const ImageParms& parms);
3178 private:
3179 bool checkNonNearestFilteredResult (const tcu::ConstPixelBufferAccess& result,
3180 const tcu::ConstPixelBufferAccess& clampedReference,
3181 const tcu::ConstPixelBufferAccess& unclampedReference,
3182 const tcu::TextureFormat& sourceFormat);
3183 bool checkNearestFilteredResult (const tcu::ConstPixelBufferAccess& result,
3184 const tcu::ConstPixelBufferAccess& source);
3185
3186 bool checkCompressedNonNearestFilteredResult (const tcu::ConstPixelBufferAccess& result,
3187 const tcu::ConstPixelBufferAccess& clampedReference,
3188 const tcu::ConstPixelBufferAccess& unclampedReference,
3189 const tcu::CompressedTexFormat format);
3190 bool checkCompressedNearestFilteredResult (const tcu::ConstPixelBufferAccess& result,
3191 const tcu::ConstPixelBufferAccess& source,
3192 const tcu::CompressedTexFormat format);
3193
3194
3195 Move<VkImage> m_source;
3196 de::MovePtr<Allocation> m_sourceImageAlloc;
3197 Move<VkImage> m_destination;
3198 de::MovePtr<Allocation> m_destinationImageAlloc;
3199
3200 de::MovePtr<tcu::TextureLevel> m_unclampedExpectedTextureLevel;
3201
3202 // helper used only when bliting from compressed formats
3203 typedef de::SharedPtr<CompressedTextureForBlit> CompressedTextureForBlitSp;
3204 CompressedTextureForBlitSp m_sourceCompressedTexture;
3205 CompressedTextureForBlitSp m_destinationCompressedTexture;
3206 };
3207
BlittingImages(Context & context,TestParams params)3208 BlittingImages::BlittingImages (Context& context, TestParams params)
3209 : CopiesAndBlittingTestInstance(context, params)
3210 {
3211 const InstanceInterface& vki = context.getInstanceInterface();
3212 const DeviceInterface& vk = context.getDeviceInterface();
3213 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
3214 const VkDevice vkDevice = m_device;
3215 Allocator& memAlloc = context.getDefaultAllocator();
3216
3217 // Create source image
3218 {
3219 const VkImageCreateInfo sourceImageParams =
3220 {
3221 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
3222 DE_NULL, // const void* pNext;
3223 getCreateFlags(m_params.src.image), // VkImageCreateFlags flags;
3224 m_params.src.image.imageType, // VkImageType imageType;
3225 m_params.src.image.format, // VkFormat format;
3226 getExtent3D(m_params.src.image), // VkExtent3D extent;
3227 1u, // deUint32 mipLevels;
3228 getArraySize(m_params.src.image), // deUint32 arraySize;
3229 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
3230 m_params.src.image.tiling, // VkImageTiling tiling;
3231 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
3232 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
3233 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
3234 0u, // deUint32 queueFamilyIndexCount;
3235 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
3236 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
3237 };
3238
3239 m_source = createImage(vk, vkDevice, &sourceImageParams);
3240 m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
3241 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
3242 }
3243
3244 // Create destination image
3245 {
3246 const VkImageCreateInfo destinationImageParams =
3247 {
3248 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
3249 DE_NULL, // const void* pNext;
3250 getCreateFlags(m_params.dst.image), // VkImageCreateFlags flags;
3251 m_params.dst.image.imageType, // VkImageType imageType;
3252 m_params.dst.image.format, // VkFormat format;
3253 getExtent3D(m_params.dst.image), // VkExtent3D extent;
3254 1u, // deUint32 mipLevels;
3255 getArraySize(m_params.dst.image), // deUint32 arraySize;
3256 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
3257 m_params.dst.image.tiling, // VkImageTiling tiling;
3258 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
3259 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
3260 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
3261 0u, // deUint32 queueFamilyIndexCount;
3262 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
3263 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
3264 };
3265
3266 m_destination = createImage(vk, vkDevice, &destinationImageParams);
3267 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
3268 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
3269 }
3270 }
3271
iterate(void)3272 tcu::TestStatus BlittingImages::iterate (void)
3273 {
3274 const DeviceInterface& vk = m_context.getDeviceInterface();
3275 const VkDevice vkDevice = m_device;
3276 const VkQueue queue = m_queue;
3277
3278 const ImageParms& srcImageParams = m_params.src.image;
3279 const int srcWidth = static_cast<int>(srcImageParams.extent.width);
3280 const int srcHeight = static_cast<int>(srcImageParams.extent.height);
3281 const int srcDepth = static_cast<int>(srcImageParams.extent.depth);
3282 const ImageParms& dstImageParams = m_params.dst.image;
3283 const int dstWidth = static_cast<int>(dstImageParams.extent.width);
3284 const int dstHeight = static_cast<int>(dstImageParams.extent.height);
3285 const int dstDepth = static_cast<int>(dstImageParams.extent.depth);
3286
3287 std::vector<VkImageBlit> regions;
3288 std::vector<VkImageBlit2KHR> regions2KHR;
3289
3290 // setup blit regions - they are also needed for reference generation
3291 if (m_params.extensionUse == EXTENSION_USE_NONE)
3292 {
3293 regions.reserve(m_params.regions.size());
3294 for (const auto& r : m_params.regions)
3295 regions.push_back(r.imageBlit);
3296 }
3297 else
3298 {
3299 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
3300 regions2KHR.reserve(m_params.regions.size());
3301 for (const auto& r : m_params.regions)
3302 regions2KHR.push_back(convertvkImageBlitTovkImageBlit2KHR(r.imageBlit));
3303 }
3304
3305 // generate source image
3306 if (isCompressedFormat(srcImageParams.format))
3307 {
3308 // for compressed images srcImageParams.fillMode is not used - we are using random data
3309 tcu::CompressedTexFormat compressedFormat = mapVkCompressedFormat(srcImageParams.format);
3310 m_sourceCompressedTexture = CompressedTextureForBlitSp(new CompressedTextureForBlit(compressedFormat, srcWidth, srcHeight, srcDepth));
3311 uploadCompressedImage(m_source.get(), srcImageParams);
3312 }
3313 else
3314 {
3315 // non-compressed image is filled with selected fillMode
3316 const tcu::TextureFormat srcTcuFormat = mapVkFormat(srcImageParams.format);
3317 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat, srcWidth, srcHeight, srcDepth));
3318 generateBuffer(m_sourceTextureLevel->getAccess(), srcWidth, srcHeight, srcDepth, srcImageParams.fillMode);
3319 uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), srcImageParams);
3320 }
3321
3322 // generate destination image
3323 if (isCompressedFormat(dstImageParams.format))
3324 {
3325 // compressed images are filled with random data
3326 tcu::CompressedTexFormat compressedFormat = mapVkCompressedFormat(dstImageParams.format);
3327 m_destinationCompressedTexture = CompressedTextureForBlitSp(new CompressedTextureForBlit(compressedFormat, srcWidth, srcHeight, srcDepth));
3328 uploadCompressedImage(m_destination.get(), dstImageParams);
3329 }
3330 else
3331 {
3332 // non-compressed image is filled with white background
3333 const tcu::TextureFormat dstTcuFormat = mapVkFormat(dstImageParams.format);
3334 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat, dstWidth, dstHeight, dstDepth));
3335 generateBuffer(m_destinationTextureLevel->getAccess(), dstWidth, dstHeight, dstDepth, dstImageParams.fillMode);
3336 uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), dstImageParams);
3337 }
3338
3339 generateExpectedResult();
3340
3341 // Barriers for copying images to buffer
3342 const VkImageMemoryBarrier imageBarriers[]
3343 {
3344 {
3345 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
3346 DE_NULL, // const void* pNext;
3347 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
3348 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
3349 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
3350 srcImageParams.operationLayout, // VkImageLayout newLayout;
3351 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
3352 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
3353 m_source.get(), // VkImage image;
3354 { // VkImageSubresourceRange subresourceRange;
3355 getAspectFlags(srcImageParams.format), // VkImageAspectFlags aspectMask;
3356 0u, // deUint32 baseMipLevel;
3357 1u, // deUint32 mipLevels;
3358 0u, // deUint32 baseArraySlice;
3359 1u // deUint32 arraySize;
3360 }
3361 },
3362 {
3363 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
3364 DE_NULL, // const void* pNext;
3365 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
3366 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
3367 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
3368 dstImageParams.operationLayout, // VkImageLayout newLayout;
3369 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
3370 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
3371 m_destination.get(), // VkImage image;
3372 { // VkImageSubresourceRange subresourceRange;
3373 getAspectFlags(dstImageParams.format), // VkImageAspectFlags aspectMask;
3374 0u, // deUint32 baseMipLevel;
3375 1u, // deUint32 mipLevels;
3376 0u, // deUint32 baseArraySlice;
3377 1u // deUint32 arraySize;
3378 }
3379 }
3380 };
3381
3382 beginCommandBuffer(vk, *m_cmdBuffer);
3383 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);
3384
3385 if (m_params.extensionUse == EXTENSION_USE_NONE)
3386 {
3387 vk.cmdBlitImage(*m_cmdBuffer, m_source.get(), srcImageParams.operationLayout, m_destination.get(), dstImageParams.operationLayout, (deUint32)m_params.regions.size(), ®ions[0], m_params.filter);
3388 }
3389 #ifndef CTS_USES_VULKANSC
3390 else
3391 {
3392 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
3393 const VkBlitImageInfo2KHR blitImageInfo2KHR
3394 {
3395 VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR, // VkStructureType sType;
3396 DE_NULL, // const void* pNext;
3397 m_source.get(), // VkImage srcImage;
3398 srcImageParams.operationLayout, // VkImageLayout srcImageLayout;
3399 m_destination.get(), // VkImage dstImage;
3400 dstImageParams.operationLayout, // VkImageLayout dstImageLayout;
3401 (deUint32)m_params.regions.size(), // uint32_t regionCount;
3402 ®ions2KHR[0], // const VkImageBlit2KHR* pRegions;
3403 m_params.filter, // VkFilter filter;
3404 };
3405 vk.cmdBlitImage2(*m_cmdBuffer, &blitImageInfo2KHR);
3406 }
3407 #endif // CTS_USES_VULKANSC
3408
3409 endCommandBuffer(vk, *m_cmdBuffer);
3410 submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
3411 m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
3412
3413 de::MovePtr<tcu::TextureLevel> resultLevel = readImage(*m_destination, dstImageParams);
3414 tcu::PixelBufferAccess resultAccess = resultLevel->getAccess();
3415
3416 // if blit was done to a compressed format we need to decompress it to be able to verify it
3417 if (m_destinationCompressedTexture)
3418 {
3419 deUint8* const compressedDataSrc (static_cast<deUint8*>(resultAccess.getDataPtr()));
3420 const tcu::CompressedTexFormat dstCompressedFormat (mapVkCompressedFormat(dstImageParams.format));
3421 tcu::TextureLevel decompressedLevel (getUncompressedFormat(dstCompressedFormat), dstWidth, dstHeight, dstDepth);
3422 tcu::PixelBufferAccess decompressedAccess (decompressedLevel.getAccess());
3423
3424 tcu::decompress(decompressedAccess, dstCompressedFormat, compressedDataSrc);
3425
3426 return checkTestResult(decompressedAccess);
3427 }
3428
3429 return checkTestResult(resultAccess);
3430 }
3431
calculateFloatConversionError(int srcBits)3432 static float calculateFloatConversionError (int srcBits)
3433 {
3434 if (srcBits > 0)
3435 {
3436 const int clampedBits = de::clamp<int>(srcBits, 0, 32);
3437 const float srcMaxValue = de::max((float)(1ULL<<clampedBits) - 1.0f, 1.0f);
3438 const float error = 1.0f / srcMaxValue;
3439
3440 return de::clamp<float>(error, 0.0f, 1.0f);
3441 }
3442 else
3443 return 1.0f;
3444 }
3445
getFormatThreshold(const tcu::TextureFormat & format)3446 tcu::Vec4 getFormatThreshold (const tcu::TextureFormat& format)
3447 {
3448 tcu::Vec4 threshold(0.01f);
3449
3450 switch (format.type)
3451 {
3452 case tcu::TextureFormat::HALF_FLOAT:
3453 threshold = tcu::Vec4(0.005f);
3454 break;
3455
3456 case tcu::TextureFormat::FLOAT:
3457 case tcu::TextureFormat::FLOAT64:
3458 threshold = tcu::Vec4(0.001f);
3459 break;
3460
3461 case tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
3462 threshold = tcu::Vec4(0.02f, 0.02f, 0.0625f, 1.0f);
3463 break;
3464
3465 case tcu::TextureFormat::UNSIGNED_INT_999_E5_REV:
3466 threshold = tcu::Vec4(0.05f, 0.05f, 0.05f, 1.0f);
3467 break;
3468
3469 case tcu::TextureFormat::UNORM_INT_1010102_REV:
3470 threshold = tcu::Vec4(0.002f, 0.002f, 0.002f, 0.3f);
3471 break;
3472
3473 case tcu:: TextureFormat::UNORM_INT8:
3474 threshold = tcu::Vec4(0.008f, 0.008f, 0.008f, 0.008f);
3475 break;
3476
3477 default:
3478 const tcu::IVec4 bits = tcu::getTextureFormatMantissaBitDepth(format);
3479 threshold = tcu::Vec4(calculateFloatConversionError(bits.x()),
3480 calculateFloatConversionError(bits.y()),
3481 calculateFloatConversionError(bits.z()),
3482 calculateFloatConversionError(bits.w()));
3483 }
3484
3485 // Return value matching the channel order specified by the format
3486 if (format.order == tcu::TextureFormat::BGR || format.order == tcu::TextureFormat::BGRA)
3487 return threshold.swizzle(2, 1, 0, 3);
3488 else
3489 return threshold;
3490 }
3491
getCompressedFormatThreshold(const tcu::CompressedTexFormat & format)3492 tcu::Vec4 getCompressedFormatThreshold(const tcu::CompressedTexFormat& format)
3493 {
3494 bool isSigned(false);
3495 tcu::IVec4 bitDepth(0);
3496
3497 switch (format)
3498 {
3499 case tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_R11:
3500 bitDepth = { 7, 0, 0, 0 };
3501 isSigned = true;
3502 break;
3503
3504 case tcu::COMPRESSEDTEXFORMAT_EAC_R11:
3505 bitDepth = { 8, 0, 0, 0 };
3506 break;
3507
3508 case tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11:
3509 bitDepth = { 7, 7, 0, 0 };
3510 isSigned = true;
3511 break;
3512
3513 case tcu::COMPRESSEDTEXFORMAT_EAC_RG11:
3514 bitDepth = { 8, 8, 0, 0 };
3515 break;
3516
3517 case tcu::COMPRESSEDTEXFORMAT_ETC1_RGB8:
3518 case tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8:
3519 case tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8:
3520 bitDepth = { 8, 8, 8, 0 };
3521 break;
3522
3523 case tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
3524 case tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
3525 bitDepth = { 8, 8, 8, 1 };
3526 break;
3527
3528 case tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8:
3529 case tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8:
3530 case tcu::COMPRESSEDTEXFORMAT_ASTC_4x4_RGBA:
3531 case tcu::COMPRESSEDTEXFORMAT_ASTC_5x4_RGBA:
3532 case tcu::COMPRESSEDTEXFORMAT_ASTC_5x5_RGBA:
3533 case tcu::COMPRESSEDTEXFORMAT_ASTC_6x5_RGBA:
3534 case tcu::COMPRESSEDTEXFORMAT_ASTC_6x6_RGBA:
3535 case tcu::COMPRESSEDTEXFORMAT_ASTC_8x5_RGBA:
3536 case tcu::COMPRESSEDTEXFORMAT_ASTC_8x6_RGBA:
3537 case tcu::COMPRESSEDTEXFORMAT_ASTC_8x8_RGBA:
3538 case tcu::COMPRESSEDTEXFORMAT_ASTC_10x5_RGBA:
3539 case tcu::COMPRESSEDTEXFORMAT_ASTC_10x6_RGBA:
3540 case tcu::COMPRESSEDTEXFORMAT_ASTC_10x8_RGBA:
3541 case tcu::COMPRESSEDTEXFORMAT_ASTC_10x10_RGBA:
3542 case tcu::COMPRESSEDTEXFORMAT_ASTC_12x10_RGBA:
3543 case tcu::COMPRESSEDTEXFORMAT_ASTC_12x12_RGBA:
3544 case tcu::COMPRESSEDTEXFORMAT_ASTC_4x4_SRGB8_ALPHA8:
3545 case tcu::COMPRESSEDTEXFORMAT_ASTC_5x4_SRGB8_ALPHA8:
3546 case tcu::COMPRESSEDTEXFORMAT_ASTC_5x5_SRGB8_ALPHA8:
3547 case tcu::COMPRESSEDTEXFORMAT_ASTC_6x5_SRGB8_ALPHA8:
3548 case tcu::COMPRESSEDTEXFORMAT_ASTC_6x6_SRGB8_ALPHA8:
3549 case tcu::COMPRESSEDTEXFORMAT_ASTC_8x5_SRGB8_ALPHA8:
3550 case tcu::COMPRESSEDTEXFORMAT_ASTC_8x6_SRGB8_ALPHA8:
3551 case tcu::COMPRESSEDTEXFORMAT_ASTC_8x8_SRGB8_ALPHA8:
3552 case tcu::COMPRESSEDTEXFORMAT_ASTC_10x5_SRGB8_ALPHA8:
3553 case tcu::COMPRESSEDTEXFORMAT_ASTC_10x6_SRGB8_ALPHA8:
3554 case tcu::COMPRESSEDTEXFORMAT_ASTC_10x8_SRGB8_ALPHA8:
3555 case tcu::COMPRESSEDTEXFORMAT_ASTC_10x10_SRGB8_ALPHA8:
3556 case tcu::COMPRESSEDTEXFORMAT_ASTC_12x10_SRGB8_ALPHA8:
3557 case tcu::COMPRESSEDTEXFORMAT_ASTC_12x12_SRGB8_ALPHA8:
3558 bitDepth = { 8, 8, 8, 8 };
3559 break;
3560
3561 case tcu::COMPRESSEDTEXFORMAT_BC1_RGB_UNORM_BLOCK:
3562 case tcu::COMPRESSEDTEXFORMAT_BC1_RGB_SRGB_BLOCK:
3563 case tcu::COMPRESSEDTEXFORMAT_BC2_UNORM_BLOCK:
3564 case tcu::COMPRESSEDTEXFORMAT_BC2_SRGB_BLOCK:
3565 case tcu::COMPRESSEDTEXFORMAT_BC3_UNORM_BLOCK:
3566 case tcu::COMPRESSEDTEXFORMAT_BC3_SRGB_BLOCK:
3567 bitDepth = { 5, 6, 5, 0 };
3568 break;
3569
3570 case tcu::COMPRESSEDTEXFORMAT_BC1_RGBA_UNORM_BLOCK:
3571 case tcu::COMPRESSEDTEXFORMAT_BC1_RGBA_SRGB_BLOCK:
3572 case tcu::COMPRESSEDTEXFORMAT_BC7_UNORM_BLOCK:
3573 case tcu::COMPRESSEDTEXFORMAT_BC7_SRGB_BLOCK:
3574 bitDepth = { 5, 5, 5, 1 };
3575 break;
3576
3577 case tcu::COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK:
3578 bitDepth = { 7, 0, 0, 0 };
3579 isSigned = true;
3580 break;
3581
3582 case tcu::COMPRESSEDTEXFORMAT_BC4_UNORM_BLOCK:
3583 bitDepth = { 8, 0, 0, 0 };
3584 break;
3585
3586 case tcu::COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK:
3587 bitDepth = { 7, 7, 0, 0 };
3588 isSigned = true;
3589 break;
3590
3591 case tcu::COMPRESSEDTEXFORMAT_BC5_UNORM_BLOCK:
3592 bitDepth = { 8, 8, 0, 0 };
3593 break;
3594
3595 case tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK:
3596 return tcu::Vec4(0.01f);
3597 case tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK:
3598 return tcu::Vec4(0.005f);
3599
3600 default:
3601 DE_ASSERT(DE_FALSE);
3602 }
3603
3604 const float range = isSigned ? 1.0f - (-1.0f)
3605 : 1.0f - 0.0f;
3606 tcu::Vec4 v;
3607 for (int i = 0; i < 4; ++i)
3608 {
3609 if (bitDepth[i] == 0)
3610 v[i] = 1.0f;
3611 else
3612 v[i] = range / static_cast<float>((1 << bitDepth[i]) - 1);
3613 }
3614 return v;
3615 }
3616
checkNonNearestFilteredResult(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & clampedExpected,const tcu::ConstPixelBufferAccess & unclampedExpected,const tcu::TextureFormat & srcFormat)3617 bool BlittingImages::checkNonNearestFilteredResult (const tcu::ConstPixelBufferAccess& result,
3618 const tcu::ConstPixelBufferAccess& clampedExpected,
3619 const tcu::ConstPixelBufferAccess& unclampedExpected,
3620 const tcu::TextureFormat& srcFormat)
3621 {
3622 tcu::TestLog& log (m_context.getTestContext().getLog());
3623 const tcu::TextureFormat dstFormat = result.getFormat();
3624 const tcu::TextureChannelClass dstChannelClass = tcu::getTextureChannelClass(dstFormat.type);
3625 const tcu::TextureChannelClass srcChannelClass = tcu::getTextureChannelClass(srcFormat.type);
3626 bool isOk = false;
3627
3628 log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
3629
3630 // if either of srcImage or dstImage stores values as a signed/unsigned integer,
3631 // the other must also store values a signed/unsigned integer
3632 // e.g. blit unorm to uscaled is not allowed as uscaled formats store data as integers
3633 // despite the fact that both formats are sampled as floats
3634 bool dstImageIsIntClass = dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
3635 dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
3636 bool srcImageIsIntClass = srcChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
3637 srcChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
3638 if (dstImageIsIntClass != srcImageIsIntClass)
3639 {
3640 log << tcu::TestLog::EndSection;
3641 return false;
3642 }
3643
3644 if (isFloatFormat(dstFormat))
3645 {
3646 const bool srcIsSRGB = tcu::isSRGB(srcFormat);
3647 const tcu::Vec4 srcMaxDiff = getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2.0f : 1.0f);
3648 const tcu::Vec4 dstMaxDiff = getFormatThreshold(dstFormat);
3649 const tcu::Vec4 threshold = ( srcMaxDiff + dstMaxDiff ) * ((m_params.filter == VK_FILTER_CUBIC_EXT) ? 1.5f : 1.0f);
3650
3651 isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
3652 log << tcu::TestLog::EndSection;
3653
3654 if (!isOk)
3655 {
3656 log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
3657 isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
3658 log << tcu::TestLog::EndSection;
3659 }
3660 }
3661 else
3662 {
3663 tcu::UVec4 threshold;
3664 // Calculate threshold depending on channel width of destination format.
3665 const tcu::IVec4 dstBitDepth = tcu::getTextureFormatBitDepth(dstFormat);
3666 const tcu::IVec4 srcBitDepth = tcu::getTextureFormatBitDepth(srcFormat);
3667 for (deUint32 i = 0; i < 4; ++i)
3668 {
3669 DE_ASSERT(dstBitDepth[i] < std::numeric_limits<uint64_t>::digits);
3670 DE_ASSERT(srcBitDepth[i] < std::numeric_limits<uint64_t>::digits);
3671 deUint64 threshold64 = 1 + de::max( ( ( UINT64_C(1) << dstBitDepth[i] ) - 1 ) / de::clamp((UINT64_C(1) << srcBitDepth[i]) - 1, UINT64_C(1), UINT64_C(256)), UINT64_C(1));
3672 DE_ASSERT(threshold64 <= std::numeric_limits<uint32_t>::max());
3673 threshold[i] = static_cast<deUint32>(threshold64);
3674 }
3675
3676 isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
3677 log << tcu::TestLog::EndSection;
3678
3679 if (!isOk)
3680 {
3681 log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
3682 isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
3683 log << tcu::TestLog::EndSection;
3684 }
3685 }
3686
3687 return isOk;
3688 }
3689
checkCompressedNonNearestFilteredResult(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & clampedReference,const tcu::ConstPixelBufferAccess & unclampedReference,const tcu::CompressedTexFormat format)3690 bool BlittingImages::checkCompressedNonNearestFilteredResult(const tcu::ConstPixelBufferAccess& result,
3691 const tcu::ConstPixelBufferAccess& clampedReference,
3692 const tcu::ConstPixelBufferAccess& unclampedReference,
3693 const tcu::CompressedTexFormat format)
3694 {
3695 tcu::TestLog& log = m_context.getTestContext().getLog();
3696 const tcu::TextureFormat dstFormat = result.getFormat();
3697
3698 // there are rare cases wher one or few pixels have slightly bigger error
3699 // in one of channels this accepted error allows those casses to pass
3700 const tcu::Vec4 acceptedError (0.06f);
3701
3702 const tcu::Vec4 srcMaxDiff = getCompressedFormatThreshold(format);
3703 const tcu::Vec4 dstMaxDiff = m_destinationCompressedTexture ?
3704 getCompressedFormatThreshold(m_destinationCompressedTexture->getCompressedTexture().getFormat()) :
3705 getFormatThreshold(dstFormat);
3706 const tcu::Vec4 threshold = (srcMaxDiff + dstMaxDiff) * ((m_params.filter == VK_FILTER_CUBIC_EXT) ? 1.5f : 1.0f) + acceptedError;
3707
3708 bool filteredResultVerification(false);
3709 tcu::Vec4 filteredResultMinValue(-6e6);
3710 tcu::Vec4 filteredResultMaxValue(6e6);
3711 tcu::TextureLevel filteredResult;
3712 tcu::TextureLevel filteredClampedReference;
3713 tcu::TextureLevel filteredUnclampedReference;
3714
3715 if (((format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK) ||
3716 (format == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK)))
3717 {
3718 if ((dstFormat.type == tcu::TextureFormat::FLOAT) ||
3719 (dstFormat.type == tcu::TextureFormat::HALF_FLOAT))
3720 {
3721 // for compressed formats we are using random data and for bc6h formats
3722 // this will give us also large color values; when we are bliting to
3723 // a format that accepts large values we can end up with large diferences
3724 // betwean filtered result and reference; to avoid that we need to remove
3725 // values that are to big from verification
3726 filteredResultVerification = true;
3727 filteredResultMinValue = tcu::Vec4(-10.0f);
3728 filteredResultMaxValue = tcu::Vec4( 10.0f);
3729 }
3730 else if (dstFormat.type == tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV)
3731 {
3732 // we need to clamp some formats to <0;1> range as it has
3733 // small precision for big numbers compared to reference
3734 filteredResultVerification = true;
3735 filteredResultMinValue = tcu::Vec4(0.0f);
3736 filteredResultMaxValue = tcu::Vec4(1.0f);
3737 }
3738 // else don't use filtered verification
3739 }
3740
3741 if (filteredResultVerification)
3742 {
3743 filteredResult.setStorage(dstFormat, result.getWidth(), result.getHeight(), result.getDepth());
3744 tcu::PixelBufferAccess filteredResultAcccess(filteredResult.getAccess());
3745
3746 filteredClampedReference.setStorage(dstFormat, result.getWidth(), result.getHeight(), result.getDepth());
3747 tcu::PixelBufferAccess filteredClampedAcccess(filteredClampedReference.getAccess());
3748
3749 filteredUnclampedReference.setStorage(dstFormat, result.getWidth(), result.getHeight(), result.getDepth());
3750 tcu::PixelBufferAccess filteredUnclampedResultAcccess(filteredUnclampedReference.getAccess());
3751
3752 for (deInt32 z = 0; z < result.getDepth(); z++)
3753 for (deInt32 y = 0; y < result.getHeight(); y++)
3754 for (deInt32 x = 0; x < result.getWidth(); x++)
3755 {
3756 tcu::Vec4 resultTexel = result.getPixel(x, y, z);
3757 tcu::Vec4 clampedReferenceTexel = clampedReference.getPixel(x, y, z);
3758 tcu::Vec4 unclampedReferenceTexel = unclampedReference.getPixel(x, y, z);
3759
3760 resultTexel = tcu::clamp(resultTexel, filteredResultMinValue, filteredResultMaxValue);
3761 clampedReferenceTexel = tcu::clamp(clampedReferenceTexel, filteredResultMinValue, filteredResultMaxValue);
3762 unclampedReferenceTexel = tcu::clamp(unclampedReferenceTexel, filteredResultMinValue, filteredResultMaxValue);
3763
3764 filteredResultAcccess.setPixel(resultTexel, x, y, z);
3765 filteredClampedAcccess.setPixel(clampedReferenceTexel, x, y, z);
3766 filteredUnclampedResultAcccess.setPixel(unclampedReferenceTexel, x, y, z);
3767 }
3768 }
3769
3770 const tcu::ConstPixelBufferAccess clampedRef = filteredResultVerification ? filteredClampedReference.getAccess() : clampedReference;
3771 const tcu::ConstPixelBufferAccess res = filteredResultVerification ? filteredResult.getAccess() : result;
3772
3773 log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
3774 bool isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedRef, res, threshold, tcu::COMPARE_LOG_RESULT);
3775 log << tcu::TestLog::EndSection;
3776
3777 if (!isOk)
3778 {
3779 const tcu::ConstPixelBufferAccess unclampedRef = filteredResultVerification ? filteredUnclampedReference.getAccess() : unclampedReference;
3780
3781 log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
3782 isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedRef, res, threshold, tcu::COMPARE_LOG_RESULT);
3783 log << tcu::TestLog::EndSection;
3784 }
3785
3786 return isOk;
3787 }
3788
3789 //! Utility to encapsulate coordinate computation and loops.
3790 struct CompareEachPixelInEachRegion
3791 {
~CompareEachPixelInEachRegionvkt::api::__anon4493ca420111::CompareEachPixelInEachRegion3792 virtual ~CompareEachPixelInEachRegion (void) {}
3793 virtual bool compare (const void* pUserData, const int x, const int y, const int z, const tcu::Vec3& srcNormCoord) const = 0;
3794
forEachvkt::api::__anon4493ca420111::CompareEachPixelInEachRegion3795 bool forEach (const void* pUserData,
3796 const std::vector<CopyRegion>& regions,
3797 const int sourceWidth,
3798 const int sourceHeight,
3799 const int sourceDepth,
3800 const tcu::PixelBufferAccess& errorMask) const
3801 {
3802 bool compareOk = true;
3803
3804 for (std::vector<CopyRegion>::const_iterator regionIter = regions.begin(); regionIter != regions.end(); ++regionIter)
3805 {
3806 const VkImageBlit& blit = regionIter->imageBlit;
3807
3808 const int xStart = deMin32(blit.dstOffsets[0].x, blit.dstOffsets[1].x);
3809 const int yStart = deMin32(blit.dstOffsets[0].y, blit.dstOffsets[1].y);
3810 const int zStart = deMin32(blit.dstOffsets[0].z, blit.dstOffsets[1].z);
3811 const int xEnd = deMax32(blit.dstOffsets[0].x, blit.dstOffsets[1].x);
3812 const int yEnd = deMax32(blit.dstOffsets[0].y, blit.dstOffsets[1].y);
3813 const int zEnd = deMax32(blit.dstOffsets[0].z, blit.dstOffsets[1].z);
3814 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);
3815 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);
3816 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);
3817 const float srcInvW = 1.0f / static_cast<float>(sourceWidth);
3818 const float srcInvH = 1.0f / static_cast<float>(sourceHeight);
3819 const float srcInvD = 1.0f / static_cast<float>(sourceDepth);
3820
3821 for (int z = zStart; z < zEnd; z++)
3822 for (int y = yStart; y < yEnd; y++)
3823 for (int x = xStart; x < xEnd; x++)
3824 {
3825 const tcu::Vec3 srcNormCoord
3826 (
3827 (xScale * (static_cast<float>(x - blit.dstOffsets[0].x) + 0.5f) + static_cast<float>(blit.srcOffsets[0].x)) * srcInvW,
3828 (yScale * (static_cast<float>(y - blit.dstOffsets[0].y) + 0.5f) + static_cast<float>(blit.srcOffsets[0].y)) * srcInvH,
3829 (zScale * (static_cast<float>(z - blit.dstOffsets[0].z) + 0.5f) + static_cast<float>(blit.srcOffsets[0].z)) * srcInvD
3830 );
3831
3832 if (!compare(pUserData, x, y, z, srcNormCoord))
3833 {
3834 errorMask.setPixel(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y, z);
3835 compareOk = false;
3836 }
3837 }
3838 }
3839 return compareOk;
3840 }
3841 };
3842
getFloatOrFixedPointFormatThreshold(const tcu::TextureFormat & format)3843 tcu::Vec4 getFloatOrFixedPointFormatThreshold (const tcu::TextureFormat& format)
3844 {
3845 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
3846 const tcu::IVec4 bitDepth = tcu::getTextureFormatBitDepth(format);
3847
3848 if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
3849 {
3850 return getFormatThreshold(format);
3851 }
3852 else if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
3853 channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT)
3854 {
3855 const bool isSigned = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT);
3856 const float range = isSigned ? 1.0f - (-1.0f)
3857 : 1.0f - 0.0f;
3858
3859 tcu::Vec4 v;
3860 for (int i = 0; i < 4; ++i)
3861 {
3862 if (bitDepth[i] == 0)
3863 v[i] = 1.0f;
3864 else
3865 v[i] = range / static_cast<float>((1 << bitDepth[i]) - 1);
3866 }
3867 return v;
3868 }
3869 else
3870 {
3871 DE_ASSERT(0);
3872 return tcu::Vec4();
3873 }
3874 }
3875
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)3876 bool floatNearestBlitCompare (const tcu::ConstPixelBufferAccess& source,
3877 const tcu::ConstPixelBufferAccess& result,
3878 const tcu::Vec4& sourceThreshold,
3879 const tcu::Vec4& resultThreshold,
3880 const tcu::PixelBufferAccess& errorMask,
3881 const std::vector<CopyRegion>& regions)
3882 {
3883 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,
3884 0.0f, true, tcu::Sampler::COMPAREMODE_NONE, 0, tcu::Vec4(0.0f), true);
3885 const tcu::IVec4 dstBitDepth (tcu::getTextureFormatBitDepth(result.getFormat()));
3886 tcu::LookupPrecision precision;
3887
3888 precision.colorMask = tcu::notEqual(dstBitDepth, tcu::IVec4(0));
3889 precision.colorThreshold = tcu::max(sourceThreshold, resultThreshold);
3890
3891 const struct Capture
3892 {
3893 const tcu::ConstPixelBufferAccess& source;
3894 const tcu::ConstPixelBufferAccess& result;
3895 const tcu::Sampler& sampler;
3896 const tcu::LookupPrecision& precision;
3897 const bool isSRGB;
3898 } capture =
3899 {
3900 source, result, sampler, precision, tcu::isSRGB(result.getFormat())
3901 };
3902
3903 const struct Loop : CompareEachPixelInEachRegion
3904 {
3905 Loop (void) {}
3906
3907 bool compare (const void* pUserData, const int x, const int y, const int z, const tcu::Vec3& srcNormCoord) const
3908 {
3909 const Capture& c = *static_cast<const Capture*>(pUserData);
3910 const tcu::TexLookupScaleMode lookupScaleDontCare = tcu::TEX_LOOKUP_SCALE_MINIFY;
3911 tcu::Vec4 dstColor = c.result.getPixel(x, y, z);
3912
3913 // TexLookupVerifier performs a conversion to linear space, so we have to as well
3914 if (c.isSRGB)
3915 dstColor = tcu::sRGBToLinear(dstColor);
3916
3917 return tcu::isLevel3DLookupResultValid(c.source, c.sampler, lookupScaleDontCare, c.precision, srcNormCoord, dstColor);
3918 }
3919 } loop;
3920
3921 return loop.forEach(&capture, regions, source.getWidth(), source.getHeight(), source.getDepth(), errorMask);
3922 }
3923
intNearestBlitCompare(const tcu::ConstPixelBufferAccess & source,const tcu::ConstPixelBufferAccess & result,const tcu::PixelBufferAccess & errorMask,const std::vector<CopyRegion> & regions)3924 bool intNearestBlitCompare (const tcu::ConstPixelBufferAccess& source,
3925 const tcu::ConstPixelBufferAccess& result,
3926 const tcu::PixelBufferAccess& errorMask,
3927 const std::vector<CopyRegion>& regions)
3928 {
3929 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,
3930 0.0f, true, tcu::Sampler::COMPAREMODE_NONE, 0, tcu::Vec4(0.0f), true);
3931 tcu::IntLookupPrecision precision;
3932
3933 {
3934 const tcu::IVec4 srcBitDepth = tcu::getTextureFormatBitDepth(source.getFormat());
3935 const tcu::IVec4 dstBitDepth = tcu::getTextureFormatBitDepth(result.getFormat());
3936
3937 for (deUint32 i = 0; i < 4; ++i) {
3938 precision.colorThreshold[i] = de::max(de::max(srcBitDepth[i] / 8, dstBitDepth[i] / 8), 1);
3939 precision.colorMask[i] = dstBitDepth[i] != 0;
3940 }
3941 }
3942
3943 // Prepare a source image with a matching (converted) pixel format. Ideally, we would've used a wrapper that
3944 // does the conversion on the fly without wasting memory, but this approach is more straightforward.
3945 tcu::TextureLevel convertedSourceTexture (result.getFormat(), source.getWidth(), source.getHeight(), source.getDepth());
3946 const tcu::PixelBufferAccess convertedSource = convertedSourceTexture.getAccess();
3947
3948 for (int z = 0; z < source.getDepth(); ++z)
3949 for (int y = 0; y < source.getHeight(); ++y)
3950 for (int x = 0; x < source.getWidth(); ++x)
3951 convertedSource.setPixel(source.getPixelInt(x, y, z), x, y, z); // will be clamped to max. representable value
3952
3953 const struct Capture
3954 {
3955 const tcu::ConstPixelBufferAccess& source;
3956 const tcu::ConstPixelBufferAccess& result;
3957 const tcu::Sampler& sampler;
3958 const tcu::IntLookupPrecision& precision;
3959 } capture =
3960 {
3961 convertedSource, result, sampler, precision
3962 };
3963
3964 const struct Loop : CompareEachPixelInEachRegion
3965 {
3966 Loop (void) {}
3967
3968 bool compare (const void* pUserData, const int x, const int y, const int z, const tcu::Vec3& srcNormCoord) const
3969 {
3970 const Capture& c = *static_cast<const Capture*>(pUserData);
3971 const tcu::TexLookupScaleMode lookupScaleDontCare = tcu::TEX_LOOKUP_SCALE_MINIFY;
3972 const tcu::IVec4 dstColor = c.result.getPixelInt(x, y, z);
3973
3974 return tcu::isLevel3DLookupResultValid(c.source, c.sampler, lookupScaleDontCare, c.precision, srcNormCoord, dstColor);
3975 }
3976 } loop;
3977
3978 return loop.forEach(&capture, regions, source.getWidth(), source.getHeight(), source.getDepth(), errorMask);
3979 }
3980
checkNearestFilteredResult(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & source)3981 bool BlittingImages::checkNearestFilteredResult (const tcu::ConstPixelBufferAccess& result,
3982 const tcu::ConstPixelBufferAccess& source)
3983 {
3984 tcu::TestLog& log (m_context.getTestContext().getLog());
3985 const tcu::TextureFormat dstFormat = result.getFormat();
3986 const tcu::TextureFormat srcFormat = source.getFormat();
3987 const tcu::TextureChannelClass dstChannelClass = tcu::getTextureChannelClass(dstFormat.type);
3988 const tcu::TextureChannelClass srcChannelClass = tcu::getTextureChannelClass(srcFormat.type);
3989
3990 tcu::TextureLevel errorMaskStorage (tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), result.getWidth(), result.getHeight(), result.getDepth());
3991 tcu::PixelBufferAccess errorMask = errorMaskStorage.getAccess();
3992 tcu::Vec4 pixelBias (0.0f, 0.0f, 0.0f, 0.0f);
3993 tcu::Vec4 pixelScale (1.0f, 1.0f, 1.0f, 1.0f);
3994 bool ok = false;
3995
3996 tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
3997
3998 // if either of srcImage or dstImage stores values as a signed/unsigned integer,
3999 // the other must also store values a signed/unsigned integer
4000 // e.g. blit unorm to uscaled is not allowed as uscaled formats store data as integers
4001 // despite the fact that both formats are sampled as floats
4002 bool dstImageIsIntClass = dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
4003 dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
4004 bool srcImageIsIntClass = srcChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
4005 srcChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
4006 if (dstImageIsIntClass != srcImageIsIntClass)
4007 return false;
4008
4009 if (dstImageIsIntClass)
4010 {
4011 ok = intNearestBlitCompare(source, result, errorMask, m_params.regions);
4012 }
4013 else
4014 {
4015 const tcu::Vec4 srcMaxDiff = getFloatOrFixedPointFormatThreshold(source.getFormat());
4016 const tcu::Vec4 dstMaxDiff = getFloatOrFixedPointFormatThreshold(result.getFormat());
4017 ok = floatNearestBlitCompare(source, result, srcMaxDiff, dstMaxDiff, errorMask, m_params.regions);
4018 }
4019
4020 if (result.getFormat() != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
4021 tcu::computePixelScaleBias(result, pixelScale, pixelBias);
4022
4023 if (!ok)
4024 {
4025 log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
4026 << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
4027 << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask)
4028 << tcu::TestLog::EndImageSet;
4029 }
4030 else
4031 {
4032 log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
4033 << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
4034 << tcu::TestLog::EndImageSet;
4035 }
4036
4037 return ok;
4038 }
4039
checkCompressedNearestFilteredResult(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & source,const tcu::CompressedTexFormat format)4040 bool BlittingImages::checkCompressedNearestFilteredResult (const tcu::ConstPixelBufferAccess& result,
4041 const tcu::ConstPixelBufferAccess& source,
4042 const tcu::CompressedTexFormat format)
4043 {
4044 tcu::TestLog& log (m_context.getTestContext().getLog());
4045 tcu::TextureFormat errorMaskFormat (tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8);
4046 tcu::TextureLevel errorMaskStorage (errorMaskFormat, result.getWidth(), result.getHeight(), result.getDepth());
4047 tcu::PixelBufferAccess errorMask (errorMaskStorage.getAccess());
4048 tcu::Vec4 pixelBias (0.0f, 0.0f, 0.0f, 0.0f);
4049 tcu::Vec4 pixelScale (1.0f, 1.0f, 1.0f, 1.0f);
4050 const tcu::TextureFormat& resultFormat (result.getFormat());
4051 VkFormat nativeResultFormat (mapTextureFormat(resultFormat));
4052
4053 // there are rare cases wher one or few pixels have slightly bigger error
4054 // in one of channels this accepted error allows those casses to pass
4055 const tcu::Vec4 acceptedError (0.04f);
4056 const tcu::Vec4 srcMaxDiff (acceptedError + getCompressedFormatThreshold(format));
4057 const tcu::Vec4 dstMaxDiff (acceptedError + (m_destinationCompressedTexture ?
4058 getCompressedFormatThreshold(m_destinationCompressedTexture->getCompressedTexture().getFormat()) :
4059 getFloatOrFixedPointFormatThreshold(resultFormat)));
4060
4061 tcu::TextureLevel clampedSourceLevel;
4062 bool clampSource (false);
4063 tcu::Vec4 clampSourceMinValue (-1.0f);
4064 tcu::Vec4 clampSourceMaxValue (1.0f);
4065 tcu::TextureLevel clampedResultLevel;
4066 bool clampResult (false);
4067
4068 tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
4069
4070 if (resultFormat != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
4071 tcu::computePixelScaleBias(result, pixelScale, pixelBias);
4072
4073 log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
4074 << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias);
4075
4076 // for compressed formats source buffer access is not actual compressed format
4077 // but equivalent uncompressed format that is some cases needs additional
4078 // modifications so that sampling it will produce valid reference
4079 if ((format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK) ||
4080 (format == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK))
4081 {
4082 if (resultFormat.type == tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV)
4083 {
4084 // for compressed formats we are using random data and for some formats it
4085 // can be outside of <-1;1> range - for cases where result is not a float
4086 // format we need to clamp source to <-1;1> range as this will be done on
4087 // the device but not in software sampler in framework
4088 clampSource = true;
4089 // for this format we also need to clamp the result as precision of
4090 // this format is smaller then precision of calculations in framework;
4091 // the biger color valus are the bigger errors can be
4092 clampResult = true;
4093
4094 if (format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK)
4095 clampSourceMinValue = tcu::Vec4(0.0f);
4096 }
4097 else if ((resultFormat.type != tcu::TextureFormat::FLOAT) &&
4098 (resultFormat.type != tcu::TextureFormat::HALF_FLOAT))
4099 {
4100 // clamp source for all non float formats
4101 clampSource = true;
4102 }
4103 }
4104
4105 if (isUnormFormat(nativeResultFormat) || isUfloatFormat(nativeResultFormat))
4106 {
4107 // when tested compressed format is signed but the result format
4108 // is unsigned we need to clamp source to <0; x> so that proper
4109 // reference is calculated
4110 if ((format == tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_R11) ||
4111 (format == tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11) ||
4112 (format == tcu::COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK) ||
4113 (format == tcu::COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK) ||
4114 (format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK))
4115 {
4116 clampSource = true;
4117 clampSourceMinValue = tcu::Vec4(0.0f);
4118 }
4119 }
4120
4121 if (clampSource || clampResult)
4122 {
4123 if (clampSource)
4124 {
4125 clampedSourceLevel.setStorage(source.getFormat(), source.getWidth(), source.getHeight(), source.getDepth());
4126 tcu::PixelBufferAccess clampedSourceAcccess(clampedSourceLevel.getAccess());
4127
4128 for (deInt32 z = 0; z < source.getDepth() ; z++)
4129 for (deInt32 y = 0; y < source.getHeight() ; y++)
4130 for (deInt32 x = 0; x < source.getWidth() ; x++)
4131 {
4132 tcu::Vec4 texel = source.getPixel(x, y, z);
4133 texel = tcu::clamp(texel, tcu::Vec4(clampSourceMinValue), tcu::Vec4(clampSourceMaxValue));
4134 clampedSourceAcccess.setPixel(texel, x, y, z);
4135 }
4136 }
4137
4138 if (clampResult)
4139 {
4140 clampedResultLevel.setStorage(result.getFormat(), result.getWidth(), result.getHeight(), result.getDepth());
4141 tcu::PixelBufferAccess clampedResultAcccess(clampedResultLevel.getAccess());
4142
4143 for (deInt32 z = 0; z < result.getDepth() ; z++)
4144 for (deInt32 y = 0; y < result.getHeight() ; y++)
4145 for (deInt32 x = 0; x < result.getWidth() ; x++)
4146 {
4147 tcu::Vec4 texel = result.getPixel(x, y, z);
4148 texel = tcu::clamp(texel, tcu::Vec4(-1.0f), tcu::Vec4(1.0f));
4149 clampedResultAcccess.setPixel(texel, x, y, z);
4150 }
4151 }
4152 }
4153
4154 const tcu::ConstPixelBufferAccess src = clampSource ? clampedSourceLevel.getAccess() : source;
4155 const tcu::ConstPixelBufferAccess res = clampResult ? clampedResultLevel.getAccess() : result;
4156
4157 if (floatNearestBlitCompare(src, res, srcMaxDiff, dstMaxDiff, errorMask, m_params.regions))
4158 {
4159 log << tcu::TestLog::EndImageSet;
4160 return true;
4161 }
4162
4163 log << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask)
4164 << tcu::TestLog::EndImageSet;
4165 return false;
4166 }
4167
checkTestResult(tcu::ConstPixelBufferAccess result)4168 tcu::TestStatus BlittingImages::checkTestResult (tcu::ConstPixelBufferAccess result)
4169 {
4170 DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR || m_params.filter == VK_FILTER_CUBIC_EXT);
4171 const std::string failMessage("Result image is incorrect");
4172
4173 if (m_params.filter != VK_FILTER_NEAREST)
4174 {
4175 if (tcu::isCombinedDepthStencilType(result.getFormat().type))
4176 {
4177 if (tcu::hasDepthComponent(result.getFormat().order))
4178 {
4179 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_DEPTH;
4180 const tcu::ConstPixelBufferAccess depthResult = tcu::getEffectiveDepthStencilAccess(result, mode);
4181 const tcu::ConstPixelBufferAccess clampedExpected = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
4182 const tcu::ConstPixelBufferAccess unclampedExpected = tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode);
4183 const tcu::TextureFormat sourceFormat = tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode);
4184
4185 if (!checkNonNearestFilteredResult(depthResult, clampedExpected, unclampedExpected, sourceFormat))
4186 return tcu::TestStatus::fail(failMessage);
4187 }
4188
4189 if (tcu::hasStencilComponent(result.getFormat().order))
4190 {
4191 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_STENCIL;
4192 const tcu::ConstPixelBufferAccess stencilResult = tcu::getEffectiveDepthStencilAccess(result, mode);
4193 const tcu::ConstPixelBufferAccess clampedExpected = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
4194 const tcu::ConstPixelBufferAccess unclampedExpected = tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode);
4195 const tcu::TextureFormat sourceFormat = tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode);
4196
4197 if (!checkNonNearestFilteredResult(stencilResult, clampedExpected, unclampedExpected, sourceFormat))
4198 return tcu::TestStatus::fail(failMessage);
4199 }
4200 }
4201 else if (m_sourceCompressedTexture)
4202 {
4203 const tcu::CompressedTexture& compressedLevel = m_sourceCompressedTexture->getCompressedTexture();
4204 if (!checkCompressedNonNearestFilteredResult(result, m_expectedTextureLevel[0]->getAccess(), m_unclampedExpectedTextureLevel->getAccess(), compressedLevel.getFormat()))
4205 return tcu::TestStatus::fail(failMessage);
4206 }
4207 else
4208 {
4209 const tcu::TextureFormat sourceFormat = mapVkFormat(m_params.src.image.format);
4210 if (!checkNonNearestFilteredResult(result, m_expectedTextureLevel[0]->getAccess(), m_unclampedExpectedTextureLevel->getAccess(), sourceFormat))
4211 return tcu::TestStatus::fail(failMessage);
4212 }
4213 }
4214 else // NEAREST filtering
4215 {
4216 if (tcu::isCombinedDepthStencilType(result.getFormat().type))
4217 {
4218 if (tcu::hasDepthComponent(result.getFormat().order))
4219 {
4220 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_DEPTH;
4221 const tcu::ConstPixelBufferAccess depthResult = tcu::getEffectiveDepthStencilAccess(result, mode);
4222 const tcu::ConstPixelBufferAccess depthSource = tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode);
4223
4224 if (!checkNearestFilteredResult(depthResult, depthSource))
4225 return tcu::TestStatus::fail(failMessage);
4226 }
4227
4228 if (tcu::hasStencilComponent(result.getFormat().order))
4229 {
4230 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_STENCIL;
4231 const tcu::ConstPixelBufferAccess stencilResult = tcu::getEffectiveDepthStencilAccess(result, mode);
4232 const tcu::ConstPixelBufferAccess stencilSource = tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode);
4233
4234 if (!checkNearestFilteredResult(stencilResult, stencilSource))
4235 return tcu::TestStatus::fail(failMessage);
4236 }
4237 }
4238 else if (m_sourceCompressedTexture)
4239 {
4240 const tcu::CompressedTexture& compressedLevel = m_sourceCompressedTexture->getCompressedTexture();
4241 const tcu::PixelBufferAccess& decompressedLevel = m_sourceCompressedTexture->getDecompressedAccess();
4242
4243 if (!checkCompressedNearestFilteredResult(result, decompressedLevel, compressedLevel.getFormat()))
4244 return tcu::TestStatus::fail(failMessage);
4245 }
4246 else if (!checkNearestFilteredResult(result, m_sourceTextureLevel->getAccess()))
4247 return tcu::TestStatus::fail(failMessage);
4248 }
4249
4250 return tcu::TestStatus::pass("Pass");
4251 }
4252
linearToSRGBIfNeeded(const tcu::TextureFormat & format,const tcu::Vec4 & color)4253 tcu::Vec4 linearToSRGBIfNeeded (const tcu::TextureFormat& format, const tcu::Vec4& color)
4254 {
4255 return isSRGB(format) ? linearToSRGB(color) : color;
4256 }
4257
scaleFromWholeSrcBuffer(const tcu::PixelBufferAccess & dst,const tcu::ConstPixelBufferAccess & src,const VkOffset3D regionOffset,const VkOffset3D regionExtent,tcu::Sampler::FilterMode filter,const MirrorMode mirrorMode=0u)4258 void scaleFromWholeSrcBuffer (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const VkOffset3D regionOffset, const VkOffset3D regionExtent, tcu::Sampler::FilterMode filter, const MirrorMode mirrorMode = 0u)
4259 {
4260 DE_ASSERT(filter == tcu::Sampler::LINEAR || filter == tcu::Sampler::CUBIC);
4261
4262 tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
4263 filter, filter, 0.0f, false, tcu::Sampler::COMPAREMODE_NONE, 0, tcu::Vec4(0.0f), true);
4264
4265 float sX = (float)regionExtent.x / (float)dst.getWidth();
4266 float sY = (float)regionExtent.y / (float)dst.getHeight();
4267 float sZ = (float)regionExtent.z / (float)dst.getDepth();
4268
4269 for (int z = 0; z < dst.getDepth(); z++)
4270 for (int y = 0; y < dst.getHeight(); y++)
4271 for (int x = 0; x < dst.getWidth(); x++)
4272 {
4273 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;
4274 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;
4275 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;
4276 if (dst.getDepth() > 1)
4277 dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample3D(sampler, filter, srcX, srcY, srcZ)), x, y, z);
4278 else
4279 dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample2D(sampler, filter, srcX, srcY, 0)), x, y);
4280 }
4281 }
4282
blit(const tcu::PixelBufferAccess & dst,const tcu::ConstPixelBufferAccess & src,const tcu::Sampler::FilterMode filter,const MirrorMode mirrorMode)4283 void blit (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const tcu::Sampler::FilterMode filter, const MirrorMode mirrorMode)
4284 {
4285 DE_ASSERT(filter == tcu::Sampler::NEAREST || filter == tcu::Sampler::LINEAR || filter == tcu::Sampler::CUBIC);
4286
4287 tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
4288 filter, filter, 0.0f, false, tcu::Sampler::COMPAREMODE_NONE, 0, tcu::Vec4(0.0f), true);
4289
4290 const float sX = (float)src.getWidth() / (float)dst.getWidth();
4291 const float sY = (float)src.getHeight() / (float)dst.getHeight();
4292 const float sZ = (float)src.getDepth() / (float)dst.getDepth();
4293
4294 const int xOffset = (mirrorMode & MIRROR_MODE_X) ? dst.getWidth() - 1 : 0;
4295 const int yOffset = (mirrorMode & MIRROR_MODE_Y) ? dst.getHeight() - 1 : 0;
4296 const int zOffset = (mirrorMode & MIRROR_MODE_Z) ? dst.getDepth() - 1 : 0;
4297
4298 const int xScale = (mirrorMode & MIRROR_MODE_X) ? -1 : 1;
4299 const int yScale = (mirrorMode & MIRROR_MODE_Y) ? -1 : 1;
4300 const int zScale = (mirrorMode & MIRROR_MODE_Z) ? -1 : 1;
4301
4302 for (int z = 0; z < dst.getDepth(); ++z)
4303 for (int y = 0; y < dst.getHeight(); ++y)
4304 for (int x = 0; x < dst.getWidth(); ++x)
4305 {
4306 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);
4307 }
4308 }
4309
flipCoordinates(CopyRegion & region,const MirrorMode mirrorMode)4310 void flipCoordinates (CopyRegion& region, const MirrorMode mirrorMode)
4311 {
4312 const VkOffset3D dstOffset0 = region.imageBlit.dstOffsets[0];
4313 const VkOffset3D dstOffset1 = region.imageBlit.dstOffsets[1];
4314 const VkOffset3D srcOffset0 = region.imageBlit.srcOffsets[0];
4315 const VkOffset3D srcOffset1 = region.imageBlit.srcOffsets[1];
4316
4317 if (mirrorMode != 0u)
4318 {
4319 //sourceRegion
4320 region.imageBlit.srcOffsets[0].x = std::min(srcOffset0.x, srcOffset1.x);
4321 region.imageBlit.srcOffsets[0].y = std::min(srcOffset0.y, srcOffset1.y);
4322 region.imageBlit.srcOffsets[0].z = std::min(srcOffset0.z, srcOffset1.z);
4323
4324 region.imageBlit.srcOffsets[1].x = std::max(srcOffset0.x, srcOffset1.x);
4325 region.imageBlit.srcOffsets[1].y = std::max(srcOffset0.y, srcOffset1.y);
4326 region.imageBlit.srcOffsets[1].z = std::max(srcOffset0.z, srcOffset1.z);
4327
4328 //destinationRegion
4329 region.imageBlit.dstOffsets[0].x = std::min(dstOffset0.x, dstOffset1.x);
4330 region.imageBlit.dstOffsets[0].y = std::min(dstOffset0.y, dstOffset1.y);
4331 region.imageBlit.dstOffsets[0].z = std::min(dstOffset0.z, dstOffset1.z);
4332
4333 region.imageBlit.dstOffsets[1].x = std::max(dstOffset0.x, dstOffset1.x);
4334 region.imageBlit.dstOffsets[1].y = std::max(dstOffset0.y, dstOffset1.y);
4335 region.imageBlit.dstOffsets[1].z = std::max(dstOffset0.z, dstOffset1.z);
4336 }
4337 }
4338
4339 // Mirror X, Y and Z as required by the offset values in the 3 axes.
getMirrorMode(const VkOffset3D from,const VkOffset3D to)4340 MirrorMode getMirrorMode(const VkOffset3D from, const VkOffset3D to)
4341 {
4342 MirrorMode mode = 0u;
4343
4344 if (from.x > to.x)
4345 mode |= MIRROR_MODE_X;
4346
4347 if (from.y > to.y)
4348 mode |= MIRROR_MODE_Y;
4349
4350 if (from.z > to.z)
4351 mode |= MIRROR_MODE_Z;
4352
4353 return mode;
4354 }
4355
4356 // 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)4357 MirrorMode getMirrorMode(const VkOffset3D s1, const VkOffset3D s2, const VkOffset3D d1, const VkOffset3D d2)
4358 {
4359 static const MirrorModeBits kBits[] = { MIRROR_MODE_X, MIRROR_MODE_Y, MIRROR_MODE_Z };
4360
4361 const MirrorMode source = getMirrorMode(s1, s2);
4362 const MirrorMode destination = getMirrorMode(d1, d2);
4363
4364 MirrorMode mode = 0u;
4365
4366 for (int i = 0; i < DE_LENGTH_OF_ARRAY(kBits); ++i)
4367 {
4368 const MirrorModeBits bit = kBits[i];
4369 if ((source & bit) != (destination & bit))
4370 mode |= bit;
4371 }
4372
4373 return mode;
4374 }
4375
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)4376 void BlittingImages::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
4377 {
4378 DE_UNREF(mipLevel);
4379
4380 const MirrorMode mirrorMode = getMirrorMode(region.imageBlit.srcOffsets[0],
4381 region.imageBlit.srcOffsets[1],
4382 region.imageBlit.dstOffsets[0],
4383 region.imageBlit.dstOffsets[1]);
4384
4385 flipCoordinates(region, mirrorMode);
4386
4387 const VkOffset3D srcOffset = region.imageBlit.srcOffsets[0];
4388 const VkOffset3D srcExtent =
4389 {
4390 region.imageBlit.srcOffsets[1].x - srcOffset.x,
4391 region.imageBlit.srcOffsets[1].y - srcOffset.y,
4392 region.imageBlit.srcOffsets[1].z - srcOffset.z,
4393 };
4394 const VkOffset3D dstOffset = region.imageBlit.dstOffsets[0];
4395 const VkOffset3D dstExtent =
4396 {
4397 region.imageBlit.dstOffsets[1].x - dstOffset.x,
4398 region.imageBlit.dstOffsets[1].y - dstOffset.y,
4399 region.imageBlit.dstOffsets[1].z - dstOffset.z,
4400 };
4401
4402 tcu::Sampler::FilterMode filter;
4403 switch (m_params.filter)
4404 {
4405 case VK_FILTER_LINEAR: filter = tcu::Sampler::LINEAR; break;
4406 case VK_FILTER_CUBIC_EXT: filter = tcu::Sampler::CUBIC; break;
4407 case VK_FILTER_NEAREST:
4408 default: filter = tcu::Sampler::NEAREST; break;
4409 }
4410
4411 if (tcu::isCombinedDepthStencilType(src.getFormat().type))
4412 {
4413 DE_ASSERT(src.getFormat() == dst.getFormat());
4414
4415 // Scale depth.
4416 if (tcu::hasDepthComponent(src.getFormat().order))
4417 {
4418 const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, srcExtent.x, srcExtent.y, srcExtent.z), tcu::Sampler::MODE_DEPTH);
4419 const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z), tcu::Sampler::MODE_DEPTH);
4420 tcu::scale(dstSubRegion, srcSubRegion, filter);
4421
4422 if (filter != tcu::Sampler::NEAREST)
4423 {
4424 const tcu::ConstPixelBufferAccess depthSrc = getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH);
4425 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);
4426 scaleFromWholeSrcBuffer(unclampedSubRegion, depthSrc, srcOffset, srcExtent, filter, mirrorMode);
4427 }
4428 }
4429
4430 // Scale stencil.
4431 if (tcu::hasStencilComponent(src.getFormat().order))
4432 {
4433 const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, srcExtent.x, srcExtent.y, srcExtent.z), tcu::Sampler::MODE_STENCIL);
4434 const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z), tcu::Sampler::MODE_STENCIL);
4435 blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
4436
4437 if (filter != tcu::Sampler::NEAREST)
4438 {
4439 const tcu::ConstPixelBufferAccess stencilSrc = getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL);
4440 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);
4441 scaleFromWholeSrcBuffer(unclampedSubRegion, stencilSrc, srcOffset, srcExtent, filter, mirrorMode);
4442 }
4443 }
4444 }
4445 else
4446 {
4447 const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, srcExtent.x, srcExtent.y, srcExtent.z);
4448 const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z);
4449 blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
4450
4451 if (filter != tcu::Sampler::NEAREST)
4452 {
4453 const tcu::PixelBufferAccess unclampedSubRegion = tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z);
4454 scaleFromWholeSrcBuffer(unclampedSubRegion, src, srcOffset, srcExtent, filter, mirrorMode);
4455 }
4456 }
4457 }
4458
generateExpectedResult(void)4459 void BlittingImages::generateExpectedResult (void)
4460 {
4461 const tcu::ConstPixelBufferAccess src = m_sourceCompressedTexture ? m_sourceCompressedTexture->getDecompressedAccess() : m_sourceTextureLevel->getAccess();
4462 const tcu::ConstPixelBufferAccess dst = m_destinationCompressedTexture ? m_destinationCompressedTexture->getDecompressedAccess() : m_destinationTextureLevel->getAccess();
4463
4464 m_expectedTextureLevel[0] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
4465 tcu::copy(m_expectedTextureLevel[0]->getAccess(), dst);
4466
4467 if (m_params.filter != VK_FILTER_NEAREST)
4468 {
4469 m_unclampedExpectedTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
4470 tcu::copy(m_unclampedExpectedTextureLevel->getAccess(), dst);
4471 }
4472
4473 for (deUint32 i = 0; i < m_params.regions.size(); i++)
4474 {
4475 CopyRegion region = m_params.regions[i];
4476 copyRegionToTextureLevel(src, m_expectedTextureLevel[0]->getAccess(), region);
4477 }
4478 }
4479
uploadCompressedImage(const VkImage & image,const ImageParms & parms)4480 void BlittingImages::uploadCompressedImage (const VkImage& image, const ImageParms& parms)
4481 {
4482 DE_ASSERT(m_sourceCompressedTexture);
4483
4484 const InstanceInterface& vki = m_context.getInstanceInterface();
4485 const DeviceInterface& vk = m_context.getDeviceInterface();
4486 const VkPhysicalDevice vkPhysDevice = m_context.getPhysicalDevice();
4487 const VkDevice vkDevice = m_device;
4488 const VkQueue queue = m_queue;
4489 Allocator& memAlloc = *m_allocator;
4490 Move<VkBuffer> buffer;
4491 const deUint32 bufferSize = m_sourceCompressedTexture->getCompressedTexture().getDataSize();
4492 de::MovePtr<Allocation> bufferAlloc;
4493 const deUint32 arraySize = getArraySize(parms);
4494 const VkExtent3D imageExtent
4495 {
4496 parms.extent.width,
4497 (parms.imageType != VK_IMAGE_TYPE_1D) ? parms.extent.height : 1u,
4498 (parms.imageType == VK_IMAGE_TYPE_3D) ? parms.extent.depth : 1u,
4499 };
4500
4501 // Create source buffer
4502 {
4503 const VkBufferCreateInfo bufferParams
4504 {
4505 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
4506 DE_NULL, // const void* pNext;
4507 0u, // VkBufferCreateFlags flags;
4508 bufferSize, // VkDeviceSize size;
4509 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage;
4510 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
4511 0u, // deUint32 queueFamilyIndexCount;
4512 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
4513 };
4514
4515 buffer = createBuffer(vk, vkDevice, &bufferParams);
4516 bufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *buffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
4517 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
4518 }
4519
4520 // Barriers for copying buffer to image
4521 const VkBufferMemoryBarrier preBufferBarrier
4522 {
4523 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
4524 DE_NULL, // const void* pNext;
4525 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask;
4526 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
4527 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
4528 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
4529 *buffer, // VkBuffer buffer;
4530 0u, // VkDeviceSize offset;
4531 bufferSize // VkDeviceSize size;
4532 };
4533
4534 const VkImageMemoryBarrier preImageBarrier
4535 {
4536 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
4537 DE_NULL, // const void* pNext;
4538 0u, // VkAccessFlags srcAccessMask;
4539 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
4540 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
4541 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
4542 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
4543 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
4544 image, // VkImage image;
4545 { // VkImageSubresourceRange subresourceRange;
4546 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect;
4547 0u, // deUint32 baseMipLevel;
4548 1u, // deUint32 mipLevels;
4549 0u, // deUint32 baseArraySlice;
4550 arraySize, // deUint32 arraySize;
4551 }
4552 };
4553
4554 const VkImageMemoryBarrier postImageBarrier
4555 {
4556 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
4557 DE_NULL, // const void* pNext;
4558 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
4559 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
4560 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
4561 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
4562 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
4563 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
4564 image, // VkImage image;
4565 { // VkImageSubresourceRange subresourceRange;
4566 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect;
4567 0u, // deUint32 baseMipLevel;
4568 1u, // deUint32 mipLevels;
4569 0u, // deUint32 baseArraySlice;
4570 arraySize, // deUint32 arraySize;
4571 }
4572 };
4573
4574 const VkExtent3D copyExtent
4575 {
4576 imageExtent.width,
4577 imageExtent.height,
4578 imageExtent.depth
4579 };
4580
4581 VkBufferImageCopy copyRegion
4582 {
4583 0u, // VkDeviceSize bufferOffset;
4584 copyExtent.width, // deUint32 bufferRowLength;
4585 copyExtent.height, // deUint32 bufferImageHeight;
4586 {
4587 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect;
4588 0u, // deUint32 mipLevel;
4589 0u, // deUint32 baseArrayLayer;
4590 arraySize, // deUint32 layerCount;
4591 }, // VkImageSubresourceLayers imageSubresource;
4592 { 0, 0, 0 }, // VkOffset3D imageOffset;
4593 copyExtent // VkExtent3D imageExtent;
4594 };
4595
4596 // Write buffer data
4597 deMemcpy(bufferAlloc->getHostPtr(), m_sourceCompressedTexture->getCompressedTexture().getData(), bufferSize);
4598 flushAlloc(vk, vkDevice, *bufferAlloc);
4599
4600 // Copy buffer to image
4601 beginCommandBuffer(vk, *m_cmdBuffer);
4602 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL,
4603 1, &preBufferBarrier, 1, &preImageBarrier);
4604 vk.cmdCopyBufferToImage(*m_cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ©Region);
4605 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);
4606 endCommandBuffer(vk, *m_cmdBuffer);
4607
4608 submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
4609 m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
4610 }
4611
4612
4613 class BlitImageTestCase : public vkt::TestCase
4614 {
4615 public:
BlitImageTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)4616 BlitImageTestCase (tcu::TestContext& testCtx,
4617 const std::string& name,
4618 const std::string& description,
4619 const TestParams params)
4620 : vkt::TestCase (testCtx, name, description)
4621 , m_params (params)
4622 {}
4623
createInstance(Context & context) const4624 virtual TestInstance* createInstance (Context& context) const
4625 {
4626 return new BlittingImages(context, m_params);
4627 }
4628
checkSupport(Context & context) const4629 virtual void checkSupport (Context& context) const
4630 {
4631 VkImageFormatProperties properties;
4632 if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
4633 m_params.src.image.format,
4634 m_params.src.image.imageType,
4635 m_params.src.image.tiling,
4636 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
4637 0,
4638 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
4639 {
4640 TCU_THROW(NotSupportedError, "Source format not supported");
4641 }
4642 if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
4643 m_params.dst.image.format,
4644 m_params.dst.image.imageType,
4645 m_params.dst.image.tiling,
4646 VK_IMAGE_USAGE_TRANSFER_DST_BIT,
4647 0,
4648 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
4649 {
4650 TCU_THROW(NotSupportedError, "Destination format not supported");
4651 }
4652
4653 VkFormatProperties srcFormatProperties;
4654 context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_params.src.image.format, &srcFormatProperties);
4655 VkFormatFeatureFlags srcFormatFeatures = m_params.src.image.tiling == VK_IMAGE_TILING_LINEAR ? srcFormatProperties.linearTilingFeatures : srcFormatProperties.optimalTilingFeatures;
4656 if (!(srcFormatFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT))
4657 {
4658 TCU_THROW(NotSupportedError, "Format feature blit source not supported");
4659 }
4660
4661 VkFormatProperties dstFormatProperties;
4662 context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_params.dst.image.format, &dstFormatProperties);
4663 VkFormatFeatureFlags dstFormatFeatures = m_params.dst.image.tiling == VK_IMAGE_TILING_LINEAR ? dstFormatProperties.linearTilingFeatures : dstFormatProperties.optimalTilingFeatures;
4664 if (!(dstFormatFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT))
4665 {
4666 TCU_THROW(NotSupportedError, "Format feature blit destination not supported");
4667 }
4668
4669 if (m_params.filter == VK_FILTER_LINEAR && !(srcFormatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
4670 {
4671 TCU_THROW(NotSupportedError, "Source format feature sampled image filter linear not supported");
4672 }
4673
4674 if (m_params.filter == VK_FILTER_CUBIC_EXT)
4675 {
4676 context.requireDeviceFunctionality("VK_EXT_filter_cubic");
4677
4678 if (!(srcFormatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT))
4679 {
4680 TCU_THROW(NotSupportedError, "Source format feature sampled image filter cubic not supported");
4681 }
4682 }
4683
4684 if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
4685 {
4686 if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
4687 {
4688 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
4689 }
4690 }
4691 }
4692
4693 private:
4694 TestParams m_params;
4695 };
4696
4697 class BlittingMipmaps : public CopiesAndBlittingTestInstance
4698 {
4699 public:
4700 BlittingMipmaps (Context& context,
4701 TestParams params);
4702 virtual tcu::TestStatus iterate (void);
4703 protected:
4704 virtual tcu::TestStatus checkTestResult (tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess());
4705 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
4706 virtual void generateExpectedResult (void);
4707 private:
4708 bool checkNonNearestFilteredResult (void);
4709 bool checkNearestFilteredResult (void);
4710
4711 Move<VkImage> m_source;
4712 de::MovePtr<Allocation> m_sourceImageAlloc;
4713 Move<VkImage> m_destination;
4714 de::MovePtr<Allocation> m_destinationImageAlloc;
4715
4716 de::MovePtr<tcu::TextureLevel> m_unclampedExpectedTextureLevel[16];
4717 };
4718
BlittingMipmaps(Context & context,TestParams params)4719 BlittingMipmaps::BlittingMipmaps (Context& context, TestParams params)
4720 : CopiesAndBlittingTestInstance (context, params)
4721 {
4722 const InstanceInterface& vki = context.getInstanceInterface();
4723 const DeviceInterface& vk = context.getDeviceInterface();
4724 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
4725 const VkDevice vkDevice = m_device;
4726 Allocator& memAlloc = context.getDefaultAllocator();
4727
4728 // Create source image
4729 {
4730 const VkImageCreateInfo sourceImageParams =
4731 {
4732 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
4733 DE_NULL, // const void* pNext;
4734 getCreateFlags(m_params.src.image), // VkImageCreateFlags flags;
4735 m_params.src.image.imageType, // VkImageType imageType;
4736 m_params.src.image.format, // VkFormat format;
4737 getExtent3D(m_params.src.image), // VkExtent3D extent;
4738 1u, // deUint32 mipLevels;
4739 getArraySize(m_params.src.image), // deUint32 arraySize;
4740 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
4741 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
4742 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
4743 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
4744 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
4745 0u, // deUint32 queueFamilyIndexCount;
4746 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
4747 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
4748 };
4749
4750 m_source = createImage(vk, vkDevice, &sourceImageParams);
4751 m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
4752 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
4753 }
4754
4755 // Create destination image
4756 {
4757 const VkImageCreateInfo destinationImageParams =
4758 {
4759 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
4760 DE_NULL, // const void* pNext;
4761 getCreateFlags(m_params.dst.image), // VkImageCreateFlags flags;
4762 m_params.dst.image.imageType, // VkImageType imageType;
4763 m_params.dst.image.format, // VkFormat format;
4764 getExtent3D(m_params.dst.image), // VkExtent3D extent;
4765 m_params.mipLevels, // deUint32 mipLevels;
4766 getArraySize(m_params.dst.image), // deUint32 arraySize;
4767 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
4768 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
4769 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
4770 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
4771 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
4772 0u, // deUint32 queueFamilyIndexCount;
4773 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
4774 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
4775 };
4776
4777 m_destination = createImage(vk, vkDevice, &destinationImageParams);
4778 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
4779 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
4780 }
4781 }
4782
iterate(void)4783 tcu::TestStatus BlittingMipmaps::iterate (void)
4784 {
4785 const tcu::TextureFormat srcTcuFormat = mapVkFormat(m_params.src.image.format);
4786 const tcu::TextureFormat dstTcuFormat = mapVkFormat(m_params.dst.image.format);
4787 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
4788 m_params.src.image.extent.width,
4789 m_params.src.image.extent.height,
4790 m_params.src.image.extent.depth));
4791 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);
4792 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
4793 (int)m_params.dst.image.extent.width,
4794 (int)m_params.dst.image.extent.height,
4795 (int)m_params.dst.image.extent.depth));
4796 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);
4797 generateExpectedResult();
4798
4799 uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
4800
4801 uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, m_params.mipLevels);
4802
4803 const DeviceInterface& vk = m_context.getDeviceInterface();
4804 const VkDevice vkDevice = m_device;
4805 const VkQueue queue = m_queue;
4806
4807 std::vector<VkImageBlit> regions;
4808 std::vector<VkImageBlit2KHR> regions2KHR;
4809 for (deUint32 i = 0; i < m_params.regions.size(); i++)
4810 {
4811 if (m_params.extensionUse == EXTENSION_USE_NONE)
4812 {
4813 regions.push_back(m_params.regions[i].imageBlit);
4814 }
4815 else
4816 {
4817 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
4818 regions2KHR.push_back(convertvkImageBlitTovkImageBlit2KHR(m_params.regions[i].imageBlit));
4819 }
4820 }
4821
4822 // Copy source image to mip level 0 when generating mipmaps with multiple blit commands
4823 if (!m_params.singleCommand)
4824 uploadImage(m_sourceTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, 1u);
4825
4826 beginCommandBuffer(vk, *m_cmdBuffer);
4827
4828 // Blit all mip levels with a single blit command
4829 if (m_params.singleCommand)
4830 {
4831 {
4832 // Source image layout
4833 const VkImageMemoryBarrier srcImageBarrier =
4834 {
4835 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
4836 DE_NULL, // const void* pNext;
4837 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
4838 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
4839 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
4840 m_params.src.image.operationLayout, // VkImageLayout newLayout;
4841 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
4842 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
4843 m_source.get(), // VkImage image;
4844 { // VkImageSubresourceRange subresourceRange;
4845 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
4846 0u, // deUint32 baseMipLevel;
4847 1u, // deUint32 mipLevels;
4848 0u, // deUint32 baseArraySlice;
4849 getArraySize(m_params.src.image) // deUint32 arraySize;
4850 }
4851 };
4852
4853 // Destination image layout
4854 const VkImageMemoryBarrier dstImageBarrier =
4855 {
4856 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
4857 DE_NULL, // const void* pNext;
4858 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
4859 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
4860 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
4861 m_params.dst.image.operationLayout, // VkImageLayout newLayout;
4862 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
4863 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
4864 m_destination.get(), // VkImage image;
4865 { // VkImageSubresourceRange subresourceRange;
4866 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
4867 0u, // deUint32 baseMipLevel;
4868 m_params.mipLevels, // deUint32 mipLevels;
4869 0u, // deUint32 baseArraySlice;
4870 getArraySize(m_params.dst.image) // deUint32 arraySize;
4871 }
4872 };
4873
4874 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);
4875 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);
4876
4877 if (m_params.extensionUse == EXTENSION_USE_NONE)
4878 {
4879 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);
4880 }
4881 #ifndef CTS_USES_VULKANSC
4882 else
4883 {
4884 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
4885 const VkBlitImageInfo2KHR BlitImageInfo2KHR =
4886 {
4887 VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR, // VkStructureType sType;
4888 DE_NULL, // const void* pNext;
4889 m_source.get(), // VkImage srcImage;
4890 m_params.src.image.operationLayout, // VkImageLayout srcImageLayout;
4891 m_destination.get(), // VkImage dstImage;
4892 m_params.dst.image.operationLayout, // VkImageLayout dstImageLayout;
4893 (deUint32)m_params.regions.size(), // uint32_t regionCount;
4894 ®ions2KHR[0], // const VkImageBlit2KHR* pRegions;
4895 m_params.filter // VkFilter filter;
4896 };
4897 vk.cmdBlitImage2(*m_cmdBuffer, &BlitImageInfo2KHR);
4898 }
4899 #endif // CTS_USES_VULKANSC
4900 }
4901 }
4902 // Blit mip levels with multiple blit commands
4903 else
4904 {
4905 // Prepare all mip levels for reading
4906 {
4907 for (deUint32 barrierno = 0; barrierno < m_params.barrierCount; barrierno++)
4908 {
4909 VkImageMemoryBarrier preImageBarrier =
4910 {
4911 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
4912 DE_NULL, // const void* pNext;
4913 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
4914 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
4915 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
4916 m_params.src.image.operationLayout, // VkImageLayout newLayout;
4917 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
4918 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
4919 m_destination.get(), // VkImage image;
4920 { // VkImageSubresourceRange subresourceRange;
4921 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
4922 0u, // deUint32 baseMipLevel;
4923 VK_REMAINING_MIP_LEVELS, // deUint32 mipLevels;
4924 0u, // deUint32 baseArraySlice;
4925 getArraySize(m_params.src.image) // deUint32 arraySize;
4926 }
4927 };
4928
4929 if (getArraySize(m_params.src.image) == 1)
4930 {
4931 DE_ASSERT(barrierno < m_params.mipLevels);
4932 preImageBarrier.subresourceRange.baseMipLevel = barrierno;
4933 preImageBarrier.subresourceRange.levelCount = (barrierno + 1 < m_params.barrierCount) ? 1 : VK_REMAINING_MIP_LEVELS;
4934 }
4935 else
4936 {
4937 preImageBarrier.subresourceRange.baseArrayLayer = barrierno;
4938 preImageBarrier.subresourceRange.layerCount = (barrierno + 1 < m_params.barrierCount) ? 1 : VK_REMAINING_ARRAY_LAYERS;
4939 }
4940 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);
4941 }
4942 }
4943
4944 for (deUint32 regionNdx = 0u; regionNdx < (deUint32)m_params.regions.size(); regionNdx++)
4945 {
4946 const deUint32 mipLevel = m_params.regions[regionNdx].imageBlit.dstSubresource.mipLevel;
4947
4948 // Prepare single mip level for writing
4949 const VkImageMemoryBarrier preImageBarrier =
4950 {
4951 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
4952 DE_NULL, // const void* pNext;
4953 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags srcAccessMask;
4954 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
4955 m_params.src.image.operationLayout, // VkImageLayout oldLayout;
4956 m_params.dst.image.operationLayout, // VkImageLayout newLayout;
4957 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
4958 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
4959 m_destination.get(), // VkImage image;
4960 { // VkImageSubresourceRange subresourceRange;
4961 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
4962 mipLevel, // deUint32 baseMipLevel;
4963 1u, // deUint32 mipLevels;
4964 0u, // deUint32 baseArraySlice;
4965 getArraySize(m_params.dst.image) // deUint32 arraySize;
4966 }
4967 };
4968
4969 // Prepare single mip level for reading
4970 const VkImageMemoryBarrier postImageBarrier =
4971 {
4972 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
4973 DE_NULL, // const void* pNext;
4974 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
4975 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
4976 m_params.dst.image.operationLayout, // VkImageLayout oldLayout;
4977 m_params.src.image.operationLayout, // VkImageLayout newLayout;
4978 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
4979 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
4980 m_destination.get(), // VkImage image;
4981 { // VkImageSubresourceRange subresourceRange;
4982 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
4983 mipLevel, // deUint32 baseMipLevel;
4984 1u, // deUint32 mipLevels;
4985 0u, // deUint32 baseArraySlice;
4986 getArraySize(m_params.src.image) // deUint32 arraySize;
4987 }
4988 };
4989
4990 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);
4991
4992 if (m_params.extensionUse == EXTENSION_USE_NONE)
4993 {
4994 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);
4995 }
4996 #ifndef CTS_USES_VULKANSC
4997 else
4998 {
4999 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
5000 const VkBlitImageInfo2KHR BlitImageInfo2KHR =
5001 {
5002 VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR, // VkStructureType sType;
5003 DE_NULL, // const void* pNext;
5004 m_destination.get(), // VkImage srcImage;
5005 m_params.src.image.operationLayout, // VkImageLayout srcImageLayout;
5006 m_destination.get(), // VkImage dstImage;
5007 m_params.dst.image.operationLayout, // VkImageLayout dstImageLayout;
5008 1u, // uint32_t regionCount;
5009 ®ions2KHR[regionNdx], // const VkImageBlit2KHR* pRegions;
5010 m_params.filter // VkFilter filter;
5011 };
5012 vk.cmdBlitImage2(*m_cmdBuffer, &BlitImageInfo2KHR);
5013 }
5014 #endif // CTS_USES_VULKANSC
5015
5016 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);
5017 }
5018
5019 // Prepare all mip levels for writing
5020 {
5021 const VkImageMemoryBarrier postImageBarrier =
5022 {
5023 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
5024 DE_NULL, // const void* pNext;
5025 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags srcAccessMask;
5026 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
5027 m_params.src.image.operationLayout, // VkImageLayout oldLayout;
5028 m_params.dst.image.operationLayout, // VkImageLayout newLayout;
5029 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
5030 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
5031 m_destination.get(), // VkImage image;
5032 { // VkImageSubresourceRange subresourceRange;
5033 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
5034 0u, // deUint32 baseMipLevel;
5035 VK_REMAINING_MIP_LEVELS, // deUint32 mipLevels;
5036 0u, // deUint32 baseArraySlice;
5037 getArraySize(m_params.dst.image) // deUint32 arraySize;
5038 }
5039 };
5040
5041 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);
5042 }
5043 }
5044
5045 endCommandBuffer(vk, *m_cmdBuffer);
5046 submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
5047 m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
5048
5049 return checkTestResult();
5050 }
5051
checkNonNearestFilteredResult(void)5052 bool BlittingMipmaps::checkNonNearestFilteredResult (void)
5053 {
5054 tcu::TestLog& log (m_context.getTestContext().getLog());
5055 bool allLevelsOk = true;
5056
5057 for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
5058 {
5059 // Update reference results with previous results that have been verified.
5060 // This needs to be done such that accumulated errors don't exceed the fixed threshold.
5061 for (deUint32 i = 0; i < m_params.regions.size(); i++)
5062 {
5063 const CopyRegion region = m_params.regions[i];
5064 const deUint32 srcMipLevel = m_params.regions[i].imageBlit.srcSubresource.mipLevel;
5065 const deUint32 dstMipLevel = m_params.regions[i].imageBlit.dstSubresource.mipLevel;
5066 de::MovePtr<tcu::TextureLevel> prevResultLevel;
5067 tcu::ConstPixelBufferAccess src;
5068 if (srcMipLevel < mipLevelNdx)
5069 {
5070 // Generate expected result from rendered result that was previously verified
5071 prevResultLevel = readImage(*m_destination, m_params.dst.image, srcMipLevel);
5072 src = prevResultLevel->getAccess();
5073 }
5074 else
5075 {
5076 // Previous reference mipmaps might have changed, so recompute expected result
5077 src = m_expectedTextureLevel[srcMipLevel]->getAccess();
5078 }
5079 copyRegionToTextureLevel(src, m_expectedTextureLevel[dstMipLevel]->getAccess(), region, dstMipLevel);
5080 }
5081
5082 de::MovePtr<tcu::TextureLevel> resultLevel = readImage(*m_destination, m_params.dst.image, mipLevelNdx);
5083 const tcu::ConstPixelBufferAccess& resultAccess = resultLevel->getAccess();
5084
5085 const tcu::Sampler::DepthStencilMode mode = tcu::hasDepthComponent(resultAccess.getFormat().order) ? tcu::Sampler::MODE_DEPTH :
5086 tcu::hasStencilComponent(resultAccess.getFormat().order) ? tcu::Sampler::MODE_STENCIL :
5087 tcu::Sampler::MODE_LAST;
5088 const tcu::ConstPixelBufferAccess result = tcu::hasDepthComponent(resultAccess.getFormat().order) ? getEffectiveDepthStencilAccess(resultAccess, mode) :
5089 tcu::hasStencilComponent(resultAccess.getFormat().order) ? getEffectiveDepthStencilAccess(resultAccess, mode) :
5090 resultAccess;
5091 const tcu::ConstPixelBufferAccess clampedLevel = tcu::hasDepthComponent(resultAccess.getFormat().order) ? getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
5092 tcu::hasStencilComponent(resultAccess.getFormat().order) ? getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
5093 m_expectedTextureLevel[mipLevelNdx]->getAccess();
5094 const tcu::ConstPixelBufferAccess unclampedLevel = tcu::hasDepthComponent(resultAccess.getFormat().order) ? getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
5095 tcu::hasStencilComponent(resultAccess.getFormat().order) ? getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
5096 m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess();
5097 const tcu::TextureFormat srcFormat = tcu::hasDepthComponent(resultAccess.getFormat().order) ? tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode) :
5098 tcu::hasStencilComponent(resultAccess.getFormat().order) ? tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode) :
5099 mapVkFormat(m_params.src.image.format);
5100
5101 const tcu::TextureFormat dstFormat = result.getFormat();
5102 bool singleLevelOk = false;
5103 std::vector <CopyRegion> mipLevelRegions;
5104
5105 for (size_t regionNdx = 0u; regionNdx < m_params.regions.size(); regionNdx++)
5106 if (m_params.regions.at(regionNdx).imageBlit.dstSubresource.mipLevel == mipLevelNdx)
5107 mipLevelRegions.push_back(m_params.regions.at(regionNdx));
5108
5109 log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
5110
5111 if (isFloatFormat(dstFormat))
5112 {
5113 const bool srcIsSRGB = tcu::isSRGB(srcFormat);
5114 const tcu::Vec4 srcMaxDiff = getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2.0f : 1.0f);
5115 const tcu::Vec4 dstMaxDiff = getFormatThreshold(dstFormat);
5116 const tcu::Vec4 threshold = ( srcMaxDiff + dstMaxDiff ) * ((m_params.filter == VK_FILTER_CUBIC_EXT)? 1.5f : 1.0f);
5117
5118 singleLevelOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
5119 log << tcu::TestLog::EndSection;
5120
5121 if (!singleLevelOk)
5122 {
5123 log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
5124 singleLevelOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
5125 log << tcu::TestLog::EndSection;
5126 }
5127 }
5128 else
5129 {
5130 tcu::UVec4 threshold;
5131 // Calculate threshold depending on channel width of destination format.
5132 const tcu::IVec4 dstBitDepth = tcu::getTextureFormatBitDepth(dstFormat);
5133 const tcu::IVec4 srcBitDepth = tcu::getTextureFormatBitDepth(srcFormat);
5134 for (deUint32 i = 0; i < 4; ++i)
5135 {
5136 DE_ASSERT(dstBitDepth[i] < std::numeric_limits<uint64_t>::digits);
5137 DE_ASSERT(srcBitDepth[i] < std::numeric_limits<uint64_t>::digits);
5138 deUint64 threshold64 = 1 + de::max( ( ( UINT64_C(1) << dstBitDepth[i] ) - 1 ) / de::clamp((UINT64_C(1) << srcBitDepth[i]) - 1, UINT64_C(1), UINT64_C(256)), UINT64_C(1));
5139 DE_ASSERT(threshold64 <= std::numeric_limits<uint32_t>::max());
5140 threshold[i] = static_cast<deUint32>(threshold64);
5141 }
5142
5143 singleLevelOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
5144 log << tcu::TestLog::EndSection;
5145
5146 if (!singleLevelOk)
5147 {
5148 log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
5149 singleLevelOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", unclampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
5150 log << tcu::TestLog::EndSection;
5151 }
5152 }
5153 allLevelsOk &= singleLevelOk;
5154 }
5155
5156 return allLevelsOk;
5157 }
5158
checkNearestFilteredResult(void)5159 bool BlittingMipmaps::checkNearestFilteredResult (void)
5160 {
5161 bool allLevelsOk = true;
5162 tcu::TestLog& log (m_context.getTestContext().getLog());
5163
5164 for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
5165 {
5166 de::MovePtr<tcu::TextureLevel> resultLevel = readImage(*m_destination, m_params.dst.image, mipLevelNdx);
5167 const tcu::ConstPixelBufferAccess& resultAccess = resultLevel->getAccess();
5168
5169 const tcu::Sampler::DepthStencilMode mode = tcu::hasDepthComponent(resultAccess.getFormat().order) ? tcu::Sampler::MODE_DEPTH :
5170 tcu::hasStencilComponent(resultAccess.getFormat().order) ? tcu::Sampler::MODE_STENCIL :
5171 tcu::Sampler::MODE_LAST;
5172 const tcu::ConstPixelBufferAccess result = tcu::hasDepthComponent(resultAccess.getFormat().order) ? getEffectiveDepthStencilAccess(resultAccess, mode) :
5173 tcu::hasStencilComponent(resultAccess.getFormat().order) ? getEffectiveDepthStencilAccess(resultAccess, mode) :
5174 resultAccess;
5175 const tcu::ConstPixelBufferAccess source = (m_params.singleCommand || mipLevelNdx == 0) ? // Read from source image
5176 tcu::hasDepthComponent(resultAccess.getFormat().order) ? tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode) :
5177 tcu::hasStencilComponent(resultAccess.getFormat().order) ? tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode) :
5178 m_sourceTextureLevel->getAccess()
5179 // Read from destination image
5180 : tcu::hasDepthComponent(resultAccess.getFormat().order) ? tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess(), mode) :
5181 tcu::hasStencilComponent(resultAccess.getFormat().order) ? tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess(), mode) :
5182 m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess();
5183 const tcu::TextureFormat dstFormat = result.getFormat();
5184 const tcu::TextureChannelClass dstChannelClass = tcu::getTextureChannelClass(dstFormat.type);
5185 bool singleLevelOk = false;
5186 std::vector <CopyRegion> mipLevelRegions;
5187
5188 for (size_t regionNdx = 0u; regionNdx < m_params.regions.size(); regionNdx++)
5189 if (m_params.regions.at(regionNdx).imageBlit.dstSubresource.mipLevel == mipLevelNdx)
5190 mipLevelRegions.push_back(m_params.regions.at(regionNdx));
5191
5192 tcu::TextureLevel errorMaskStorage (tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), result.getWidth(), result.getHeight(), result.getDepth());
5193 tcu::PixelBufferAccess errorMask = errorMaskStorage.getAccess();
5194 tcu::Vec4 pixelBias (0.0f, 0.0f, 0.0f, 0.0f);
5195 tcu::Vec4 pixelScale (1.0f, 1.0f, 1.0f, 1.0f);
5196
5197 tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
5198
5199 if (dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
5200 dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
5201 {
5202 singleLevelOk = intNearestBlitCompare(source, result, errorMask, mipLevelRegions);
5203 }
5204 else
5205 {
5206 const tcu::Vec4 srcMaxDiff = getFloatOrFixedPointFormatThreshold(source.getFormat());
5207 const tcu::Vec4 dstMaxDiff = getFloatOrFixedPointFormatThreshold(result.getFormat());
5208
5209 singleLevelOk = floatNearestBlitCompare(source, result, srcMaxDiff, dstMaxDiff, errorMask, mipLevelRegions);
5210 }
5211
5212 if (dstFormat != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
5213 tcu::computePixelScaleBias(result, pixelScale, pixelBias);
5214
5215 if (!singleLevelOk)
5216 {
5217 log << tcu::TestLog::ImageSet("Compare", "Result comparsion, level " + de::toString(mipLevelNdx))
5218 << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
5219 << tcu::TestLog::Image("Reference", "Reference", source, pixelScale, pixelBias)
5220 << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask)
5221 << tcu::TestLog::EndImageSet;
5222 }
5223 else
5224 {
5225 log << tcu::TestLog::ImageSet("Compare", "Result comparsion, level " + de::toString(mipLevelNdx))
5226 << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
5227 << tcu::TestLog::EndImageSet;
5228 }
5229
5230 allLevelsOk &= singleLevelOk;
5231 }
5232
5233 return allLevelsOk;
5234 }
5235
checkTestResult(tcu::ConstPixelBufferAccess result)5236 tcu::TestStatus BlittingMipmaps::checkTestResult (tcu::ConstPixelBufferAccess result)
5237 {
5238 DE_UNREF(result);
5239 DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR || m_params.filter == VK_FILTER_CUBIC_EXT);
5240 const std::string failMessage("Result image is incorrect");
5241
5242 if (m_params.filter != VK_FILTER_NEAREST)
5243 {
5244 if (!checkNonNearestFilteredResult())
5245 return tcu::TestStatus::fail(failMessage);
5246 }
5247 else // NEAREST filtering
5248 {
5249 if (!checkNearestFilteredResult())
5250 return tcu::TestStatus::fail(failMessage);
5251 }
5252
5253 return tcu::TestStatus::pass("Pass");
5254 }
5255
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)5256 void BlittingMipmaps::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
5257 {
5258 DE_ASSERT(src.getDepth() == dst.getDepth());
5259
5260 const MirrorMode mirrorMode = getMirrorMode(region.imageBlit.srcOffsets[0],
5261 region.imageBlit.srcOffsets[1],
5262 region.imageBlit.dstOffsets[0],
5263 region.imageBlit.dstOffsets[1]);
5264
5265 flipCoordinates(region, mirrorMode);
5266
5267 const VkOffset3D srcOffset = region.imageBlit.srcOffsets[0];
5268 const VkOffset3D srcExtent =
5269 {
5270 region.imageBlit.srcOffsets[1].x - srcOffset.x,
5271 region.imageBlit.srcOffsets[1].y - srcOffset.y,
5272 region.imageBlit.srcOffsets[1].z - srcOffset.z
5273 };
5274 const VkOffset3D dstOffset = region.imageBlit.dstOffsets[0];
5275 const VkOffset3D dstExtent =
5276 {
5277 region.imageBlit.dstOffsets[1].x - dstOffset.x,
5278 region.imageBlit.dstOffsets[1].y - dstOffset.y,
5279 region.imageBlit.dstOffsets[1].z - dstOffset.z
5280 };
5281
5282 tcu::Sampler::FilterMode filter;
5283 switch (m_params.filter)
5284 {
5285 case VK_FILTER_LINEAR: filter = tcu::Sampler::LINEAR; break;
5286 case VK_FILTER_CUBIC_EXT: filter = tcu::Sampler::CUBIC; break;
5287 case VK_FILTER_NEAREST:
5288 default: filter = tcu::Sampler::NEAREST; break;
5289 }
5290
5291 if (tcu::isCombinedDepthStencilType(src.getFormat().type))
5292 {
5293 DE_ASSERT(src.getFormat() == dst.getFormat());
5294 // Scale depth.
5295 if (tcu::hasDepthComponent(src.getFormat().order))
5296 {
5297 const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_DEPTH);
5298 const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH);
5299 tcu::scale(dstSubRegion, srcSubRegion, filter);
5300
5301 if (filter != tcu::Sampler::NEAREST)
5302 {
5303 const tcu::ConstPixelBufferAccess depthSrc = getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH);
5304 const tcu::PixelBufferAccess unclampedSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel[0]->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH);
5305 scaleFromWholeSrcBuffer(unclampedSubRegion, depthSrc, srcOffset, srcExtent, filter);
5306 }
5307 }
5308
5309 // Scale stencil.
5310 if (tcu::hasStencilComponent(src.getFormat().order))
5311 {
5312 const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_STENCIL);
5313 const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
5314 blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
5315
5316 if (filter != tcu::Sampler::NEAREST)
5317 {
5318 const tcu::ConstPixelBufferAccess stencilSrc = getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL);
5319 const tcu::PixelBufferAccess unclampedSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel[0]->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
5320 scaleFromWholeSrcBuffer(unclampedSubRegion, stencilSrc, srcOffset, srcExtent, filter);
5321 }
5322 }
5323 }
5324 else
5325 {
5326 for (int layerNdx = 0u; layerNdx < src.getDepth(); layerNdx++)
5327 {
5328 const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, srcOffset.x, srcOffset.y, layerNdx, srcExtent.x, srcExtent.y, 1);
5329 const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dst, dstOffset.x, dstOffset.y, layerNdx, dstExtent.x, dstExtent.y, 1);
5330 blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
5331
5332 if (filter != tcu::Sampler::NEAREST)
5333 {
5334 const tcu::PixelBufferAccess unclampedSubRegion = tcu::getSubregion(m_unclampedExpectedTextureLevel[mipLevel]->getAccess(), dstOffset.x, dstOffset.y, layerNdx, dstExtent.x, dstExtent.y, 1);
5335 scaleFromWholeSrcBuffer(unclampedSubRegion, srcSubRegion, srcOffset, srcExtent, filter);
5336 }
5337 }
5338 }
5339 }
5340
generateExpectedResult(void)5341 void BlittingMipmaps::generateExpectedResult (void)
5342 {
5343 const tcu::ConstPixelBufferAccess src = m_sourceTextureLevel->getAccess();
5344 const tcu::ConstPixelBufferAccess dst = m_destinationTextureLevel->getAccess();
5345
5346 for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
5347 m_expectedTextureLevel[mipLevelNdx] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth() >> mipLevelNdx, dst.getHeight() >> mipLevelNdx, dst.getDepth()));
5348
5349 tcu::copy(m_expectedTextureLevel[0]->getAccess(), src);
5350
5351 if (m_params.filter != VK_FILTER_NEAREST)
5352 {
5353 for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
5354 m_unclampedExpectedTextureLevel[mipLevelNdx] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth() >> mipLevelNdx, dst.getHeight() >> mipLevelNdx, dst.getDepth()));
5355
5356 tcu::copy(m_unclampedExpectedTextureLevel[0]->getAccess(), src);
5357 }
5358
5359 for (deUint32 i = 0; i < m_params.regions.size(); i++)
5360 {
5361 CopyRegion region = m_params.regions[i];
5362 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);
5363 }
5364 }
5365
5366 class BlitMipmapTestCase : public vkt::TestCase
5367 {
5368 public:
BlitMipmapTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)5369 BlitMipmapTestCase (tcu::TestContext& testCtx,
5370 const std::string& name,
5371 const std::string& description,
5372 const TestParams params)
5373 : vkt::TestCase (testCtx, name, description)
5374 , m_params (params)
5375 {}
5376
createInstance(Context & context) const5377 virtual TestInstance* createInstance (Context& context) const
5378 {
5379 return new BlittingMipmaps(context, m_params);
5380 }
5381
checkSupport(Context & context) const5382 virtual void checkSupport (Context& context) const
5383 {
5384 const InstanceInterface& vki = context.getInstanceInterface();
5385 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
5386 {
5387 VkImageFormatProperties properties;
5388 if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
5389 m_params.src.image.format,
5390 VK_IMAGE_TYPE_2D,
5391 VK_IMAGE_TILING_OPTIMAL,
5392 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
5393 0,
5394 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
5395 {
5396 TCU_THROW(NotSupportedError, "Format not supported");
5397 }
5398 else if ((m_params.src.image.extent.width > properties.maxExtent.width) ||
5399 (m_params.src.image.extent.height > properties.maxExtent.height) ||
5400 (m_params.src.image.extent.depth > properties.maxArrayLayers))
5401 {
5402 TCU_THROW(NotSupportedError, "Image size not supported");
5403 }
5404 }
5405
5406 {
5407 VkImageFormatProperties properties;
5408 if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
5409 m_params.dst.image.format,
5410 VK_IMAGE_TYPE_2D,
5411 VK_IMAGE_TILING_OPTIMAL,
5412 VK_IMAGE_USAGE_TRANSFER_DST_BIT,
5413 0,
5414 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
5415 {
5416 TCU_THROW(NotSupportedError, "Format not supported");
5417 }
5418 else if ((m_params.dst.image.extent.width > properties.maxExtent.width) ||
5419 (m_params.dst.image.extent.height > properties.maxExtent.height) ||
5420 (m_params.dst.image.extent.depth > properties.maxArrayLayers))
5421 {
5422 TCU_THROW(NotSupportedError, "Image size not supported");
5423 }
5424 else if (m_params.mipLevels > properties.maxMipLevels)
5425 {
5426 TCU_THROW(NotSupportedError, "Number of mip levels not supported");
5427 }
5428 else if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
5429 (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
5430 {
5431 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
5432 }
5433 }
5434
5435 const VkFormatProperties srcFormatProperties = getPhysicalDeviceFormatProperties (vki, vkPhysDevice, m_params.src.image.format);
5436 if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT))
5437 {
5438 TCU_THROW(NotSupportedError, "Format feature blit source not supported");
5439 }
5440
5441 const VkFormatProperties dstFormatProperties = getPhysicalDeviceFormatProperties (vki, vkPhysDevice, m_params.dst.image.format);
5442 if (!(dstFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT))
5443 {
5444 TCU_THROW(NotSupportedError, "Format feature blit destination not supported");
5445 }
5446
5447 if (m_params.filter == VK_FILTER_LINEAR && !(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
5448 TCU_THROW(NotSupportedError, "Source format feature sampled image filter linear not supported");
5449
5450 if (m_params.filter == VK_FILTER_CUBIC_EXT)
5451 {
5452 context.requireDeviceFunctionality("VK_EXT_filter_cubic");
5453
5454 if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT))
5455 {
5456 TCU_THROW(NotSupportedError, "Source format feature sampled image filter cubic not supported");
5457 }
5458 }
5459 }
5460
5461 private:
5462 TestParams m_params;
5463 };
5464
5465 // Resolve image to image.
5466
5467 enum ResolveImageToImageOptions{NO_OPTIONAL_OPERATION = 0,
5468 COPY_MS_IMAGE_TO_MS_IMAGE,
5469 COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE,
5470 COPY_MS_IMAGE_LAYER_TO_MS_IMAGE,
5471 COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION,
5472 COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB,
5473 COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE,
5474 COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER};
5475
removeExtensions(const std::vector<std::string> & a,const std::vector<const char * > & b)5476 std::vector<std::string> removeExtensions (const std::vector<std::string>& a, const std::vector<const char*>& b)
5477 {
5478 std::vector<std::string> res;
5479 std::set<std::string> removeExts (b.begin(), b.end());
5480
5481 for (const auto & aIter : a)
5482 {
5483 if (!de::contains(removeExts, aIter))
5484 res.push_back(aIter);
5485 }
5486
5487 return res;
5488 }
5489
5490
5491 // 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)5492 Move<VkDevice> createCustomDevice (Context& context,
5493 const ResolveImageToImageOptions imageCreateOptions,
5494 #ifdef CTS_USES_VULKANSC
5495 const CustomInstance& customInstance,
5496 #endif // CTS_USES_VULKANSC
5497 uint32_t& queueFamilyIndex)
5498 {
5499 #ifdef CTS_USES_VULKANSC
5500 const InstanceInterface& instanceDriver = customInstance.getDriver();
5501 const VkPhysicalDevice physicalDevice = chooseDevice(instanceDriver, customInstance, context.getTestContext().getCommandLine());
5502 #else
5503 const InstanceInterface& instanceDriver = context.getInstanceInterface();
5504 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
5505 #endif // CTS_USES_VULKANSC
5506
5507 // This function can only be used to create a device with compute only or transfer only queue.
5508 DE_ASSERT(imageCreateOptions == COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE || imageCreateOptions == COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER);
5509
5510 // When testing with compute or transfer queue, find a queue family that supports compute or transfer queue, but does NOT support graphics queue.
5511 const std::vector<VkQueueFamilyProperties> queueFamilies = getPhysicalDeviceQueueFamilyProperties(context.getInstanceInterface(), context.getPhysicalDevice());
5512
5513 queueFamilyIndex = 0;
5514 for (const auto &queueFamily: queueFamilies)
5515 {
5516 if (imageCreateOptions == COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE)
5517 {
5518 if (queueFamily.queueFlags & VK_QUEUE_COMPUTE_BIT && !(queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT))
5519 break;
5520 else
5521 queueFamilyIndex++;
5522 }
5523 else if (imageCreateOptions == COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER)
5524 {
5525 if (queueFamily.queueFlags & VK_QUEUE_TRANSFER_BIT && !(queueFamily.queueFlags & VK_QUEUE_COMPUTE_BIT) && !(queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT))
5526 break;
5527 else
5528 queueFamilyIndex++;
5529 }
5530 }
5531
5532 // One should be found, because this is checked in "checkSupport" function.
5533 DE_ASSERT(queueFamilyIndex < queueFamilies.size());
5534
5535 const float queuePriority = 1.0f;
5536 const VkDeviceQueueCreateInfo deviceQueueCreateInfos[] = {
5537 {
5538 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // VkStructureType sType;
5539 DE_NULL, // const void* pNext;
5540 (VkDeviceQueueCreateFlags)0u, // VkDeviceQueueCreateFlags flags;
5541 context.getUniversalQueueFamilyIndex(), // uint32_t queueFamilyIndex;
5542 1u, // uint32_t queueCount;
5543 &queuePriority, // const float* pQueuePriorities;
5544 },
5545 {
5546 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // VkStructureType sType;
5547 DE_NULL, // const void* pNext;
5548 (VkDeviceQueueCreateFlags)0u, // VkDeviceQueueCreateFlags flags;
5549 queueFamilyIndex, // uint32_t queueFamilyIndex;
5550 1u, // uint32_t queueCount;
5551 &queuePriority, // const float* pQueuePriorities;
5552 }
5553 };
5554
5555 // context.getDeviceExtensions() returns supported device extension including extensions that have been promoted to
5556 // Vulkan core. The core extensions must be removed from the list.
5557 std::vector<const char*> coreExtensions;
5558 getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
5559 std::vector<std::string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));
5560
5561 std::vector<const char*> extensionNames;
5562 extensionNames.reserve(nonCoreExtensions.size());
5563 for (const std::string& extension : nonCoreExtensions)
5564 extensionNames.push_back(extension.c_str());
5565
5566 const auto& deviceFeatures2 = context.getDeviceFeatures2();
5567
5568 const void *pNext = &deviceFeatures2;
5569 #ifdef CTS_USES_VULKANSC
5570 VkDeviceObjectReservationCreateInfo memReservationInfo = context.getTestContext().getCommandLine().isSubProcess() ? context.getResourceInterface()->getStatMax() : resetDeviceObjectReservationCreateInfo();
5571 memReservationInfo.pNext = pNext;
5572 pNext = &memReservationInfo;
5573
5574 VkPipelineCacheCreateInfo pcCI;
5575 std::vector<VkPipelinePoolSize> poolSizes;
5576 if (context.getTestContext().getCommandLine().isSubProcess())
5577 {
5578 if (context.getResourceInterface()->getCacheDataSize() > 0)
5579 {
5580 pcCI =
5581 {
5582 VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, // VkStructureType sType;
5583 DE_NULL, // const void* pNext;
5584 VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT |
5585 VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT, // VkPipelineCacheCreateFlags flags;
5586 context.getResourceInterface()->getCacheDataSize(), // deUintptr initialDataSize;
5587 context.getResourceInterface()->getCacheData() // const void* pInitialData;
5588 };
5589 memReservationInfo.pipelineCacheCreateInfoCount = 1;
5590 memReservationInfo.pPipelineCacheCreateInfos = &pcCI;
5591 }
5592 poolSizes = context.getResourceInterface()->getPipelinePoolSizes();
5593 if (!poolSizes.empty())
5594 {
5595 memReservationInfo.pipelinePoolSizeCount = deUint32(poolSizes.size());
5596 memReservationInfo.pPipelinePoolSizes = poolSizes.data();
5597 }
5598 }
5599 #endif // CTS_USES_VULKANSC
5600
5601 const VkDeviceCreateInfo deviceCreateInfo =
5602 {
5603 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // VkStructureType sType;
5604 pNext, // const void* pNext;
5605 (VkDeviceCreateFlags)0u, // VkDeviceCreateFlags flags;
5606 DE_LENGTH_OF_ARRAY(deviceQueueCreateInfos), // uint32_t queueCreateInfoCount;
5607 deviceQueueCreateInfos, // const VkDeviceQueueCreateInfo* pQueueCreateInfos;
5608 0u, // uint32_t enabledLayerCount;
5609 DE_NULL, // const char* const* ppEnabledLayerNames;
5610 static_cast<uint32_t>(extensionNames.size()), // uint32_t enabledExtensionCount;
5611 extensionNames.data(), // const char* const* ppEnabledExtensionNames;
5612 DE_NULL, // const VkPhysicalDeviceFeatures* pEnabledFeatures;
5613 };
5614
5615 #ifndef CTS_USES_VULKANSC
5616 return vkt::createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), context.getPlatformInterface(), context.getInstance(), instanceDriver, physicalDevice, &deviceCreateInfo);
5617 #else
5618 return vkt::createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), context.getPlatformInterface(), customInstance, instanceDriver, physicalDevice, &deviceCreateInfo);
5619 #endif // CTS_USES_VULKANSC
5620 }
5621
5622 class ResolveImageToImage : public CopiesAndBlittingTestInstance
5623 {
5624 public:
5625 ResolveImageToImage (Context& context,
5626 TestParams params,
5627 ResolveImageToImageOptions options);
5628 virtual tcu::TestStatus iterate (void);
shouldVerifyIntermediateResults(ResolveImageToImageOptions option)5629 static inline bool shouldVerifyIntermediateResults (ResolveImageToImageOptions option)
5630 {
5631 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;
5632 }
~ResolveImageToImage()5633 ~ResolveImageToImage()
5634 {
5635 // Destroy the command pool (and free the related command buffer).
5636 // This must be done before the m_customDevice is destroyed.
5637 m_cmdBuffer = Move<VkCommandBuffer>();
5638 m_cmdPool = Move<VkCommandPool>();
5639 }
5640 protected:
5641 virtual tcu::TestStatus checkTestResult (tcu::ConstPixelBufferAccess result);
5642 void copyMSImageToMSImage (deUint32 copyArraySize);
5643 tcu::TestStatus checkIntermediateCopy (void);
5644 private:
5645 const CustomInstance m_customInstance;
5646 Move<VkDevice> m_customDevice;
5647
5648 #ifndef CTS_USES_VULKANSC
5649 de::MovePtr<vk::DeviceDriver> m_deviceDriver;
5650 #else
5651 de::MovePtr<DeviceDriverSC, DeinitDeviceDeleter> m_deviceDriver;
5652 #endif // CTS_USES_VULKANSC
5653
5654 Move<VkCommandPool> m_alternativeCmdPool;
5655 Move<VkCommandBuffer> m_alternativeCmdBuffer;
5656 VkQueue m_alternativeQueue;
5657 uint32_t m_alternativeQueueFamilyIndex;
5658 de::MovePtr<vk::Allocator> m_alternativeAllocator;
5659 Move<VkImage> m_multisampledImage;
5660 de::MovePtr<Allocation> m_multisampledImageAlloc;
5661
5662 Move<VkImage> m_destination;
5663 de::MovePtr<Allocation> m_destinationImageAlloc;
5664
5665 Move<VkImage> m_multisampledCopyImage;
5666 de::MovePtr<Allocation> m_multisampledCopyImageAlloc;
5667 Move<VkImage> m_multisampledCopyNoCabImage;
5668 de::MovePtr<Allocation> m_multisampledCopyImageNoCabAlloc;
5669
5670 const ResolveImageToImageOptions m_options;
5671
5672 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src,
5673 tcu::PixelBufferAccess dst,
5674 CopyRegion region,
5675 deUint32 mipLevel = 0u);
5676 };
5677
ResolveImageToImage(Context & context,TestParams params,const ResolveImageToImageOptions options)5678 ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, const ResolveImageToImageOptions options)
5679 : CopiesAndBlittingTestInstance (context, params)
5680 , m_customInstance (createCustomInstanceFromContext(context))
5681 , m_options (options)
5682 {
5683
5684
5685 #ifdef CTS_USES_VULKANSC
5686 const InstanceInterface& vki = m_customInstance.getDriver();
5687 #else
5688 const InstanceInterface& vki = m_context.getInstanceInterface();
5689 #endif // CTS_USES_VULKANSC
5690
5691 uint32_t queueFamilyIndex = 0;
5692 // Create custom device for compute and transfer only queue tests.
5693 if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER)
5694 {
5695 // 'queueFamilyIndex' will be updated in 'createCustomDevice()' to match the requested queue type.
5696 #ifdef CTS_USES_VULKANSC
5697 m_customDevice = createCustomDevice(context, m_options, m_customInstance, queueFamilyIndex);
5698 #else
5699 m_customDevice = createCustomDevice(context, m_options, queueFamilyIndex);
5700 #endif // CTS_USES_VULKANSC
5701 m_device = m_customDevice.get();
5702
5703 #ifndef CTS_USES_VULKANSC
5704 m_deviceDriver = de::MovePtr<DeviceDriver>(new DeviceDriver(context.getPlatformInterface(), m_customInstance, m_device));
5705 #else
5706 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));
5707 #endif // CTS_USES_VULKANSC
5708
5709 m_queue = getDeviceQueue(m_context.getDeviceInterface(), m_device, context.getUniversalQueueFamilyIndex(), 0u);
5710 m_alternativeQueue = getDeviceQueue(m_context.getDeviceInterface(), m_device, queueFamilyIndex, 0u);
5711 }
5712
5713 m_alternativeQueueFamilyIndex = queueFamilyIndex;
5714
5715 #ifndef CTS_USES_VULKANSC
5716 const DeviceInterface& vk = m_context.getDeviceInterface();
5717 #else
5718 const DeviceInterface& vk = (DE_NULL != m_deviceDriver) ? *m_deviceDriver : m_context.getDeviceInterface();
5719 #endif // CTS_USES_VULKANSC
5720
5721 m_alternativeAllocator = de::MovePtr<Allocator>(new SimpleAllocator(vk, m_device, getPhysicalDeviceMemoryProperties(vki, context.getPhysicalDevice())));
5722 m_allocator = m_alternativeAllocator.get();
5723
5724 // Release the command buffer.
5725 m_cmdBuffer = Move<VkCommandBuffer>();
5726
5727 // Create a new command pool and allocate a command buffer with universal queue family index and destroy the old one.
5728 m_cmdPool = createCommandPool(vk, m_device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, context.getUniversalQueueFamilyIndex());
5729 m_cmdBuffer = allocateCommandBuffer(vk, m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
5730
5731 // Create a command pool and allocate a command buffer from the queue family supporting compute / transfer capabilities.
5732 m_alternativeCmdPool = createCommandPool(vk, m_device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
5733 m_alternativeCmdBuffer = allocateCommandBuffer(vk, m_device, *m_alternativeCmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
5734
5735 Allocator& memAlloc = *m_allocator;
5736 const VkPhysicalDevice vkPhysDevice = m_context.getPhysicalDevice();
5737 const VkDevice vkDevice = m_device;
5738 const VkComponentMapping componentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
5739 Move<VkRenderPass> renderPass;
5740
5741 Move<VkShaderModule> vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
5742 Move<VkShaderModule> fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
5743 std::vector<tcu::Vec4> vertices;
5744
5745 Move<VkBuffer> vertexBuffer;
5746 de::MovePtr<Allocation> vertexBufferAlloc;
5747
5748 Move<VkPipelineLayout> pipelineLayout;
5749 Move<VkPipeline> graphicsPipeline;
5750
5751 const VkSampleCountFlagBits rasterizationSamples = m_params.samples;
5752
5753 // Create color image.
5754 {
5755 VkImageCreateInfo colorImageParams =
5756 {
5757 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
5758 DE_NULL, // const void* pNext;
5759 getCreateFlags(m_params.src.image), // VkImageCreateFlags flags;
5760 m_params.src.image.imageType, // VkImageType imageType;
5761 m_params.src.image.format, // VkFormat format;
5762 getExtent3D(m_params.src.image), // VkExtent3D extent;
5763 1u, // deUint32 mipLevels;
5764 getArraySize(m_params.src.image), // deUint32 arrayLayers;
5765 rasterizationSamples, // VkSampleCountFlagBits samples;
5766 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
5767 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT // VkImageUsageFlags usage;
5768 | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
5769 | VK_IMAGE_USAGE_TRANSFER_DST_BIT
5770 | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
5771 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
5772 0u, // deUint32 queueFamilyIndexCount;
5773 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
5774 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
5775 };
5776
5777 m_multisampledImage = createImage(vk, vkDevice, &colorImageParams);
5778 VkMemoryRequirements req = getImageMemoryRequirements(vk, vkDevice, *m_multisampledImage);
5779
5780 // Allocate and bind color image memory.
5781 deUint32 offset = m_params.imageOffset ? static_cast<deUint32>(req.alignment) : 0u;
5782 m_multisampledImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledImage, MemoryRequirement::Any,
5783 memAlloc, m_params.allocationKind, offset);
5784
5785 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledImage, m_multisampledImageAlloc->getMemory(), offset));
5786
5787 switch (m_options)
5788 {
5789 case COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION:
5790 case COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE:
5791 case COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER:
5792 case COPY_MS_IMAGE_TO_MS_IMAGE:
5793 {
5794 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;
5795 m_multisampledCopyImage = createImage(vk, vkDevice, &colorImageParams);
5796 // Allocate and bind color image memory.
5797 m_multisampledCopyImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
5798 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
5799 break;
5800 }
5801 case COPY_MS_IMAGE_LAYER_TO_MS_IMAGE:
5802 case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
5803 {
5804 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;
5805 colorImageParams.arrayLayers = getArraySize(m_params.dst.image);
5806 m_multisampledCopyImage = createImage(vk, vkDevice, &colorImageParams);
5807 // Allocate and bind color image memory.
5808 m_multisampledCopyImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
5809 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
5810 break;
5811 }
5812 case COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB:
5813 {
5814 colorImageParams.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
5815 colorImageParams.arrayLayers = getArraySize(m_params.dst.image);
5816 m_multisampledCopyImage = createImage(vk, vkDevice, &colorImageParams);
5817 m_multisampledCopyNoCabImage = createImage(vk, vkDevice, &colorImageParams);
5818 // Allocate and bind color image memory.
5819 m_multisampledCopyImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
5820 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
5821 m_multisampledCopyImageNoCabAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyNoCabImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
5822 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyNoCabImage, m_multisampledCopyImageNoCabAlloc->getMemory(), m_multisampledCopyImageNoCabAlloc->getOffset()));
5823 break;
5824 }
5825
5826 default :
5827 break;
5828 }
5829 }
5830
5831 // Create destination image.
5832 {
5833 const VkImageCreateInfo destinationImageParams =
5834 {
5835 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
5836 DE_NULL, // const void* pNext;
5837 getCreateFlags(m_params.dst.image), // VkImageCreateFlags flags;
5838 m_params.dst.image.imageType, // VkImageType imageType;
5839 m_params.dst.image.format, // VkFormat format;
5840 getExtent3D(m_params.dst.image), // VkExtent3D extent;
5841 1u, // deUint32 mipLevels;
5842 getArraySize(m_params.dst.image), // deUint32 arraySize;
5843 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
5844 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
5845 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
5846 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
5847 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
5848 0u, // deUint32 queueFamilyIndexCount;
5849 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
5850 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
5851 };
5852
5853 m_destination = createImage(vk, vkDevice, &destinationImageParams);
5854 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
5855 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
5856 }
5857
5858 // Barriers for image clearing.
5859 std::vector<VkImageMemoryBarrier> srcImageBarriers;
5860
5861 const VkImageMemoryBarrier m_multisampledImageBarrier =
5862 {
5863 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
5864 DE_NULL, // const void* pNext;
5865 0u, // VkAccessFlags srcAccessMask;
5866 VK_ACCESS_MEMORY_WRITE_BIT, // VkAccessFlags dstAccessMask;
5867 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
5868 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
5869 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
5870 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
5871 m_multisampledImage.get(), // VkImage image;
5872 { // VkImageSubresourceRange subresourceRange;
5873 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
5874 0u, // deUint32 baseMipLevel;
5875 1u, // deUint32 mipLevels;
5876 0u, // deUint32 baseArraySlice;
5877 getArraySize(m_params.src.image) // deUint32 arraySize;
5878 }
5879 };
5880 const VkImageMemoryBarrier m_multisampledCopyImageBarrier =
5881 {
5882 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
5883 DE_NULL, // const void* pNext;
5884 0u, // VkAccessFlags srcAccessMask;
5885 VK_ACCESS_MEMORY_WRITE_BIT, // VkAccessFlags dstAccessMask;
5886 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
5887 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
5888 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
5889 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
5890 m_multisampledCopyImage.get(), // VkImage image;
5891 { // VkImageSubresourceRange subresourceRange;
5892 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
5893 0u, // deUint32 baseMipLevel;
5894 1u, // deUint32 mipLevels;
5895 0u, // deUint32 baseArraySlice;
5896 getArraySize(m_params.dst.image) // deUint32 arraySize;
5897 }
5898 };
5899 const VkImageMemoryBarrier m_multisampledCopyImageNoCabBarrier =
5900 {
5901 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
5902 DE_NULL, // const void* pNext;
5903 0u, // VkAccessFlags srcAccessMask;
5904 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
5905 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
5906 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
5907 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
5908 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
5909 m_multisampledCopyNoCabImage.get(), // VkImage image;
5910 { // VkImageSubresourceRange subresourceRange;
5911 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
5912 0u, // deUint32 baseMipLevel;
5913 1u, // deUint32 mipLevels;
5914 0u, // deUint32 baseArraySlice;
5915 getArraySize(m_params.dst.image) // deUint32 arraySize;
5916 }
5917 };
5918
5919 // Only use one barrier if no options have been given.
5920 if (m_options != DE_NULL)
5921 {
5922 srcImageBarriers.push_back(m_multisampledImageBarrier);
5923 srcImageBarriers.push_back(m_multisampledCopyImageBarrier);
5924 // Add the third barrier if option is as below.
5925 if(m_options == COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB)
5926 srcImageBarriers.push_back(m_multisampledCopyImageNoCabBarrier);
5927 }
5928 else
5929 {
5930 srcImageBarriers.push_back(m_multisampledImageBarrier);
5931 }
5932
5933 // Create render pass.
5934 {
5935 const VkAttachmentDescription attachmentDescription =
5936 {
5937 0u, // VkAttachmentDescriptionFlags flags;
5938 m_params.src.image.format, // VkFormat format;
5939 rasterizationSamples, // VkSampleCountFlagBits samples;
5940 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
5941 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
5942 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
5943 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
5944 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout initialLayout;
5945 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL // VkImageLayout finalLayout;
5946 };
5947
5948 const VkAttachmentReference colorAttachmentReference =
5949 {
5950 0u, // deUint32 attachment;
5951 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
5952 };
5953
5954 const VkSubpassDescription subpassDescription =
5955 {
5956 0u, // VkSubpassDescriptionFlags flags;
5957 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
5958 0u, // deUint32 inputAttachmentCount;
5959 DE_NULL, // const VkAttachmentReference* pInputAttachments;
5960 1u, // deUint32 colorAttachmentCount;
5961 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments;
5962 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
5963 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
5964 0u, // deUint32 preserveAttachmentCount;
5965 DE_NULL // const VkAttachmentReference* pPreserveAttachments;
5966 };
5967
5968 // Subpass dependency is used to synchronize the memory access of the image clear and color attachment write in some test cases.
5969 const VkSubpassDependency subpassDependency =
5970 {
5971 VK_SUBPASS_EXTERNAL, //uint32_t srcSubpass;
5972 0u, //uint32_t dstSubpass;
5973 VK_PIPELINE_STAGE_TRANSFER_BIT, //VkPipelineStageFlags srcStageMask;
5974 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, //VkPipelineStageFlags dstStageMask;
5975 VK_ACCESS_TRANSFER_WRITE_BIT, //VkAccessFlags srcAccessMask;
5976 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, //VkAccessFlags dstAccessMask;
5977 0u //VkDependencyFlags dependencyFlags;
5978 };
5979
5980 const deBool useSubpassDependency = m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION;
5981 const VkRenderPassCreateInfo renderPassParams =
5982 {
5983 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
5984 DE_NULL, // const void* pNext;
5985 0u, // VkRenderPassCreateFlags flags;
5986 1u, // deUint32 attachmentCount;
5987 &attachmentDescription, // const VkAttachmentDescription* pAttachments;
5988 1u, // deUint32 subpassCount;
5989 &subpassDescription, // const VkSubpassDescription* pSubpasses;
5990 useSubpassDependency ? 1u : 0u, // deUint32 dependencyCount;
5991 &subpassDependency // const VkSubpassDependency* pDependencies;
5992 };
5993
5994 renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
5995 }
5996
5997 // Create pipeline layout
5998 {
5999 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
6000 {
6001 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
6002 DE_NULL, // const void* pNext;
6003 0u, // VkPipelineLayoutCreateFlags flags;
6004 0u, // deUint32 setLayoutCount;
6005 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
6006 0u, // deUint32 pushConstantRangeCount;
6007 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
6008 };
6009
6010 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
6011 }
6012
6013 // Create upper half triangle.
6014 {
6015 const tcu::Vec4 a (-1.0, -1.0, 0.0, 1.0);
6016 const tcu::Vec4 b (1.0, -1.0, 0.0, 1.0);
6017 const tcu::Vec4 c (1.0, 1.0, 0.0, 1.0);
6018 // Add triangle.
6019 vertices.push_back(a);
6020 vertices.push_back(c);
6021 vertices.push_back(b);
6022 }
6023
6024 // Create vertex buffer.
6025 {
6026 const VkDeviceSize vertexDataSize = vertices.size() * sizeof(tcu::Vec4);
6027 const VkBufferCreateInfo vertexBufferParams =
6028 {
6029 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
6030 DE_NULL, // const void* pNext;
6031 0u, // VkBufferCreateFlags flags;
6032 vertexDataSize, // VkDeviceSize size;
6033 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
6034 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
6035 0u, // deUint32 queueFamilyIndexCount;
6036 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
6037 };
6038
6039 vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
6040 vertexBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *vertexBuffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
6041 VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset()));
6042
6043 // Load vertices into vertex buffer.
6044 deMemcpy(vertexBufferAlloc->getHostPtr(), vertices.data(), (size_t)vertexDataSize);
6045 flushAlloc(vk, vkDevice, *vertexBufferAlloc);
6046 }
6047
6048 {
6049 Move<VkFramebuffer> framebuffer;
6050 Move<VkImageView> sourceAttachmentView;
6051
6052 uint32_t baseArrayLayer = m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE ? 2u : 0u;
6053
6054 // Create color attachment view.
6055 {
6056 const VkImageViewCreateInfo colorAttachmentViewParams =
6057 {
6058 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
6059 DE_NULL, // const void* pNext;
6060 0u, // VkImageViewCreateFlags flags;
6061 *m_multisampledImage, // VkImage image;
6062 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
6063 m_params.src.image.format, // VkFormat format;
6064 componentMappingRGBA, // VkComponentMapping components;
6065 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, baseArrayLayer, 1u } // VkImageSubresourceRange subresourceRange;
6066 };
6067 sourceAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
6068 }
6069
6070 // Create framebuffer
6071 {
6072 const VkFramebufferCreateInfo framebufferParams =
6073 {
6074 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
6075 DE_NULL, // const void* pNext;
6076 0u, // VkFramebufferCreateFlags flags;
6077 *renderPass, // VkRenderPass renderPass;
6078 1u, // deUint32 attachmentCount;
6079 &sourceAttachmentView.get(), // const VkImageView* pAttachments;
6080 m_params.src.image.extent.width, // deUint32 width;
6081 m_params.src.image.extent.height, // deUint32 height;
6082 1u // deUint32 layers;
6083 };
6084
6085 framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
6086 }
6087
6088 // Create pipeline
6089 {
6090 const std::vector<VkViewport> viewports (1, makeViewport(m_params.src.image.extent));
6091 const std::vector<VkRect2D> scissors (1, makeRect2D(m_params.src.image.extent));
6092
6093 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
6094 {
6095 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
6096 DE_NULL, // const void* pNext;
6097 0u, // VkPipelineMultisampleStateCreateFlags flags;
6098 rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples;
6099 VK_FALSE, // VkBool32 sampleShadingEnable;
6100 0.0f, // float minSampleShading;
6101 DE_NULL, // const VkSampleMask* pSampleMask;
6102 VK_FALSE, // VkBool32 alphaToCoverageEnable;
6103 VK_FALSE // VkBool32 alphaToOneEnable;
6104 };
6105
6106 graphicsPipeline = makeGraphicsPipeline(vk, // const DeviceInterface& vk
6107 vkDevice, // const VkDevice device
6108 *pipelineLayout, // const VkPipelineLayout pipelineLayout
6109 *vertexShaderModule, // const VkShaderModule vertexShaderModule
6110 DE_NULL, // const VkShaderModule tessellationControlModule
6111 DE_NULL, // const VkShaderModule tessellationEvalModule
6112 DE_NULL, // const VkShaderModule geometryShaderModule
6113 *fragmentShaderModule, // const VkShaderModule fragmentShaderModule
6114 *renderPass, // const VkRenderPass renderPass
6115 viewports, // const std::vector<VkViewport>& viewports
6116 scissors, // const std::vector<VkRect2D>& scissors
6117 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
6118 0u, // const deUint32 subpass
6119 0u, // const deUint32 patchControlPoints
6120 DE_NULL, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
6121 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
6122 &multisampleStateParams); // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
6123 }
6124
6125 // Create command buffer
6126 {
6127 beginCommandBuffer(vk, *m_cmdBuffer, 0u);
6128
6129 if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION)
6130 {
6131 // Change the image layouts.
6132 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());
6133
6134 // Clear the 'm_multisampledImage'.
6135 {
6136 const VkClearColorValue clearValue = {{0.0f, 0.0f, 0.0f, 1.0f}};
6137 const auto clearRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, m_params.src.image.extent.depth);
6138 vk.cmdClearColorImage(*m_cmdBuffer, m_multisampledImage.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue, 1u, &clearRange);
6139 }
6140
6141 // Clear the 'm_multisampledCopyImage' with different color.
6142 {
6143 const VkClearColorValue clearValue = {{1.0f, 1.0f, 1.0f, 1.0f}};
6144 const auto clearRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, m_params.src.image.extent.depth);
6145 vk.cmdClearColorImage(*m_cmdBuffer, m_multisampledCopyImage.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue, 1u, &clearRange);
6146 }
6147 }
6148 else
6149 {
6150 // Change the image layouts.
6151 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());
6152 }
6153
6154 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));
6155
6156 const VkDeviceSize vertexBufferOffset = 0u;
6157
6158 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
6159 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
6160 vk.cmdDraw(*m_cmdBuffer, (deUint32)vertices.size(), 1, 0, 0);
6161
6162 endRenderPass(vk, *m_cmdBuffer);
6163 endCommandBuffer(vk, *m_cmdBuffer);
6164 }
6165
6166 // Queue submit.
6167 {
6168 submitCommandsAndWait (vk, vkDevice, m_queue, *m_cmdBuffer);
6169 m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
6170 }
6171 }
6172 }
6173
iterate(void)6174 tcu::TestStatus ResolveImageToImage::iterate (void)
6175 {
6176 const tcu::TextureFormat srcTcuFormat = mapVkFormat(m_params.src.image.format);
6177 const tcu::TextureFormat dstTcuFormat = mapVkFormat(m_params.dst.image.format);
6178
6179 // upload the destination image
6180 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
6181 (int)m_params.dst.image.extent.width,
6182 (int)m_params.dst.image.extent.height,
6183 (int)m_params.dst.image.extent.depth));
6184 generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
6185 uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
6186
6187 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
6188 (int)m_params.src.image.extent.width,
6189 (int)m_params.src.image.extent.height,
6190 (int)m_params.dst.image.extent.depth));
6191
6192 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);
6193 generateExpectedResult();
6194
6195 VkImage sourceImage = m_multisampledImage.get();
6196 deUint32 sourceArraySize = getArraySize(m_params.src.image);
6197
6198 switch (m_options)
6199 {
6200 case COPY_MS_IMAGE_LAYER_TO_MS_IMAGE:
6201 case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
6202 // Duplicate the multisampled image to a multisampled image array
6203 sourceArraySize = getArraySize(m_params.dst.image); // fall through
6204 case COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION:
6205 case COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB:
6206 case COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE:
6207 case COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER:
6208 case COPY_MS_IMAGE_TO_MS_IMAGE:
6209 copyMSImageToMSImage(sourceArraySize);
6210 sourceImage = m_multisampledCopyImage.get();
6211 break;
6212 default:
6213 break;
6214 }
6215
6216 const DeviceInterface& vk = m_context.getDeviceInterface();
6217 const VkDevice vkDevice = m_device;
6218 const VkQueue queue = m_queue;
6219
6220 std::vector<VkImageResolve> imageResolves;
6221 std::vector<VkImageResolve2KHR> imageResolves2KHR;
6222 for (CopyRegion region : m_params.regions)
6223 {
6224 // If copying multiple regions, make sure that the same regions are
6225 // used for resolving as the ones used for copying.
6226 if(m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION)
6227 {
6228 VkExtent3D partialExtent = {getExtent3D(m_params.src.image).width / 2,
6229 getExtent3D(m_params.src.image).height / 2,
6230 getExtent3D(m_params.src.image).depth};
6231
6232 const VkImageResolve imageResolve =
6233 {
6234 region.imageResolve.srcSubresource, // VkImageSubresourceLayers srcSubresource;
6235 region.imageResolve.dstOffset, // VkOffset3D srcOffset;
6236 region.imageResolve.dstSubresource, // VkImageSubresourceLayers dstSubresource;
6237 region.imageResolve.dstOffset, // VkOffset3D dstOffset;
6238 partialExtent, // VkExtent3D extent;
6239 };
6240
6241 if (m_params.extensionUse == EXTENSION_USE_NONE)
6242 {
6243 imageResolves.push_back(imageResolve);
6244 }
6245 else
6246 {
6247 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6248 imageResolves2KHR.push_back(convertvkImageResolveTovkImageResolve2KHR(imageResolve));
6249 }
6250 }
6251 else
6252 {
6253 if (m_params.extensionUse == EXTENSION_USE_NONE)
6254 {
6255 imageResolves.push_back(region.imageResolve);
6256 }
6257 else
6258 {
6259 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6260 imageResolves2KHR.push_back(convertvkImageResolveTovkImageResolve2KHR(region.imageResolve));
6261 }
6262 }
6263 }
6264
6265 const VkImageMemoryBarrier imageBarriers[] =
6266 {
6267 // source image
6268 {
6269 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
6270 DE_NULL, // const void* pNext;
6271 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask;
6272 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
6273 m_options == NO_OPTIONAL_OPERATION ?
6274 m_params.dst.image.operationLayout :
6275 m_params.src.image.operationLayout, // VkImageLayout oldLayout;
6276 m_params.src.image.operationLayout, // VkImageLayout newLayout;
6277 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
6278 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
6279 sourceImage, // VkImage image;
6280 { // VkImageSubresourceRange subresourceRange;
6281 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
6282 0u, // deUint32 baseMipLevel;
6283 1u, // deUint32 mipLevels;
6284 0u, // deUint32 baseArraySlice;
6285 sourceArraySize // deUint32 arraySize;
6286 }
6287 },
6288 // destination image
6289 {
6290 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
6291 DE_NULL, // const void* pNext;
6292 0u, // VkAccessFlags srcAccessMask;
6293 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
6294 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
6295 m_params.dst.image.operationLayout, // VkImageLayout newLayout;
6296 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
6297 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
6298 m_destination.get(), // VkImage image;
6299 { // VkImageSubresourceRange subresourceRange;
6300 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
6301 0u, // deUint32 baseMipLevel;
6302 1u, // deUint32 mipLevels;
6303 0u, // deUint32 baseArraySlice;
6304 getArraySize(m_params.dst.image) // deUint32 arraySize;
6305 }
6306 },
6307 };
6308
6309 const VkImageMemoryBarrier postImageBarrier =
6310 {
6311 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
6312 DE_NULL, // const void* pNext;
6313 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
6314 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
6315 m_params.dst.image.operationLayout, // VkImageLayout oldLayout;
6316 m_params.dst.image.operationLayout, // VkImageLayout newLayout;
6317 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
6318 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
6319 m_destination.get(), // VkImage image;
6320 { // VkImageSubresourceRange subresourceRange;
6321 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
6322 0u, // deUint32 baseMipLevel;
6323 1u, // deUint32 mipLevels;
6324 0u, // deUint32 baseArraySlice;
6325 getArraySize(m_params.dst.image) // deUint32 arraySize;
6326 }
6327 };
6328
6329 beginCommandBuffer(vk, *m_cmdBuffer);
6330 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);
6331
6332 if (m_params.extensionUse == EXTENSION_USE_NONE)
6333 {
6334 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());
6335 }
6336 #ifndef CTS_USES_VULKANSC
6337 else
6338 {
6339 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6340 const VkResolveImageInfo2KHR ResolveImageInfo2KHR =
6341 {
6342 VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2_KHR, // VkStructureType sType;
6343 DE_NULL, // const void* pNext;
6344 sourceImage, // VkImage srcImage;
6345 m_params.src.image.operationLayout, // VkImageLayout srcImageLayout;
6346 m_destination.get(), // VkImage dstImage;
6347 m_params.dst.image.operationLayout, // VkImageLayout dstImageLayout;
6348 (deUint32)m_params.regions.size(), // uint32_t regionCount;
6349 imageResolves2KHR.data() // const VkImageResolve2KHR* pRegions;
6350 };
6351 vk.cmdResolveImage2(*m_cmdBuffer, &ResolveImageInfo2KHR);
6352 }
6353 #endif // CTS_USES_VULKANSC
6354
6355 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);
6356 endCommandBuffer(vk, *m_cmdBuffer);
6357 submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
6358 m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
6359
6360 de::MovePtr<tcu::TextureLevel> resultTextureLevel = readImage(*m_destination, m_params.dst.image);
6361
6362 if (shouldVerifyIntermediateResults(m_options))
6363 {
6364 // Verify the intermediate multisample copy operation happens properly instead of, for example, shuffling samples around or
6365 // resolving the image and giving every sample the same value.
6366 const auto intermediateResult = checkIntermediateCopy();
6367 if (intermediateResult.getCode() != QP_TEST_RESULT_PASS)
6368 return intermediateResult;
6369 }
6370
6371 return checkTestResult(resultTextureLevel->getAccess());
6372 }
6373
checkTestResult(tcu::ConstPixelBufferAccess result)6374 tcu::TestStatus ResolveImageToImage::checkTestResult (tcu::ConstPixelBufferAccess result)
6375 {
6376 const tcu::ConstPixelBufferAccess expected = m_expectedTextureLevel[0]->getAccess();
6377 const float fuzzyThreshold = 0.01f;
6378
6379 if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
6380 {
6381 // Check that all the layers that have not been written to are solid white.
6382 tcu::Vec4 expectedColor (1.0f, 1.0f, 1.0f, 1.0f);
6383 for (int arrayLayerNdx = 0; arrayLayerNdx < (int)getArraySize(m_params.dst.image) - 1; ++arrayLayerNdx)
6384 {
6385 const tcu::ConstPixelBufferAccess resultSub = getSubregion (result, 0u, 0u, arrayLayerNdx, result.getWidth(), result.getHeight(), 1u);
6386 if(resultSub.getPixel(0, 0) != expectedColor)
6387 return tcu::TestStatus::fail("CopiesAndBlitting test. Layers image differs from initialized value.");
6388 }
6389
6390 // Check that the layer that has been copied to is the same as the layer that has been copied from.
6391 const tcu::ConstPixelBufferAccess expectedSub = getSubregion (expected, 0u, 0u, 2u, expected.getWidth(), expected.getHeight(), 1u);
6392 const tcu::ConstPixelBufferAccess resultSub = getSubregion (result, 0u, 0u, 4u, result.getWidth(), result.getHeight(), 1u);
6393 if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedSub, resultSub, fuzzyThreshold, tcu::COMPARE_LOG_RESULT))
6394 return tcu::TestStatus::fail("CopiesAndBlitting test");
6395 }
6396 else
6397 {
6398 for (int arrayLayerNdx = 0; arrayLayerNdx < (int)getArraySize(m_params.dst.image); ++arrayLayerNdx)
6399 {
6400 const tcu::ConstPixelBufferAccess expectedSub = getSubregion (expected, 0u, 0u, arrayLayerNdx, expected.getWidth(), expected.getHeight(), 1u);
6401 const tcu::ConstPixelBufferAccess resultSub = getSubregion (result, 0u, 0u, arrayLayerNdx, result.getWidth(), result.getHeight(), 1u);
6402 if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedSub, resultSub, fuzzyThreshold, tcu::COMPARE_LOG_RESULT))
6403 return tcu::TestStatus::fail("CopiesAndBlitting test");
6404 }
6405 }
6406
6407 return tcu::TestStatus::pass("CopiesAndBlitting test");
6408 }
6409
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)6410 void ResolveImageToImage::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
6411 {
6412 DE_UNREF(mipLevel);
6413
6414 VkOffset3D srcOffset = region.imageResolve.srcOffset;
6415 srcOffset.z = region.imageResolve.srcSubresource.baseArrayLayer;
6416 VkOffset3D dstOffset = region.imageResolve.dstOffset;
6417 dstOffset.z = region.imageResolve.dstSubresource.baseArrayLayer;
6418 VkExtent3D extent = region.imageResolve.extent;
6419 extent.depth = region.imageResolve.srcSubresource.layerCount;
6420
6421 const tcu::ConstPixelBufferAccess srcSubRegion = getSubregion (src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
6422 // CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
6423 const tcu::PixelBufferAccess dstWithSrcFormat (srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
6424 const tcu::PixelBufferAccess dstSubRegion = getSubregion (dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
6425
6426 tcu::copy(dstSubRegion, srcSubRegion);
6427 }
6428
checkIntermediateCopy(void)6429 tcu::TestStatus ResolveImageToImage::checkIntermediateCopy (void)
6430 {
6431 const auto& vkd = m_context.getDeviceInterface();
6432 const auto device = m_device;
6433 const auto queue = m_queue;
6434 const auto queueIndex = m_context.getUniversalQueueFamilyIndex();
6435 auto& alloc = *m_allocator;
6436 const auto currentLayout = m_params.src.image.operationLayout;
6437 const auto numDstLayers = getArraySize(m_params.dst.image);
6438 const auto numInputAttachments = m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE ? 2u : numDstLayers + 1u; // For the source image.
6439 constexpr auto numSets = 2u; // 1 for the output buffer, 1 for the input attachments.
6440 const auto fbWidth = m_params.src.image.extent.width;
6441 const auto fbHeight = m_params.src.image.extent.height;
6442
6443 // Push constants.
6444 const std::array<int, 3> pushConstantData =
6445 {{
6446 static_cast<int>(fbWidth),
6447 static_cast<int>(fbHeight),
6448 static_cast<int>(m_params.samples),
6449 }};
6450 const auto pushConstantSize = static_cast<deUint32>(pushConstantData.size() * sizeof(decltype(pushConstantData)::value_type));
6451
6452 // Shader modules.
6453 const auto vertexModule = createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
6454 const auto verificationModule = createShaderModule(vkd, device, m_context.getBinaryCollection().get("verify"), 0u);
6455
6456 // Descriptor sets.
6457 DescriptorPoolBuilder poolBuilder;
6458 poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
6459 poolBuilder.addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, numInputAttachments);
6460 const auto descriptorPool = poolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, numSets);
6461
6462 DescriptorSetLayoutBuilder layoutBuilderBuffer;
6463 layoutBuilderBuffer.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
6464 const auto outputBufferSetLayout = layoutBuilderBuffer.build(vkd, device);
6465
6466 DescriptorSetLayoutBuilder layoutBuilderAttachments;
6467 for (deUint32 i = 0u; i < numInputAttachments; ++i)
6468 layoutBuilderAttachments.addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT);
6469 const auto inputAttachmentsSetLayout = layoutBuilderAttachments.build(vkd, device);
6470
6471 const auto descriptorSetBuffer = makeDescriptorSet(vkd, device, descriptorPool.get(), outputBufferSetLayout.get());
6472 const auto descriptorSetAttachments = makeDescriptorSet(vkd, device, descriptorPool.get(), inputAttachmentsSetLayout.get());
6473
6474 // Array with raw descriptor sets.
6475 const std::array<VkDescriptorSet, numSets> descriptorSets =
6476 {{
6477 descriptorSetBuffer.get(),
6478 descriptorSetAttachments.get(),
6479 }};
6480
6481 // Pipeline layout.
6482 const std::array<VkDescriptorSetLayout, numSets> setLayouts =
6483 {{
6484 outputBufferSetLayout.get(),
6485 inputAttachmentsSetLayout.get(),
6486 }};
6487
6488 const VkPushConstantRange pushConstantRange =
6489 {
6490 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
6491 0u, // deUint32 offset;
6492 pushConstantSize, // deUint32 size;
6493 };
6494
6495 const VkPipelineLayoutCreateInfo pipelineLayoutInfo =
6496 {
6497 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
6498 nullptr, // const void* pNext;
6499 0u, // VkPipelineLayoutCreateFlags flags;
6500 static_cast<deUint32>(setLayouts.size()), // deUint32 setLayoutCount;
6501 setLayouts.data(), // const VkDescriptorSetLayout* pSetLayouts;
6502 1u, // deUint32 pushConstantRangeCount;
6503 &pushConstantRange, // const VkPushConstantRange* pPushConstantRanges;
6504 };
6505
6506 const auto pipelineLayout = createPipelineLayout(vkd, device, &pipelineLayoutInfo);
6507
6508 // Render pass.
6509 const VkAttachmentDescription commonAttachmentDescription =
6510 {
6511 0u, // VkAttachmentDescriptionFlags flags;
6512 m_params.src.image.format, // VkFormat format;
6513 m_params.samples, // VkSampleCountFlagBits samples;
6514 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
6515 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
6516 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
6517 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
6518 currentLayout, // VkImageLayout initialLayout;
6519 currentLayout, // VkImageLayout finalLayout;
6520 };
6521 const std::vector<VkAttachmentDescription> attachmentDescriptions(numInputAttachments, commonAttachmentDescription);
6522
6523 std::vector<VkAttachmentReference> inputAttachmentReferences;
6524 inputAttachmentReferences.reserve(numInputAttachments);
6525 for (deUint32 i = 0u; i < numInputAttachments; ++i)
6526 {
6527 const VkAttachmentReference reference = { i, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL };
6528 inputAttachmentReferences.push_back(reference);
6529 }
6530
6531 const VkSubpassDescription subpassDescription =
6532 {
6533 0u, // VkSubpassDescriptionFlags flags;
6534 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
6535 static_cast<deUint32>(inputAttachmentReferences.size()), // deUint32 inputAttachmentCount;
6536 inputAttachmentReferences.data(), // const VkAttachmentReference* pInputAttachments;
6537 0u, // deUint32 colorAttachmentCount;
6538 nullptr, // const VkAttachmentReference* pColorAttachments;
6539 nullptr, // const VkAttachmentReference* pResolveAttachments;
6540 nullptr, // const VkAttachmentReference* pDepthStencilAttachment;
6541 0u, // deUint32 preserveAttachmentCount;
6542 nullptr, // const deUint32* pPreserveAttachments;
6543 };
6544
6545 const VkRenderPassCreateInfo renderPassInfo =
6546 {
6547 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
6548 nullptr, // const void* pNext;
6549 0u, // VkRenderPassCreateFlags flags;
6550 static_cast<deUint32>(attachmentDescriptions.size()), // deUint32 attachmentCount;
6551 attachmentDescriptions.data(), // const VkAttachmentDescription* pAttachments;
6552 1u, // deUint32 subpassCount;
6553 &subpassDescription, // const VkSubpassDescription* pSubpasses;
6554 0u, // deUint32 dependencyCount;
6555 nullptr, // const VkSubpassDependency* pDependencies;
6556 };
6557
6558 const auto renderPass = createRenderPass(vkd, device, &renderPassInfo);
6559
6560 // Framebuffer.
6561 std::vector<Move<VkImageView>> imageViews;
6562 std::vector<VkImageView> imageViewsRaw;
6563
6564
6565 if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
6566 {
6567 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)));
6568 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)));
6569 }
6570 else
6571 {
6572 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)));
6573 for (deUint32 i = 0u; i < numDstLayers; ++i)
6574 {
6575 const auto subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, i, 1u);
6576 imageViews.push_back(makeImageView(vkd, device, m_multisampledCopyImage.get(), VK_IMAGE_VIEW_TYPE_2D, m_params.dst.image.format, subresourceRange));
6577 }
6578 }
6579
6580
6581 imageViewsRaw.reserve(imageViews.size());
6582 std::transform(begin(imageViews), end(imageViews), std::back_inserter(imageViewsRaw), [](const Move<VkImageView>& ptr) { return ptr.get(); });
6583
6584 const auto framebuffer = makeFramebuffer(vkd, device, renderPass.get(), static_cast<deUint32>(imageViewsRaw.size()), imageViewsRaw.data(), fbWidth, fbHeight);
6585
6586 // Storage buffer.
6587 const auto bufferCount = static_cast<size_t>(fbWidth * fbHeight * m_params.samples);
6588 const auto bufferSize = static_cast<VkDeviceSize>(bufferCount * sizeof(deInt32));
6589 BufferWithMemory buffer (vkd, device, alloc, makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible);
6590 auto& bufferAlloc = buffer.getAllocation();
6591 void* bufferData = bufferAlloc.getHostPtr();
6592
6593 // Update descriptor sets.
6594 DescriptorSetUpdateBuilder updater;
6595
6596 const auto bufferInfo = makeDescriptorBufferInfo(buffer.get(), 0ull, bufferSize);
6597 updater.writeSingle(descriptorSetBuffer.get(), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferInfo);
6598
6599 std::vector<VkDescriptorImageInfo> imageInfos;
6600 imageInfos.reserve(imageViewsRaw.size());
6601 for (size_t i = 0; i < imageViewsRaw.size(); ++i)
6602 imageInfos.push_back(makeDescriptorImageInfo(DE_NULL, imageViewsRaw[i], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL));
6603
6604 for (size_t i = 0; i < imageInfos.size(); ++i)
6605 updater.writeSingle(descriptorSetAttachments.get(), DescriptorSetUpdateBuilder::Location::binding(static_cast<deUint32>(i)), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &imageInfos[i]);
6606
6607 updater.update(vkd, device);
6608
6609 // Vertex buffer.
6610 std::vector<tcu::Vec4> fullScreenQuad;
6611 {
6612 // Full screen quad so every framebuffer pixel and sample location is verified by the shader.
6613 const tcu::Vec4 topLeft (-1.0f, -1.0f, 0.0f, 1.0f);
6614 const tcu::Vec4 topRight ( 1.0f, -1.0f, 0.0f, 1.0f);
6615 const tcu::Vec4 bottomLeft (-1.0f, 1.0f, 0.0f, 1.0f);
6616 const tcu::Vec4 bottomRight ( 1.0f, 1.0f, 0.0f, 1.0f);
6617
6618 fullScreenQuad.reserve(6u);
6619 fullScreenQuad.push_back(topLeft);
6620 fullScreenQuad.push_back(topRight);
6621 fullScreenQuad.push_back(bottomRight);
6622 fullScreenQuad.push_back(topLeft);
6623 fullScreenQuad.push_back(bottomRight);
6624 fullScreenQuad.push_back(bottomLeft);
6625 }
6626
6627 const auto vertexBufferSize = static_cast<VkDeviceSize>(fullScreenQuad.size() * sizeof(decltype(fullScreenQuad)::value_type));
6628 const auto vertexBufferInfo = makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
6629 const BufferWithMemory vertexBuffer (vkd, device, alloc, vertexBufferInfo, MemoryRequirement::HostVisible);
6630 const auto vertexBufferHandler = vertexBuffer.get();
6631 auto& vertexBufferAlloc = vertexBuffer.getAllocation();
6632 void* vertexBufferData = vertexBufferAlloc.getHostPtr();
6633 const VkDeviceSize vertexBufferOffset = 0ull;
6634
6635 deMemcpy(vertexBufferData, fullScreenQuad.data(), static_cast<size_t>(vertexBufferSize));
6636 flushAlloc(vkd, device, vertexBufferAlloc);
6637
6638 // Graphics pipeline.
6639 const std::vector<VkViewport> viewports (1, makeViewport(m_params.src.image.extent));
6640 const std::vector<VkRect2D> scissors (1, makeRect2D(m_params.src.image.extent));
6641
6642 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
6643 {
6644 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
6645 nullptr, // const void* pNext;
6646 0u, // VkPipelineMultisampleStateCreateFlags flags;
6647 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
6648 VK_FALSE, // VkBool32 sampleShadingEnable;
6649 0.0f, // float minSampleShading;
6650 nullptr, // const VkSampleMask* pSampleMask;
6651 VK_FALSE, // VkBool32 alphaToCoverageEnable;
6652 VK_FALSE // VkBool32 alphaToOneEnable;
6653 };
6654
6655 const auto graphicsPipeline = makeGraphicsPipeline(
6656 vkd, // const DeviceInterface& vk
6657 device, // const VkDevice device
6658 pipelineLayout.get(), // const VkPipelineLayout pipelineLayout
6659 vertexModule.get(), // const VkShaderModule vertexShaderModule
6660 DE_NULL, // const VkShaderModule tessellationControlModule
6661 DE_NULL, // const VkShaderModule tessellationEvalModule
6662 DE_NULL, // const VkShaderModule geometryShaderModule
6663 verificationModule.get(), // const VkShaderModule fragmentShaderModule
6664 renderPass.get(), // const VkRenderPass renderPass
6665 viewports, // const std::vector<VkViewport>& viewports
6666 scissors, // const std::vector<VkRect2D>& scissors
6667 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
6668 0u, // const deUint32 subpass
6669 0u, // const deUint32 patchControlPoints
6670 nullptr, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
6671 nullptr, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
6672 &multisampleStateParams); // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
6673
6674 // Command buffer.
6675 const auto cmdPool = makeCommandPool(vkd, device, queueIndex);
6676 const auto cmdBufferPtr = allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
6677 const auto cmdBuffer = cmdBufferPtr.get();
6678
6679 // Make sure multisample copy data is available to the fragment shader.
6680 const auto imagesBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT);
6681
6682 // Make sure verification buffer data is available on the host.
6683 const auto bufferBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
6684
6685 // Record and submit command buffer.
6686 beginCommandBuffer(vkd, cmdBuffer);
6687 vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 1u, &imagesBarrier, 0u, nullptr, 0u, nullptr);
6688 beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffer.get(), makeRect2D(m_params.src.image.extent));
6689 vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline.get());
6690 vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBufferHandler, &vertexBufferOffset);
6691 vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), VK_SHADER_STAGE_FRAGMENT_BIT, 0u, pushConstantSize, pushConstantData.data());
6692 vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u, static_cast<deUint32>(descriptorSets.size()), descriptorSets.data(), 0u, nullptr);
6693 vkd.cmdDraw(cmdBuffer, static_cast<deUint32>(fullScreenQuad.size()), 1u, 0u, 0u);
6694 endRenderPass(vkd, cmdBuffer);
6695 vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &bufferBarrier, 0u, nullptr, 0u, nullptr);
6696 endCommandBuffer(vkd, cmdBuffer);
6697 submitCommandsAndWait(vkd, device, queue, cmdBuffer);
6698 m_context.resetCommandPoolForVKSC(device, *cmdPool);
6699
6700 // Verify intermediate results.
6701 invalidateAlloc(vkd, device, bufferAlloc);
6702 std::vector<deInt32> outputFlags (bufferCount, 0);
6703 deMemcpy(outputFlags.data(), bufferData, static_cast<size_t>(bufferSize));
6704
6705 auto& log = m_context.getTestContext().getLog();
6706 log << tcu::TestLog::Message << "Verifying intermediate multisample copy results" << tcu::TestLog::EndMessage;
6707
6708 const auto sampleCount = static_cast<deUint32>(m_params.samples);
6709
6710 for (deUint32 x = 0u; x < fbWidth; ++x)
6711 for (deUint32 y = 0u; y < fbHeight; ++y)
6712 for (deUint32 s = 0u; s < sampleCount; ++s)
6713 {
6714 const auto index = (y * fbWidth + x) * sampleCount + s;
6715 if (!outputFlags[index])
6716 {
6717 std::ostringstream msg;
6718 msg << "Intermediate verification failed for coordinates (" << x << ", " << y << ") sample " << s;
6719 return tcu::TestStatus::fail(msg.str());
6720 }
6721 }
6722
6723 log << tcu::TestLog::Message << "Intermediate multisample copy verification passed" << tcu::TestLog::EndMessage;
6724 return tcu::TestStatus::pass("Pass");
6725 }
6726
copyMSImageToMSImage(deUint32 copyArraySize)6727 void ResolveImageToImage::copyMSImageToMSImage (deUint32 copyArraySize)
6728 {
6729 const bool useTwoQueues = m_options == COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER;
6730 const DeviceInterface& vk = m_context.getDeviceInterface();
6731 const VkDevice vkDevice = m_device;
6732 const VkQueue queue = useTwoQueues ? m_alternativeQueue : m_queue;
6733 const VkCommandBuffer commandBuffer = useTwoQueues ? m_alternativeCmdBuffer.get() : m_cmdBuffer.get();
6734 const VkCommandPool commandPool = useTwoQueues ? m_alternativeCmdPool.get() : m_cmdPool.get();
6735 const tcu::TextureFormat srcTcuFormat = mapVkFormat(m_params.src.image.format);
6736 std::vector<VkImageCopy> imageCopies;
6737 std::vector<VkImageCopy2KHR> imageCopies2KHR;
6738
6739 if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
6740 {
6741 const VkImageSubresourceLayers sourceSubresourceLayers =
6742 {
6743 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
6744 0u, // deUint32 mipLevel;
6745 2u, // deUint32 baseArrayLayer;
6746 1u // deUint32 layerCount;
6747 };
6748
6749 const VkImageSubresourceLayers destinationSubresourceLayers =
6750 {
6751 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;//getAspectFlags(dstTcuFormat)
6752 0u, // deUint32 mipLevel;
6753 4u, // deUint32 baseArrayLayer;
6754 1u // deUint32 layerCount;
6755 };
6756
6757 const VkImageCopy imageCopy =
6758 {
6759 sourceSubresourceLayers, // VkImageSubresourceLayers srcSubresource;
6760 {0, 0, 0}, // VkOffset3D srcOffset;
6761 destinationSubresourceLayers, // VkImageSubresourceLayers dstSubresource;
6762 {0, 0, 0}, // VkOffset3D dstOffset;
6763 getExtent3D(m_params.src.image), // VkExtent3D extent;
6764 };
6765
6766 if (m_params.extensionUse == EXTENSION_USE_NONE)
6767 {
6768 imageCopies.push_back(imageCopy);
6769 }
6770 else
6771 {
6772 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6773 imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
6774 }
6775 }
6776 else if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION)
6777 {
6778 VkExtent3D partialExtent = {getExtent3D(m_params.src.image).width / 2,
6779 getExtent3D(m_params.src.image).height / 2,
6780 getExtent3D(m_params.src.image).depth};
6781
6782 for (CopyRegion region : m_params.regions)
6783 {
6784 const VkImageCopy imageCopy =
6785 {
6786 region.imageResolve.srcSubresource, // VkImageSubresourceLayers srcSubresource;
6787 region.imageResolve.srcOffset, // VkOffset3D srcOffset;
6788 region.imageResolve.dstSubresource, // VkImageSubresourceLayers dstSubresource;
6789 region.imageResolve.dstOffset, // VkOffset3D dstOffset;
6790 partialExtent, // VkExtent3D extent;
6791 };
6792
6793 if (m_params.extensionUse == EXTENSION_USE_NONE)
6794 {
6795 imageCopies.push_back(imageCopy);
6796 }
6797 else
6798 {
6799 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6800 imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
6801 }
6802 }
6803 }
6804 else
6805 {
6806 for (deUint32 layerNdx = 0; layerNdx < copyArraySize; ++layerNdx)
6807 {
6808 const VkImageSubresourceLayers sourceSubresourceLayers =
6809 {
6810 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
6811 0u, // deUint32 mipLevel;
6812 0u, // deUint32 baseArrayLayer;
6813 1u // deUint32 layerCount;
6814 };
6815
6816 const VkImageSubresourceLayers destinationSubresourceLayers =
6817 {
6818 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;//getAspectFlags(dstTcuFormat)
6819 0u, // deUint32 mipLevel;
6820 layerNdx, // deUint32 baseArrayLayer;
6821 1u // deUint32 layerCount;
6822 };
6823
6824 const VkImageCopy imageCopy =
6825 {
6826 sourceSubresourceLayers, // VkImageSubresourceLayers srcSubresource;
6827 {0, 0, 0}, // VkOffset3D srcOffset;
6828 destinationSubresourceLayers, // VkImageSubresourceLayers dstSubresource;
6829 {0, 0, 0}, // VkOffset3D dstOffset;
6830 getExtent3D(m_params.src.image), // VkExtent3D extent;
6831 };
6832
6833 if (m_params.extensionUse == EXTENSION_USE_NONE)
6834 {
6835 imageCopies.push_back(imageCopy);
6836 }
6837 else
6838 {
6839 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6840 imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
6841 }
6842 }
6843 }
6844
6845 VkImageSubresourceRange subresourceRange = {
6846 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask
6847 0u, // deUint32 baseMipLevel
6848 1u, // deUint32 mipLevels
6849 0u, // deUint32 baseArraySlice
6850 copyArraySize // deUint32 arraySize
6851 };
6852
6853 // m_multisampledImage
6854 const VkImageMemoryBarrier m_multisampledImageBarrier =
6855 {
6856 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
6857 DE_NULL, // const void* pNext;
6858 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask;
6859 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
6860 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
6861 m_params.src.image.operationLayout, // VkImageLayout newLayout;
6862 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
6863 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
6864 m_multisampledImage.get(), // VkImage image;
6865 { // VkImageSubresourceRange subresourceRange;
6866 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
6867 0u, // deUint32 baseMipLevel;
6868 1u, // deUint32 mipLevels;
6869 0u, // deUint32 baseArraySlice;
6870 getArraySize(m_params.src.image) // deUint32 arraySize;
6871 }
6872 };
6873 // m_multisampledCopyImage
6874 VkImageMemoryBarrier m_multisampledCopyImageBarrier =
6875 {
6876 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
6877 DE_NULL, // const void* pNext;
6878 0, // VkAccessFlags srcAccessMask;
6879 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
6880 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
6881 m_params.dst.image.operationLayout, // VkImageLayout newLayout;
6882 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
6883 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
6884 m_multisampledCopyImage.get(), // VkImage image;
6885 subresourceRange // VkImageSubresourceRange subresourceRange;
6886 };
6887
6888 // m_multisampledCopyNoCabImage (no USAGE_COLOR_ATTACHMENT_BIT)
6889 const VkImageMemoryBarrier m_multisampledCopyNoCabImageBarrier =
6890 {
6891 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
6892 DE_NULL, // const void* pNext;
6893 0, // VkAccessFlags srcAccessMask;
6894 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
6895 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
6896 m_params.dst.image.operationLayout, // VkImageLayout newLayout;
6897 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
6898 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
6899 m_multisampledCopyNoCabImage.get(), // VkImage image;
6900 subresourceRange // VkImageSubresourceRange subresourceRange;
6901 };
6902
6903 // destination image
6904 const VkImageMemoryBarrier multisampledCopyImagePostBarrier =
6905 {
6906 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
6907 DE_NULL, // const void* pNext;
6908 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
6909 VK_ACCESS_MEMORY_READ_BIT, // VkAccessFlags dstAccessMask;
6910 m_params.dst.image.operationLayout, // VkImageLayout oldLayout;
6911 m_params.src.image.operationLayout, // VkImageLayout newLayout;
6912 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
6913 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
6914 m_multisampledCopyImage.get(), // VkImage image;
6915 subresourceRange // VkImageSubresourceRange subresourceRange;
6916 };
6917
6918 // destination image (no USAGE_COLOR_ATTACHMENT_BIT)
6919 const VkImageMemoryBarrier betweenCopyImageBarrier =
6920 {
6921 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
6922 DE_NULL, // const void* pNext;
6923 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
6924 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
6925 m_params.dst.image.operationLayout, // VkImageLayout oldLayout;
6926 m_params.src.image.operationLayout, // VkImageLayout newLayout;
6927 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
6928 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
6929 m_multisampledCopyNoCabImage.get(), // VkImage image;
6930 subresourceRange // VkImageSubresourceRange subresourceRange;
6931 };
6932
6933 // Queue family ownership transfer. Move ownership of the m_multisampledImage and m_multisampledImageCopy to the compute/transfer queue.
6934 if (useTwoQueues)
6935 {
6936 // Release ownership from graphics queue.
6937 {
6938 std::vector<VkImageMemoryBarrier> barriers;
6939 barriers.reserve(2);
6940
6941 // Barrier for m_multisampledImage
6942 VkImageMemoryBarrier releaseBarrier = m_multisampledImageBarrier;
6943 releaseBarrier.dstAccessMask = 0u; // dstAccessMask is ignored in ownership release operation.
6944 releaseBarrier.srcQueueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
6945 releaseBarrier.dstQueueFamilyIndex = m_alternativeQueueFamilyIndex;
6946 barriers.push_back(releaseBarrier);
6947
6948 // Barrier for m_multisampledCopyImage
6949 releaseBarrier = m_multisampledCopyImageBarrier;
6950 releaseBarrier.dstAccessMask = 0u; // dstAccessMask is ignored in ownership release operation.
6951 releaseBarrier.srcQueueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
6952 releaseBarrier.dstQueueFamilyIndex = m_alternativeQueueFamilyIndex;
6953 barriers.push_back(releaseBarrier);
6954
6955 beginCommandBuffer(vk, m_cmdBuffer.get());
6956 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());
6957 endCommandBuffer(vk, m_cmdBuffer.get());
6958 submitCommandsAndWait(vk, vkDevice, m_queue, m_cmdBuffer.get());
6959 m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
6960 }
6961
6962 // Acquire ownership to compute / transfer queue.
6963 {
6964 std::vector<VkImageMemoryBarrier> barriers;
6965 barriers.reserve(2);
6966
6967 // Barrier for m_multisampledImage
6968 VkImageMemoryBarrier acquireBarrier = m_multisampledImageBarrier;
6969 acquireBarrier.srcAccessMask = 0u; // srcAccessMask is ignored in ownership acquire operation.
6970 acquireBarrier.srcQueueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
6971 acquireBarrier.dstQueueFamilyIndex = m_alternativeQueueFamilyIndex;
6972 barriers.push_back(acquireBarrier);
6973
6974 // Barrier for m_multisampledImage
6975 acquireBarrier = m_multisampledCopyImageBarrier;
6976 acquireBarrier.srcAccessMask = 0u; // srcAccessMask is ignored in ownership acquire operation.
6977 acquireBarrier.srcQueueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
6978 acquireBarrier.dstQueueFamilyIndex = m_alternativeQueueFamilyIndex;
6979 barriers.push_back(acquireBarrier);
6980
6981 beginCommandBuffer(vk, commandBuffer);
6982 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());
6983 endCommandBuffer(vk, commandBuffer);
6984 submitCommandsAndWait(vk, vkDevice, queue, commandBuffer);
6985 m_context.resetCommandPoolForVKSC(vkDevice, commandPool);
6986 }
6987
6988 beginCommandBuffer(vk, commandBuffer);
6989 }
6990 else
6991 {
6992 std::vector<VkImageMemoryBarrier> imageBarriers;
6993
6994 imageBarriers.push_back(m_multisampledImageBarrier);
6995 // Only use one barrier if no options have been given.
6996 if (m_options != NO_OPTIONAL_OPERATION)
6997 {
6998 imageBarriers.push_back(m_multisampledCopyImageBarrier);
6999 // Add the third barrier if option is as below.
7000 if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB)
7001 imageBarriers.push_back(m_multisampledCopyNoCabImageBarrier);
7002 }
7003
7004 beginCommandBuffer(vk, commandBuffer);
7005 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());
7006 }
7007
7008 if (m_params.extensionUse == EXTENSION_USE_NONE)
7009 {
7010 if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB)
7011 {
7012 vk.cmdCopyImage(commandBuffer, m_multisampledImage.get(), m_params.src.image.operationLayout, m_multisampledCopyNoCabImage.get(), m_params.dst.image.operationLayout, (deUint32)imageCopies.size(), imageCopies.data());
7013 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);
7014 vk.cmdCopyImage(commandBuffer, m_multisampledCopyNoCabImage.get(), m_params.src.image.operationLayout, m_multisampledCopyImage.get(), m_params.dst.image.operationLayout, (deUint32)imageCopies.size(), imageCopies.data());
7015 }
7016 else
7017 {
7018 vk.cmdCopyImage(commandBuffer, m_multisampledImage.get(), m_params.src.image.operationLayout, m_multisampledCopyImage.get(), m_params.dst.image.operationLayout, (deUint32)imageCopies.size(), imageCopies.data());
7019 }
7020 }
7021 #ifndef CTS_USES_VULKANSC
7022 else
7023 {
7024 if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB)
7025 {
7026 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
7027 const VkCopyImageInfo2KHR copyImageInfo2KHR =
7028 {
7029 VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR, // VkStructureType sType;
7030 DE_NULL, // const void* pNext;
7031 m_multisampledImage.get(), // VkImage srcImage;
7032 m_params.src.image.operationLayout, // VkImageLayout srcImageLayout;
7033 m_multisampledCopyNoCabImage.get(), // VkImage dstImage;
7034 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout dstImageLayout;
7035 (deUint32)imageCopies2KHR.size(), // uint32_t regionCount;
7036 imageCopies2KHR.data() // const VkImageCopy2KHR* pRegions;
7037 };
7038 const VkCopyImageInfo2KHR copyImageInfo2KHRCopy =
7039 {
7040 VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR, // VkStructureType sType;
7041 DE_NULL, // const void* pNext;
7042 m_multisampledCopyNoCabImage.get(), // VkImage srcImage;
7043 vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout srcImageLayout;
7044 m_multisampledCopyImage.get(), // VkImage dstImage;
7045 m_params.dst.image.operationLayout, // VkImageLayout dstImageLayout;
7046 (deUint32)imageCopies2KHR.size(), // uint32_t regionCount;
7047 imageCopies2KHR.data() // const VkImageCopy2KHR* pRegions;
7048 };
7049
7050 vk.cmdCopyImage2(commandBuffer, ©ImageInfo2KHR);
7051 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);
7052 vk.cmdCopyImage2(commandBuffer, ©ImageInfo2KHRCopy);
7053 }
7054 else
7055 {
7056 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
7057 const VkCopyImageInfo2KHR copyImageInfo2KHR =
7058 {
7059 VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR, // VkStructureType sType;
7060 DE_NULL, // const void* pNext;
7061 m_multisampledImage.get(), // VkImage srcImage;
7062 m_params.src.image.operationLayout, // VkImageLayout srcImageLayout;
7063 m_multisampledCopyImage.get(), // VkImage dstImage;
7064 m_params.dst.image.operationLayout, // VkImageLayout dstImageLayout;
7065 (deUint32)imageCopies2KHR.size(), // uint32_t regionCount;
7066 imageCopies2KHR.data() // const VkImageCopy2KHR* pRegions;
7067 };
7068 vk.cmdCopyImage2(commandBuffer, ©ImageInfo2KHR);
7069 }
7070 }
7071 #endif // CTS_USES_VULKANSC
7072
7073 if (useTwoQueues)
7074 {
7075 endCommandBuffer(vk, commandBuffer);
7076 submitCommandsAndWait(vk, vkDevice, queue, commandBuffer);
7077 m_context.resetCommandPoolForVKSC(vkDevice, commandPool);
7078
7079 VkImageMemoryBarrier srcImageBarrier = makeImageMemoryBarrier(
7080 0u,
7081 0u,
7082 m_params.src.image.operationLayout,
7083 m_params.src.image.operationLayout,
7084 m_multisampledImage.get(),
7085 m_multisampledImageBarrier.subresourceRange,
7086 m_alternativeQueueFamilyIndex,
7087 m_context.getUniversalQueueFamilyIndex());
7088 // Release ownership from compute / transfer queue.
7089 {
7090 std::vector<VkImageMemoryBarrier> barriers;
7091 barriers.reserve(2);
7092
7093 VkImageMemoryBarrier releaseBarrier = multisampledCopyImagePostBarrier;
7094 releaseBarrier.dstAccessMask = 0u; // dstAccessMask is ignored in ownership release operation.
7095 releaseBarrier.srcQueueFamilyIndex = m_alternativeQueueFamilyIndex;
7096 releaseBarrier.dstQueueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
7097 barriers.push_back(releaseBarrier);
7098
7099 releaseBarrier = srcImageBarrier;
7100 releaseBarrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
7101 releaseBarrier.dstAccessMask = 0u; // dstAccessMask is ignored in ownership release operation.
7102 barriers.push_back(releaseBarrier);
7103
7104 beginCommandBuffer(vk, commandBuffer);
7105 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());
7106 endCommandBuffer(vk, commandBuffer);
7107 submitCommandsAndWait(vk, vkDevice, queue, commandBuffer);
7108 m_context.resetCommandPoolForVKSC(vkDevice, commandPool);
7109 }
7110
7111 // Acquire ownership to graphics queue.
7112 {
7113 std::vector<VkImageMemoryBarrier> barriers;
7114 barriers.reserve(2);
7115
7116 VkImageMemoryBarrier acquireBarrier = multisampledCopyImagePostBarrier;
7117 acquireBarrier.srcAccessMask = 0u; // srcAccessMask is ignored in ownership acquire operation.
7118 acquireBarrier.srcQueueFamilyIndex = m_alternativeQueueFamilyIndex;
7119 acquireBarrier.dstQueueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
7120 barriers.push_back(acquireBarrier);
7121
7122 acquireBarrier = srcImageBarrier;
7123 acquireBarrier.srcAccessMask = 0u; // srcAccessMask is ignored in ownership acquire operation.
7124 acquireBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
7125 barriers.push_back(acquireBarrier);
7126
7127 beginCommandBuffer(vk, m_cmdBuffer.get());
7128 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());
7129 endCommandBuffer(vk, m_cmdBuffer.get());
7130 submitCommandsAndWait(vk, vkDevice, m_queue, m_cmdBuffer.get());
7131 m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
7132 }
7133 }
7134 else
7135 {
7136 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);
7137 endCommandBuffer(vk, commandBuffer);
7138 submitCommandsAndWait (vk, vkDevice, queue, commandBuffer);
7139 m_context.resetCommandPoolForVKSC(vkDevice, commandPool);
7140 }
7141 }
7142
7143 class ResolveImageToImageTestCase : public vkt::TestCase
7144 {
7145 public:
ResolveImageToImageTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params,const ResolveImageToImageOptions options=NO_OPTIONAL_OPERATION)7146 ResolveImageToImageTestCase (tcu::TestContext& testCtx,
7147 const std::string& name,
7148 const std::string& description,
7149 const TestParams params,
7150 const ResolveImageToImageOptions options = NO_OPTIONAL_OPERATION)
7151 : vkt::TestCase (testCtx, name, description)
7152 , m_params (params)
7153 , m_options (options)
7154 {}
7155
7156 virtual void initPrograms (SourceCollections& programCollection) const;
7157
createInstance(Context & context) const7158 virtual TestInstance* createInstance (Context& context) const
7159 {
7160 return new ResolveImageToImage(context, m_params, m_options);
7161 }
7162
checkSupport(Context & context) const7163 virtual void checkSupport (Context& context) const
7164 {
7165 const VkSampleCountFlagBits rasterizationSamples = m_params.samples;
7166
7167 // Intermediate result check uses fragmentStoresAndAtomics.
7168 if (ResolveImageToImage::shouldVerifyIntermediateResults(m_options) && !context.getDeviceFeatures().fragmentStoresAndAtomics)
7169 {
7170 TCU_THROW(NotSupportedError, "fragmentStoresAndAtomics not supported");
7171 }
7172
7173 if (!(context.getDeviceProperties().limits.framebufferColorSampleCounts & rasterizationSamples))
7174 throw tcu::NotSupportedError("Unsupported number of rasterization samples");
7175
7176 VkImageFormatProperties properties;
7177 if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
7178 m_params.src.image.format,
7179 m_params.src.image.imageType,
7180 VK_IMAGE_TILING_OPTIMAL,
7181 VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
7182 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
7183 (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
7184 m_params.dst.image.format,
7185 m_params.dst.image.imageType,
7186 VK_IMAGE_TILING_OPTIMAL,
7187 VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0,
7188 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
7189 {
7190 TCU_THROW(NotSupportedError, "Format not supported");
7191 }
7192
7193 if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
7194 (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
7195 {
7196 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
7197 }
7198
7199 // Find at least one queue family that supports compute queue but does NOT support graphics queue.
7200 if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE)
7201 {
7202 bool foundQueue = false;
7203 const std::vector<VkQueueFamilyProperties> queueFamilies = getPhysicalDeviceQueueFamilyProperties(context.getInstanceInterface(), context.getPhysicalDevice());
7204 for (const auto& queueFamily : queueFamilies)
7205 {
7206 if (queueFamily.queueFlags & VK_QUEUE_COMPUTE_BIT && !(queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT))
7207 {
7208 foundQueue = true;
7209 break;
7210 }
7211 }
7212 if (!foundQueue)
7213 TCU_THROW(NotSupportedError, "No queue family found that only supports compute queue.");
7214 }
7215
7216 // Find at least one queue family that supports transfer queue but does NOT support graphics and compute queue.
7217 if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER)
7218 {
7219 bool foundQueue = false;
7220 const std::vector<VkQueueFamilyProperties> queueFamilies = getPhysicalDeviceQueueFamilyProperties(context.getInstanceInterface(), context.getPhysicalDevice());
7221 for (const auto& queueFamily : queueFamilies)
7222 {
7223 if (queueFamily.queueFlags & VK_QUEUE_TRANSFER_BIT && !(queueFamily.queueFlags & VK_QUEUE_COMPUTE_BIT) && !(queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT))
7224 {
7225 foundQueue = true;
7226 break;
7227 }
7228 }
7229 if (!foundQueue)
7230 TCU_THROW(NotSupportedError, "No queue family found that only supports transfer queue.");
7231 }
7232 }
7233
7234 private:
7235 TestParams m_params;
7236 const ResolveImageToImageOptions m_options;
7237 };
7238
initPrograms(SourceCollections & programCollection) const7239 void ResolveImageToImageTestCase::initPrograms (SourceCollections& programCollection) const
7240 {
7241 programCollection.glslSources.add("vert") << glu::VertexSource(
7242 "#version 310 es\n"
7243 "layout (location = 0) in highp vec4 a_position;\n"
7244 "void main()\n"
7245 "{\n"
7246 " gl_Position = a_position;\n"
7247 "}\n");
7248
7249
7250 programCollection.glslSources.add("frag") << glu::FragmentSource(
7251 "#version 310 es\n"
7252 "layout (location = 0) out highp vec4 o_color;\n"
7253 "void main()\n"
7254 "{\n"
7255 " o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
7256 "}\n");
7257
7258 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)
7259 {
7260 // The shader verifies all layers in the copied image are the same as the source image.
7261 // This needs an image view per layer in the copied image.
7262 // Set 0 contains the output buffer.
7263 // Set 1 contains the input attachments.
7264
7265 std::ostringstream verificationShader;
7266
7267 verificationShader
7268 << "#version 450\n"
7269 << "\n"
7270 << "layout (push_constant, std430) uniform PushConstants {\n"
7271 << " int width;\n"
7272 << " int height;\n"
7273 << " int samples;\n"
7274 << "};\n"
7275 << "layout (set=0, binding=0) buffer VerificationResults {\n"
7276 << " int verificationFlags[];\n"
7277 << "};\n"
7278 << "layout (input_attachment_index=0, set=1, binding=0) uniform subpassInputMS attachment0;\n"
7279 ;
7280
7281 const auto dstLayers = getArraySize(m_params.dst.image);
7282
7283 if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
7284 {
7285 verificationShader << "layout (input_attachment_index=1, set=1, binding=1) uniform subpassInputMS attachment1;\n";
7286 }
7287 else
7288 {
7289 for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
7290 {
7291 const auto i = layerNdx + 1u;
7292 verificationShader << "layout (input_attachment_index=" << i << ", set=1, binding=" << i << ") uniform subpassInputMS attachment" << i << ";\n";
7293 }
7294 }
7295
7296 // Using a loop to iterate over each sample avoids the need for the sampleRateShading feature. The pipeline needs to be
7297 // created with a single sample.
7298 verificationShader
7299 << "\n"
7300 << "void main() {\n"
7301 << " for (int sampleID = 0; sampleID < samples; ++sampleID) {\n"
7302 << " vec4 orig = subpassLoad(attachment0, sampleID);\n"
7303 ;
7304
7305 std::ostringstream testCondition;
7306 if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
7307 {
7308 verificationShader << " vec4 copy = subpassLoad(attachment1, sampleID);\n";
7309 testCondition << "orig == copy";
7310 }
7311 else
7312 {
7313 for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
7314 {
7315 const auto i = layerNdx + 1u;
7316 verificationShader << " vec4 copy" << i << " = subpassLoad(attachment" << i << ", sampleID);\n";
7317 }
7318
7319 for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
7320 {
7321 const auto i = layerNdx + 1u;
7322 testCondition << (layerNdx == 0u ? "" : " && ") << "orig == copy" << i;
7323 }
7324 }
7325
7326 verificationShader
7327 << "\n"
7328 << " ivec3 coords = ivec3(int(gl_FragCoord.x), int(gl_FragCoord.y), sampleID);\n"
7329 << " int bufferPos = (coords.y * width + coords.x) * samples + coords.z;\n"
7330 << "\n"
7331 << " verificationFlags[bufferPos] = ((" << testCondition.str() << ") ? 1 : 0); \n"
7332 << " }\n"
7333 << "}\n"
7334 ;
7335
7336 programCollection.glslSources.add("verify") << glu::FragmentSource(verificationShader.str());
7337 }
7338 }
7339
7340 class DepthStencilMSAA : public vkt::TestInstance
7341 {
7342 public:
7343 enum CopyOptions {COPY_WHOLE_IMAGE, COPY_ARRAY_TO_ARRAY, COPY_PARTIAL};
7344
7345 struct TestParameters
7346 {
7347 AllocationKind allocationKind;
7348 ExtensionUse extensionUse;
7349 CopyOptions copyOptions;
7350 VkSampleCountFlagBits samples;
7351 VkImageLayout srcImageLayout;
7352 VkImageLayout dstImageLayout;
7353 VkFormat imageFormat;
7354 VkImageAspectFlags copyAspect;
7355 deBool imageOffset;
7356 };
7357
7358 DepthStencilMSAA (Context& context,
7359 TestParameters testParameters);
7360 tcu::TestStatus iterate (void) override;
7361 protected:
7362 tcu::TestStatus checkCopyResults (VkCommandBuffer cmdBuffer,
7363 const VkImageAspectFlagBits& aspectToVerify,
7364 VkImage srcImage,
7365 VkImage dstImage);
7366
7367 private:
7368 // Returns image aspects used in the copy regions.
getUsedImageAspects()7369 VkImageAspectFlags getUsedImageAspects ()
7370 {
7371 auto aspectFlags = (VkImageAspectFlags)0;
7372 for (const auto ®ion : m_regions)
7373 {
7374 aspectFlags |= region.imageCopy.srcSubresource.aspectMask;
7375 }
7376 return aspectFlags;
7377 }
7378
7379 ImageParms m_srcImage;
7380 ImageParms m_dstImage;
7381 std::vector<CopyRegion> m_regions;
7382 const TestParameters m_params;
7383 const float m_clearValue = 0.0f;
7384 };
7385
DepthStencilMSAA(Context & context,TestParameters testParameters)7386 DepthStencilMSAA::DepthStencilMSAA (Context& context, TestParameters testParameters)
7387 : vkt::TestInstance(context)
7388 , m_params(testParameters)
7389 {
7390 // params.src.image is the parameters used to create the copy source image
7391 m_srcImage.imageType = VK_IMAGE_TYPE_2D;
7392 m_srcImage.format = testParameters.imageFormat;
7393 m_srcImage.extent = defaultExtent;
7394 m_srcImage.tiling = VK_IMAGE_TILING_OPTIMAL;
7395 m_srcImage.operationLayout = testParameters.srcImageLayout;
7396 m_srcImage.createFlags = 0u;
7397
7398 // params.src.image is the parameters used to create the copy destination image
7399 m_dstImage.imageType = VK_IMAGE_TYPE_2D;
7400 m_dstImage.format = testParameters.imageFormat;
7401 m_dstImage.extent = defaultExtent;
7402 m_dstImage.tiling = VK_IMAGE_TILING_OPTIMAL;
7403 m_dstImage.operationLayout = testParameters.dstImageLayout;
7404 m_dstImage.createFlags = 0u;
7405
7406 const VkImageSubresourceLayers depthSubresourceLayers =
7407 {
7408 VK_IMAGE_ASPECT_DEPTH_BIT, // VkImageAspectFlags aspectMask;
7409 0u, // uint32_t mipLevel;
7410 0u, // uint32_t baseArrayLayer;
7411 1u // uint32_t layerCount;
7412 };
7413
7414 const VkImageSubresourceLayers stencilSubresourceLayers =
7415 {
7416 VK_IMAGE_ASPECT_STENCIL_BIT, // VkImageAspectFlags aspectMask;
7417 0u, // uint32_t mipLevel;
7418 0u, // uint32_t baseArrayLayer;
7419 1u // uint32_t layerCount;
7420 };
7421
7422 VkImageCopy depthCopy =
7423 {
7424 depthSubresourceLayers, // VkImageSubresourceLayers srcSubresource;
7425 {0, 0, 0}, // VkOffset3D srcOffset;
7426 depthSubresourceLayers, // VkImageSubresourceLayers dstSubresource;
7427 {0, 0, 0}, // VkOffset3D dstOffset;
7428 defaultExtent, // VkExtent3D extent;
7429 };
7430
7431 VkImageCopy stencilCopy =
7432 {
7433 stencilSubresourceLayers, // VkImageSubresourceLayers srcSubresource;
7434 {0, 0, 0}, // VkOffset3D srcOffset;
7435 stencilSubresourceLayers, // VkImageSubresourceLayers dstSubresource;
7436 {0, 0, 0}, // VkOffset3D dstOffset;
7437 defaultExtent, // VkExtent3D extent;
7438 };
7439
7440 if (testParameters.copyOptions == DepthStencilMSAA::COPY_ARRAY_TO_ARRAY)
7441 {
7442 m_srcImage.extent.depth = 5u;
7443 depthCopy.srcSubresource.baseArrayLayer = 2u;
7444 depthCopy.dstSubresource.baseArrayLayer = 3u;
7445 stencilCopy.srcSubresource.baseArrayLayer = 2u;
7446 stencilCopy.dstSubresource.baseArrayLayer = 3u;
7447 }
7448
7449 CopyRegion depthCopyRegion;
7450 CopyRegion stencilCopyRegion;
7451 depthCopyRegion.imageCopy = depthCopy;
7452 stencilCopyRegion.imageCopy = stencilCopy;
7453
7454 std::vector<CopyRegion> depthRegions;
7455 std::vector<CopyRegion> stencilRegions;
7456
7457 if (testParameters.copyOptions == DepthStencilMSAA::COPY_PARTIAL)
7458 {
7459 if (testParameters.copyAspect & VK_IMAGE_ASPECT_DEPTH_BIT)
7460 {
7461 depthCopyRegion.imageCopy.extent = {defaultHalfSize, defaultHalfSize, 1};
7462 // Copy region from bottom right to bottom left
7463 depthCopyRegion.imageCopy.srcOffset = {defaultHalfSize, defaultHalfSize, 0};
7464 depthCopyRegion.imageCopy.dstOffset = {0, defaultHalfSize, 0};
7465 depthRegions.push_back(depthCopyRegion);
7466 // Copy region from top right to bottom right
7467 depthCopyRegion.imageCopy.srcOffset = {defaultHalfSize, 0, 0};
7468 depthCopyRegion.imageCopy.dstOffset = {defaultHalfSize, defaultHalfSize, 0};
7469 depthRegions.push_back(depthCopyRegion);
7470 }
7471 if (testParameters.copyAspect & VK_IMAGE_ASPECT_STENCIL_BIT)
7472 {
7473 stencilCopyRegion.imageCopy.extent = {defaultHalfSize, defaultHalfSize, 1};
7474 // Copy region from bottom right to bottom left
7475 stencilCopyRegion.imageCopy.srcOffset = {defaultHalfSize, defaultHalfSize, 0};
7476 stencilCopyRegion.imageCopy.dstOffset = {0, defaultHalfSize, 0};
7477 stencilRegions.push_back(stencilCopyRegion);
7478 // Copy region from top right to bottom right
7479 stencilCopyRegion.imageCopy.srcOffset = {defaultHalfSize, 0, 0};
7480 stencilCopyRegion.imageCopy.dstOffset = {defaultHalfSize, defaultHalfSize, 0};
7481 stencilRegions.push_back(stencilCopyRegion);
7482 }
7483 }
7484 else
7485 {
7486 // Copy the default region (full image)
7487 if (testParameters.copyAspect & VK_IMAGE_ASPECT_DEPTH_BIT)
7488 {
7489 depthRegions.push_back(depthCopyRegion);
7490 }
7491 if (testParameters.copyAspect & VK_IMAGE_ASPECT_STENCIL_BIT)
7492 {
7493 stencilRegions.push_back(stencilCopyRegion);
7494 }
7495 }
7496
7497 if (testParameters.copyAspect & VK_IMAGE_ASPECT_DEPTH_BIT)
7498 {
7499 m_regions.insert(m_regions.end(), depthRegions.begin(), depthRegions.end());
7500 }
7501
7502 if (testParameters.copyAspect & VK_IMAGE_ASPECT_STENCIL_BIT)
7503 {
7504 m_regions.insert(m_regions.end(), stencilRegions.begin(), stencilRegions.end());
7505 }
7506 }
7507
iterate(void)7508 tcu::TestStatus DepthStencilMSAA::iterate (void)
7509 {
7510 const DeviceInterface& vk = m_context.getDeviceInterface();
7511 const InstanceInterface& vki = m_context.getInstanceInterface();
7512 const VkDevice vkDevice = m_context.getDevice();
7513 const VkPhysicalDevice vkPhysDevice = m_context.getPhysicalDevice();
7514 const VkQueue queue = m_context.getUniversalQueue();
7515 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
7516 Allocator& memAlloc = m_context.getDefaultAllocator();
7517 Move<VkCommandPool> cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
7518 Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
7519
7520 const tcu::TextureFormat srcTcuFormat = mapVkFormat(m_srcImage.format);
7521 const tcu::TextureFormat dstTcuFormat = mapVkFormat(m_dstImage.format);
7522 VkImageAspectFlags aspectFlags = getUsedImageAspects();
7523 deUint32 sourceArraySize = getArraySize(m_srcImage);
7524
7525 Move<VkImage> srcImage;
7526 de::MovePtr<Allocation> srcImageAlloc;
7527 Move<VkImage> dstImage;
7528 de::MovePtr<Allocation> dstImageAlloc;
7529
7530 // 1. Create the images and draw a triangle to the source image.
7531 {
7532 const VkComponentMapping componentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
7533 Move<VkShaderModule> vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
7534 Move<VkShaderModule> fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
7535 std::vector<tcu::Vec4> vertices;
7536 Move<VkBuffer> vertexBuffer;
7537 de::MovePtr<Allocation> vertexBufferAlloc;
7538 Move<VkPipelineLayout> pipelineLayout;
7539 Move<VkPipeline> graphicsPipeline;
7540 Move<VkRenderPass> renderPass;
7541
7542 // Create multisampled depth/stencil image (srcImage) and the copy destination image (dstImage).
7543 {
7544 VkImageCreateInfo multiSampledImageParams =
7545 {
7546 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
7547 DE_NULL, // const void* pNext;
7548 getCreateFlags(m_srcImage), // VkImageCreateFlags flags;
7549 m_srcImage.imageType, // VkImageType imageType;
7550 m_srcImage.format, // VkFormat format;
7551 getExtent3D(m_srcImage), // VkExtent3D extent;
7552 1u, // deUint32 mipLevels;
7553 getArraySize(m_srcImage), // deUint32 arrayLayers;
7554 m_params.samples, // VkSampleCountFlagBits samples;
7555 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
7556 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT // VkImageUsageFlags usage;
7557 | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
7558 | VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
7559 | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
7560 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
7561 1u, // deUint32 queueFamilyIndexCount;
7562 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
7563 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
7564 };
7565
7566 srcImage = createImage(vk, vkDevice, &multiSampledImageParams);
7567
7568 VkMemoryRequirements req = getImageMemoryRequirements(vk, vkDevice, *srcImage);
7569 deUint32 offset = m_params.imageOffset ? static_cast<deUint32>(req.alignment) : 0;
7570
7571 srcImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, srcImage.get(), MemoryRequirement::Any, memAlloc,
7572 m_params.allocationKind, offset);
7573 VK_CHECK(vk.bindImageMemory(vkDevice, srcImage.get(), srcImageAlloc->getMemory(), srcImageAlloc->getOffset() + offset));
7574
7575 dstImage = createImage(vk, vkDevice, &multiSampledImageParams);
7576 dstImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, dstImage.get(), MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
7577 VK_CHECK(vk.bindImageMemory(vkDevice, dstImage.get(), dstImageAlloc->getMemory(), dstImageAlloc->getOffset()));
7578 }
7579
7580 // Create render pass.
7581 {
7582 const VkImageLayout initialLayout = m_params.copyOptions == COPY_ARRAY_TO_ARRAY ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED;
7583 const VkAttachmentDescription attachmentDescription =
7584 {
7585 0u, // VkAttachmentDescriptionFlags flags
7586 m_srcImage.format, // VkFormat format
7587 m_params.samples, // VkSampleCountFlagBits samples
7588 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp
7589 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp
7590 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp stencilLoadOp
7591 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp
7592 initialLayout, // VkImageLayout initialLayout
7593 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout
7594 };
7595
7596 const VkAttachmentReference attachmentReference =
7597 {
7598 0u, // deUint32 attachment
7599 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout layout
7600 };
7601
7602 const VkSubpassDescription subpassDescription =
7603 {
7604 0u, // VkSubpassDescriptionFlags flags
7605 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint
7606 0u, // deUint32 inputAttachmentCount
7607 DE_NULL, // const VkAttachmentReference* pInputAttachments
7608 0u, // deUint32 colorAttachmentCount
7609 DE_NULL, // const VkAttachmentReference* pColorAttachments
7610 DE_NULL, // const VkAttachmentReference* pResolveAttachments
7611 &attachmentReference, // const VkAttachmentReference* pDepthStencilAttachment
7612 0u, // deUint32 preserveAttachmentCount
7613 DE_NULL // const VkAttachmentReference* pPreserveAttachments
7614 };
7615
7616 const VkRenderPassCreateInfo renderPassParams =
7617 {
7618 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
7619 DE_NULL, // const void* pNext;
7620 0u, // VkRenderPassCreateFlags flags;
7621 1u, // deUint32 attachmentCount;
7622 &attachmentDescription, // const VkAttachmentDescription* pAttachments;
7623 1u, // deUint32 subpassCount;
7624 &subpassDescription, // const VkSubpassDescription* pSubpasses;
7625 0u, // deUint32 dependencyCount;
7626 DE_NULL // const VkSubpassDependency* pDependencies;
7627 };
7628
7629 renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
7630 }
7631
7632 // Create pipeline layout
7633 {
7634 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
7635 {
7636 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
7637 DE_NULL, // const void* pNext;
7638 0u, // VkPipelineLayoutCreateFlags flags;
7639 0u, // deUint32 setLayoutCount;
7640 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
7641 0u, // deUint32 pushConstantRangeCount;
7642 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
7643 };
7644
7645 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
7646 }
7647
7648 // Create upper half triangle.
7649 {
7650 // Add triangle.
7651 vertices.emplace_back(-1.0f, -1.0f, 0.0f, 1.0f);
7652 vertices.emplace_back(1.0f, -1.0f, 0.0f, 1.0f);
7653 vertices.emplace_back(1.0f, 1.0f, 0.0f, 1.0f);
7654 }
7655
7656 // Create vertex buffer.
7657 {
7658 const VkDeviceSize vertexDataSize = vertices.size() * sizeof(tcu::Vec4);
7659 const VkBufferCreateInfo vertexBufferParams =
7660 {
7661 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
7662 DE_NULL, // const void* pNext;
7663 0u, // VkBufferCreateFlags flags;
7664 vertexDataSize, // VkDeviceSize size;
7665 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
7666 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
7667 1u, // deUint32 queueFamilyIndexCount;
7668 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
7669 };
7670
7671 vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
7672 vertexBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *vertexBuffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
7673 VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset()));
7674
7675 // Load vertices into vertex buffer.
7676 deMemcpy(vertexBufferAlloc->getHostPtr(), vertices.data(), (size_t)vertexDataSize);
7677 flushAlloc(vk, vkDevice, *vertexBufferAlloc);
7678 }
7679
7680 {
7681 Move<VkFramebuffer> framebuffer;
7682 Move<VkImageView> sourceAttachmentView;
7683
7684 // Create depth/stencil attachment view.
7685 {
7686 const uint32_t arrayLayer = m_params.copyOptions == COPY_ARRAY_TO_ARRAY ? 2u : 0u;
7687 const VkImageViewCreateInfo depthStencilAttachmentViewParams =
7688 {
7689 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
7690 DE_NULL, // const void* pNext;
7691 0u, // VkImageViewCreateFlags flags;
7692 *srcImage, // VkImage image;
7693 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
7694 m_srcImage.format, // VkFormat format;
7695 componentMappingRGBA, // VkComponentMapping components;
7696 { aspectFlags, 0u, 1u, arrayLayer, 1u } // VkImageSubresourceRange subresourceRange;
7697 };
7698 sourceAttachmentView = createImageView(vk, vkDevice, &depthStencilAttachmentViewParams);
7699 }
7700
7701 // Create framebuffer
7702 {
7703 const VkFramebufferCreateInfo framebufferParams =
7704 {
7705 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
7706 DE_NULL, // const void* pNext;
7707 0u, // VkFramebufferCreateFlags flags;
7708 *renderPass, // VkRenderPass renderPass;
7709 1u, // deUint32 attachmentCount;
7710 &sourceAttachmentView.get(), // const VkImageView* pAttachments;
7711 m_srcImage.extent.width, // deUint32 width;
7712 m_srcImage.extent.height, // deUint32 height;
7713 1u // deUint32 layers;
7714 };
7715
7716 framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
7717 }
7718
7719 // Create pipeline
7720 {
7721 const std::vector<VkViewport> viewports (1, makeViewport(m_srcImage.extent));
7722 const std::vector<VkRect2D> scissors (1, makeRect2D(m_srcImage.extent));
7723
7724 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
7725 {
7726 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
7727 DE_NULL, // const void* pNext;
7728 0u, // VkPipelineMultisampleStateCreateFlags flags;
7729 m_params.samples, // VkSampleCountFlagBits rasterizationSamples;
7730 VK_FALSE, // VkBool32 sampleShadingEnable;
7731 0.0f, // float minSampleShading;
7732 DE_NULL, // const VkSampleMask* pSampleMask;
7733 VK_FALSE, // VkBool32 alphaToCoverageEnable;
7734 VK_FALSE // VkBool32 alphaToOneEnable;
7735 };
7736
7737 const VkStencilOpState stencilOpState =
7738 {
7739 VK_STENCIL_OP_KEEP, // VkStencilOp failOp
7740 VK_STENCIL_OP_REPLACE, // VkStencilOp passOp
7741 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp
7742 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp
7743 0, // deUint32 compareMask
7744 0xFF, // deUint32 writeMask
7745 0xFF // deUint32 reference
7746 };
7747
7748 const VkPipelineDepthStencilStateCreateInfo depthStencilStateCreateInfoDefault =
7749 {
7750 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType
7751 DE_NULL, // const void* pNext
7752 0u, // VkPipelineDepthStencilStateCreateFlags flags
7753 aspectFlags & VK_IMAGE_ASPECT_DEPTH_BIT ? VK_TRUE : VK_FALSE, // VkBool32 depthTestEnable
7754 aspectFlags & VK_IMAGE_ASPECT_DEPTH_BIT ? VK_TRUE : VK_FALSE, // VkBool32 depthWriteEnable
7755 VK_COMPARE_OP_ALWAYS, // VkCompareOp depthCompareOp
7756 VK_FALSE, // VkBool32 depthBoundsTestEnable
7757 aspectFlags & VK_IMAGE_ASPECT_STENCIL_BIT ? VK_TRUE : VK_FALSE, // VkBool32 stencilTestEnable
7758 stencilOpState, // VkStencilOpState front
7759 stencilOpState, // VkStencilOpState back
7760 0.0f, // float minDepthBounds
7761 1.0f, // float maxDepthBounds
7762 };
7763
7764 graphicsPipeline = makeGraphicsPipeline(vk, // const DeviceInterface& vk
7765 vkDevice, // const VkDevice device
7766 *pipelineLayout, // const VkPipelineLayout pipelineLayout
7767 *vertexShaderModule, // const VkShaderModule vertexShaderModule
7768 DE_NULL, // const VkShaderModule tessellationControlModule
7769 DE_NULL, // const VkShaderModule tessellationEvalModule
7770 DE_NULL, // const VkShaderModule geometryShaderModule
7771 *fragmentShaderModule, // const VkShaderModule fragmentShaderModule
7772 *renderPass, // const VkRenderPass renderPass
7773 viewports, // const std::vector<VkViewport>& viewports
7774 scissors, // const std::vector<VkRect2D>& scissors
7775 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
7776 0u, // const deUint32 subpass
7777 0u, // const deUint32 patchControlPoints
7778 DE_NULL, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
7779 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
7780 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
7781 &depthStencilStateCreateInfoDefault); // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
7782 }
7783
7784 // Create command buffer
7785 {
7786 beginCommandBuffer(vk, *cmdBuffer, 0u);
7787
7788 const VkClearValue srcImageClearValue = makeClearValueDepthStencil(0.1f, 0x10);
7789
7790 // Change the layout of each layer of the depth / stencil image to VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL and clear the images.
7791 const VkClearValue copiedImageClearValue = makeClearValueDepthStencil(m_clearValue, (uint32_t)m_clearValue);
7792 const auto subResourceRange = makeImageSubresourceRange( // VkImageSubresourceRange subresourceRange
7793 (getAspectFlags(m_srcImage.format)), // VkImageAspectFlags aspectMask
7794 0u, // uint32_t baseMipLevel
7795 1u, // uint32_t levelCount
7796 0u, // uint32_t baseArrayLayer
7797 getArraySize(m_srcImage));
7798
7799 const VkImageMemoryBarrier preClearBarrier = makeImageMemoryBarrier(
7800 0u, // VkAccessFlags srcAccessMask
7801 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask
7802 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
7803 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout
7804 srcImage.get(), // VkImage image
7805 subResourceRange); // VkImageSubresourceRange subresourceRange
7806 std::vector<VkImageMemoryBarrier> preClearBarriers(2u, preClearBarrier);
7807 preClearBarriers[1].image = dstImage.get();
7808 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
7809 (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 2, preClearBarriers.data());
7810
7811 vk.cmdClearDepthStencilImage(
7812 *cmdBuffer, // VkCommandBuffer commandBuffer
7813 srcImage.get(), // VkImage image
7814 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout imageLayout
7815 &srcImageClearValue.depthStencil, // const VkClearDepthStencilValue* pDepthStencil
7816 1u, // uint32_t rangeCount
7817 &subResourceRange); // const VkImageSubresourceRange* pRanges
7818
7819 vk.cmdClearDepthStencilImage(
7820 *cmdBuffer, // VkCommandBuffer commandBuffer
7821 dstImage.get(), // VkImage image
7822 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout imageLayout
7823 &copiedImageClearValue.depthStencil, // const VkClearDepthStencilValue* pDepthStencil
7824 1u, // uint32_t rangeCount
7825 &subResourceRange); // const VkImageSubresourceRange* pRanges
7826
7827 // Post clear barrier
7828 const VkImageMemoryBarrier postClearBarrier = makeImageMemoryBarrier(
7829 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask
7830 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
7831 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout
7832 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout
7833 srcImage.get(), // VkImage image
7834 subResourceRange); // VkImageSubresourceRange subresourceRange
7835
7836 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
7837 (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postClearBarrier);
7838
7839 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(0, 0, m_srcImage.extent.width, m_srcImage.extent.height), 1u, &srcImageClearValue);
7840
7841 const VkDeviceSize vertexBufferOffset = 0u;
7842
7843 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
7844 vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
7845 vk.cmdDraw(*cmdBuffer, (deUint32)vertices.size(), 1, 0, 0);
7846
7847 endRenderPass(vk, *cmdBuffer);
7848 endCommandBuffer(vk, *cmdBuffer);
7849 }
7850
7851 submitCommandsAndWait (vk, vkDevice, queue, *cmdBuffer);
7852 m_context.resetCommandPoolForVKSC(vkDevice, *cmdPool);
7853 }
7854 }
7855
7856 // 2. Record a command buffer that contains the copy operation(s).
7857 beginCommandBuffer(vk, *cmdBuffer);
7858 {
7859 // Change the image layouts and synchronize the memory access before copying
7860 {
7861 const VkImageMemoryBarrier imageBarriers[] =
7862 {
7863 // srcImage
7864 makeImageMemoryBarrier(
7865 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
7866 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask
7867 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout
7868 m_srcImage.operationLayout, // VkImageLayout newLayout
7869 srcImage.get(), // VkImage image
7870 makeImageSubresourceRange( // VkImageSubresourceRange subresourceRange
7871 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask
7872 0u, // deUint32 baseMipLevel
7873 1u, // deUint32 levelCount
7874 0u, // deUint32 baseArrayLayer
7875 sourceArraySize // deUint32 layerCount
7876 )),
7877 // dstImage
7878 makeImageMemoryBarrier(
7879 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask
7880 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask
7881 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout
7882 m_dstImage.operationLayout, // VkImageLayout newLayout
7883 dstImage.get(), // VkImage image
7884 makeImageSubresourceRange( // VkImageSubresourceRange subresourceRange
7885 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask
7886 0u, // deUint32 baseMipLevel
7887 1u, // deUint32 levelCount
7888 0u, // deUint32 baseArrayLayer
7889 sourceArraySize // deUint32 layerCount
7890 )),
7891 };
7892 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
7893 (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 2u, imageBarriers);
7894 }
7895
7896 std::vector<VkImageCopy> imageCopies;
7897 std::vector<VkImageCopy2KHR> imageCopies2KHR;
7898 for (const auto & region : m_regions)
7899 {
7900 if (m_params.extensionUse == EXTENSION_USE_NONE)
7901 {
7902 imageCopies.push_back(region.imageCopy);
7903 }
7904 else
7905 {
7906 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
7907 imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(region.imageCopy));
7908 }
7909 }
7910
7911 if (m_params.extensionUse == EXTENSION_USE_NONE)
7912 {
7913 vk.cmdCopyImage(*cmdBuffer, srcImage.get(), m_srcImage.operationLayout, dstImage.get(), m_dstImage.operationLayout, (deUint32)imageCopies.size(), imageCopies.data());
7914 }
7915 #ifndef CTS_USES_VULKANSC
7916 else
7917 {
7918 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
7919 const VkCopyImageInfo2KHR copyImageInfo2KHR =
7920 {
7921 VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR, // VkStructureType sType;
7922 DE_NULL, // const void* pNext;
7923 srcImage.get(), // VkImage srcImage;
7924 m_srcImage.operationLayout, // VkImageLayout srcImageLayout;
7925 dstImage.get(), // VkImage dstImage;
7926 m_dstImage.operationLayout, // VkImageLayout dstImageLayout;
7927 (deUint32)imageCopies2KHR.size(), // uint32_t regionCount;
7928 imageCopies2KHR.data() // const VkImageCopy2KHR* pRegions;
7929 };
7930
7931 vk.cmdCopyImage2(*cmdBuffer, ©ImageInfo2KHR);
7932 }
7933 #endif // CTS_USES_VULKANSC
7934 }
7935 endCommandBuffer(vk, *cmdBuffer);
7936 submitCommandsAndWait (vk, vkDevice, queue, *cmdBuffer);
7937 m_context.resetCommandPoolForVKSC(vkDevice, *cmdPool);
7938
7939 // Verify that all samples have been copied properly from all aspects.
7940 const auto usedImageAspects = getUsedImageAspects();
7941 if (usedImageAspects & VK_IMAGE_ASPECT_DEPTH_BIT)
7942 {
7943 auto copyResult = checkCopyResults(cmdBuffer.get(), VK_IMAGE_ASPECT_DEPTH_BIT, srcImage.get(), dstImage.get());
7944 if (copyResult.getCode() != QP_TEST_RESULT_PASS)
7945 return copyResult;
7946 }
7947 if (usedImageAspects & VK_IMAGE_ASPECT_STENCIL_BIT)
7948 {
7949 auto copyResult = checkCopyResults(cmdBuffer.get(), VK_IMAGE_ASPECT_STENCIL_BIT, srcImage.get(), dstImage.get());
7950 if (copyResult.getCode() != QP_TEST_RESULT_PASS)
7951 return copyResult;
7952 }
7953 return tcu::TestStatus::pass("pass");
7954 }
7955
checkCopyResults(VkCommandBuffer cmdBuffer,const VkImageAspectFlagBits & aspectToVerify,VkImage srcImage,VkImage dstImage)7956 tcu::TestStatus DepthStencilMSAA::checkCopyResults (VkCommandBuffer cmdBuffer, const VkImageAspectFlagBits& aspectToVerify, VkImage srcImage, VkImage dstImage)
7957 {
7958 DE_ASSERT((aspectToVerify & VK_IMAGE_ASPECT_DEPTH_BIT) || (aspectToVerify & VK_IMAGE_ASPECT_STENCIL_BIT));
7959
7960 const auto& vkd = m_context.getDeviceInterface();
7961 const auto device = m_context.getDevice();
7962 const auto queue = m_context.getUniversalQueue();
7963 auto& alloc = m_context.getDefaultAllocator();
7964 const auto layerCount = getArraySize(m_srcImage);
7965 const auto numInputAttachments = layerCount + 1u; // +1 for the source image.
7966 const auto numOutputBuffers = 2u; // 1 for the reference and 1 for the copied values.
7967 const auto numSets = 2u; // 1 for the output buffers, 1 for the input attachments.
7968 const auto fbWidth = m_srcImage.extent.width;
7969 const auto fbHeight = m_srcImage.extent.height;
7970 const auto aspectFlags = getUsedImageAspects();
7971
7972 // Shader modules.
7973 const auto vertexModule = createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
7974 const auto verificationModule = createShaderModule(vkd, device, m_context.getBinaryCollection().get(aspectToVerify & VK_IMAGE_ASPECT_DEPTH_BIT ? "verify_depth" : "verify_stencil"), 0u);
7975
7976 // Descriptor sets.
7977 DescriptorPoolBuilder poolBuilder;
7978 poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, numOutputBuffers);
7979 poolBuilder.addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, numInputAttachments);
7980 const auto descriptorPool = poolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, numSets);
7981
7982 DescriptorSetLayoutBuilder layoutBuilderBuffer;
7983 layoutBuilderBuffer.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
7984 layoutBuilderBuffer.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
7985 const auto outputBufferSetLayout = layoutBuilderBuffer.build(vkd, device);
7986
7987 DescriptorSetLayoutBuilder layoutBuilderAttachments;
7988 for (deUint32 i = 0u; i < numInputAttachments; ++i)
7989 layoutBuilderAttachments.addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT);
7990 const auto inputAttachmentsSetLayout = layoutBuilderAttachments.build(vkd, device);
7991
7992 const auto descriptorSetBuffer = makeDescriptorSet(vkd, device, descriptorPool.get(), outputBufferSetLayout.get());
7993 const auto descriptorSetAttachments = makeDescriptorSet(vkd, device, descriptorPool.get(), inputAttachmentsSetLayout.get());
7994
7995 // Array with raw descriptor sets.
7996 const std::array<VkDescriptorSet, numSets> descriptorSets =
7997 {{
7998 descriptorSetBuffer.get(),
7999 descriptorSetAttachments.get(),
8000 }};
8001
8002 // Pipeline layout.
8003 const std::array<VkDescriptorSetLayout, numSets> setLayouts =
8004 {{
8005 outputBufferSetLayout.get(),
8006 inputAttachmentsSetLayout.get(),
8007 }};
8008
8009 // Push constants.
8010 std::array<int, 3> pushConstantData =
8011 {{
8012 static_cast<int>(fbWidth),
8013 static_cast<int>(fbHeight),
8014 static_cast<int>(m_params.samples),
8015 }};
8016
8017 const auto pushConstantSize = static_cast<deUint32>(pushConstantData.size() * sizeof(decltype(pushConstantData)::value_type));
8018
8019 const VkPushConstantRange pushConstantRange =
8020 {
8021 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
8022 0u, // deUint32 offset;
8023 pushConstantSize, // deUint32 size;
8024 };
8025
8026 const VkPipelineLayoutCreateInfo pipelineLayoutInfo =
8027 {
8028 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
8029 nullptr, // const void* pNext;
8030 0u, // VkPipelineLayoutCreateFlags flags;
8031 static_cast<deUint32>(setLayouts.size()), // deUint32 setLayoutCount;
8032 setLayouts.data(), // const VkDescriptorSetLayout* pSetLayouts;
8033 1u, // deUint32 pushConstantRangeCount;
8034 &pushConstantRange, // const VkPushConstantRange* pPushConstantRanges;
8035 };
8036
8037 const auto pipelineLayout = createPipelineLayout(vkd, device, &pipelineLayoutInfo);
8038
8039 // Render pass.
8040 const VkAttachmentDescription commonAttachmentDescription =
8041 {
8042 0u, // VkAttachmentDescriptionFlags flags;
8043 m_srcImage.format, // VkFormat format;
8044 m_params.samples, // VkSampleCountFlagBits samples;
8045 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
8046 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
8047 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
8048 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
8049 m_dstImage.operationLayout, // VkImageLayout initialLayout;
8050 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout finalLayout;
8051 };
8052
8053 std::vector<VkAttachmentDescription> attachmentDescriptions(numInputAttachments, commonAttachmentDescription);
8054 // Set the first attachment's (m_srcImage) initial layout to match the layout it was left after copying.
8055 attachmentDescriptions[0].initialLayout = m_srcImage.operationLayout;
8056
8057 std::vector<VkAttachmentReference> inputAttachmentReferences;
8058 inputAttachmentReferences.reserve(numInputAttachments);
8059 for (deUint32 i = 0u; i < numInputAttachments; ++i)
8060 {
8061 const VkAttachmentReference reference = { i, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL };
8062 inputAttachmentReferences.push_back(reference);
8063 }
8064
8065 const VkSubpassDescription subpassDescription =
8066 {
8067 0u, // VkSubpassDescriptionFlags flags;
8068 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
8069 static_cast<deUint32>(inputAttachmentReferences.size()), // deUint32 inputAttachmentCount;
8070 inputAttachmentReferences.data(), // const VkAttachmentReference* pInputAttachments;
8071 0u, // deUint32 colorAttachmentCount;
8072 nullptr, // const VkAttachmentReference* pColorAttachments;
8073 nullptr, // const VkAttachmentReference* pResolveAttachments;
8074 nullptr, // const VkAttachmentReference* pDepthStencilAttachment;
8075 0u, // deUint32 preserveAttachmentCount;
8076 nullptr, // const deUint32* pPreserveAttachments;
8077 };
8078
8079 const VkRenderPassCreateInfo renderPassInfo =
8080 {
8081 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
8082 nullptr, // const void* pNext;
8083 0u, // VkRenderPassCreateFlags flags;
8084 static_cast<deUint32>(attachmentDescriptions.size()), // deUint32 attachmentCount;
8085 attachmentDescriptions.data(), // const VkAttachmentDescription* pAttachments;
8086 1u, // deUint32 subpassCount;
8087 &subpassDescription, // const VkSubpassDescription* pSubpasses;
8088 0u, // deUint32 dependencyCount;
8089 nullptr, // const VkSubpassDependency* pDependencies;
8090 };
8091
8092 const auto renderPass = createRenderPass(vkd, device, &renderPassInfo);
8093
8094 // Framebuffer.
8095 std::vector<Move<VkImageView>> imageViews;
8096 std::vector<VkImageView> imageViewsRaw;
8097
8098 const uint32_t srcArrayLayer = m_params.copyOptions == COPY_ARRAY_TO_ARRAY ? 2u : 0u;
8099 imageViews.push_back(makeImageView(vkd, device, srcImage, VK_IMAGE_VIEW_TYPE_2D, m_srcImage.format, makeImageSubresourceRange(aspectFlags, 0u, 1u, srcArrayLayer, 1u)));
8100 for (deUint32 i = 0u; i < layerCount; ++i)
8101 {
8102 const auto subresourceRange = makeImageSubresourceRange(aspectFlags, 0u, 1u, i, 1u);
8103 imageViews.push_back(makeImageView(vkd, device, dstImage, VK_IMAGE_VIEW_TYPE_2D, m_srcImage.format, subresourceRange));
8104 }
8105
8106 imageViewsRaw.reserve(imageViews.size());
8107 std::transform(begin(imageViews), end(imageViews), std::back_inserter(imageViewsRaw), [](const Move<VkImageView>& ptr) { return ptr.get(); });
8108
8109 const auto framebuffer = makeFramebuffer(vkd, device, renderPass.get(), static_cast<deUint32>(imageViewsRaw.size()), imageViewsRaw.data(), fbWidth, fbHeight);
8110
8111 // Create storage buffers for both original and copied multisampled depth/stencil images.
8112 const auto bufferCount = static_cast<size_t>(fbWidth * fbHeight * m_params.samples);
8113 const auto bufferSize = static_cast<VkDeviceSize>(bufferCount * sizeof(float));
8114 BufferWithMemory bufferOriginal (vkd, device, alloc, makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible);
8115 BufferWithMemory bufferCopied (vkd, device, alloc, makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible);
8116 auto& bufferOriginalAlloc = bufferOriginal.getAllocation();
8117 auto& bufferCopiedAlloc = bufferCopied.getAllocation();
8118
8119 // Update descriptor sets.
8120 DescriptorSetUpdateBuilder updater;
8121
8122 const auto bufferOriginalInfo = makeDescriptorBufferInfo(bufferOriginal.get(), 0ull, bufferSize);
8123 const auto bufferCopiedInfo = makeDescriptorBufferInfo(bufferCopied.get(), 0ull, bufferSize);
8124 updater.writeSingle(descriptorSetBuffer.get(), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferOriginalInfo);
8125 updater.writeSingle(descriptorSetBuffer.get(), DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferCopiedInfo);
8126
8127 std::vector<VkDescriptorImageInfo> imageInfos;
8128 imageInfos.reserve(imageViewsRaw.size());
8129 for (size_t i = 0; i < imageViewsRaw.size(); ++i)
8130 {
8131 imageInfos.push_back(makeDescriptorImageInfo(DE_NULL, imageViewsRaw[i], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL));
8132 updater.writeSingle(descriptorSetAttachments.get(), DescriptorSetUpdateBuilder::Location::binding(static_cast<deUint32>(i)), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &imageInfos[i]);
8133 }
8134
8135 updater.update(vkd, device);
8136
8137 // Vertex buffer.
8138 std::vector<tcu::Vec4> fullScreenQuad;
8139 {
8140 // Full screen quad so every framebuffer pixel and sample location is verified by the shader.
8141 const tcu::Vec4 topLeft (-1.0f, -1.0f, 0.0f, 1.0f);
8142 const tcu::Vec4 topRight ( 1.0f, -1.0f, 0.0f, 1.0f);
8143 const tcu::Vec4 bottomLeft (-1.0f, 1.0f, 0.0f, 1.0f);
8144 const tcu::Vec4 bottomRight ( 1.0f, 1.0f, 0.0f, 1.0f);
8145
8146 fullScreenQuad.reserve(6u);
8147 fullScreenQuad.push_back(topLeft);
8148 fullScreenQuad.push_back(topRight);
8149 fullScreenQuad.push_back(bottomRight);
8150 fullScreenQuad.push_back(topLeft);
8151 fullScreenQuad.push_back(bottomRight);
8152 fullScreenQuad.push_back(bottomLeft);
8153 }
8154
8155 const auto vertexBufferSize = static_cast<VkDeviceSize>(fullScreenQuad.size() * sizeof(decltype(fullScreenQuad)::value_type));
8156 const auto vertexBufferInfo = makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
8157 const BufferWithMemory vertexBuffer (vkd, device, alloc, vertexBufferInfo, MemoryRequirement::HostVisible);
8158 const VkDeviceSize vertexBufferOffset = 0ull;
8159
8160 deMemcpy(vertexBuffer.getAllocation().getHostPtr(), fullScreenQuad.data(), static_cast<size_t>(vertexBufferSize));
8161 flushAlloc(vkd, device, vertexBuffer.getAllocation());
8162
8163 // Graphics pipeline.
8164 const std::vector<VkViewport> viewports (1, makeViewport(m_srcImage.extent));
8165 const std::vector<VkRect2D> scissors (1, makeRect2D(m_srcImage.extent));
8166
8167 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
8168 {
8169 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
8170 nullptr, // const void* pNext;
8171 0u, // VkPipelineMultisampleStateCreateFlags flags;
8172 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
8173 VK_FALSE, // VkBool32 sampleShadingEnable;
8174 0.0f, // float minSampleShading;
8175 nullptr, // const VkSampleMask* pSampleMask;
8176 VK_FALSE, // VkBool32 alphaToCoverageEnable;
8177 VK_FALSE // VkBool32 alphaToOneEnable;
8178 };
8179
8180 const auto graphicsPipeline = makeGraphicsPipeline(
8181 vkd, // const DeviceInterface& vk
8182 device, // const VkDevice device
8183 pipelineLayout.get(), // const VkPipelineLayout pipelineLayout
8184 vertexModule.get(), // const VkShaderModule vertexShaderModule
8185 DE_NULL, // const VkShaderModule tessellationControlModule
8186 DE_NULL, // const VkShaderModule tessellationEvalModule
8187 DE_NULL, // const VkShaderModule geometryShaderModule
8188 verificationModule.get(), // const VkShaderModule fragmentShaderModule
8189 renderPass.get(), // const VkRenderPass renderPass
8190 viewports, // const std::vector<VkViewport>& viewports
8191 scissors, // const std::vector<VkRect2D>& scissors
8192 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
8193 0u, // const deUint32 subpass
8194 0u, // const deUint32 patchControlPoints
8195 nullptr, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
8196 nullptr, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
8197 &multisampleStateParams); // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
8198
8199 // Make sure multisample copy data is available to the fragment shader.
8200 const auto imagesBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT);
8201
8202 // Record and submit command buffer.
8203 beginCommandBuffer(vkd, cmdBuffer);
8204 vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 1u, &imagesBarrier, 0u, nullptr, 0u, nullptr);
8205 beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffer.get(), makeRect2D(m_srcImage.extent));
8206 vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline.get());
8207 vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
8208
8209 vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), VK_SHADER_STAGE_FRAGMENT_BIT, 0u, pushConstantSize, pushConstantData.data());
8210 vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u, static_cast<deUint32>(descriptorSets.size()), descriptorSets.data(), 0u, nullptr);
8211 vkd.cmdDraw(cmdBuffer, static_cast<deUint32>(fullScreenQuad.size()), 1u, 0u, 0u);
8212
8213 endRenderPass(vkd, cmdBuffer);
8214
8215 // Make sure verification buffer data is available on the host.
8216 const auto bufferBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
8217 vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &bufferBarrier, 0u, nullptr, 0u, nullptr);
8218 endCommandBuffer(vkd, cmdBuffer);
8219 submitCommandsAndWait(vkd, device, queue, cmdBuffer);
8220
8221 // Verify intermediate results.
8222 invalidateAlloc(vkd, device, bufferOriginalAlloc);
8223 invalidateAlloc(vkd, device, bufferCopiedAlloc);
8224 std::vector<float> outputOriginal (bufferCount, 0);
8225 std::vector<float> outputCopied (bufferCount, 0);
8226 deMemcpy(outputOriginal.data(), bufferOriginalAlloc.getHostPtr(), static_cast<size_t>(bufferSize));
8227 deMemcpy(outputCopied.data(), bufferCopiedAlloc.getHostPtr(), static_cast<size_t>(bufferSize));
8228
8229 auto& log = m_context.getTestContext().getLog();
8230 log << tcu::TestLog::Message << "Verifying intermediate multisample copy results" << tcu::TestLog::EndMessage;
8231
8232 const auto sampleCount = static_cast<deUint32>(m_params.samples);
8233
8234 // Verify copied region(s)
8235 for (const auto ®ion : m_regions)
8236 {
8237 for (uint32_t x = 0u; x < region.imageCopy.extent.width; ++x)
8238 for (uint32_t y = 0u; y < region.imageCopy.extent.height; ++y)
8239 for (uint32_t s = 0u; s < sampleCount; ++s)
8240 {
8241 tcu::UVec2 srcCoord(x + region.imageCopy.srcOffset.x, y + region.imageCopy.srcOffset.y);
8242 tcu::UVec2 dstCoord(x + region.imageCopy.dstOffset.x, y + region.imageCopy.dstOffset.y);
8243 const auto srcIndex = (srcCoord.y() * fbWidth + srcCoord.x()) * sampleCount + s;
8244 const auto dstIndex = (dstCoord.y() * fbWidth + dstCoord.x()) * sampleCount + s;
8245 if (outputOriginal[srcIndex] != outputCopied[dstIndex])
8246 {
8247 std::ostringstream msg;
8248 msg << "Intermediate verification failed for coordinates (" << x << ", " << y << ") sample " << s << ". "
8249 << "result: " << outputCopied[dstIndex] << " expected: " << outputOriginal[srcIndex];
8250 return tcu::TestStatus::fail(msg.str());
8251 }
8252 }
8253 }
8254
8255 if (m_params.copyOptions == COPY_PARTIAL)
8256 {
8257 // In the partial copy tests the destination image contains copied data only in the bottom half of the image.
8258 // Verify that the upper half of the image is left at it's clear value (0).
8259 for (uint32_t x = 0u; x < m_srcImage.extent.width; x++)
8260 for (uint32_t y = 0u; y < m_srcImage.extent.height / 2; y++)
8261 for (uint32_t s = 0u; s < sampleCount; ++s)
8262 {
8263 const auto bufferIndex = (y * fbWidth + x) * sampleCount + s;
8264 if (outputCopied[bufferIndex] != m_clearValue)
8265 {
8266 std::ostringstream msg;
8267 msg << "Intermediate verification failed for coordinates (" << x << ", " << y << ") sample " << s << ". "
8268 << "result: " << outputCopied[bufferIndex] << " expected: 0.0" ;
8269 return tcu::TestStatus::fail(msg.str());
8270 }
8271 }
8272 }
8273
8274 log << tcu::TestLog::Message << "Intermediate multisample copy verification passed" << tcu::TestLog::EndMessage;
8275 return tcu::TestStatus::pass("Pass");
8276 }
8277
8278 class DepthStencilMSAATestCase : public vkt::TestCase
8279 {
8280 public:
DepthStencilMSAATestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const DepthStencilMSAA::TestParameters testParams)8281 DepthStencilMSAATestCase (tcu::TestContext& testCtx,
8282 const std::string& name,
8283 const std::string& description,
8284 const DepthStencilMSAA::TestParameters testParams)
8285 : vkt::TestCase (testCtx, name, description)
8286 , m_params (testParams)
8287 {}
8288
8289 virtual void initPrograms (SourceCollections& programCollection) const;
8290
createInstance(Context & context) const8291 virtual TestInstance* createInstance (Context& context) const
8292 {
8293 return new DepthStencilMSAA(context, m_params);
8294 }
8295
checkSupport(Context & context) const8296 virtual void checkSupport (Context& context) const
8297 {
8298 const VkSampleCountFlagBits rasterizationSamples = m_params.samples;
8299
8300 if (!context.getDeviceFeatures().fragmentStoresAndAtomics)
8301 TCU_THROW(NotSupportedError, "fragmentStoresAndAtomics not supported");
8302
8303 if ((m_params.copyAspect & VK_IMAGE_ASPECT_DEPTH_BIT) && !(context.getDeviceProperties().limits.framebufferDepthSampleCounts & rasterizationSamples))
8304 TCU_THROW(NotSupportedError, "Unsupported number of depth samples");
8305
8306 if ((m_params.copyAspect & VK_IMAGE_ASPECT_STENCIL_BIT) && !(context.getDeviceProperties().limits.framebufferDepthSampleCounts & rasterizationSamples))
8307 TCU_THROW(NotSupportedError, "Unsupported number of stencil samples");
8308
8309 VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
8310 | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
8311 | VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
8312 | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
8313
8314 VkImageFormatProperties properties;
8315 if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
8316 m_params.imageFormat,
8317 VK_IMAGE_TYPE_2D,
8318 VK_IMAGE_TILING_OPTIMAL,
8319 usageFlags, 0,
8320 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
8321 {
8322 TCU_THROW(NotSupportedError, "Format not supported");
8323 }
8324
8325 if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
8326 (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
8327 {
8328 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
8329 }
8330 }
8331
8332 private:
8333
getArrayLayerCount() const8334 uint32_t getArrayLayerCount () const
8335 {
8336 return (m_params.copyOptions == DepthStencilMSAA::COPY_ARRAY_TO_ARRAY) ? 5u : 1u;
8337 }
8338
createVerificationShader(std::ostringstream & shaderCode,const VkImageAspectFlagBits attachmentAspect) const8339 void createVerificationShader (std::ostringstream& shaderCode, const VkImageAspectFlagBits attachmentAspect) const
8340 {
8341 DE_ASSERT(attachmentAspect & (VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT));
8342 // The shader copies the sample values from the source and destination image to output buffers OriginalValue and
8343 // CopiedValues, respectively. If the dst image contains multiple array layers, only one layer has the copied data
8344 // and the rest should be filled with the clear value (0). This is also verified in this shader.
8345 // Array layer cases need an image view per layer in the copied image.
8346 // Set 0 contains the output buffers.
8347 // Set 1 contains the input attachments.
8348
8349 std::string inputAttachmentPrefix = attachmentAspect == VK_IMAGE_ASPECT_STENCIL_BIT ? "u" : "";
8350
8351 shaderCode
8352 << "#version 450\n"
8353 << "\n"
8354 << "layout (push_constant, std430) uniform PushConstants {\n"
8355 << " int width;\n"
8356 << " int height;\n"
8357 << " int samples;\n"
8358 << "};\n"
8359 << "layout (set=0, binding=0) buffer OriginalValues {\n"
8360 << " float outputOriginal[];\n"
8361 << "};\n"
8362 << "layout (set=0, binding=1) buffer CopiedValues {\n"
8363 << " float outputCopied[];\n"
8364 << "};\n"
8365 << "layout (input_attachment_index=0, set=1, binding=0) uniform " << inputAttachmentPrefix << "subpassInputMS attachment0;\n"
8366 ;
8367
8368 const auto layerCount = getArrayLayerCount();
8369 for (deUint32 layerNdx = 0u; layerNdx < layerCount; ++layerNdx)
8370 {
8371 const auto i = layerNdx + 1u;
8372 shaderCode << "layout (input_attachment_index=" << i << ", set=1, binding=" << i << ") uniform " << inputAttachmentPrefix << "subpassInputMS attachment" << i << ";\n";
8373 }
8374
8375 // Using a loop to iterate over each sample avoids the need for the sampleRateShading feature. The pipeline needs to be
8376 // created with a single sample.
8377 shaderCode
8378 << "\n"
8379 << "void main() {\n"
8380 << " for (int sampleID = 0; sampleID < samples; ++sampleID) {\n"
8381 << " ivec3 coords = ivec3(int(gl_FragCoord.x), int(gl_FragCoord.y), sampleID);\n"
8382 << " int bufferPos = (coords.y * width + coords.x) * samples + coords.z;\n"
8383 << " " << inputAttachmentPrefix << "vec4 orig = subpassLoad(attachment0, sampleID);\n"
8384 << " outputOriginal[bufferPos] = orig.r;\n"
8385 ;
8386
8387 for (deUint32 layerNdx = 0u; layerNdx < layerCount; ++layerNdx)
8388 {
8389 const auto i = layerNdx + 1u;
8390 shaderCode << " " << inputAttachmentPrefix << "vec4 copy" << i << " = subpassLoad(attachment" << i << ", sampleID);\n";
8391 }
8392
8393 std::ostringstream testCondition;
8394 std::string layerToVerify = m_params.copyOptions == DepthStencilMSAA::COPY_ARRAY_TO_ARRAY ? "copy4" : "copy1";
8395 shaderCode
8396 << "\n"
8397 << " outputCopied[bufferPos] = " << layerToVerify << ".r; \n";
8398
8399 if (m_params.copyOptions == DepthStencilMSAA::COPY_ARRAY_TO_ARRAY)
8400 {
8401 // 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.
8402 // This verifies that all the samples in the other layers have proper values.
8403 shaderCode << " bool equalEmptyLayers = ";
8404 for (deUint32 layerNdx = 0u; layerNdx < layerCount; ++layerNdx)
8405 {
8406 if (layerNdx == 3)
8407 continue;
8408 const auto i = layerNdx + 1u;
8409 shaderCode << "copy" << i << ".r == " << (attachmentAspect == VK_IMAGE_ASPECT_STENCIL_BIT ? "0" : "0.0") << (layerNdx < 4u ? " && " : ";\n");
8410 }
8411 shaderCode
8412 << " if (!equalEmptyLayers)\n"
8413 << " outputCopied[bufferPos]--; \n";
8414 }
8415
8416 shaderCode
8417 << " }\n"
8418 << "}\n";
8419 }
8420
8421 DepthStencilMSAA::TestParameters m_params;
8422 };
8423
initPrograms(SourceCollections & programCollection) const8424 void DepthStencilMSAATestCase::initPrograms (SourceCollections& programCollection) const
8425 {
8426 programCollection.glslSources.add("vert") << glu::VertexSource(
8427 "#version 310 es\n"
8428 "layout (location = 0) in highp vec4 a_position;\n"
8429 "void main()\n"
8430 "{\n"
8431 " gl_Position = vec4(a_position.xy, 1.0, 1.0);\n"
8432 "}\n");
8433
8434 programCollection.glslSources.add("frag") << glu::FragmentSource(
8435 "#version 310 es\n"
8436 "void main()\n"
8437 "{}\n");
8438
8439 // Create the verifying shader for the depth aspect if the depth is used.
8440 if (m_params.copyAspect & VK_IMAGE_ASPECT_DEPTH_BIT)
8441 {
8442 std::ostringstream verificationShader;
8443 // All the depth formats are float types, so the input attachment prefix is not used.
8444 createVerificationShader(verificationShader, VK_IMAGE_ASPECT_DEPTH_BIT);
8445 programCollection.glslSources.add("verify_depth") << glu::FragmentSource(verificationShader.str());
8446 }
8447
8448 // Create the verifying shader for the stencil aspect if the stencil is used.
8449 if (m_params.copyAspect & VK_IMAGE_ASPECT_STENCIL_BIT)
8450 {
8451 std::ostringstream verificationShader;
8452 // All the stencil formats are uint types, so the input attachment prefix is "u".
8453 createVerificationShader(verificationShader, VK_IMAGE_ASPECT_STENCIL_BIT);
8454 programCollection.glslSources.add("verify_stencil") << glu::FragmentSource(verificationShader.str());
8455 }
8456 }
8457
8458 struct BufferOffsetParams
8459 {
8460 static constexpr deUint32 kMaxOffset = 8u;
8461
8462 deUint32 srcOffset;
8463 deUint32 dstOffset;
8464 };
8465
checkZerosAt(const std::vector<deUint8> & bufferData,deUint32 from,deUint32 count)8466 void checkZerosAt(const std::vector<deUint8>& bufferData, deUint32 from, deUint32 count)
8467 {
8468 constexpr deUint8 zero{0};
8469 for (deUint32 i = 0; i < count; ++i)
8470 {
8471 const auto& val = bufferData[from + i];
8472 if (val != zero)
8473 {
8474 std::ostringstream msg;
8475 msg << "Unexpected non-zero byte found at position " << (from + i) << ": " << static_cast<int>(val);
8476 TCU_FAIL(msg.str());
8477 }
8478 }
8479 }
8480
bufferOffsetTest(Context & ctx,BufferOffsetParams params)8481 tcu::TestStatus bufferOffsetTest (Context& ctx, BufferOffsetParams params)
8482 {
8483 // 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.
8484 constexpr auto kMaxOffset = BufferOffsetParams::kMaxOffset;
8485 constexpr auto kBlockSize = kMaxOffset * 2u;
8486 constexpr auto kBufferSize = kMaxOffset * kBlockSize;
8487
8488 DE_ASSERT(params.srcOffset < kMaxOffset);
8489 DE_ASSERT(params.dstOffset < kMaxOffset);
8490
8491 const auto& vkd = ctx.getDeviceInterface();
8492 const auto device = ctx.getDevice();
8493 auto& alloc = ctx.getDefaultAllocator();
8494 const auto qIndex = ctx.getUniversalQueueFamilyIndex();
8495 const auto queue = ctx.getUniversalQueue();
8496
8497 const auto srcBufferInfo = makeBufferCreateInfo(kBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
8498 const auto dstBufferInfo = makeBufferCreateInfo(kBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
8499
8500 BufferWithMemory srcBuffer (vkd, device, alloc, srcBufferInfo, MemoryRequirement::HostVisible);
8501 BufferWithMemory dstBuffer (vkd, device, alloc, dstBufferInfo, MemoryRequirement::HostVisible);
8502 auto& srcAlloc = srcBuffer.getAllocation();
8503 auto& dstAlloc = dstBuffer.getAllocation();
8504
8505 // Zero-out destination buffer.
8506 deMemset(dstAlloc.getHostPtr(), 0, kBufferSize);
8507 flushAlloc(vkd, device, dstAlloc);
8508
8509 // Fill source buffer with nonzero bytes.
8510 std::vector<deUint8> srcData;
8511 srcData.reserve(kBufferSize);
8512 for (deUint32 i = 0; i < kBufferSize; ++i)
8513 srcData.push_back(static_cast<deUint8>(100u + i));
8514 deMemcpy(srcAlloc.getHostPtr(), srcData.data(), de::dataSize(srcData));
8515 flushAlloc(vkd, device, srcAlloc);
8516
8517 // Copy regions.
8518 std::vector<VkBufferCopy> copies;
8519 copies.reserve(kMaxOffset);
8520 for (deUint32 i = 0; i < kMaxOffset; ++i)
8521 {
8522 const auto blockStart = kBlockSize * i;
8523 const auto copySize = i + 1u;
8524 const auto bufferCopy = makeBufferCopy(params.srcOffset + blockStart, params.dstOffset + blockStart, copySize);
8525 copies.push_back(bufferCopy);
8526 }
8527
8528 const auto cmdPool = makeCommandPool(vkd, device, qIndex);
8529 const auto cmdBufferPtr = allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
8530 const auto cmdBuffer = cmdBufferPtr.get();
8531
8532 beginCommandBuffer(vkd, cmdBuffer);
8533 vkd.cmdCopyBuffer(cmdBuffer, srcBuffer.get(), dstBuffer.get(), static_cast<deUint32>(copies.size()), copies.data());
8534 const auto barrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
8535 vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &barrier, 0u, nullptr, 0u, nullptr);
8536 endCommandBuffer(vkd, cmdBuffer);
8537 submitCommandsAndWait(vkd, device, queue, cmdBuffer);
8538 invalidateAlloc(vkd, device, dstAlloc);
8539
8540 // Verify destination buffer data.
8541 std::vector<deUint8> dstData(kBufferSize);
8542 deMemcpy(dstData.data(), dstAlloc.getHostPtr(), de::dataSize(dstData));
8543
8544 for (deUint32 blockIdx = 0; blockIdx < kMaxOffset; ++blockIdx)
8545 {
8546 const auto blockStart = kBlockSize * blockIdx;
8547 const auto copySize = blockIdx + 1u;
8548
8549 // Verify no data has been written before dstOffset.
8550 checkZerosAt(dstData, blockStart, params.dstOffset);
8551
8552 // Verify copied block.
8553 for (deUint32 i = 0; i < copySize; ++i)
8554 {
8555 const auto& dstVal = dstData[blockStart + params.dstOffset + i];
8556 const auto& srcVal = srcData[blockStart + params.srcOffset + i];
8557 if (dstVal != srcVal)
8558 {
8559 std::ostringstream msg;
8560 msg << "Unexpected value found at position " << (blockStart + params.dstOffset + i) << ": expected " << static_cast<int>(srcVal) << " but found " << static_cast<int>(dstVal);
8561 TCU_FAIL(msg.str());
8562 }
8563 }
8564
8565 // Verify no data has been written after copy block.
8566 checkZerosAt(dstData, blockStart + params.dstOffset + copySize, kBlockSize - (params.dstOffset + copySize));
8567 }
8568
8569 return tcu::TestStatus::pass("Pass");
8570 }
8571
getSampleCountCaseName(VkSampleCountFlagBits sampleFlag)8572 std::string getSampleCountCaseName (VkSampleCountFlagBits sampleFlag)
8573 {
8574 return de::toLower(de::toString(getSampleCountFlagsStr(sampleFlag)).substr(16));
8575 }
8576
getFormatCaseName(VkFormat format)8577 std::string getFormatCaseName (VkFormat format)
8578 {
8579 return de::toLower(de::toString(getFormatStr(format)).substr(10));
8580 }
8581
getImageLayoutCaseName(VkImageLayout layout)8582 std::string getImageLayoutCaseName (VkImageLayout layout)
8583 {
8584 switch (layout)
8585 {
8586 case VK_IMAGE_LAYOUT_GENERAL:
8587 return "general";
8588 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
8589 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
8590 return "optimal";
8591 default:
8592 DE_ASSERT(false);
8593 return "";
8594 }
8595 }
8596
addImageToImageSimpleTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)8597 void addImageToImageSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
8598 {
8599 tcu::TestContext& testCtx = group->getTestContext();
8600
8601 {
8602 TestParams params;
8603 params.src.image.imageType = VK_IMAGE_TYPE_2D;
8604 params.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
8605 params.src.image.extent = defaultExtent;
8606 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8607 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8608 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
8609 params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
8610 params.dst.image.extent = defaultExtent;
8611 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8612 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8613 params.allocationKind = allocationKind;
8614 params.extensionUse = extensionUse;
8615
8616 {
8617 const VkImageCopy testCopy =
8618 {
8619 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
8620 {0, 0, 0}, // VkOffset3D srcOffset;
8621 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
8622 {0, 0, 0}, // VkOffset3D dstOffset;
8623 defaultExtent, // VkExtent3D extent;
8624 };
8625
8626 CopyRegion imageCopy;
8627 imageCopy.imageCopy = testCopy;
8628 params.regions.push_back(imageCopy);
8629 }
8630
8631 group->addChild(new CopyImageToImageTestCase(testCtx, "whole_image", "Whole image", params));
8632 }
8633
8634 {
8635 TestParams params;
8636 params.src.image.imageType = VK_IMAGE_TYPE_2D;
8637 params.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
8638 params.src.image.extent = defaultExtent;
8639 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8640 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8641 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
8642 params.dst.image.format = VK_FORMAT_R32_UINT;
8643 params.dst.image.extent = defaultExtent;
8644 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8645 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8646 params.allocationKind = allocationKind;
8647 params.extensionUse = extensionUse;
8648
8649 {
8650 const VkImageCopy testCopy =
8651 {
8652 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
8653 {0, 0, 0}, // VkOffset3D srcOffset;
8654 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
8655 {0, 0, 0}, // VkOffset3D dstOffset;
8656 defaultExtent, // VkExtent3D extent;
8657 };
8658
8659 CopyRegion imageCopy;
8660 imageCopy.imageCopy = testCopy;
8661 params.regions.push_back(imageCopy);
8662 }
8663
8664 group->addChild(new CopyImageToImageTestCase(testCtx, "whole_image_diff_fromat", "Whole image with different format", params));
8665 }
8666
8667 {
8668 TestParams params;
8669 params.src.image.imageType = VK_IMAGE_TYPE_2D;
8670 params.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
8671 params.src.image.extent = defaultExtent;
8672 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8673 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8674 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
8675 params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
8676 params.dst.image.extent = defaultExtent;
8677 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8678 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8679 params.allocationKind = allocationKind;
8680 params.extensionUse = extensionUse;
8681
8682 {
8683 const VkImageCopy testCopy =
8684 {
8685 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
8686 {0, 0, 0}, // VkOffset3D srcOffset;
8687 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
8688 {defaultQuarterSize, defaultQuarterSize / 2, 0}, // VkOffset3D dstOffset;
8689 {defaultQuarterSize / 2, defaultQuarterSize / 2, 1}, // VkExtent3D extent;
8690 };
8691
8692 CopyRegion imageCopy;
8693 imageCopy.imageCopy = testCopy;
8694 params.regions.push_back(imageCopy);
8695 }
8696
8697 group->addChild(new CopyImageToImageTestCase(testCtx, "partial_image", "Partial image", params));
8698 }
8699
8700 static const struct
8701 {
8702 std::string name;
8703 vk::VkFormat format1;
8704 vk::VkFormat format2;
8705 } formats [] =
8706 {
8707 { "diff_format", vk::VK_FORMAT_R32_UINT, vk::VK_FORMAT_R8G8B8A8_UNORM },
8708 { "same_format", vk::VK_FORMAT_R8G8B8A8_UNORM, vk::VK_FORMAT_R8G8B8A8_UNORM }
8709 };
8710 static const struct
8711 {
8712 std::string name;
8713 vk::VkBool32 clear;
8714 } clears [] =
8715 {
8716 { "clear", VK_TRUE },
8717 { "noclear", VK_FALSE }
8718 };
8719 static const struct
8720 {
8721 std::string name;
8722 VkExtent3D extent;
8723 } extents [] =
8724 {
8725 { "npot", {65u, 63u, 1u} },
8726 { "pot", {64u, 64u, 1u} }
8727 };
8728
8729 for (const auto& format : formats)
8730 {
8731 for (const auto& clear : clears)
8732 {
8733 for (const auto& extent : extents)
8734 {
8735 TestParams params;
8736 params.src.image.imageType = VK_IMAGE_TYPE_2D;
8737 params.src.image.format = format.format1;
8738 params.src.image.extent = extent.extent;
8739 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8740 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8741 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
8742 params.dst.image.format = format.format2;
8743 params.dst.image.extent = extent.extent;
8744 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8745 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8746 params.allocationKind = allocationKind;
8747 params.extensionUse = extensionUse;
8748 params.clearDestination = clear.clear;
8749
8750 {
8751 VkImageCopy testCopy =
8752 {
8753 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
8754 {34, 34, 0}, // VkOffset3D srcOffset;
8755 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
8756 {0, 0, 0}, // VkOffset3D dstOffset;
8757 {31, 29, 1} // VkExtent3D extent;
8758 };
8759
8760 if (extent.name == "pot")
8761 {
8762 testCopy.srcOffset = { 16, 16, 0 };
8763 testCopy.extent = { 32, 32, 1 };
8764 }
8765
8766 CopyRegion imageCopy;
8767 imageCopy.imageCopy = testCopy;
8768 params.regions.push_back(imageCopy);
8769 }
8770
8771 // Example test case name: "partial_image_npot_diff_format_clear"
8772 const std::string testCaseName = "partial_image_" + extent.name + "_" + format.name + "_" + clear.name;
8773
8774 group->addChild(new CopyImageToImageTestCase(testCtx, testCaseName, "", params));
8775 }
8776 }
8777 }
8778
8779 {
8780 TestParams params;
8781 params.src.image.imageType = VK_IMAGE_TYPE_2D;
8782 params.src.image.format = VK_FORMAT_D32_SFLOAT;
8783 params.src.image.extent = defaultExtent;
8784 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8785 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8786 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
8787 params.dst.image.format = VK_FORMAT_D32_SFLOAT;
8788 params.dst.image.extent = defaultExtent;
8789 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8790 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8791 params.allocationKind = allocationKind;
8792 params.extensionUse = extensionUse;
8793
8794 {
8795 const VkImageSubresourceLayers sourceLayer =
8796 {
8797 VK_IMAGE_ASPECT_DEPTH_BIT, // VkImageAspectFlags aspectMask;
8798 0u, // deUint32 mipLevel;
8799 0u, // deUint32 baseArrayLayer;
8800 1u // deUint32 layerCount;
8801 };
8802 const VkImageCopy testCopy =
8803 {
8804 sourceLayer, // VkImageSubresourceLayers srcSubresource;
8805 {0, 0, 0}, // VkOffset3D srcOffset;
8806 sourceLayer, // VkImageSubresourceLayers dstSubresource;
8807 {defaultQuarterSize, defaultQuarterSize / 2, 0}, // VkOffset3D dstOffset;
8808 {defaultQuarterSize / 2, defaultQuarterSize / 2, 1}, // VkExtent3D extent;
8809 };
8810
8811 CopyRegion imageCopy;
8812 imageCopy.imageCopy = testCopy;
8813 params.regions.push_back(imageCopy);
8814 }
8815
8816 group->addChild(new CopyImageToImageTestCase(testCtx, "depth", "With depth", params));
8817 }
8818
8819 {
8820 TestParams params;
8821 params.src.image.imageType = VK_IMAGE_TYPE_2D;
8822 params.src.image.format = VK_FORMAT_S8_UINT;
8823 params.src.image.extent = defaultExtent;
8824 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8825 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8826 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
8827 params.dst.image.format = VK_FORMAT_S8_UINT;
8828 params.dst.image.extent = defaultExtent;
8829 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8830 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8831 params.allocationKind = allocationKind;
8832 params.extensionUse = extensionUse;
8833
8834 {
8835 const VkImageSubresourceLayers sourceLayer =
8836 {
8837 VK_IMAGE_ASPECT_STENCIL_BIT, // VkImageAspectFlags aspectMask;
8838 0u, // deUint32 mipLevel;
8839 0u, // deUint32 baseArrayLayer;
8840 1u // deUint32 layerCount;
8841 };
8842 const VkImageCopy testCopy =
8843 {
8844 sourceLayer, // VkImageSubresourceLayers srcSubresource;
8845 {0, 0, 0}, // VkOffset3D srcOffset;
8846 sourceLayer, // VkImageSubresourceLayers dstSubresource;
8847 {defaultQuarterSize, defaultQuarterSize / 2, 0}, // VkOffset3D dstOffset;
8848 {defaultQuarterSize / 2, defaultQuarterSize / 2, 1}, // VkExtent3D extent;
8849 };
8850
8851 CopyRegion imageCopy;
8852 imageCopy.imageCopy = testCopy;
8853 params.regions.push_back(imageCopy);
8854 }
8855
8856 group->addChild(new CopyImageToImageTestCase(testCtx, "stencil", "With stencil", params));
8857 }
8858 }
8859
8860 struct CopyColorTestParams
8861 {
8862 TestParams params;
8863 const VkFormat* compatibleFormats;
8864 };
8865
addImageToImageAllFormatsColorSrcFormatDstFormatTests(tcu::TestCaseGroup * group,TestParams params)8866 void addImageToImageAllFormatsColorSrcFormatDstFormatTests (tcu::TestCaseGroup* group, TestParams params)
8867 {
8868 const VkImageLayout copySrcLayouts[] =
8869 {
8870 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
8871 VK_IMAGE_LAYOUT_GENERAL
8872 };
8873 const VkImageLayout copyDstLayouts[] =
8874 {
8875 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
8876 VK_IMAGE_LAYOUT_GENERAL
8877 };
8878
8879 for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx)
8880 {
8881 params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
8882
8883 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx)
8884 {
8885 params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
8886
8887 const std::string testName = getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
8888 getImageLayoutCaseName(params.dst.image.operationLayout);
8889 const std::string description = "From layout " + getImageLayoutCaseName(params.src.image.operationLayout) +
8890 " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
8891 group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, description, params));
8892 }
8893 }
8894 }
8895
isAllowedImageToImageAllFormatsColorSrcFormatTests(const CopyColorTestParams & testParams)8896 bool isAllowedImageToImageAllFormatsColorSrcFormatTests(const CopyColorTestParams& testParams)
8897 {
8898 bool result = true;
8899
8900 if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED)
8901 {
8902 DE_ASSERT(!dedicatedAllocationImageToImageFormatsToTestSet.empty());
8903
8904 result =
8905 de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.dst.image.format) ||
8906 de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.src.image.format);
8907 }
8908
8909 return result;
8910 }
8911
addImageToImageAllFormatsColorSrcFormatTests(tcu::TestCaseGroup * group,CopyColorTestParams testParams)8912 void addImageToImageAllFormatsColorSrcFormatTests (tcu::TestCaseGroup* group, CopyColorTestParams testParams)
8913 {
8914 // If testParams.compatibleFormats is nullptr, the destination format will be copied from the source format.
8915 const VkFormat srcFormatOnly[2] = { testParams.params.src.image.format, VK_FORMAT_UNDEFINED };
8916 const VkFormat* formatList = (testParams.compatibleFormats ? testParams.compatibleFormats : srcFormatOnly);
8917
8918 for (int dstFormatIndex = 0; formatList[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex)
8919 {
8920 testParams.params.dst.image.format = formatList[dstFormatIndex];
8921
8922 const VkFormat srcFormat = testParams.params.src.image.format;
8923 const VkFormat dstFormat = testParams.params.dst.image.format;
8924
8925 if (!isSupportedByFramework(dstFormat) && !isCompressedFormat(dstFormat))
8926 continue;
8927
8928 if (!isAllowedImageToImageAllFormatsColorSrcFormatTests(testParams))
8929 continue;
8930
8931 if (isCompressedFormat(srcFormat) && isCompressedFormat(dstFormat))
8932 if ((getBlockWidth(srcFormat) != getBlockWidth(dstFormat)) || (getBlockHeight(srcFormat) != getBlockHeight(dstFormat)))
8933 continue;
8934
8935 const std::string description = "Copy to destination format " + getFormatCaseName(dstFormat);
8936 addTestGroup(group, getFormatCaseName(dstFormat), description, addImageToImageAllFormatsColorSrcFormatDstFormatTests, testParams.params);
8937 }
8938 }
8939
8940 const VkFormat compatibleFormats8Bit[] =
8941 {
8942 VK_FORMAT_R4G4_UNORM_PACK8,
8943 VK_FORMAT_R8_UNORM,
8944 VK_FORMAT_R8_SNORM,
8945 VK_FORMAT_R8_USCALED,
8946 VK_FORMAT_R8_SSCALED,
8947 VK_FORMAT_R8_UINT,
8948 VK_FORMAT_R8_SINT,
8949 VK_FORMAT_R8_SRGB,
8950
8951 VK_FORMAT_UNDEFINED
8952 };
8953 const VkFormat compatibleFormats16Bit[] =
8954 {
8955 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
8956 VK_FORMAT_B4G4R4A4_UNORM_PACK16,
8957 VK_FORMAT_R5G6B5_UNORM_PACK16,
8958 VK_FORMAT_B5G6R5_UNORM_PACK16,
8959 VK_FORMAT_R5G5B5A1_UNORM_PACK16,
8960 VK_FORMAT_B5G5R5A1_UNORM_PACK16,
8961 VK_FORMAT_A1R5G5B5_UNORM_PACK16,
8962 VK_FORMAT_R8G8_UNORM,
8963 VK_FORMAT_R8G8_SNORM,
8964 VK_FORMAT_R8G8_USCALED,
8965 VK_FORMAT_R8G8_SSCALED,
8966 VK_FORMAT_R8G8_UINT,
8967 VK_FORMAT_R8G8_SINT,
8968 VK_FORMAT_R8G8_SRGB,
8969 VK_FORMAT_R16_UNORM,
8970 VK_FORMAT_R16_SNORM,
8971 VK_FORMAT_R16_USCALED,
8972 VK_FORMAT_R16_SSCALED,
8973 VK_FORMAT_R16_UINT,
8974 VK_FORMAT_R16_SINT,
8975 VK_FORMAT_R16_SFLOAT,
8976 VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
8977 VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
8978
8979 VK_FORMAT_UNDEFINED
8980 };
8981 const VkFormat compatibleFormats24Bit[] =
8982 {
8983 VK_FORMAT_R8G8B8_UNORM,
8984 VK_FORMAT_R8G8B8_SNORM,
8985 VK_FORMAT_R8G8B8_USCALED,
8986 VK_FORMAT_R8G8B8_SSCALED,
8987 VK_FORMAT_R8G8B8_UINT,
8988 VK_FORMAT_R8G8B8_SINT,
8989 VK_FORMAT_R8G8B8_SRGB,
8990 VK_FORMAT_B8G8R8_UNORM,
8991 VK_FORMAT_B8G8R8_SNORM,
8992 VK_FORMAT_B8G8R8_USCALED,
8993 VK_FORMAT_B8G8R8_SSCALED,
8994 VK_FORMAT_B8G8R8_UINT,
8995 VK_FORMAT_B8G8R8_SINT,
8996 VK_FORMAT_B8G8R8_SRGB,
8997
8998 VK_FORMAT_UNDEFINED
8999 };
9000 const VkFormat compatibleFormats32Bit[] =
9001 {
9002 VK_FORMAT_R8G8B8A8_UNORM,
9003 VK_FORMAT_R8G8B8A8_SNORM,
9004 VK_FORMAT_R8G8B8A8_USCALED,
9005 VK_FORMAT_R8G8B8A8_SSCALED,
9006 VK_FORMAT_R8G8B8A8_UINT,
9007 VK_FORMAT_R8G8B8A8_SINT,
9008 VK_FORMAT_R8G8B8A8_SRGB,
9009 VK_FORMAT_B8G8R8A8_UNORM,
9010 VK_FORMAT_B8G8R8A8_SNORM,
9011 VK_FORMAT_B8G8R8A8_USCALED,
9012 VK_FORMAT_B8G8R8A8_SSCALED,
9013 VK_FORMAT_B8G8R8A8_UINT,
9014 VK_FORMAT_B8G8R8A8_SINT,
9015 VK_FORMAT_B8G8R8A8_SRGB,
9016 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
9017 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
9018 VK_FORMAT_A8B8G8R8_USCALED_PACK32,
9019 VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
9020 VK_FORMAT_A8B8G8R8_UINT_PACK32,
9021 VK_FORMAT_A8B8G8R8_SINT_PACK32,
9022 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
9023 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
9024 VK_FORMAT_A2R10G10B10_SNORM_PACK32,
9025 VK_FORMAT_A2R10G10B10_USCALED_PACK32,
9026 VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
9027 VK_FORMAT_A2R10G10B10_UINT_PACK32,
9028 VK_FORMAT_A2R10G10B10_SINT_PACK32,
9029 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
9030 VK_FORMAT_A2B10G10R10_SNORM_PACK32,
9031 VK_FORMAT_A2B10G10R10_USCALED_PACK32,
9032 VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
9033 VK_FORMAT_A2B10G10R10_UINT_PACK32,
9034 VK_FORMAT_A2B10G10R10_SINT_PACK32,
9035 VK_FORMAT_R16G16_UNORM,
9036 VK_FORMAT_R16G16_SNORM,
9037 VK_FORMAT_R16G16_USCALED,
9038 VK_FORMAT_R16G16_SSCALED,
9039 VK_FORMAT_R16G16_UINT,
9040 VK_FORMAT_R16G16_SINT,
9041 VK_FORMAT_R16G16_SFLOAT,
9042 VK_FORMAT_R32_UINT,
9043 VK_FORMAT_R32_SINT,
9044 VK_FORMAT_R32_SFLOAT,
9045
9046 VK_FORMAT_UNDEFINED
9047 };
9048 const VkFormat compatibleFormats48Bit[] =
9049 {
9050 VK_FORMAT_R16G16B16_UNORM,
9051 VK_FORMAT_R16G16B16_SNORM,
9052 VK_FORMAT_R16G16B16_USCALED,
9053 VK_FORMAT_R16G16B16_SSCALED,
9054 VK_FORMAT_R16G16B16_UINT,
9055 VK_FORMAT_R16G16B16_SINT,
9056 VK_FORMAT_R16G16B16_SFLOAT,
9057
9058 VK_FORMAT_UNDEFINED
9059 };
9060 const VkFormat compatibleFormats64Bit[] =
9061 {
9062 VK_FORMAT_R16G16B16A16_UNORM,
9063 VK_FORMAT_R16G16B16A16_SNORM,
9064 VK_FORMAT_R16G16B16A16_USCALED,
9065 VK_FORMAT_R16G16B16A16_SSCALED,
9066 VK_FORMAT_R16G16B16A16_UINT,
9067 VK_FORMAT_R16G16B16A16_SINT,
9068 VK_FORMAT_R16G16B16A16_SFLOAT,
9069 VK_FORMAT_R32G32_UINT,
9070 VK_FORMAT_R32G32_SINT,
9071 VK_FORMAT_R32G32_SFLOAT,
9072 VK_FORMAT_R64_UINT,
9073 VK_FORMAT_R64_SINT,
9074 VK_FORMAT_R64_SFLOAT,
9075
9076 VK_FORMAT_BC1_RGB_UNORM_BLOCK,
9077 VK_FORMAT_BC1_RGB_SRGB_BLOCK,
9078 VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
9079 VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
9080 VK_FORMAT_BC4_UNORM_BLOCK,
9081 VK_FORMAT_BC4_SNORM_BLOCK,
9082
9083 VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
9084 VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
9085 VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
9086 VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
9087
9088 VK_FORMAT_EAC_R11_UNORM_BLOCK,
9089 VK_FORMAT_EAC_R11_SNORM_BLOCK,
9090
9091 VK_FORMAT_UNDEFINED
9092 };
9093 const VkFormat compatibleFormats96Bit[] =
9094 {
9095 VK_FORMAT_R32G32B32_UINT,
9096 VK_FORMAT_R32G32B32_SINT,
9097 VK_FORMAT_R32G32B32_SFLOAT,
9098
9099 VK_FORMAT_UNDEFINED
9100 };
9101 const VkFormat compatibleFormats128Bit[] =
9102 {
9103 VK_FORMAT_R32G32B32A32_UINT,
9104 VK_FORMAT_R32G32B32A32_SINT,
9105 VK_FORMAT_R32G32B32A32_SFLOAT,
9106 VK_FORMAT_R64G64_UINT,
9107 VK_FORMAT_R64G64_SINT,
9108 VK_FORMAT_R64G64_SFLOAT,
9109
9110 VK_FORMAT_BC2_UNORM_BLOCK,
9111 VK_FORMAT_BC2_SRGB_BLOCK,
9112 VK_FORMAT_BC3_UNORM_BLOCK,
9113 VK_FORMAT_BC3_SRGB_BLOCK,
9114 VK_FORMAT_BC5_UNORM_BLOCK,
9115 VK_FORMAT_BC5_SNORM_BLOCK,
9116 VK_FORMAT_BC6H_UFLOAT_BLOCK,
9117 VK_FORMAT_BC6H_SFLOAT_BLOCK,
9118 VK_FORMAT_BC7_UNORM_BLOCK,
9119 VK_FORMAT_BC7_SRGB_BLOCK,
9120
9121 VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
9122 VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
9123
9124 VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
9125 VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
9126
9127 VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
9128 VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
9129 VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
9130 VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
9131 VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
9132 VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
9133 VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
9134 VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
9135 VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
9136 VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
9137 VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
9138 VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
9139 VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
9140 VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
9141 VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
9142 VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
9143 VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
9144 VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
9145 VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
9146 VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
9147 VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
9148 VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
9149 VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
9150 VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
9151 VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
9152 VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
9153 VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
9154 VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
9155
9156 VK_FORMAT_UNDEFINED
9157 };
9158 const VkFormat compatibleFormats192Bit[] =
9159 {
9160 VK_FORMAT_R64G64B64_UINT,
9161 VK_FORMAT_R64G64B64_SINT,
9162 VK_FORMAT_R64G64B64_SFLOAT,
9163
9164 VK_FORMAT_UNDEFINED
9165 };
9166 const VkFormat compatibleFormats256Bit[] =
9167 {
9168 VK_FORMAT_R64G64B64A64_UINT,
9169 VK_FORMAT_R64G64B64A64_SINT,
9170 VK_FORMAT_R64G64B64A64_SFLOAT,
9171
9172 VK_FORMAT_UNDEFINED
9173 };
9174
9175 const VkFormat* colorImageFormatsToTest[] =
9176 {
9177 compatibleFormats8Bit,
9178 compatibleFormats16Bit,
9179 compatibleFormats24Bit,
9180 compatibleFormats32Bit,
9181 compatibleFormats48Bit,
9182 compatibleFormats64Bit,
9183 compatibleFormats96Bit,
9184 compatibleFormats128Bit,
9185 compatibleFormats192Bit,
9186 compatibleFormats256Bit
9187 };
9188
9189 const VkFormat dedicatedAllocationImageToImageFormatsToTest[] =
9190 {
9191 // From compatibleFormats8Bit
9192 VK_FORMAT_R4G4_UNORM_PACK8,
9193 VK_FORMAT_R8_SRGB,
9194
9195 // From compatibleFormats16Bit
9196 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
9197 VK_FORMAT_R16_SFLOAT,
9198
9199 // From compatibleFormats24Bit
9200 VK_FORMAT_R8G8B8_UNORM,
9201 VK_FORMAT_B8G8R8_SRGB,
9202
9203 // From compatibleFormats32Bit
9204 VK_FORMAT_R8G8B8A8_UNORM,
9205 VK_FORMAT_R32_SFLOAT,
9206
9207 // From compatibleFormats48Bit
9208 VK_FORMAT_R16G16B16_UNORM,
9209 VK_FORMAT_R16G16B16_SFLOAT,
9210
9211 // From compatibleFormats64Bit
9212 VK_FORMAT_R16G16B16A16_UNORM,
9213 VK_FORMAT_R64_SFLOAT,
9214
9215 // From compatibleFormats96Bit
9216 VK_FORMAT_R32G32B32_UINT,
9217 VK_FORMAT_R32G32B32_SFLOAT,
9218
9219 // From compatibleFormats128Bit
9220 VK_FORMAT_R32G32B32A32_UINT,
9221 VK_FORMAT_R64G64_SFLOAT,
9222
9223 // From compatibleFormats192Bit
9224 VK_FORMAT_R64G64B64_UINT,
9225 VK_FORMAT_R64G64B64_SFLOAT,
9226
9227 // From compatibleFormats256Bit
9228 VK_FORMAT_R64G64B64A64_UINT,
9229 VK_FORMAT_R64G64B64A64_SFLOAT,
9230 };
9231
addImageToImageAllFormatsColorTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)9232 void addImageToImageAllFormatsColorTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9233 {
9234 if (allocationKind == ALLOCATION_KIND_DEDICATED)
9235 {
9236 const int numOfDedicatedAllocationImageToImageFormatsToTest = DE_LENGTH_OF_ARRAY(dedicatedAllocationImageToImageFormatsToTest);
9237 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfDedicatedAllocationImageToImageFormatsToTest; ++compatibleFormatsIndex)
9238 dedicatedAllocationImageToImageFormatsToTestSet.insert(dedicatedAllocationImageToImageFormatsToTest[compatibleFormatsIndex]);
9239 }
9240
9241 // 2D tests.
9242 {
9243 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D copies"));
9244
9245 TestParams params;
9246 params.src.image.imageType = VK_IMAGE_TYPE_2D;
9247 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
9248 params.src.image.extent = defaultExtent;
9249 params.dst.image.extent = defaultExtent;
9250 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9251 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9252 params.allocationKind = allocationKind;
9253 params.extensionUse = extensionUse;
9254
9255 for (deInt32 i = 0; i < defaultSize; i += defaultQuarterSize)
9256 {
9257 const VkImageCopy testCopy =
9258 {
9259 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
9260 {0, 0, 0}, // VkOffset3D srcOffset;
9261 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
9262 {i, defaultSize - i - defaultQuarterSize, 0}, // VkOffset3D dstOffset;
9263 {defaultQuarterSize, defaultQuarterSize, 1}, // VkExtent3D extent;
9264 };
9265
9266 CopyRegion imageCopy;
9267 imageCopy.imageCopy = testCopy;
9268
9269 params.regions.push_back(imageCopy);
9270 }
9271
9272 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
9273 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
9274 {
9275 const VkFormat* compatibleFormats = colorImageFormatsToTest[compatibleFormatsIndex];
9276 for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
9277 {
9278 params.src.image.format = compatibleFormats[srcFormatIndex];
9279 if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
9280 continue;
9281
9282 CopyColorTestParams testParams;
9283 testParams.params = params;
9284 testParams.compatibleFormats = compatibleFormats;
9285
9286 const std::string testName = getFormatCaseName(params.src.image.format);
9287 const std::string description = "Copy from source format " + getFormatCaseName(params.src.image.format);
9288 addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsColorSrcFormatTests, testParams);
9289 }
9290 }
9291
9292 group->addChild(subGroup.release());
9293 }
9294
9295 // 1D tests.
9296 {
9297 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D copies"));
9298
9299 TestParams params;
9300 params.src.image.imageType = VK_IMAGE_TYPE_1D;
9301 params.dst.image.imageType = VK_IMAGE_TYPE_1D;
9302 params.src.image.extent = default1dExtent;
9303 params.dst.image.extent = default1dExtent;
9304 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9305 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9306 params.allocationKind = allocationKind;
9307 params.extensionUse = extensionUse;
9308
9309 for (deInt32 i = defaultQuarterSize; i < defaultSize; i += defaultSize / 2)
9310 {
9311 const VkImageCopy testCopy =
9312 {
9313 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
9314 {0, 0, 0}, // VkOffset3D srcOffset;
9315 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
9316 {i, 0, 0}, // VkOffset3D dstOffset;
9317 {defaultQuarterSize, 1, 1}, // VkExtent3D extent;
9318 };
9319
9320 CopyRegion imageCopy;
9321 imageCopy.imageCopy = testCopy;
9322
9323 params.regions.push_back(imageCopy);
9324 }
9325
9326 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
9327 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
9328 {
9329 const VkFormat* compatibleFormats = colorImageFormatsToTest[compatibleFormatsIndex];
9330 for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
9331 {
9332 params.src.image.format = compatibleFormats[srcFormatIndex];
9333 if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
9334 continue;
9335
9336 CopyColorTestParams testParams;
9337 testParams.params = params;
9338 testParams.compatibleFormats = nullptr;
9339
9340 const std::string testName = getFormatCaseName(params.src.image.format);
9341 const std::string description = "Copy from source format " + getFormatCaseName(params.src.image.format);
9342 addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsColorSrcFormatTests, testParams);
9343 }
9344 }
9345
9346 group->addChild(subGroup.release());
9347 }
9348
9349 // 3D tests. Note we use smaller dimensions here for performance reasons.
9350 {
9351 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D copies"));
9352
9353 TestParams params;
9354 params.src.image.imageType = VK_IMAGE_TYPE_3D;
9355 params.dst.image.imageType = VK_IMAGE_TYPE_3D;
9356 params.src.image.extent = default3dExtent;
9357 params.dst.image.extent = default3dExtent;
9358 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9359 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9360 params.allocationKind = allocationKind;
9361 params.extensionUse = extensionUse;
9362
9363 for (deInt32 i = 0; i < defaultQuarterSize; i += defaultSixteenthSize)
9364 {
9365 const VkImageCopy testCopy =
9366 {
9367 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
9368 {0, 0, 0}, // VkOffset3D srcOffset;
9369 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
9370 {i, defaultQuarterSize - i - defaultSixteenthSize, i}, // VkOffset3D dstOffset;
9371 {defaultSixteenthSize, defaultSixteenthSize, defaultSixteenthSize}, // VkExtent3D extent;
9372 };
9373
9374 CopyRegion imageCopy;
9375 imageCopy.imageCopy = testCopy;
9376
9377 params.regions.push_back(imageCopy);
9378 }
9379
9380 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
9381 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
9382 {
9383 const VkFormat* compatibleFormats = colorImageFormatsToTest[compatibleFormatsIndex];
9384 for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
9385 {
9386 params.src.image.format = compatibleFormats[srcFormatIndex];
9387 if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
9388 continue;
9389
9390 CopyColorTestParams testParams;
9391 testParams.params = params;
9392 testParams.compatibleFormats = nullptr;
9393
9394 const std::string testName = getFormatCaseName(params.src.image.format);
9395 const std::string description = "Copy from source format " + getFormatCaseName(params.src.image.format);
9396 addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsColorSrcFormatTests, testParams);
9397 }
9398 }
9399
9400 group->addChild(subGroup.release());
9401 }
9402 }
9403
addImageToImageDimensionsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)9404 void addImageToImageDimensionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9405 {
9406 tcu::TestContext& testCtx = group->getTestContext();
9407
9408 const VkFormat testFormats[][2] =
9409 {
9410 // From compatibleFormats8Bit
9411 {
9412 VK_FORMAT_R4G4_UNORM_PACK8,
9413 VK_FORMAT_R8_SRGB
9414 },
9415 // From compatibleFormats16Bit
9416 {
9417 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
9418 VK_FORMAT_R16_SFLOAT,
9419 },
9420 // From compatibleFormats24Bit
9421 {
9422 VK_FORMAT_R8G8B8_UNORM,
9423 VK_FORMAT_B8G8R8_SRGB
9424 },
9425 // From compatibleFormats32Bit
9426 {
9427 VK_FORMAT_R8G8B8A8_UNORM,
9428 VK_FORMAT_R32_SFLOAT
9429 },
9430 // From compatibleFormats48Bit
9431 {
9432 VK_FORMAT_R16G16B16_UNORM,
9433 VK_FORMAT_R16G16B16_SFLOAT
9434 },
9435 // From compatibleFormats64Bit
9436 {
9437 VK_FORMAT_R16G16B16A16_UNORM,
9438 VK_FORMAT_R64_SFLOAT
9439 },
9440 // From compatibleFormats96Bit
9441 {
9442 VK_FORMAT_R32G32B32_UINT,
9443 VK_FORMAT_R32G32B32_SFLOAT
9444 },
9445 // From compatibleFormats128Bit
9446 {
9447 VK_FORMAT_R32G32B32A32_UINT,
9448 VK_FORMAT_R64G64_SFLOAT
9449 },
9450 // From compatibleFormats192Bit
9451 {
9452 VK_FORMAT_R64G64B64_UINT,
9453 VK_FORMAT_R64G64B64_SFLOAT,
9454 },
9455 // From compatibleFormats256Bit
9456 {
9457 VK_FORMAT_R64G64B64A64_UINT,
9458 VK_FORMAT_R64G64B64A64_SFLOAT
9459 }
9460 };
9461
9462 const tcu::UVec2 imageDimensions[] =
9463 {
9464 // large pot x small pot
9465 tcu::UVec2(4096, 4u),
9466 tcu::UVec2(8192, 4u),
9467 tcu::UVec2(16384, 4u),
9468 tcu::UVec2(32768, 4u),
9469
9470 // large pot x small npot
9471 tcu::UVec2(4096, 6u),
9472 tcu::UVec2(8192, 6u),
9473 tcu::UVec2(16384, 6u),
9474 tcu::UVec2(32768, 6u),
9475
9476 // small pot x large pot
9477 tcu::UVec2(4u, 4096),
9478 tcu::UVec2(4u, 8192),
9479 tcu::UVec2(4u, 16384),
9480 tcu::UVec2(4u, 32768),
9481
9482 // small npot x large pot
9483 tcu::UVec2(6u, 4096),
9484 tcu::UVec2(6u, 8192),
9485 tcu::UVec2(6u, 16384),
9486 tcu::UVec2(6u, 32768)
9487 };
9488
9489 const VkImageLayout copySrcLayouts[] =
9490 {
9491 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
9492 VK_IMAGE_LAYOUT_GENERAL
9493 };
9494
9495 const VkImageLayout copyDstLayouts[] =
9496 {
9497 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
9498 VK_IMAGE_LAYOUT_GENERAL
9499 };
9500
9501 if (allocationKind == ALLOCATION_KIND_DEDICATED)
9502 {
9503 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(dedicatedAllocationImageToImageFormatsToTest); compatibleFormatsIndex++)
9504 dedicatedAllocationImageToImageFormatsToTestSet.insert(dedicatedAllocationImageToImageFormatsToTest[compatibleFormatsIndex]);
9505 }
9506
9507 // Image dimensions
9508 for (size_t dimensionNdx = 0; dimensionNdx < DE_LENGTH_OF_ARRAY(imageDimensions); dimensionNdx++)
9509 {
9510 CopyRegion copyRegion;
9511 CopyColorTestParams testParams;
9512
9513 const VkExtent3D extent = { imageDimensions[dimensionNdx].x(), imageDimensions[dimensionNdx].y(), 1 };
9514
9515 const VkImageCopy testCopy =
9516 {
9517 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
9518 {0, 0, 0}, // VkOffset3D srcOffset;
9519 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
9520 {0, 0, 0}, // VkOffset3D dstOffset;
9521 extent, // VkExtent3D extent;
9522 };
9523
9524 testParams.params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9525 testParams.params.src.image.imageType = VK_IMAGE_TYPE_2D;
9526 testParams.params.src.image.extent = extent;
9527
9528 testParams.params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9529 testParams.params.dst.image.imageType = VK_IMAGE_TYPE_2D;
9530 testParams.params.dst.image.extent = extent;
9531
9532 copyRegion.imageCopy = testCopy;
9533 testParams.params.allocationKind = allocationKind;
9534 testParams.params.extensionUse = extensionUse;
9535
9536 testParams.params.regions.push_back(copyRegion);
9537
9538 const std::string dimensionStr = "src" + de::toString(testParams.params.src.image.extent.width) + "x" + de::toString(testParams.params.src.image.extent.height)
9539 + "_dst" + de::toString(testParams.params.dst.image.extent.width) + "x" + de::toString(testParams.params.dst.image.extent.height);
9540 tcu::TestCaseGroup* imageSizeGroup = new tcu::TestCaseGroup(testCtx, dimensionStr.c_str(), ("Image sizes " + dimensionStr).c_str());
9541
9542 // Compatible formats for copying
9543 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(testFormats); compatibleFormatsIndex++)
9544 {
9545 const VkFormat* compatibleFormats = testFormats[compatibleFormatsIndex];
9546
9547 testParams.compatibleFormats = compatibleFormats;
9548
9549 // Source image format
9550 for (int srcFormatIndex = 0; srcFormatIndex < DE_LENGTH_OF_ARRAY(testFormats[compatibleFormatsIndex]); srcFormatIndex++)
9551 {
9552 testParams.params.src.image.format = testParams.compatibleFormats[srcFormatIndex];
9553
9554 if (!isSupportedByFramework(testParams.params.src.image.format) && !isCompressedFormat(testParams.params.src.image.format))
9555 continue;
9556
9557 const std::string srcDescription = "Copy from source format " + getFormatCaseName(testParams.params.src.image.format);
9558 tcu::TestCaseGroup* srcFormatGroup = new tcu::TestCaseGroup(testCtx, getFormatCaseName(testParams.params.src.image.format).c_str(), srcDescription.c_str());
9559
9560 // Destination image format
9561 for (int dstFormatIndex = 0; dstFormatIndex < DE_LENGTH_OF_ARRAY(testFormats[compatibleFormatsIndex]); dstFormatIndex++)
9562 {
9563 testParams.params.dst.image.format = testParams.compatibleFormats[dstFormatIndex];
9564
9565 if (!isSupportedByFramework(testParams.params.dst.image.format) && !isCompressedFormat(testParams.params.dst.image.format))
9566 continue;
9567
9568 if (!isAllowedImageToImageAllFormatsColorSrcFormatTests(testParams))
9569 continue;
9570
9571 if (isCompressedFormat(testParams.params.src.image.format) && isCompressedFormat(testParams.params.dst.image.format))
9572 {
9573 if ((getBlockWidth(testParams.params.src.image.format) != getBlockWidth(testParams.params.dst.image.format))
9574 || (getBlockHeight(testParams.params.src.image.format) != getBlockHeight(testParams.params.dst.image.format)))
9575 continue;
9576 }
9577
9578 const std::string dstDescription = "Copy to destination format " + getFormatCaseName(testParams.params.dst.image.format);
9579 tcu::TestCaseGroup* dstFormatGroup = new tcu::TestCaseGroup(testCtx, getFormatCaseName(testParams.params.dst.image.format).c_str(), dstDescription.c_str());
9580
9581 // Source/destionation image layouts
9582 for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); srcLayoutNdx++)
9583 {
9584 testParams.params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
9585
9586 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); dstLayoutNdx++)
9587 {
9588 testParams.params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
9589
9590 const std::string testName = getImageLayoutCaseName(testParams.params.src.image.operationLayout) + "_" + getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
9591 const std::string description = "From layout " + getImageLayoutCaseName(testParams.params.src.image.operationLayout) + " to " + getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
9592 const TestParams params = testParams.params;
9593
9594 dstFormatGroup->addChild(new CopyImageToImageTestCase(testCtx, testName, description, params));
9595 }
9596 }
9597
9598 srcFormatGroup->addChild(dstFormatGroup);
9599 }
9600
9601 imageSizeGroup->addChild(srcFormatGroup);
9602 }
9603 }
9604
9605 group->addChild(imageSizeGroup);
9606 }
9607 }
9608
addImageToImageAllFormatsDepthStencilFormatsTests(tcu::TestCaseGroup * group,TestParams params)9609 void addImageToImageAllFormatsDepthStencilFormatsTests (tcu::TestCaseGroup* group, TestParams params)
9610 {
9611 const VkImageLayout copySrcLayouts[] =
9612 {
9613 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
9614 VK_IMAGE_LAYOUT_GENERAL
9615 };
9616 const VkImageLayout copyDstLayouts[] =
9617 {
9618 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
9619 VK_IMAGE_LAYOUT_GENERAL
9620 };
9621
9622 for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx)
9623 {
9624 params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
9625 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx)
9626 {
9627 params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
9628
9629 const std::string testName = getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
9630 getImageLayoutCaseName(params.dst.image.operationLayout);
9631 const std::string description = "From layout " + getImageLayoutCaseName(params.src.image.operationLayout) +
9632 " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
9633 group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, description, params));
9634 }
9635 }
9636 }
9637
addImageToImageAllFormatsDepthStencilTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)9638 void addImageToImageAllFormatsDepthStencilTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9639 {
9640 const VkFormat depthAndStencilFormats[] =
9641 {
9642 VK_FORMAT_D16_UNORM,
9643 VK_FORMAT_X8_D24_UNORM_PACK32,
9644 VK_FORMAT_D32_SFLOAT,
9645 VK_FORMAT_S8_UINT,
9646 VK_FORMAT_D16_UNORM_S8_UINT,
9647 VK_FORMAT_D24_UNORM_S8_UINT,
9648 VK_FORMAT_D32_SFLOAT_S8_UINT,
9649 };
9650
9651 // 2D tests.
9652 {
9653 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D copies"));
9654
9655 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
9656 {
9657 TestParams params;
9658 params.src.image.imageType = VK_IMAGE_TYPE_2D;
9659 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
9660 params.src.image.extent = defaultExtent;
9661 params.dst.image.extent = defaultExtent;
9662 params.src.image.format = depthAndStencilFormats[compatibleFormatsIndex];
9663 params.dst.image.format = params.src.image.format;
9664 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9665 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9666 params.allocationKind = allocationKind;
9667 params.extensionUse = extensionUse;
9668 params.separateDepthStencilLayouts = DE_FALSE;
9669
9670 bool hasDepth = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
9671 bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
9672
9673 const VkImageSubresourceLayers defaultDepthSourceLayer = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
9674 const VkImageSubresourceLayers defaultStencilSourceLayer = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
9675 const VkImageSubresourceLayers defaultDSSourceLayer = { VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
9676
9677 for (deInt32 i = 0; i < defaultSize; i += defaultQuarterSize)
9678 {
9679 CopyRegion copyRegion;
9680 const VkOffset3D srcOffset = {0, 0, 0};
9681 const VkOffset3D dstOffset = {i, defaultSize - i - defaultQuarterSize, 0};
9682 const VkExtent3D extent = {defaultQuarterSize, defaultQuarterSize, 1};
9683
9684 if (hasDepth)
9685 {
9686 const VkImageCopy testCopy =
9687 {
9688 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
9689 srcOffset, // VkOffset3D srcOffset;
9690 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
9691 dstOffset, // VkOffset3D dstOffset;
9692 extent, // VkExtent3D extent;
9693 };
9694
9695 copyRegion.imageCopy = testCopy;
9696 params.regions.push_back(copyRegion);
9697 }
9698 if (hasStencil)
9699 {
9700 const VkImageCopy testCopy =
9701 {
9702 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
9703 srcOffset, // VkOffset3D srcOffset;
9704 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
9705 dstOffset, // VkOffset3D dstOffset;
9706 extent, // VkExtent3D extent;
9707 };
9708
9709 copyRegion.imageCopy = testCopy;
9710 params.regions.push_back(copyRegion);
9711 }
9712 }
9713
9714 const std::string testName = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
9715 const std::string description = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
9716 addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params);
9717
9718 if (hasDepth && hasStencil)
9719 {
9720 params.separateDepthStencilLayouts = DE_TRUE;
9721 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_separate_layouts";
9722 const std::string description2 = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
9723 addTestGroup(subGroup.get(), testName2, description2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
9724
9725 // DS Image copy
9726 {
9727 params.separateDepthStencilLayouts = DE_FALSE;
9728 // Clear previous vkImageCopy elements
9729 params.regions.clear();
9730
9731 for (deInt32 i = 0; i < defaultSize; i += defaultQuarterSize)
9732 {
9733 CopyRegion copyRegion;
9734 const VkOffset3D srcOffset = {0, 0, 0};
9735 const VkOffset3D dstOffset = {i, defaultSize - i - defaultQuarterSize, 0};
9736 const VkExtent3D extent = {defaultQuarterSize, defaultQuarterSize, 1};
9737
9738 const VkImageCopy testCopy =
9739 {
9740 defaultDSSourceLayer, // VkImageSubresourceLayers srcSubresource;
9741 srcOffset, // VkOffset3D srcOffset;
9742 defaultDSSourceLayer, // VkImageSubresourceLayers dstSubresource;
9743 dstOffset, // VkOffset3D dstOffset;
9744 extent, // VkExtent3D extent;
9745 };
9746
9747 copyRegion.imageCopy = testCopy;
9748 params.regions.push_back(copyRegion);
9749 }
9750
9751 const std::string testName3 = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_depth_stencil_aspects";
9752 const std::string description3 = "Copy both depth and stencil aspects from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
9753 addTestGroup(subGroup.get(), testName3, description3, addImageToImageAllFormatsDepthStencilFormatsTests, params);
9754 }
9755 }
9756 }
9757
9758 group->addChild(subGroup.release());
9759 }
9760
9761 // 1D tests.
9762 {
9763 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D copies"));
9764
9765 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
9766 {
9767 TestParams params;
9768 params.src.image.imageType = VK_IMAGE_TYPE_1D;
9769 params.dst.image.imageType = VK_IMAGE_TYPE_1D;
9770 params.src.image.extent = default1dExtent;
9771 params.dst.image.extent = default1dExtent;
9772 params.src.image.format = depthAndStencilFormats[compatibleFormatsIndex];
9773 params.dst.image.format = params.src.image.format;
9774 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9775 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9776 params.allocationKind = allocationKind;
9777 params.extensionUse = extensionUse;
9778
9779 bool hasDepth = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
9780 bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
9781
9782 const VkImageSubresourceLayers defaultDepthSourceLayer = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
9783 const VkImageSubresourceLayers defaultStencilSourceLayer = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
9784
9785 for (deInt32 i = defaultQuarterSize; i < defaultSize; i += defaultSize / 2)
9786 {
9787 CopyRegion copyRegion;
9788 const VkOffset3D srcOffset = {0, 0, 0};
9789 const VkOffset3D dstOffset = {i, 0, 0};
9790 const VkExtent3D extent = {defaultQuarterSize, 1, 1};
9791
9792 if (hasDepth)
9793 {
9794 const VkImageCopy testCopy =
9795 {
9796 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
9797 srcOffset, // VkOffset3D srcOffset;
9798 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
9799 dstOffset, // VkOffset3D dstOffset;
9800 extent, // VkExtent3D extent;
9801 };
9802
9803 copyRegion.imageCopy = testCopy;
9804 params.regions.push_back(copyRegion);
9805 }
9806 if (hasStencil)
9807 {
9808 const VkImageCopy testCopy =
9809 {
9810 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
9811 srcOffset, // VkOffset3D srcOffset;
9812 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
9813 dstOffset, // VkOffset3D dstOffset;
9814 extent, // VkExtent3D extent;
9815 };
9816
9817 copyRegion.imageCopy = testCopy;
9818 params.regions.push_back(copyRegion);
9819 }
9820 }
9821
9822 const std::string testName = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
9823 const std::string description = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
9824 addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params);
9825
9826 if (hasDepth && hasStencil)
9827 {
9828 params.separateDepthStencilLayouts = DE_TRUE;
9829 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_separate_layouts";
9830 const std::string description2 = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
9831 addTestGroup(subGroup.get(), testName2, description2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
9832 }
9833 }
9834
9835 group->addChild(subGroup.release());
9836 }
9837
9838 // 3D tests. Note we use smaller dimensions here for performance reasons.
9839 {
9840 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D copies"));
9841
9842 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
9843 {
9844 TestParams params;
9845 params.src.image.imageType = VK_IMAGE_TYPE_3D;
9846 params.dst.image.imageType = VK_IMAGE_TYPE_3D;
9847 params.src.image.extent = default3dExtent;
9848 params.dst.image.extent = default3dExtent;
9849 params.src.image.format = depthAndStencilFormats[compatibleFormatsIndex];
9850 params.dst.image.format = params.src.image.format;
9851 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9852 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9853 params.allocationKind = allocationKind;
9854 params.extensionUse = extensionUse;
9855
9856 bool hasDepth = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
9857 bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
9858
9859 const VkImageSubresourceLayers defaultDepthSourceLayer = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
9860 const VkImageSubresourceLayers defaultStencilSourceLayer = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
9861
9862 for (deInt32 i = 0; i < defaultQuarterSize; i += defaultSixteenthSize)
9863 {
9864 CopyRegion copyRegion;
9865 const VkOffset3D srcOffset = {0, 0, 0};
9866 const VkOffset3D dstOffset = {i, defaultQuarterSize - i - defaultSixteenthSize, i};
9867 const VkExtent3D extent = {defaultSixteenthSize, defaultSixteenthSize, defaultSixteenthSize};
9868
9869 if (hasDepth)
9870 {
9871 const VkImageCopy testCopy =
9872 {
9873 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
9874 srcOffset, // VkOffset3D srcOffset;
9875 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
9876 dstOffset, // VkOffset3D dstOffset;
9877 extent, // VkExtent3D extent;
9878 };
9879
9880 copyRegion.imageCopy = testCopy;
9881 params.regions.push_back(copyRegion);
9882 }
9883 if (hasStencil)
9884 {
9885 const VkImageCopy testCopy =
9886 {
9887 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
9888 srcOffset, // VkOffset3D srcOffset;
9889 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
9890 dstOffset, // VkOffset3D dstOffset;
9891 extent, // VkExtent3D extent;
9892 };
9893
9894 copyRegion.imageCopy = testCopy;
9895 params.regions.push_back(copyRegion);
9896 }
9897 }
9898
9899 const std::string testName = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
9900 const std::string description = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
9901 addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params);
9902
9903 if (hasDepth && hasStencil)
9904 {
9905 params.separateDepthStencilLayouts = DE_TRUE;
9906 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_separate_layouts";
9907 const std::string description2 = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
9908 addTestGroup(subGroup.get(), testName2, description2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
9909 }
9910 }
9911
9912 group->addChild(subGroup.release());
9913 }
9914 }
9915
addImageToImageAllFormatsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)9916 void addImageToImageAllFormatsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9917 {
9918 addTestGroup(group, "color", "Copy image to image with color formats", addImageToImageAllFormatsColorTests, allocationKind, extensionUse);
9919 addTestGroup(group, "depth_stencil", "Copy image to image with depth/stencil formats", addImageToImageAllFormatsDepthStencilTests, allocationKind, extensionUse);
9920 }
9921
addImageToImage3dImagesTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)9922 void addImageToImage3dImagesTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9923 {
9924 tcu::TestContext& testCtx = group->getTestContext();
9925
9926 {
9927 TestParams params3DTo2D;
9928 const deUint32 slicesLayers = 16u;
9929 params3DTo2D.src.image.imageType = VK_IMAGE_TYPE_3D;
9930 params3DTo2D.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
9931 params3DTo2D.src.image.extent = defaultHalfExtent;
9932 params3DTo2D.src.image.extent.depth = slicesLayers;
9933 params3DTo2D.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9934 params3DTo2D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9935 params3DTo2D.dst.image.imageType = VK_IMAGE_TYPE_2D;
9936 params3DTo2D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
9937 params3DTo2D.dst.image.extent = defaultHalfExtent;
9938 params3DTo2D.dst.image.extent.depth = slicesLayers;
9939 params3DTo2D.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9940 params3DTo2D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9941 params3DTo2D.allocationKind = allocationKind;
9942 params3DTo2D.extensionUse = extensionUse;
9943
9944 for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
9945 {
9946 const VkImageSubresourceLayers sourceLayer =
9947 {
9948 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
9949 0u, // deUint32 mipLevel;
9950 0u, // deUint32 baseArrayLayer;
9951 1u // deUint32 layerCount;
9952 };
9953
9954 const VkImageSubresourceLayers destinationLayer =
9955 {
9956 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
9957 0u, // deUint32 mipLevel;
9958 slicesLayersNdx, // deUint32 baseArrayLayer;
9959 1u // deUint32 layerCount;
9960 };
9961
9962 const VkImageCopy testCopy =
9963 {
9964 sourceLayer, // VkImageSubresourceLayers srcSubresource;
9965 {0, 0, (deInt32)slicesLayersNdx}, // VkOffset3D srcOffset;
9966 destinationLayer, // VkImageSubresourceLayers dstSubresource;
9967 {0, 0, 0}, // VkOffset3D dstOffset;
9968 defaultHalfExtent, // VkExtent3D extent;
9969 };
9970
9971 CopyRegion imageCopy;
9972 imageCopy.imageCopy = testCopy;
9973
9974 params3DTo2D.regions.push_back(imageCopy);
9975 }
9976 group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_by_slices", "copy 2d layers to 3d slices one by one", params3DTo2D));
9977 }
9978
9979 {
9980 TestParams params2DTo3D;
9981 const deUint32 slicesLayers = 16u;
9982 params2DTo3D.src.image.imageType = VK_IMAGE_TYPE_2D;
9983 params2DTo3D.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
9984 params2DTo3D.src.image.extent = defaultHalfExtent;
9985 params2DTo3D.src.image.extent.depth = slicesLayers;
9986 params2DTo3D.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9987 params2DTo3D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9988 params2DTo3D.dst.image.imageType = VK_IMAGE_TYPE_3D;
9989 params2DTo3D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
9990 params2DTo3D.dst.image.extent = defaultHalfExtent;
9991 params2DTo3D.dst.image.extent.depth = slicesLayers;
9992 params2DTo3D.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9993 params2DTo3D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9994 params2DTo3D.allocationKind = allocationKind;
9995 params2DTo3D.extensionUse = extensionUse;
9996
9997 for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
9998 {
9999 const VkImageSubresourceLayers sourceLayer =
10000 {
10001 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10002 0u, // deUint32 mipLevel;
10003 slicesLayersNdx, // deUint32 baseArrayLayer;
10004 1u // deUint32 layerCount;
10005 };
10006
10007 const VkImageSubresourceLayers destinationLayer =
10008 {
10009 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10010 0u, // deUint32 mipLevel;
10011 0u, // deUint32 baseArrayLayer;
10012 1u // deUint32 layerCount;
10013 };
10014
10015 const VkImageCopy testCopy =
10016 {
10017 sourceLayer, // VkImageSubresourceLayers srcSubresource;
10018 {0, 0, 0}, // VkOffset3D srcOffset;
10019 destinationLayer, // VkImageSubresourceLayers dstSubresource;
10020 {0, 0, (deInt32)slicesLayersNdx}, // VkOffset3D dstOffset;
10021 defaultHalfExtent, // VkExtent3D extent;
10022 };
10023
10024 CopyRegion imageCopy;
10025 imageCopy.imageCopy = testCopy;
10026
10027 params2DTo3D.regions.push_back(imageCopy);
10028 }
10029
10030 group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_by_layers", "copy 3d slices to 2d layers one by one", params2DTo3D));
10031 }
10032
10033 {
10034 TestParams params3DTo2D;
10035 const deUint32 slicesLayers = 16u;
10036 params3DTo2D.src.image.imageType = VK_IMAGE_TYPE_3D;
10037 params3DTo2D.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
10038 params3DTo2D.src.image.extent = defaultHalfExtent;
10039 params3DTo2D.src.image.extent.depth = slicesLayers;
10040 params3DTo2D.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10041 params3DTo2D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10042 params3DTo2D.dst.image.imageType = VK_IMAGE_TYPE_2D;
10043 params3DTo2D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
10044 params3DTo2D.dst.image.extent = defaultHalfExtent;
10045 params3DTo2D.dst.image.extent.depth = slicesLayers;
10046 params3DTo2D.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10047 params3DTo2D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10048 params3DTo2D.allocationKind = allocationKind;
10049 params3DTo2D.extensionUse = extensionUse;
10050
10051 {
10052 const VkImageSubresourceLayers sourceLayer =
10053 {
10054 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10055 0u, // deUint32 mipLevel;
10056 0u, // deUint32 baseArrayLayer;
10057 1u // deUint32 layerCount;
10058 };
10059
10060 const VkImageSubresourceLayers destinationLayer =
10061 {
10062 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10063 0u, // deUint32 mipLevel;
10064 0, // deUint32 baseArrayLayer;
10065 slicesLayers // deUint32 layerCount;
10066 };
10067
10068 const VkImageCopy testCopy =
10069 {
10070 sourceLayer, // VkImageSubresourceLayers srcSubresource;
10071 {0, 0, 0}, // VkOffset3D srcOffset;
10072 destinationLayer, // VkImageSubresourceLayers dstSubresource;
10073 {0, 0, 0}, // VkOffset3D dstOffset;
10074 params3DTo2D.src.image.extent // VkExtent3D extent;
10075 };
10076
10077 CopyRegion imageCopy;
10078 imageCopy.imageCopy = testCopy;
10079
10080 params3DTo2D.regions.push_back(imageCopy);
10081 }
10082 group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_whole", "copy 3d slices to 2d layers all at once", params3DTo2D));
10083 }
10084
10085 {
10086 TestParams params2DTo3D;
10087 const deUint32 slicesLayers = 16u;
10088 params2DTo3D.src.image.imageType = VK_IMAGE_TYPE_2D;
10089 params2DTo3D.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
10090 params2DTo3D.src.image.extent = defaultHalfExtent;
10091 params2DTo3D.src.image.extent.depth = slicesLayers;
10092 params2DTo3D.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10093 params2DTo3D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10094 params2DTo3D.dst.image.imageType = VK_IMAGE_TYPE_3D;
10095 params2DTo3D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
10096 params2DTo3D.dst.image.extent = defaultHalfExtent;
10097 params2DTo3D.dst.image.extent.depth = slicesLayers;
10098 params2DTo3D.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10099 params2DTo3D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10100 params2DTo3D.allocationKind = allocationKind;
10101 params2DTo3D.extensionUse = extensionUse;
10102
10103 {
10104 const VkImageSubresourceLayers sourceLayer =
10105 {
10106 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10107 0u, // deUint32 mipLevel;
10108 0u, // deUint32 baseArrayLayer;
10109 slicesLayers // deUint32 layerCount;
10110 };
10111
10112 const VkImageSubresourceLayers destinationLayer =
10113 {
10114 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10115 0u, // deUint32 mipLevel;
10116 0u, // deUint32 baseArrayLayer;
10117 1u // deUint32 layerCount;
10118 };
10119
10120 const VkImageCopy testCopy =
10121 {
10122 sourceLayer, // VkImageSubresourceLayers srcSubresource;
10123 {0, 0, 0}, // VkOffset3D srcOffset;
10124 destinationLayer, // VkImageSubresourceLayers dstSubresource;
10125 {0, 0, 0}, // VkOffset3D dstOffset;
10126 params2DTo3D.src.image.extent, // VkExtent3D extent;
10127 };
10128
10129 CopyRegion imageCopy;
10130 imageCopy.imageCopy = testCopy;
10131
10132 params2DTo3D.regions.push_back(imageCopy);
10133 }
10134
10135 group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_whole", "copy 2d layers to 3d slices all at once", params2DTo3D));
10136 }
10137
10138 {
10139 TestParams params3DTo2D;
10140 const deUint32 slicesLayers = 16u;
10141 params3DTo2D.src.image.imageType = VK_IMAGE_TYPE_3D;
10142 params3DTo2D.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
10143 params3DTo2D.src.image.extent = defaultHalfExtent;
10144 params3DTo2D.src.image.extent.depth = slicesLayers;
10145 params3DTo2D.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10146 params3DTo2D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10147 params3DTo2D.dst.image.imageType = VK_IMAGE_TYPE_2D;
10148 params3DTo2D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
10149 params3DTo2D.dst.image.extent = defaultHalfExtent;
10150 params3DTo2D.dst.image.extent.depth = slicesLayers;
10151 params3DTo2D.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10152 params3DTo2D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10153 params3DTo2D.allocationKind = allocationKind;
10154 params3DTo2D.extensionUse = extensionUse;
10155
10156 const deUint32 regionWidth = defaultHalfExtent.width / slicesLayers -1;
10157 const deUint32 regionHeight = defaultHalfExtent.height / slicesLayers -1 ;
10158
10159 for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
10160 {
10161 const VkImageSubresourceLayers sourceLayer =
10162 {
10163 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10164 0u, // deUint32 mipLevel;
10165 0u, // deUint32 baseArrayLayer;
10166 1u // deUint32 layerCount;
10167 };
10168
10169 const VkImageSubresourceLayers destinationLayer =
10170 {
10171 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10172 0u, // deUint32 mipLevel;
10173 slicesLayersNdx, // deUint32 baseArrayLayer;
10174 1u // deUint32 layerCount;
10175 };
10176
10177
10178 const VkImageCopy testCopy =
10179 {
10180 sourceLayer, // VkImageSubresourceLayers srcSubresource;
10181 {0, (deInt32)(regionHeight*slicesLayersNdx), (deInt32)slicesLayersNdx}, // VkOffset3D srcOffset;
10182 destinationLayer, // VkImageSubresourceLayers dstSubresource;
10183 {(deInt32)(regionWidth*slicesLayersNdx), 0, 0}, // VkOffset3D dstOffset;
10184 {
10185 (defaultHalfExtent.width - regionWidth*slicesLayersNdx),
10186 (defaultHalfExtent.height - regionHeight*slicesLayersNdx),
10187 1
10188 } // VkExtent3D extent;
10189 };
10190
10191 CopyRegion imageCopy;
10192 imageCopy.imageCopy = testCopy;
10193 params3DTo2D.regions.push_back(imageCopy);
10194 }
10195 group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_regions", "copy 3d slices regions to 2d layers", params3DTo2D));
10196 }
10197
10198 {
10199 TestParams params2DTo3D;
10200 const deUint32 slicesLayers = 16u;
10201 params2DTo3D.src.image.imageType = VK_IMAGE_TYPE_2D;
10202 params2DTo3D.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
10203 params2DTo3D.src.image.extent = defaultHalfExtent;
10204 params2DTo3D.src.image.extent.depth = slicesLayers;
10205 params2DTo3D.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10206 params2DTo3D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10207 params2DTo3D.dst.image.imageType = VK_IMAGE_TYPE_3D;
10208 params2DTo3D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
10209 params2DTo3D.dst.image.extent = defaultHalfExtent;
10210 params2DTo3D.dst.image.extent.depth = slicesLayers;
10211 params2DTo3D.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10212 params2DTo3D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10213 params2DTo3D.allocationKind = allocationKind;
10214 params2DTo3D.extensionUse = extensionUse;
10215
10216 const deUint32 regionWidth = defaultHalfExtent.width / slicesLayers -1;
10217 const deUint32 regionHeight = defaultHalfExtent.height / slicesLayers -1 ;
10218
10219 for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
10220 {
10221 const VkImageSubresourceLayers sourceLayer =
10222 {
10223 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10224 0u, // deUint32 mipLevel;
10225 slicesLayersNdx, // deUint32 baseArrayLayer;
10226 1u // deUint32 layerCount;
10227 };
10228
10229 const VkImageSubresourceLayers destinationLayer =
10230 {
10231 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10232 0u, // deUint32 mipLevel;
10233 0u, // deUint32 baseArrayLayer;
10234 1u // deUint32 layerCount;
10235 };
10236
10237 const VkImageCopy testCopy =
10238 {
10239 sourceLayer, // VkImageSubresourceLayers srcSubresource;
10240 {(deInt32)(regionWidth*slicesLayersNdx), 0, 0}, // VkOffset3D srcOffset;
10241 destinationLayer, // VkImageSubresourceLayers dstSubresource;
10242 {0, (deInt32)(regionHeight*slicesLayersNdx), (deInt32)(slicesLayersNdx)}, // VkOffset3D dstOffset;
10243 {
10244 defaultHalfExtent.width - regionWidth*slicesLayersNdx,
10245 defaultHalfExtent.height - regionHeight*slicesLayersNdx,
10246 1
10247 } // VkExtent3D extent;
10248 };
10249
10250 CopyRegion imageCopy;
10251 imageCopy.imageCopy = testCopy;
10252
10253 params2DTo3D.regions.push_back(imageCopy);
10254 }
10255
10256 group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_regions", "copy 2d layers regions to 3d slices", params2DTo3D));
10257 }
10258 }
10259
addImageToImageCubeTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)10260 void addImageToImageCubeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10261 {
10262 tcu::TestContext& testCtx = group->getTestContext();
10263
10264 {
10265 TestParams paramsCubeToArray;
10266 const deUint32 arrayLayers = 6u;
10267 paramsCubeToArray.src.image.createFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
10268 paramsCubeToArray.src.image.imageType = VK_IMAGE_TYPE_2D;
10269 paramsCubeToArray.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
10270 paramsCubeToArray.src.image.extent = defaultHalfExtent;
10271 paramsCubeToArray.src.image.extent.depth = arrayLayers;
10272 paramsCubeToArray.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10273 paramsCubeToArray.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10274 paramsCubeToArray.dst.image.createFlags = 0;
10275 paramsCubeToArray.dst.image.imageType = VK_IMAGE_TYPE_2D;
10276 paramsCubeToArray.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
10277 paramsCubeToArray.dst.image.extent = defaultHalfExtent;
10278 paramsCubeToArray.dst.image.extent.depth = arrayLayers;
10279 paramsCubeToArray.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10280 paramsCubeToArray.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10281 paramsCubeToArray.allocationKind = allocationKind;
10282 paramsCubeToArray.extensionUse = extensionUse;
10283
10284 for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
10285 {
10286 const VkImageSubresourceLayers sourceLayer =
10287 {
10288 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10289 0u, // deUint32 mipLevel;
10290 arrayLayersNdx, // deUint32 baseArrayLayer;
10291 1u // deUint32 layerCount;
10292 };
10293
10294 const VkImageSubresourceLayers destinationLayer =
10295 {
10296 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10297 0u, // deUint32 mipLevel;
10298 arrayLayersNdx, // deUint32 baseArrayLayer;
10299 1u // deUint32 layerCount;
10300 };
10301
10302 const VkImageCopy testCopy =
10303 {
10304 sourceLayer, // VkImageSubresourceLayers srcSubresource;
10305 {0, 0, 0}, // VkOffset3D srcOffset;
10306 destinationLayer, // VkImageSubresourceLayers dstSubresource;
10307 {0, 0, 0}, // VkOffset3D dstOffset;
10308 defaultHalfExtent // VkExtent3D extent;
10309 };
10310
10311 CopyRegion imageCopy;
10312 imageCopy.imageCopy = testCopy;
10313
10314 paramsCubeToArray.regions.push_back(imageCopy);
10315 }
10316
10317 group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_array_layers", "copy cube compatible image to 2d layers layer by layer", paramsCubeToArray));
10318 }
10319
10320 {
10321 TestParams paramsCubeToArray;
10322 const deUint32 arrayLayers = 6u;
10323 paramsCubeToArray.src.image.createFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
10324 paramsCubeToArray.src.image.imageType = VK_IMAGE_TYPE_2D;
10325 paramsCubeToArray.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
10326 paramsCubeToArray.src.image.extent = defaultHalfExtent;
10327 paramsCubeToArray.src.image.extent.depth = arrayLayers;
10328 paramsCubeToArray.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10329 paramsCubeToArray.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10330 paramsCubeToArray.dst.image.createFlags = 0;
10331 paramsCubeToArray.dst.image.imageType = VK_IMAGE_TYPE_2D;
10332 paramsCubeToArray.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
10333 paramsCubeToArray.dst.image.extent = defaultHalfExtent;
10334 paramsCubeToArray.dst.image.extent.depth = arrayLayers;
10335 paramsCubeToArray.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10336 paramsCubeToArray.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10337 paramsCubeToArray.allocationKind = allocationKind;
10338 paramsCubeToArray.extensionUse = extensionUse;
10339
10340 {
10341 const VkImageSubresourceLayers sourceLayer =
10342 {
10343 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10344 0u, // deUint32 mipLevel;
10345 0u, // deUint32 baseArrayLayer;
10346 arrayLayers // deUint32 layerCount;
10347 };
10348
10349 const VkImageSubresourceLayers destinationLayer =
10350 {
10351 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10352 0u, // deUint32 mipLevel;
10353 0u, // deUint32 baseArrayLayer;
10354 arrayLayers // deUint32 layerCount;
10355 };
10356
10357 const VkImageCopy testCopy =
10358 {
10359 sourceLayer, // VkImageSubresourceLayers srcSubresource;
10360 {0, 0, 0}, // VkOffset3D srcOffset;
10361 destinationLayer, // VkImageSubresourceLayers dstSubresource;
10362 {0, 0, 0}, // VkOffset3D dstOffset;
10363 defaultHalfExtent // VkExtent3D extent;
10364 };
10365
10366 CopyRegion imageCopy;
10367 imageCopy.imageCopy = testCopy;
10368
10369 paramsCubeToArray.regions.push_back(imageCopy);
10370 }
10371
10372 group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_array_whole", "copy cube compatible image to 2d layers all at once", paramsCubeToArray));
10373 }
10374
10375 {
10376 TestParams paramsArrayToCube;
10377 const deUint32 arrayLayers = 6u;
10378 paramsArrayToCube.src.image.createFlags = 0;
10379 paramsArrayToCube.src.image.imageType = VK_IMAGE_TYPE_2D;
10380 paramsArrayToCube.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
10381 paramsArrayToCube.src.image.extent = defaultHalfExtent;
10382 paramsArrayToCube.src.image.extent.depth = arrayLayers;
10383 paramsArrayToCube.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10384 paramsArrayToCube.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10385 paramsArrayToCube.dst.image.createFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
10386 paramsArrayToCube.dst.image.imageType = VK_IMAGE_TYPE_2D;
10387 paramsArrayToCube.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
10388 paramsArrayToCube.dst.image.extent = defaultHalfExtent;
10389 paramsArrayToCube.dst.image.extent.depth = arrayLayers;
10390 paramsArrayToCube.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10391 paramsArrayToCube.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10392 paramsArrayToCube.allocationKind = allocationKind;
10393 paramsArrayToCube.extensionUse = extensionUse;
10394
10395 for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
10396 {
10397 const VkImageSubresourceLayers sourceLayer =
10398 {
10399 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10400 0u, // deUint32 mipLevel;
10401 arrayLayersNdx, // deUint32 baseArrayLayer;
10402 1u // deUint32 layerCount;
10403 };
10404
10405 const VkImageSubresourceLayers destinationLayer =
10406 {
10407 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10408 0u, // deUint32 mipLevel;
10409 arrayLayersNdx, // deUint32 baseArrayLayer;
10410 1u // deUint32 layerCount;
10411 };
10412
10413 const VkImageCopy testCopy =
10414 {
10415 sourceLayer, // VkImageSubresourceLayers srcSubresource;
10416 {0, 0, 0}, // VkOffset3D srcOffset;
10417 destinationLayer, // VkImageSubresourceLayers dstSubresource;
10418 {0, 0, 0}, // VkOffset3D dstOffset;
10419 defaultHalfExtent // VkExtent3D extent;
10420 };
10421
10422 CopyRegion imageCopy;
10423 imageCopy.imageCopy = testCopy;
10424
10425 paramsArrayToCube.regions.push_back(imageCopy);
10426 }
10427
10428 group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_cube_layers", "copy 2d layers to cube compatible image layer by layer", paramsArrayToCube));
10429 }
10430
10431 {
10432 TestParams paramsArrayToCube;
10433 const deUint32 arrayLayers = 6u;
10434 paramsArrayToCube.src.image.createFlags = 0;
10435 paramsArrayToCube.src.image.imageType = VK_IMAGE_TYPE_2D;
10436 paramsArrayToCube.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
10437 paramsArrayToCube.src.image.extent = defaultHalfExtent;
10438 paramsArrayToCube.src.image.extent.depth = arrayLayers;
10439 paramsArrayToCube.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10440 paramsArrayToCube.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10441 paramsArrayToCube.dst.image.createFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
10442 paramsArrayToCube.dst.image.imageType = VK_IMAGE_TYPE_2D;
10443 paramsArrayToCube.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
10444 paramsArrayToCube.dst.image.extent = defaultHalfExtent;
10445 paramsArrayToCube.dst.image.extent.depth = arrayLayers;
10446 paramsArrayToCube.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10447 paramsArrayToCube.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10448 paramsArrayToCube.allocationKind = allocationKind;
10449 paramsArrayToCube.extensionUse = extensionUse;
10450
10451 {
10452 const VkImageSubresourceLayers sourceLayer =
10453 {
10454 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10455 0u, // deUint32 mipLevel;
10456 0u, // deUint32 baseArrayLayer;
10457 arrayLayers // deUint32 layerCount;
10458 };
10459
10460 const VkImageSubresourceLayers destinationLayer =
10461 {
10462 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10463 0u, // deUint32 mipLevel;
10464 0u, // deUint32 baseArrayLayer;
10465 arrayLayers // deUint32 layerCount;
10466 };
10467
10468 const VkImageCopy testCopy =
10469 {
10470 sourceLayer, // VkImageSubresourceLayers srcSubresource;
10471 {0, 0, 0}, // VkOffset3D srcOffset;
10472 destinationLayer, // VkImageSubresourceLayers dstSubresource;
10473 {0, 0, 0}, // VkOffset3D dstOffset;
10474 defaultHalfExtent // VkExtent3D extent;
10475 };
10476
10477 CopyRegion imageCopy;
10478 imageCopy.imageCopy = testCopy;
10479
10480 paramsArrayToCube.regions.push_back(imageCopy);
10481 }
10482
10483 group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_cube_whole", "copy 2d layers to cube compatible image all at once", paramsArrayToCube));
10484 }
10485
10486 {
10487 TestParams paramsCubeToArray;
10488 const deUint32 arrayLayers = 6u;
10489 paramsCubeToArray.src.image.createFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
10490 paramsCubeToArray.src.image.imageType = VK_IMAGE_TYPE_2D;
10491 paramsCubeToArray.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
10492 paramsCubeToArray.src.image.extent = defaultHalfExtent;
10493 paramsCubeToArray.src.image.extent.depth = arrayLayers;
10494 paramsCubeToArray.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10495 paramsCubeToArray.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10496 paramsCubeToArray.dst.image.createFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
10497 paramsCubeToArray.dst.image.imageType = VK_IMAGE_TYPE_2D;
10498 paramsCubeToArray.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
10499 paramsCubeToArray.dst.image.extent = defaultHalfExtent;
10500 paramsCubeToArray.dst.image.extent.depth = arrayLayers;
10501 paramsCubeToArray.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10502 paramsCubeToArray.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10503 paramsCubeToArray.allocationKind = allocationKind;
10504 paramsCubeToArray.extensionUse = extensionUse;
10505
10506 for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
10507 {
10508 const VkImageSubresourceLayers sourceLayer =
10509 {
10510 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10511 0u, // deUint32 mipLevel;
10512 arrayLayersNdx, // deUint32 baseArrayLayer;
10513 1u // deUint32 layerCount;
10514 };
10515
10516 const VkImageSubresourceLayers destinationLayer =
10517 {
10518 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10519 0u, // deUint32 mipLevel;
10520 arrayLayersNdx, // deUint32 baseArrayLayer;
10521 1u // deUint32 layerCount;
10522 };
10523
10524 const VkImageCopy testCopy =
10525 {
10526 sourceLayer, // VkImageSubresourceLayers srcSubresource;
10527 {0, 0, 0}, // VkOffset3D srcOffset;
10528 destinationLayer, // VkImageSubresourceLayers dstSubresource;
10529 {0, 0, 0}, // VkOffset3D dstOffset;
10530 defaultHalfExtent // VkExtent3D extent;
10531 };
10532
10533 CopyRegion imageCopy;
10534 imageCopy.imageCopy = testCopy;
10535
10536 paramsCubeToArray.regions.push_back(imageCopy);
10537 }
10538
10539 group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_cube_layers", "copy cube compatible image to cube compatible image layer by layer", paramsCubeToArray));
10540 }
10541
10542 {
10543 TestParams paramsCubeToCube;
10544 const deUint32 arrayLayers = 6u;
10545 paramsCubeToCube.src.image.createFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
10546 paramsCubeToCube.src.image.imageType = VK_IMAGE_TYPE_2D;
10547 paramsCubeToCube.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
10548 paramsCubeToCube.src.image.extent = defaultHalfExtent;
10549 paramsCubeToCube.src.image.extent.depth = arrayLayers;
10550 paramsCubeToCube.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10551 paramsCubeToCube.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10552 paramsCubeToCube.dst.image.createFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
10553 paramsCubeToCube.dst.image.imageType = VK_IMAGE_TYPE_2D;
10554 paramsCubeToCube.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
10555 paramsCubeToCube.dst.image.extent = defaultHalfExtent;
10556 paramsCubeToCube.dst.image.extent.depth = arrayLayers;
10557 paramsCubeToCube.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10558 paramsCubeToCube.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10559 paramsCubeToCube.allocationKind = allocationKind;
10560 paramsCubeToCube.extensionUse = extensionUse;
10561
10562 {
10563 const VkImageSubresourceLayers sourceLayer =
10564 {
10565 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10566 0u, // deUint32 mipLevel;
10567 0u, // deUint32 baseArrayLayer;
10568 arrayLayers // deUint32 layerCount;
10569 };
10570
10571 const VkImageSubresourceLayers destinationLayer =
10572 {
10573 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10574 0u, // deUint32 mipLevel;
10575 0u, // deUint32 baseArrayLayer;
10576 arrayLayers // deUint32 layerCount;
10577 };
10578
10579 const VkImageCopy testCopy =
10580 {
10581 sourceLayer, // VkImageSubresourceLayers srcSubresource;
10582 {0, 0, 0}, // VkOffset3D srcOffset;
10583 destinationLayer, // VkImageSubresourceLayers dstSubresource;
10584 {0, 0, 0}, // VkOffset3D dstOffset;
10585 defaultHalfExtent // VkExtent3D extent;
10586 };
10587
10588 CopyRegion imageCopy;
10589 imageCopy.imageCopy = testCopy;
10590
10591 paramsCubeToCube.regions.push_back(imageCopy);
10592 }
10593
10594 group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_cube_whole", "copy cube compatible image to cube compatible image all at once", paramsCubeToCube));
10595 }
10596 }
10597
addImageToImageArrayTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)10598 void addImageToImageArrayTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10599 {
10600 tcu::TestContext& testCtx = group->getTestContext();
10601
10602 {
10603 TestParams paramsArrayToArray;
10604 const deUint32 arrayLayers = 16u;
10605 paramsArrayToArray.src.image.imageType = VK_IMAGE_TYPE_2D;
10606 paramsArrayToArray.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
10607 paramsArrayToArray.src.image.extent = defaultHalfExtent;
10608 paramsArrayToArray.src.image.extent.depth = arrayLayers;
10609 paramsArrayToArray.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10610 paramsArrayToArray.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10611 paramsArrayToArray.dst.image.imageType = VK_IMAGE_TYPE_2D;
10612 paramsArrayToArray.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
10613 paramsArrayToArray.dst.image.extent = defaultHalfExtent;
10614 paramsArrayToArray.dst.image.extent.depth = arrayLayers;
10615 paramsArrayToArray.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10616 paramsArrayToArray.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10617 paramsArrayToArray.allocationKind = allocationKind;
10618 paramsArrayToArray.extensionUse = extensionUse;
10619
10620 for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
10621 {
10622 const VkImageSubresourceLayers sourceLayer =
10623 {
10624 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10625 0u, // deUint32 mipLevel;
10626 arrayLayersNdx, // deUint32 baseArrayLayer;
10627 1u // deUint32 layerCount;
10628 };
10629
10630 const VkImageSubresourceLayers destinationLayer =
10631 {
10632 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10633 0u, // deUint32 mipLevel;
10634 arrayLayersNdx, // deUint32 baseArrayLayer;
10635 1u // deUint32 layerCount;
10636 };
10637
10638 const VkImageCopy testCopy =
10639 {
10640 sourceLayer, // VkImageSubresourceLayers srcSubresource;
10641 {0, 0, 0}, // VkOffset3D srcOffset;
10642 destinationLayer, // VkImageSubresourceLayers dstSubresource;
10643 {0, 0, 0}, // VkOffset3D dstOffset;
10644 defaultHalfExtent // VkExtent3D extent;
10645 };
10646
10647 CopyRegion imageCopy;
10648 imageCopy.imageCopy = testCopy;
10649
10650 paramsArrayToArray.regions.push_back(imageCopy);
10651 }
10652
10653 group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_array_layers", "copy 2d array image to 2d array image layer by layer", paramsArrayToArray));
10654 }
10655
10656 {
10657 TestParams paramsArrayToArray;
10658 const deUint32 arrayLayers = 16u;
10659 paramsArrayToArray.src.image.imageType = VK_IMAGE_TYPE_2D;
10660 paramsArrayToArray.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
10661 paramsArrayToArray.src.image.extent = defaultHalfExtent;
10662 paramsArrayToArray.src.image.extent.depth = arrayLayers;
10663 paramsArrayToArray.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10664 paramsArrayToArray.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10665 paramsArrayToArray.dst.image.imageType = VK_IMAGE_TYPE_2D;
10666 paramsArrayToArray.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
10667 paramsArrayToArray.dst.image.extent = defaultHalfExtent;
10668 paramsArrayToArray.dst.image.extent.depth = arrayLayers;
10669 paramsArrayToArray.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10670 paramsArrayToArray.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10671 paramsArrayToArray.allocationKind = allocationKind;
10672 paramsArrayToArray.extensionUse = extensionUse;
10673
10674 {
10675 const VkImageSubresourceLayers sourceLayer =
10676 {
10677 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10678 0u, // deUint32 mipLevel;
10679 0u, // deUint32 baseArrayLayer;
10680 arrayLayers // deUint32 layerCount;
10681 };
10682
10683 const VkImageSubresourceLayers destinationLayer =
10684 {
10685 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10686 0u, // deUint32 mipLevel;
10687 0u, // deUint32 baseArrayLayer;
10688 arrayLayers // deUint32 layerCount;
10689 };
10690
10691 const VkImageCopy testCopy =
10692 {
10693 sourceLayer, // VkImageSubresourceLayers srcSubresource;
10694 {0, 0, 0}, // VkOffset3D srcOffset;
10695 destinationLayer, // VkImageSubresourceLayers dstSubresource;
10696 {0, 0, 0}, // VkOffset3D dstOffset;
10697 defaultHalfExtent // VkExtent3D extent;
10698 };
10699
10700 CopyRegion imageCopy;
10701 imageCopy.imageCopy = testCopy;
10702
10703 paramsArrayToArray.regions.push_back(imageCopy);
10704 }
10705
10706 group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_array_whole", "copy 2d array image to 2d array image all at once", paramsArrayToArray));
10707 }
10708
10709 {
10710 TestParams paramsArrayToArray;
10711 const deUint32 arrayLayers = 16u;
10712 paramsArrayToArray.src.image.imageType = VK_IMAGE_TYPE_2D;
10713 paramsArrayToArray.src.image.extent = defaultHalfExtent;
10714 paramsArrayToArray.src.image.extent.depth = arrayLayers;
10715 paramsArrayToArray.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10716 paramsArrayToArray.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10717 paramsArrayToArray.dst.image.imageType = VK_IMAGE_TYPE_2D;
10718 paramsArrayToArray.dst.image.extent = defaultHalfExtent;
10719 paramsArrayToArray.dst.image.extent.depth = arrayLayers;
10720 paramsArrayToArray.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10721 paramsArrayToArray.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10722 paramsArrayToArray.allocationKind = allocationKind;
10723 paramsArrayToArray.extensionUse = extensionUse;
10724 paramsArrayToArray.mipLevels = deLog2Floor32(deMaxu32(defaultHalfExtent.width, defaultHalfExtent.height)) + 1u;
10725
10726 for (deUint32 mipLevelNdx = 0u; mipLevelNdx < paramsArrayToArray.mipLevels; mipLevelNdx++)
10727 {
10728 const VkImageSubresourceLayers sourceLayer =
10729 {
10730 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10731 mipLevelNdx, // deUint32 mipLevel;
10732 0u, // deUint32 baseArrayLayer;
10733 arrayLayers // deUint32 layerCount;
10734 };
10735
10736 const VkImageSubresourceLayers destinationLayer =
10737 {
10738 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10739 mipLevelNdx, // deUint32 mipLevel;
10740 0u, // deUint32 baseArrayLayer;
10741 arrayLayers // deUint32 layerCount;
10742 };
10743
10744 const VkExtent3D extent =
10745 {
10746 (deUint32)deMax(defaultHalfExtent.width >> mipLevelNdx, 1), // deUint32 width;
10747 (deUint32)deMax(defaultHalfExtent.height >> mipLevelNdx, 1), // deUint32 height;
10748 1u, // deUint32 depth;
10749 };
10750
10751 const VkImageCopy testCopy =
10752 {
10753 sourceLayer, // VkImageSubresourceLayers srcSubresource;
10754 {0, 0, 0}, // VkOffset3D srcOffset;
10755 destinationLayer, // VkImageSubresourceLayers dstSubresource;
10756 {0, 0, 0}, // VkOffset3D dstOffset;
10757 extent // VkExtent3D extent;
10758 };
10759
10760 CopyRegion imageCopy;
10761 imageCopy.imageCopy = testCopy;
10762
10763 paramsArrayToArray.regions.push_back(imageCopy);
10764 }
10765
10766 VkFormat imageFormats [] = { VK_FORMAT_R8G8B8A8_UINT, VK_FORMAT_D32_SFLOAT, VK_FORMAT_D16_UNORM, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_S8_UINT};
10767
10768 for (deUint32 imageFormatsNdx = 0; imageFormatsNdx < DE_LENGTH_OF_ARRAY(imageFormats); imageFormatsNdx++)
10769 {
10770 paramsArrayToArray.src.image.format = imageFormats[imageFormatsNdx];
10771 paramsArrayToArray.dst.image.format = imageFormats[imageFormatsNdx];
10772 for (deUint32 regionNdx = 0u; regionNdx < paramsArrayToArray.regions.size(); regionNdx++)
10773 {
10774 paramsArrayToArray.regions[regionNdx].imageCopy.srcSubresource.aspectMask = getImageAspectFlags(mapVkFormat(imageFormats[imageFormatsNdx]));
10775 paramsArrayToArray.regions[regionNdx].imageCopy.dstSubresource.aspectMask = getImageAspectFlags(mapVkFormat(imageFormats[imageFormatsNdx]));
10776 }
10777 std::ostringstream testName;
10778 const std::string formatName = getFormatName(imageFormats[imageFormatsNdx]);
10779 testName << "array_to_array_whole_mipmap_" << de::toLower(formatName.substr(10));
10780 group->addChild(new CopyImageToImageMipmapTestCase(testCtx, testName.str(), "copy 2d array mipmap image to 2d array mipmap image all at once", paramsArrayToArray));
10781 }
10782 }
10783 }
10784
addImageToImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)10785 void addImageToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10786 {
10787 addTestGroup(group, "simple_tests", "Copy from image to image simple tests", addImageToImageSimpleTests, allocationKind, extensionUse);
10788 addTestGroup(group, "all_formats", "Copy from image to image with all compatible formats", addImageToImageAllFormatsTests, allocationKind, extensionUse);
10789 addTestGroup(group, "3d_images", "Coping operations on 3d images", addImageToImage3dImagesTests, allocationKind, extensionUse);
10790 addTestGroup(group, "dimensions", "Copying operations on different image dimensions", addImageToImageDimensionsTests, allocationKind, extensionUse);
10791 addTestGroup(group, "cube", "Coping operations on cube compatible images", addImageToImageCubeTests, allocationKind, extensionUse);
10792 addTestGroup(group, "array", "Copying operations on array of images", addImageToImageArrayTests, allocationKind, extensionUse);
10793 }
10794
add1dImageToBufferTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)10795 void add1dImageToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10796 {
10797 tcu::TestContext& testCtx = group->getTestContext();
10798
10799 {
10800 TestParams params;
10801 params.src.image.imageType = VK_IMAGE_TYPE_1D;
10802 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
10803 params.src.image.extent = default1dExtent;
10804 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10805 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10806 params.dst.buffer.size = defaultSize;
10807 params.allocationKind = allocationKind;
10808 params.extensionUse = extensionUse;
10809
10810 const VkBufferImageCopy bufferImageCopy =
10811 {
10812 0u, // VkDeviceSize bufferOffset;
10813 0u, // deUint32 bufferRowLength;
10814 0u, // deUint32 bufferImageHeight;
10815 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
10816 {0, 0, 0}, // VkOffset3D imageOffset;
10817 default1dExtent // VkExtent3D imageExtent;
10818 };
10819 CopyRegion copyRegion;
10820 copyRegion.bufferImageCopy = bufferImageCopy;
10821
10822 params.regions.push_back(copyRegion);
10823
10824 group->addChild(new CopyImageToBufferTestCase(testCtx, "tightly_sized_buffer", "Copy from image to a buffer that is just large enough to contain the data", params));
10825 }
10826
10827 {
10828 TestParams params;
10829 deUint32 bufferImageHeight = defaultSize + 1u;
10830 params.src.image.imageType = VK_IMAGE_TYPE_1D;
10831 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
10832 params.src.image.extent = default1dExtent;
10833 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10834 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10835 params.dst.buffer.size = bufferImageHeight;
10836 params.allocationKind = allocationKind;
10837 params.extensionUse = extensionUse;
10838
10839 const VkBufferImageCopy bufferImageCopy =
10840 {
10841 0u, // VkDeviceSize bufferOffset;
10842 0u, // deUint32 bufferRowLength;
10843 bufferImageHeight, // deUint32 bufferImageHeight;
10844 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
10845 {0, 0, 0}, // VkOffset3D imageOffset;
10846 default1dExtent // VkExtent3D imageExtent;
10847 };
10848 CopyRegion copyRegion;
10849 copyRegion.bufferImageCopy = bufferImageCopy;
10850
10851 params.regions.push_back(copyRegion);
10852
10853 group->addChild(new CopyImageToBufferTestCase(testCtx, "larger_buffer", "Copy from image to a buffer that is larger than necessary", params));
10854 }
10855
10856 {
10857 TestParams params;
10858 deUint32 arrayLayers = 16u;
10859 params.src.image.imageType = VK_IMAGE_TYPE_1D;
10860 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
10861 params.src.image.extent = default1dExtent;
10862 params.src.image.extent.depth = arrayLayers;
10863 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10864 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10865 params.dst.buffer.size = defaultSize * arrayLayers;
10866 params.allocationKind = allocationKind;
10867 params.extensionUse = extensionUse;
10868
10869 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.src.image.format));
10870 for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
10871 {
10872 const VkDeviceSize offset = defaultSize * pixelSize * arrayLayerNdx;
10873 const VkBufferImageCopy bufferImageCopy =
10874 {
10875 offset, // VkDeviceSize bufferOffset;
10876 0u, // deUint32 bufferRowLength;
10877 defaultSize, // deUint32 bufferImageHeight;
10878 {
10879 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10880 0u, // deUint32 mipLevel;
10881 arrayLayerNdx, // deUint32 baseArrayLayer;
10882 1u, // deUint32 layerCount;
10883 }, // VkImageSubresourceLayers imageSubresource;
10884 {0, 0, 0}, // VkOffset3D imageOffset;
10885 default1dExtent // VkExtent3D imageExtent;
10886 };
10887 CopyRegion copyRegion;
10888 copyRegion.bufferImageCopy = bufferImageCopy;
10889
10890 params.regions.push_back(copyRegion);
10891 }
10892
10893 group->addChild(new CopyImageToBufferTestCase(testCtx, "array_tightly_sized_buffer", "Copy each layer from array to tightly sized buffer", params));
10894 }
10895
10896 {
10897 TestParams params;
10898 deUint32 arrayLayers = 16u;
10899 deUint32 bufferImageHeight = defaultSize + 1u;
10900 params.src.image.imageType = VK_IMAGE_TYPE_1D;
10901 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
10902 params.src.image.extent = default1dExtent;
10903 params.src.image.extent.depth = arrayLayers;
10904 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10905 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10906 params.dst.buffer.size = bufferImageHeight * arrayLayers;
10907 params.allocationKind = allocationKind;
10908 params.extensionUse = extensionUse;
10909
10910 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.src.image.format));
10911 for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
10912 {
10913 const VkDeviceSize offset = bufferImageHeight * pixelSize * arrayLayerNdx;
10914 const VkBufferImageCopy bufferImageCopy =
10915 {
10916 offset, // VkDeviceSize bufferOffset;
10917 0u, // deUint32 bufferRowLength;
10918 bufferImageHeight, // deUint32 bufferImageHeight;
10919 {
10920 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
10921 0u, // deUint32 mipLevel;
10922 arrayLayerNdx, // deUint32 baseArrayLayer;
10923 1u, // deUint32 layerCount;
10924 }, // VkImageSubresourceLayers imageSubresource;
10925 {0, 0, 0}, // VkOffset3D imageOffset;
10926 default1dExtent // VkExtent3D imageExtent;
10927 };
10928 CopyRegion copyRegion;
10929 copyRegion.bufferImageCopy = bufferImageCopy;
10930
10931 params.regions.push_back(copyRegion);
10932 }
10933
10934 group->addChild(new CopyImageToBufferTestCase(testCtx, "array_larger_buffer", "Copy each layer from array to a buffer that is larger than necessary", params));
10935 }
10936 }
10937
add2dImageToBufferTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)10938 void add2dImageToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10939 {
10940 tcu::TestContext& testCtx = group->getTestContext();
10941
10942 {
10943 TestParams params;
10944 params.src.image.imageType = VK_IMAGE_TYPE_2D;
10945 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
10946 params.src.image.extent = defaultExtent;
10947 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10948 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10949 params.dst.buffer.size = defaultSize * defaultSize;
10950 params.allocationKind = allocationKind;
10951 params.extensionUse = extensionUse;
10952
10953 const VkBufferImageCopy bufferImageCopy =
10954 {
10955 0u, // VkDeviceSize bufferOffset;
10956 0u, // deUint32 bufferRowLength;
10957 0u, // deUint32 bufferImageHeight;
10958 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
10959 {0, 0, 0}, // VkOffset3D imageOffset;
10960 defaultExtent // VkExtent3D imageExtent;
10961 };
10962 CopyRegion copyRegion;
10963 copyRegion.bufferImageCopy = bufferImageCopy;
10964
10965 params.regions.push_back(copyRegion);
10966
10967 group->addChild(new CopyImageToBufferTestCase(testCtx, "whole", "Copy from image to buffer", params));
10968 }
10969
10970 {
10971 TestParams params;
10972 params.src.image.imageType = VK_IMAGE_TYPE_2D;
10973 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
10974 params.src.image.extent = defaultExtent;
10975 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10976 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10977 params.dst.buffer.size = defaultSize * defaultSize;
10978 params.allocationKind = allocationKind;
10979 params.extensionUse = extensionUse;
10980
10981 const VkBufferImageCopy bufferImageCopy =
10982 {
10983 defaultSize * defaultHalfSize, // VkDeviceSize bufferOffset;
10984 0u, // deUint32 bufferRowLength;
10985 0u, // deUint32 bufferImageHeight;
10986 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
10987 {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
10988 defaultHalfExtent // VkExtent3D imageExtent;
10989 };
10990 CopyRegion copyRegion;
10991 copyRegion.bufferImageCopy = bufferImageCopy;
10992
10993 params.regions.push_back(copyRegion);
10994
10995 group->addChild(new CopyImageToBufferTestCase(testCtx, "buffer_offset", "Copy from image to buffer with buffer offset", params));
10996 }
10997
10998 {
10999 TestParams params;
11000 params.src.image.imageType = VK_IMAGE_TYPE_2D;
11001 params.src.image.format = VK_FORMAT_R8_UNORM;
11002 params.src.image.extent = defaultExtent;
11003 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11004 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11005 params.dst.buffer.size = defaultSize * defaultSize;
11006 params.allocationKind = allocationKind;
11007 params.extensionUse = extensionUse;
11008
11009 const VkBufferImageCopy bufferImageCopy =
11010 {
11011 defaultSize * defaultHalfSize + 1u, // VkDeviceSize bufferOffset;
11012 0u, // deUint32 bufferRowLength;
11013 0u, // deUint32 bufferImageHeight;
11014 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
11015 {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
11016 defaultHalfExtent // VkExtent3D imageExtent;
11017 };
11018 CopyRegion copyRegion;
11019 copyRegion.bufferImageCopy = bufferImageCopy;
11020
11021 params.regions.push_back(copyRegion);
11022
11023 group->addChild(new CopyImageToBufferTestCase(testCtx, "buffer_offset_relaxed", "Copy from image to buffer with buffer offset not a multiple of 4", params));
11024 }
11025
11026 {
11027 TestParams params;
11028 params.src.image.imageType = VK_IMAGE_TYPE_2D;
11029 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
11030 params.src.image.extent = defaultExtent;
11031 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11032 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11033 params.dst.buffer.size = defaultSize * defaultSize;
11034 params.allocationKind = allocationKind;
11035 params.extensionUse = extensionUse;
11036
11037 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.src.image.format));
11038 const VkDeviceSize bufferSize = pixelSize * params.dst.buffer.size;
11039 const VkDeviceSize offsetSize = pixelSize * defaultQuarterSize * defaultQuarterSize;
11040 deUint32 divisor = 1;
11041 for (VkDeviceSize offset = 0; offset < bufferSize - offsetSize; offset += offsetSize, ++divisor)
11042 {
11043 const deUint32 bufferRowLength = defaultQuarterSize;
11044 const deUint32 bufferImageHeight = defaultQuarterSize;
11045 const VkExtent3D imageExtent = {defaultQuarterSize / divisor, defaultQuarterSize, 1};
11046 DE_ASSERT(!bufferRowLength || bufferRowLength >= imageExtent.width);
11047 DE_ASSERT(!bufferImageHeight || bufferImageHeight >= imageExtent.height);
11048 DE_ASSERT(imageExtent.width * imageExtent.height *imageExtent.depth <= offsetSize);
11049
11050 CopyRegion region;
11051 const VkBufferImageCopy bufferImageCopy =
11052 {
11053 offset, // VkDeviceSize bufferOffset;
11054 bufferRowLength, // deUint32 bufferRowLength;
11055 bufferImageHeight, // deUint32 bufferImageHeight;
11056 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
11057 {0, 0, 0}, // VkOffset3D imageOffset;
11058 imageExtent // VkExtent3D imageExtent;
11059 };
11060 region.bufferImageCopy = bufferImageCopy;
11061 params.regions.push_back(region);
11062 }
11063
11064 group->addChild(new CopyImageToBufferTestCase(testCtx, "regions", "Copy from image to buffer with multiple regions", params));
11065 }
11066
11067 {
11068 TestParams params;
11069 params.src.image.imageType = VK_IMAGE_TYPE_2D;
11070 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
11071 params.src.image.extent = defaultExtent;
11072 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11073 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11074 params.dst.buffer.size = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize;
11075 params.allocationKind = allocationKind;
11076 params.extensionUse = extensionUse;
11077
11078 const VkBufferImageCopy bufferImageCopy =
11079 {
11080 0u, // VkDeviceSize bufferOffset;
11081 defaultSize, // deUint32 bufferRowLength;
11082 defaultSize, // deUint32 bufferImageHeight;
11083 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
11084 {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
11085 defaultHalfExtent // VkExtent3D imageExtent;
11086 };
11087 CopyRegion copyRegion;
11088 copyRegion.bufferImageCopy = bufferImageCopy;
11089
11090 params.regions.push_back(copyRegion);
11091
11092 group->addChild(new CopyImageToBufferTestCase(testCtx, "tightly_sized_buffer", "Copy from image to a buffer that is just large enough to contain the data", params));
11093 }
11094
11095 {
11096 TestParams params;
11097 deUint32 bufferImageHeight = defaultSize + 1u;
11098 params.src.image.imageType = VK_IMAGE_TYPE_2D;
11099 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
11100 params.src.image.extent = defaultExtent;
11101 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11102 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11103 params.dst.buffer.size = bufferImageHeight * defaultSize;
11104 params.allocationKind = allocationKind;
11105 params.extensionUse = extensionUse;
11106
11107 const VkBufferImageCopy bufferImageCopy =
11108 {
11109 0u, // VkDeviceSize bufferOffset;
11110 defaultSize, // deUint32 bufferRowLength;
11111 bufferImageHeight, // deUint32 bufferImageHeight;
11112 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
11113 {0, 0, 0}, // VkOffset3D imageOffset;
11114 defaultExtent // VkExtent3D imageExtent;
11115 };
11116 CopyRegion copyRegion;
11117 copyRegion.bufferImageCopy = bufferImageCopy;
11118
11119 params.regions.push_back(copyRegion);
11120
11121 group->addChild(new CopyImageToBufferTestCase(testCtx, "larger_buffer", "Copy from image to a buffer that is larger than necessary", params));
11122 }
11123
11124 {
11125 TestParams params;
11126 params.src.image.imageType = VK_IMAGE_TYPE_2D;
11127 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
11128 params.src.image.extent = defaultExtent;
11129 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11130 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11131 params.dst.buffer.size = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultQuarterSize;
11132 params.allocationKind = allocationKind;
11133 params.extensionUse = extensionUse;
11134
11135 const VkBufferImageCopy bufferImageCopy =
11136 {
11137 defaultQuarterSize, // VkDeviceSize bufferOffset;
11138 defaultSize, // deUint32 bufferRowLength;
11139 defaultSize, // deUint32 bufferImageHeight;
11140 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
11141 {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
11142 defaultHalfExtent // VkExtent3D imageExtent;
11143 };
11144 CopyRegion copyRegion;
11145 copyRegion.bufferImageCopy = bufferImageCopy;
11146
11147 params.regions.push_back(copyRegion);
11148
11149 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));
11150 }
11151
11152 {
11153 TestParams params;
11154 deUint32 arrayLayers = 16u;
11155 params.src.image.imageType = VK_IMAGE_TYPE_2D;
11156 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
11157 params.src.image.extent = defaultHalfExtent;
11158 params.src.image.extent.depth = arrayLayers;
11159 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11160 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11161 params.dst.buffer.size = defaultHalfSize * defaultHalfSize * arrayLayers;
11162 params.allocationKind = allocationKind;
11163 params.extensionUse = extensionUse;
11164
11165 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.src.image.format));
11166 for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
11167 {
11168 const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
11169 const VkBufferImageCopy bufferImageCopy =
11170 {
11171 offset, // VkDeviceSize bufferOffset;
11172 0u, // deUint32 bufferRowLength;
11173 0u, // deUint32 bufferImageHeight;
11174 {
11175 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11176 0u, // deUint32 mipLevel;
11177 arrayLayerNdx, // deUint32 baseArrayLayer;
11178 1u, // deUint32 layerCount;
11179 }, // VkImageSubresourceLayers imageSubresource;
11180 {0, 0, 0}, // VkOffset3D imageOffset;
11181 defaultHalfExtent // VkExtent3D imageExtent;
11182 };
11183 CopyRegion copyRegion;
11184 copyRegion.bufferImageCopy = bufferImageCopy;
11185
11186 params.regions.push_back(copyRegion);
11187 }
11188 group->addChild(new CopyImageToBufferTestCase(testCtx, "array", "Copy each layer from array to buffer", params));
11189 }
11190
11191 {
11192 TestParams params;
11193 deUint32 arrayLayers = 16u;
11194 deUint32 imageBufferHeight = defaultHalfSize + 1u;
11195 params.src.image.imageType = VK_IMAGE_TYPE_2D;
11196 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
11197 params.src.image.extent = defaultHalfExtent;
11198 params.src.image.extent.depth = arrayLayers;
11199 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11200 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11201 params.dst.buffer.size = defaultHalfSize * imageBufferHeight * arrayLayers;
11202 params.allocationKind = allocationKind;
11203 params.extensionUse = extensionUse;
11204
11205 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.src.image.format));
11206 for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
11207 {
11208 const VkDeviceSize offset = defaultHalfSize * imageBufferHeight * pixelSize * arrayLayerNdx;
11209 const VkBufferImageCopy bufferImageCopy =
11210 {
11211 offset, // VkDeviceSize bufferOffset;
11212 0u, // deUint32 bufferRowLength;
11213 imageBufferHeight, // deUint32 bufferImageHeight;
11214 {
11215 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11216 0u, // deUint32 mipLevel;
11217 arrayLayerNdx, // deUint32 baseArrayLayer;
11218 1u, // deUint32 layerCount;
11219 }, // VkImageSubresourceLayers imageSubresource;
11220 {0, 0, 0}, // VkOffset3D imageOffset;
11221 defaultHalfExtent // VkExtent3D imageExtent;
11222 };
11223 CopyRegion copyRegion;
11224 copyRegion.bufferImageCopy = bufferImageCopy;
11225
11226 params.regions.push_back(copyRegion);
11227 }
11228 group->addChild(new CopyImageToBufferTestCase(testCtx, "array_larger_buffer", "Copy each layer from array to a buffer that is larger than necessary", params));
11229 }
11230
11231 {
11232 TestParams params;
11233 deUint32 arrayLayers = 16u;
11234 params.src.image.imageType = VK_IMAGE_TYPE_2D;
11235 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
11236 params.src.image.extent = defaultHalfExtent;
11237 params.src.image.extent.depth = arrayLayers;
11238 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11239 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11240 params.dst.buffer.size = defaultHalfSize * defaultHalfSize * arrayLayers;
11241 params.allocationKind = allocationKind;
11242 params.extensionUse = extensionUse;
11243
11244 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.src.image.format));
11245 for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
11246 {
11247 const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
11248 const VkBufferImageCopy bufferImageCopy =
11249 {
11250 offset, // VkDeviceSize bufferOffset;
11251 defaultHalfSize, // deUint32 bufferRowLength;
11252 defaultHalfSize, // deUint32 bufferImageHeight;
11253 {
11254 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11255 0u, // deUint32 mipLevel;
11256 arrayLayerNdx, // deUint32 baseArrayLayer;
11257 1u, // deUint32 layerCount;
11258 }, // VkImageSubresourceLayers imageSubresource;
11259 {0, 0, 0}, // VkOffset3D imageOffset;
11260 defaultHalfExtent // VkExtent3D imageExtent;
11261 };
11262 CopyRegion copyRegion;
11263 copyRegion.bufferImageCopy = bufferImageCopy;
11264
11265 params.regions.push_back(copyRegion);
11266 }
11267 group->addChild(new CopyImageToBufferTestCase(testCtx, "array_tightly_sized_buffer", "Copy each layer from array to tightly sized buffer", params));
11268 }
11269 }
11270
addImageToBufferTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)11271 void addImageToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11272 {
11273 addTestGroup(group, "1d_images", "Copying operations on 1d images", add1dImageToBufferTests, allocationKind, extensionUse);
11274 addTestGroup(group, "2d_images", "Copying operations on 2d images", add2dImageToBufferTests, allocationKind, extensionUse);
11275 }
11276
addBufferToDepthStencilTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)11277 void addBufferToDepthStencilTests(tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11278 {
11279 tcu::TestContext& testCtx = group->getTestContext();
11280
11281 const struct
11282 {
11283 const char* name;
11284 const VkFormat format;
11285 } depthAndStencilFormats[] =
11286 {
11287 { "d16_unorm", VK_FORMAT_D16_UNORM },
11288 { "x8_d24_unorm_pack32", VK_FORMAT_X8_D24_UNORM_PACK32 },
11289 { "d32_sfloat", VK_FORMAT_D32_SFLOAT },
11290 { "d16_unorm_s8_uint", VK_FORMAT_D16_UNORM_S8_UINT },
11291 { "d24_unorm_s8_uint", VK_FORMAT_D24_UNORM_S8_UINT },
11292 { "d32_sfloat_s8_uint", VK_FORMAT_D32_SFLOAT_S8_UINT }
11293 };
11294
11295 const VkImageSubresourceLayers depthSourceLayer =
11296 {
11297 VK_IMAGE_ASPECT_DEPTH_BIT, // VkImageAspectFlags aspectMask;
11298 0u, // deUint32 mipLevel;
11299 0u, // deUint32 baseArrayLayer;
11300 1u, // deUint32 layerCount;
11301 };
11302
11303 const VkBufferImageCopy bufferDepthCopy =
11304 {
11305 0u, // VkDeviceSize bufferOffset;
11306 0u, // deUint32 bufferRowLength;
11307 0u, // deUint32 bufferImageHeight;
11308 depthSourceLayer, // VkImageSubresourceLayers imageSubresource;
11309 {0, 0, 0}, // VkOffset3D imageOffset;
11310 defaultExtent // VkExtent3D imageExtent;
11311 };
11312
11313 const VkBufferImageCopy bufferDepthCopyOffset =
11314 {
11315 32, // VkDeviceSize bufferOffset;
11316 defaultHalfSize + defaultQuarterSize, // deUint32 bufferRowLength;
11317 defaultHalfSize + defaultQuarterSize, // deUint32 bufferImageHeight;
11318 depthSourceLayer, // VkImageSubresourceLayers imageSubresource;
11319 {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
11320 defaultHalfExtent // VkExtent3D imageExtent;
11321 };
11322
11323 const VkImageSubresourceLayers stencilSourceLayer =
11324 {
11325 VK_IMAGE_ASPECT_STENCIL_BIT, // VkImageAspectFlags aspectMask;
11326 0u, // deUint32 mipLevel;
11327 0u, // deUint32 baseArrayLayer;
11328 1u, // deUint32 layerCount;
11329 };
11330
11331 const VkBufferImageCopy bufferStencilCopy =
11332 {
11333 0u, // VkDeviceSize bufferOffset;
11334 0u, // deUint32 bufferRowLength;
11335 0u, // deUint32 bufferImageHeight;
11336 stencilSourceLayer, // VkImageSubresourceLayers imageSubresource;
11337 {0, 0, 0}, // VkOffset3D imageOffset;
11338 defaultExtent // VkExtent3D imageExtent;
11339 };
11340
11341 const VkBufferImageCopy bufferStencilCopyOffset =
11342 {
11343 32, // VkDeviceSize bufferOffset;
11344 defaultHalfSize + defaultQuarterSize, // deUint32 bufferRowLength;
11345 defaultHalfSize + defaultQuarterSize, // deUint32 bufferImageHeight;
11346 stencilSourceLayer, // VkImageSubresourceLayers imageSubresource;
11347 {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
11348 defaultHalfExtent // VkExtent3D imageExtent;
11349 };
11350
11351 const bool useOffset[] = {false, true};
11352
11353 // Note: Depth stencil tests I want to do
11354 // Formats: D16, D24S8, D32FS8
11355 // Test writing each component with separate CopyBufferToImage commands
11356 // Test writing both components in one CopyBufferToImage command
11357 // Swap order of writes of Depth & Stencil
11358 // whole surface, subimages?
11359 // Similar tests as BufferToImage?
11360 for (const auto config : depthAndStencilFormats)
11361 for (const auto offset : useOffset)
11362 {
11363 // TODO: Check that this format is supported before creating tests?
11364 //if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D24_UNORM_S8_UINT))
11365
11366 CopyRegion copyDepthRegion;
11367 CopyRegion copyStencilRegion;
11368 TestParams params;
11369 const tcu::TextureFormat format = mapVkFormat(config.format);
11370 const bool hasDepth = tcu::hasDepthComponent(format.order);
11371 const bool hasStencil = tcu::hasStencilComponent(format.order);
11372 std::string description = config.name;
11373
11374 if (offset)
11375 {
11376 copyDepthRegion.bufferImageCopy = bufferDepthCopyOffset;
11377 copyStencilRegion.bufferImageCopy = bufferStencilCopyOffset;
11378 description = "buffer_offset_" + description;
11379 params.src.buffer.size = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultQuarterSize;
11380 }
11381 else
11382 {
11383 copyDepthRegion.bufferImageCopy = bufferDepthCopy;
11384 copyStencilRegion.bufferImageCopy = bufferStencilCopy;
11385 params.src.buffer.size = defaultSize * defaultSize;
11386 }
11387
11388 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
11389 params.dst.image.format = config.format;
11390 params.dst.image.extent = defaultExtent;
11391 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11392 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11393 params.allocationKind = allocationKind;
11394 params.extensionUse = extensionUse;
11395
11396 if (hasDepth && hasStencil)
11397 {
11398 params.singleCommand = DE_TRUE;
11399
11400 params.regions.push_back(copyDepthRegion);
11401 params.regions.push_back(copyStencilRegion);
11402
11403 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_DS", "Copy from depth&stencil to image", params));
11404
11405 params.singleCommand = DE_FALSE;
11406
11407 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_D_S", "Copy from depth then stencil to image", params));
11408
11409 params.regions.clear();
11410 params.regions.push_back(copyStencilRegion);
11411 params.regions.push_back(copyDepthRegion);
11412
11413 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_S_D", "Copy from depth then stencil to image", params));
11414
11415 params.singleCommand = DE_TRUE;
11416 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_SD", "Copy from depth&stencil to image", params));
11417 }
11418
11419 if (hasStencil)
11420 {
11421 params.regions.clear();
11422 params.regions.push_back(copyStencilRegion);
11423
11424 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_S", "Copy from stencil to image", params));
11425 }
11426
11427 if (hasDepth)
11428 {
11429 params.regions.clear();
11430 params.regions.push_back(copyDepthRegion);
11431
11432 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_D", "Copy from depth to image", params));
11433 }
11434 }
11435 }
11436
add1dBufferToImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)11437 void add1dBufferToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11438 {
11439 tcu::TestContext& testCtx = group->getTestContext();
11440
11441 {
11442 TestParams params;
11443 params.src.buffer.size = defaultSize;
11444 params.dst.image.imageType = VK_IMAGE_TYPE_1D;
11445 params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
11446 params.dst.image.extent = default1dExtent;
11447 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11448 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11449 params.allocationKind = allocationKind;
11450 params.extensionUse = extensionUse;
11451
11452 const VkBufferImageCopy bufferImageCopy =
11453 {
11454 0u, // VkDeviceSize bufferOffset;
11455 0u, // deUint32 bufferRowLength;
11456 0u, // deUint32 bufferImageHeight;
11457 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
11458 {0, 0, 0}, // VkOffset3D imageOffset;
11459 default1dExtent // VkExtent3D imageExtent;
11460 };
11461 CopyRegion copyRegion;
11462 copyRegion.bufferImageCopy = bufferImageCopy;
11463
11464 params.regions.push_back(copyRegion);
11465
11466 group->addChild(new CopyBufferToImageTestCase(testCtx, "tightly_sized_buffer", "Copy from tightly packed buffer to image", params));
11467 }
11468
11469 {
11470 TestParams params;
11471 deUint32 bufferImageHeight = defaultSize + 1u;
11472 params.src.buffer.size = bufferImageHeight;
11473 params.dst.image.imageType = VK_IMAGE_TYPE_1D;
11474 params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
11475 params.dst.image.extent = default1dExtent;
11476 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11477 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11478 params.allocationKind = allocationKind;
11479 params.extensionUse = extensionUse;
11480
11481 const VkBufferImageCopy bufferImageCopy =
11482 {
11483 0u, // VkDeviceSize bufferOffset;
11484 0u, // deUint32 bufferRowLength;
11485 bufferImageHeight, // deUint32 bufferImageHeight;
11486 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
11487 {0, 0, 0}, // VkOffset3D imageOffset;
11488 default1dExtent // VkExtent3D imageExtent;
11489 };
11490 CopyRegion copyRegion;
11491 copyRegion.bufferImageCopy = bufferImageCopy;
11492
11493 params.regions.push_back(copyRegion);
11494
11495 group->addChild(new CopyBufferToImageTestCase(testCtx, "larger_buffer", "Copy from a buffer to image", params));
11496 }
11497
11498 {
11499 TestParams params;
11500 deUint32 arrayLayers = 16u;
11501 params.src.buffer.size = defaultSize * arrayLayers;
11502 params.dst.image.imageType = VK_IMAGE_TYPE_1D;
11503 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
11504 params.dst.image.extent = default1dExtent;
11505 params.dst.image.extent.depth = arrayLayers;
11506 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11507 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11508 params.allocationKind = allocationKind;
11509 params.extensionUse = extensionUse;
11510
11511 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.dst.image.format));
11512 for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
11513 {
11514 const VkDeviceSize offset = defaultSize * pixelSize * arrayLayerNdx;
11515 const VkBufferImageCopy bufferImageCopy =
11516 {
11517 offset, // VkDeviceSize bufferOffset;
11518 0u, // deUint32 bufferRowLength;
11519 0u, // deUint32 bufferImageHeight;
11520 {
11521 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11522 0u, // deUint32 mipLevel;
11523 arrayLayerNdx, // deUint32 baseArrayLayer;
11524 1u, // deUint32 layerCount;
11525 }, // VkImageSubresourceLayers imageSubresource;
11526 {0, 0, 0}, // VkOffset3D imageOffset;
11527 default1dExtent // VkExtent3D imageExtent;
11528 };
11529 CopyRegion copyRegion;
11530 copyRegion.bufferImageCopy = bufferImageCopy;
11531
11532 params.regions.push_back(copyRegion);
11533 }
11534
11535 group->addChild(new CopyBufferToImageTestCase(testCtx, "array_tightly_sized_buffer", "Copy from a different part of the tightly packed buffer to each layer", params));
11536 }
11537
11538 {
11539 TestParams params;
11540 deUint32 arrayLayers = 16u;
11541 deUint32 bufferImageHeight = defaultSize + 1u;
11542 params.src.buffer.size = defaultSize * arrayLayers;
11543 params.dst.image.imageType = VK_IMAGE_TYPE_1D;
11544 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
11545 params.dst.image.extent = default1dExtent;
11546 params.dst.image.extent.depth = arrayLayers;
11547 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11548 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11549 params.allocationKind = allocationKind;
11550 params.extensionUse = extensionUse;
11551
11552 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.dst.image.format));
11553 for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
11554 {
11555 const VkDeviceSize offset = defaultSize * pixelSize * arrayLayerNdx;
11556 const VkBufferImageCopy bufferImageCopy =
11557 {
11558 offset, // VkDeviceSize bufferOffset;
11559 0u, // deUint32 bufferRowLength;
11560 bufferImageHeight, // deUint32 bufferImageHeight;
11561 {
11562 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11563 0u, // deUint32 mipLevel;
11564 arrayLayerNdx, // deUint32 baseArrayLayer;
11565 1u, // deUint32 layerCount;
11566 }, // VkImageSubresourceLayers imageSubresource;
11567 {0, 0, 0}, // VkOffset3D imageOffset;
11568 default1dExtent // VkExtent3D imageExtent;
11569 };
11570 CopyRegion copyRegion;
11571 copyRegion.bufferImageCopy = bufferImageCopy;
11572
11573 params.regions.push_back(copyRegion);
11574 }
11575
11576 group->addChild(new CopyBufferToImageTestCase(testCtx, "array_larger_buffer", "Copy from a different part of the buffer to each layer", params));
11577 }
11578 }
11579
add2dBufferToImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)11580 void add2dBufferToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11581 {
11582 tcu::TestContext& testCtx = group->getTestContext();
11583
11584 {
11585 TestParams params;
11586 params.src.buffer.size = defaultSize * defaultSize;
11587 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
11588 params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
11589 params.dst.image.extent = defaultExtent;
11590 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11591 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11592 params.allocationKind = allocationKind;
11593 params.extensionUse = extensionUse;
11594
11595 const VkBufferImageCopy bufferImageCopy =
11596 {
11597 0u, // VkDeviceSize bufferOffset;
11598 0u, // deUint32 bufferRowLength;
11599 0u, // deUint32 bufferImageHeight;
11600 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
11601 {0, 0, 0}, // VkOffset3D imageOffset;
11602 defaultExtent // VkExtent3D imageExtent;
11603 };
11604 CopyRegion copyRegion;
11605 copyRegion.bufferImageCopy = bufferImageCopy;
11606
11607 params.regions.push_back(copyRegion);
11608
11609 group->addChild(new CopyBufferToImageTestCase(testCtx, "whole", "Copy from buffer to image", params));
11610 }
11611
11612 {
11613 TestParams params;
11614 params.src.buffer.size = defaultSize * defaultSize;
11615 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
11616 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
11617 params.dst.image.extent = defaultExtent;
11618 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11619 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11620 params.allocationKind = allocationKind;
11621 params.extensionUse = extensionUse;
11622
11623 CopyRegion region;
11624 deUint32 divisor = 1;
11625 for (int offset = 0; (offset + defaultQuarterSize / divisor < defaultSize) && (defaultQuarterSize > divisor); offset += defaultQuarterSize / divisor++)
11626 {
11627 const VkBufferImageCopy bufferImageCopy =
11628 {
11629 0u, // VkDeviceSize bufferOffset;
11630 0u, // deUint32 bufferRowLength;
11631 0u, // deUint32 bufferImageHeight;
11632 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
11633 {offset, defaultHalfSize, 0}, // VkOffset3D imageOffset;
11634 {defaultQuarterSize / divisor, defaultQuarterSize / divisor, 1} // VkExtent3D imageExtent;
11635 };
11636 region.bufferImageCopy = bufferImageCopy;
11637 params.regions.push_back(region);
11638 }
11639
11640 group->addChild(new CopyBufferToImageTestCase(testCtx, "regions", "Copy from buffer to image with multiple regions", params));
11641 }
11642
11643 {
11644 TestParams params;
11645 params.src.buffer.size = defaultSize * defaultSize;
11646 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
11647 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
11648 params.dst.image.extent = defaultExtent;
11649 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11650 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11651 params.allocationKind = allocationKind;
11652 params.extensionUse = extensionUse;
11653
11654 const VkBufferImageCopy bufferImageCopy =
11655 {
11656 defaultQuarterSize, // VkDeviceSize bufferOffset;
11657 defaultHalfSize + defaultQuarterSize, // deUint32 bufferRowLength;
11658 defaultHalfSize + defaultQuarterSize, // deUint32 bufferImageHeight;
11659 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
11660 {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
11661 defaultHalfExtent // VkExtent3D imageExtent;
11662 };
11663 CopyRegion copyRegion;
11664 copyRegion.bufferImageCopy = bufferImageCopy;
11665
11666 params.regions.push_back(copyRegion);
11667
11668 group->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_offset", "Copy from buffer to image with buffer offset", params));
11669 }
11670
11671 {
11672 TestParams params;
11673 params.src.buffer.size = defaultSize * defaultSize;
11674 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
11675 params.dst.image.format = VK_FORMAT_R8_UNORM;
11676 params.dst.image.extent = defaultExtent;
11677 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11678 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11679 params.allocationKind = allocationKind;
11680 params.extensionUse = extensionUse;
11681
11682 const VkBufferImageCopy bufferImageCopy =
11683 {
11684 defaultQuarterSize + 1u, // VkDeviceSize bufferOffset;
11685 defaultHalfSize + defaultQuarterSize, // deUint32 bufferRowLength;
11686 defaultHalfSize + defaultQuarterSize, // deUint32 bufferImageHeight;
11687 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
11688 {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
11689 defaultHalfExtent // VkExtent3D imageExtent;
11690 };
11691 CopyRegion copyRegion;
11692 copyRegion.bufferImageCopy = bufferImageCopy;
11693
11694 params.regions.push_back(copyRegion);
11695
11696 group->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_offset_relaxed", "Copy from buffer to image with buffer offset not a multiple of 4", params));
11697 }
11698
11699 {
11700 TestParams params;
11701 params.src.buffer.size = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize;
11702 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
11703 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
11704 params.dst.image.extent = defaultExtent;
11705 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11706 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11707 params.allocationKind = allocationKind;
11708 params.extensionUse = extensionUse;
11709
11710 const VkBufferImageCopy bufferImageCopy =
11711 {
11712 0u, // VkDeviceSize bufferOffset;
11713 defaultSize, // deUint32 bufferRowLength;
11714 defaultSize, // deUint32 bufferImageHeight;
11715 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
11716 {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
11717 defaultHalfExtent // VkExtent3D imageExtent;
11718 };
11719 CopyRegion copyRegion;
11720 copyRegion.bufferImageCopy = bufferImageCopy;
11721
11722 params.regions.push_back(copyRegion);
11723
11724 group->addChild(new CopyBufferToImageTestCase(testCtx, "tightly_sized_buffer", "Copy from buffer that is just large enough to contain the accessed elements", params));
11725 }
11726
11727 {
11728 TestParams params;
11729 deUint32 bufferImageHeight = defaultSize + 1u;
11730 params.src.buffer.size = defaultSize * bufferImageHeight;
11731 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
11732 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
11733 params.dst.image.extent = defaultExtent;
11734 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11735 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11736 params.allocationKind = allocationKind;
11737 params.extensionUse = extensionUse;
11738
11739 const VkBufferImageCopy bufferImageCopy =
11740 {
11741 0u, // VkDeviceSize bufferOffset;
11742 defaultSize, // deUint32 bufferRowLength;
11743 bufferImageHeight, // deUint32 bufferImageHeight;
11744 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
11745 {0, 0, 0}, // VkOffset3D imageOffset;
11746 defaultHalfExtent // VkExtent3D imageExtent;
11747 };
11748 CopyRegion copyRegion;
11749 copyRegion.bufferImageCopy = bufferImageCopy;
11750
11751 params.regions.push_back(copyRegion);
11752
11753 group->addChild(new CopyBufferToImageTestCase(testCtx, "larger_buffer", "Copy from buffer that is larger than necessary to image", params));
11754 }
11755
11756 {
11757 TestParams params;
11758 params.src.buffer.size = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultQuarterSize;
11759 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
11760 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
11761 params.dst.image.extent = defaultExtent;
11762 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11763 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11764 params.allocationKind = allocationKind;
11765 params.extensionUse = extensionUse;
11766
11767 const VkBufferImageCopy bufferImageCopy =
11768 {
11769 defaultQuarterSize, // VkDeviceSize bufferOffset;
11770 defaultSize, // deUint32 bufferRowLength;
11771 defaultSize, // deUint32 bufferImageHeight;
11772 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
11773 {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
11774 defaultHalfExtent // VkExtent3D imageExtent;
11775 };
11776 CopyRegion copyRegion;
11777 copyRegion.bufferImageCopy = bufferImageCopy;
11778
11779 params.regions.push_back(copyRegion);
11780
11781 group->addChild(new CopyBufferToImageTestCase(testCtx, "tightly_sized_buffer_offset", "Copy from buffer that is just large enough to contain the accessed elements", params));
11782 }
11783
11784 {
11785 TestParams params;
11786 deUint32 arrayLayers = 16u;
11787 params.src.buffer.size = defaultHalfSize * defaultHalfSize * arrayLayers;
11788 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
11789 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
11790 params.dst.image.extent = defaultHalfExtent;
11791 params.dst.image.extent.depth = arrayLayers;
11792 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11793 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11794 params.allocationKind = allocationKind;
11795 params.extensionUse = extensionUse;
11796
11797 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.dst.image.format));
11798 for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
11799 {
11800 const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
11801 const VkBufferImageCopy bufferImageCopy =
11802 {
11803 offset, // VkDeviceSize bufferOffset;
11804 0u, // deUint32 bufferRowLength;
11805 0u, // deUint32 bufferImageHeight;
11806 {
11807 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11808 0u, // deUint32 mipLevel;
11809 arrayLayerNdx, // deUint32 baseArrayLayer;
11810 1u, // deUint32 layerCount;
11811 }, // VkImageSubresourceLayers imageSubresource;
11812 {0, 0, 0}, // VkOffset3D imageOffset;
11813 defaultHalfExtent // VkExtent3D imageExtent;
11814 };
11815 CopyRegion copyRegion;
11816 copyRegion.bufferImageCopy = bufferImageCopy;
11817
11818 params.regions.push_back(copyRegion);
11819 }
11820 group->addChild(new CopyBufferToImageTestCase(testCtx, "array", "Copy from a different part of the buffer to each layer", params));
11821 }
11822
11823 {
11824 TestParams params;
11825 deUint32 arrayLayers = 16u;
11826 deUint32 bufferImageHeight = defaultHalfSize + 1u;
11827 params.src.buffer.size = defaultHalfSize * bufferImageHeight * arrayLayers;
11828 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
11829 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
11830 params.dst.image.extent = defaultHalfExtent;
11831 params.dst.image.extent.depth = arrayLayers;
11832 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11833 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11834 params.allocationKind = allocationKind;
11835 params.extensionUse = extensionUse;
11836
11837 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.dst.image.format));
11838 for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
11839 {
11840 const VkDeviceSize offset = defaultHalfSize * bufferImageHeight * pixelSize * arrayLayerNdx;
11841 const VkBufferImageCopy bufferImageCopy =
11842 {
11843 offset, // VkDeviceSize bufferOffset;
11844 defaultHalfSize, // deUint32 bufferRowLength;
11845 bufferImageHeight, // deUint32 bufferImageHeight;
11846 {
11847 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11848 0u, // deUint32 mipLevel;
11849 arrayLayerNdx, // deUint32 baseArrayLayer;
11850 1u, // deUint32 layerCount;
11851 }, // VkImageSubresourceLayers imageSubresource;
11852 {0, 0, 0}, // VkOffset3D imageOffset;
11853 defaultHalfExtent // VkExtent3D imageExtent;
11854 };
11855 CopyRegion copyRegion;
11856 copyRegion.bufferImageCopy = bufferImageCopy;
11857
11858 params.regions.push_back(copyRegion);
11859 }
11860 group->addChild(new CopyBufferToImageTestCase(testCtx, "array_larger_buffer", "Copy from different part of buffer to each layer", params));
11861 }
11862
11863 {
11864 TestParams params;
11865 deUint32 arrayLayers = 16u;
11866 params.src.buffer.size = defaultHalfSize * defaultHalfSize * arrayLayers;
11867 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
11868 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
11869 params.dst.image.extent = defaultHalfExtent;
11870 params.dst.image.extent.depth = arrayLayers;
11871 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11872 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11873 params.allocationKind = allocationKind;
11874 params.extensionUse = extensionUse;
11875
11876 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.dst.image.format));
11877 for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
11878 {
11879 const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
11880 const VkBufferImageCopy bufferImageCopy =
11881 {
11882 offset, // VkDeviceSize bufferOffset;
11883 defaultHalfSize, // deUint32 bufferRowLength;
11884 defaultHalfSize, // deUint32 bufferImageHeight;
11885 {
11886 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11887 0u, // deUint32 mipLevel;
11888 arrayLayerNdx, // deUint32 baseArrayLayer;
11889 1u, // deUint32 layerCount;
11890 }, // VkImageSubresourceLayers imageSubresource;
11891 {0, 0, 0}, // VkOffset3D imageOffset;
11892 defaultHalfExtent // VkExtent3D imageExtent;
11893 };
11894 CopyRegion copyRegion;
11895 copyRegion.bufferImageCopy = bufferImageCopy;
11896
11897 params.regions.push_back(copyRegion);
11898 }
11899 group->addChild(new CopyBufferToImageTestCase(testCtx, "array_tightly_sized_buffer", "Copy from different part of tightly sized buffer to each layer", params));
11900 }
11901 }
11902
addBufferToImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)11903 void addBufferToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11904 {
11905 addTestGroup(group, "1d_images", "Copying operations on 1d images", add1dBufferToImageTests, allocationKind, extensionUse);
11906 addTestGroup(group, "2d_images", "Copying operations on 2d images", add2dBufferToImageTests, allocationKind, extensionUse);
11907 }
11908
addBufferToBufferTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)11909 void addBufferToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11910 {
11911 tcu::TestContext& testCtx = group->getTestContext();
11912
11913 {
11914 TestParams params;
11915 params.src.buffer.size = defaultSize;
11916 params.dst.buffer.size = defaultSize;
11917 params.allocationKind = allocationKind;
11918 params.extensionUse = extensionUse;
11919
11920 const VkBufferCopy bufferCopy =
11921 {
11922 0u, // VkDeviceSize srcOffset;
11923 0u, // VkDeviceSize dstOffset;
11924 defaultSize, // VkDeviceSize size;
11925 };
11926
11927 CopyRegion copyRegion;
11928 copyRegion.bufferCopy = bufferCopy;
11929 params.regions.push_back(copyRegion);
11930
11931 group->addChild(new BufferToBufferTestCase(testCtx, "whole", "Whole buffer", params));
11932 }
11933
11934 // Filter is VK_FILTER_NEAREST.
11935 {
11936 TestParams params;
11937 params.src.buffer.size = defaultQuarterSize;
11938 params.dst.buffer.size = defaultQuarterSize;
11939 params.allocationKind = allocationKind;
11940 params.extensionUse = extensionUse;
11941
11942 const VkBufferCopy bufferCopy =
11943 {
11944 12u, // VkDeviceSize srcOffset;
11945 4u, // VkDeviceSize dstOffset;
11946 1u, // VkDeviceSize size;
11947 };
11948
11949 CopyRegion copyRegion;
11950 copyRegion.bufferCopy = bufferCopy;
11951 params.regions.push_back(copyRegion);
11952
11953 group->addChild(new BufferToBufferTestCase(testCtx, "partial", "Partial", params));
11954 }
11955
11956 {
11957 const deUint32 size = 16;
11958 TestParams params;
11959 params.src.buffer.size = size;
11960 params.dst.buffer.size = size * (size + 1);
11961 params.allocationKind = allocationKind;
11962 params.extensionUse = extensionUse;
11963
11964 // Copy region with size 1..size
11965 for (unsigned int i = 1; i <= size; i++)
11966 {
11967 const VkBufferCopy bufferCopy =
11968 {
11969 0, // VkDeviceSize srcOffset;
11970 i * size, // VkDeviceSize dstOffset;
11971 i, // VkDeviceSize size;
11972 };
11973
11974 CopyRegion copyRegion;
11975 copyRegion.bufferCopy = bufferCopy;
11976 params.regions.push_back(copyRegion);
11977 }
11978
11979 group->addChild(new BufferToBufferTestCase(testCtx, "regions", "Multiple regions", params));
11980 }
11981
11982 {
11983 TestParams params;
11984 params.src.buffer.size = 32;
11985 params.dst.buffer.size = 32;
11986 params.allocationKind = allocationKind;
11987 params.extensionUse = extensionUse;
11988
11989 // Copy four unaligned regions
11990 for (unsigned int i = 0; i < 4; i++)
11991 {
11992 const VkBufferCopy bufferCopy
11993 {
11994 3 + i * 3, // VkDeviceSize srcOffset; 3 6 9 12
11995 1 + i * 5, // VkDeviceSize dstOffset; 1 6 11 16
11996 2 + i, // VkDeviceSize size; 2 3 4 5
11997 };
11998
11999 CopyRegion copyRegion;
12000 copyRegion.bufferCopy = bufferCopy;
12001 params.regions.push_back(copyRegion);
12002 }
12003
12004 group->addChild(new BufferToBufferTestCase(testCtx, "unaligned_regions", "Multiple unaligned regions", params));
12005 }
12006 }
12007
addBlittingImageSimpleTests(tcu::TestCaseGroup * group,TestParams & params)12008 void addBlittingImageSimpleTests (tcu::TestCaseGroup* group, TestParams& params)
12009 {
12010 tcu::TestContext& testCtx = group->getTestContext();
12011
12012 // Filter is VK_FILTER_NEAREST.
12013 {
12014 params.filter = VK_FILTER_NEAREST;
12015 const std::string description = "Nearest filter";
12016
12017 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12018 group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params));
12019
12020 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
12021 const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)");
12022 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
12023
12024 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
12025 const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
12026 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
12027 }
12028
12029 // Filter is VK_FILTER_LINEAR.
12030 {
12031 params.filter = VK_FILTER_LINEAR;
12032 const std::string description = "Linear filter";
12033
12034 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12035 group->addChild(new BlitImageTestCase(testCtx, "linear", description, params));
12036
12037 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
12038 const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)");
12039 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
12040
12041 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
12042 const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
12043 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
12044 }
12045
12046 // Filter is VK_FILTER_CUBIC_EXT.
12047 // Cubic filtering can only be used with 2D images.
12048 if (params.dst.image.imageType == VK_IMAGE_TYPE_2D)
12049 {
12050 params.filter = VK_FILTER_CUBIC_EXT;
12051 const std::string description = "Cubic filter";
12052
12053 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12054 group->addChild(new BlitImageTestCase(testCtx, "cubic", description, params));
12055
12056 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
12057 const std::string descriptionOfRGBAToR32(description + " and different formats (R8G8B8A8 -> R32)");
12058 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_cubic", descriptionOfRGBAToR32, params));
12059
12060 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
12061 const std::string descriptionOfRGBAToBGRA(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
12062 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_cubic", descriptionOfRGBAToBGRA, params));
12063 }
12064 }
12065
addBlittingImageSimpleWholeTests(tcu::TestCaseGroup * group,TestParams params)12066 void addBlittingImageSimpleWholeTests (tcu::TestCaseGroup* group, TestParams params)
12067 {
12068 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12069 const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
12070 params.src.image.extent = defaultExtent;
12071 params.dst.image.extent = defaultExtent;
12072 params.src.image.extent.depth = imageDepth;
12073 params.dst.image.extent.depth = imageDepth;
12074
12075 {
12076 const VkImageBlit imageBlit =
12077 {
12078 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
12079 {
12080 { 0, 0, 0 },
12081 { defaultSize, defaultSize, imageDepth }
12082 }, // VkOffset3D srcOffsets[2];
12083
12084 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
12085 {
12086 { 0, 0, 0 },
12087 { defaultSize, defaultSize, imageDepth }
12088 } // VkOffset3D dstOffset[2];
12089 };
12090
12091 CopyRegion region;
12092 region.imageBlit = imageBlit;
12093 params.regions.push_back(region);
12094 }
12095
12096 addBlittingImageSimpleTests(group, params);
12097 }
12098
addBlittingImageSimpleMirrorXYTests(tcu::TestCaseGroup * group,TestParams params)12099 void addBlittingImageSimpleMirrorXYTests (tcu::TestCaseGroup* group, TestParams params)
12100 {
12101 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12102 const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
12103 params.src.image.extent = defaultExtent;
12104 params.dst.image.extent = defaultExtent;
12105 params.src.image.extent.depth = imageDepth;
12106 params.dst.image.extent.depth = imageDepth;
12107
12108 {
12109 const VkImageBlit imageBlit =
12110 {
12111 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
12112 {
12113 {0, 0, 0},
12114 {defaultSize, defaultSize, imageDepth}
12115 }, // VkOffset3D srcOffsets[2];
12116
12117 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
12118 {
12119 {defaultSize, defaultSize, 0},
12120 {0, 0, imageDepth}
12121 } // VkOffset3D dstOffset[2];
12122 };
12123
12124 CopyRegion region;
12125 region.imageBlit = imageBlit;
12126 params.regions.push_back(region);
12127 }
12128
12129 addBlittingImageSimpleTests(group, params);
12130 }
12131
addBlittingImageSimpleMirrorXTests(tcu::TestCaseGroup * group,TestParams params)12132 void addBlittingImageSimpleMirrorXTests (tcu::TestCaseGroup* group, TestParams params)
12133 {
12134 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12135 const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
12136 params.src.image.extent = defaultExtent;
12137 params.dst.image.extent = defaultExtent;
12138 params.src.image.extent.depth = imageDepth;
12139 params.dst.image.extent.depth = imageDepth;
12140
12141 {
12142 const VkImageBlit imageBlit =
12143 {
12144 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
12145 {
12146 {0, 0, 0},
12147 {defaultSize, defaultSize, imageDepth}
12148 }, // VkOffset3D srcOffsets[2];
12149
12150 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
12151 {
12152 {defaultSize, 0, 0},
12153 {0, defaultSize, imageDepth}
12154 } // VkOffset3D dstOffset[2];
12155 };
12156
12157 CopyRegion region;
12158 region.imageBlit = imageBlit;
12159 params.regions.push_back(region);
12160 }
12161
12162 addBlittingImageSimpleTests(group, params);
12163 }
12164
addBlittingImageSimpleMirrorYTests(tcu::TestCaseGroup * group,TestParams params)12165 void addBlittingImageSimpleMirrorYTests (tcu::TestCaseGroup* group, TestParams params)
12166 {
12167 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12168 const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
12169 params.src.image.extent = defaultExtent;
12170 params.dst.image.extent = defaultExtent;
12171 params.src.image.extent.depth = imageDepth;
12172 params.dst.image.extent.depth = imageDepth;
12173
12174 {
12175 const VkImageBlit imageBlit =
12176 {
12177 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
12178 {
12179 {0, 0, 0},
12180 {defaultSize, defaultSize, imageDepth}
12181 }, // VkOffset3D srcOffsets[2];
12182
12183 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
12184 {
12185 {0, defaultSize, 0},
12186 {defaultSize, 0, imageDepth}
12187 } // VkOffset3D dstOffset[2];
12188 };
12189
12190 CopyRegion region;
12191 region.imageBlit = imageBlit;
12192 params.regions.push_back(region);
12193 }
12194
12195 addBlittingImageSimpleTests(group, params);
12196 }
12197
addBlittingImageSimpleMirrorZTests(tcu::TestCaseGroup * group,TestParams params)12198 void addBlittingImageSimpleMirrorZTests (tcu::TestCaseGroup* group, TestParams params)
12199 {
12200 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12201 DE_ASSERT(params.src.image.imageType == VK_IMAGE_TYPE_3D);
12202 params.src.image.extent = defaultExtent;
12203 params.dst.image.extent = defaultExtent;
12204 params.src.image.extent.depth = defaultSize;
12205 params.dst.image.extent.depth = defaultSize;
12206
12207 {
12208 const VkImageBlit imageBlit =
12209 {
12210 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
12211 {
12212 {0, 0, 0},
12213 {defaultSize, defaultSize, defaultSize}
12214 }, // VkOffset3D srcOffsets[2];
12215
12216 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
12217 {
12218 {0, 0, defaultSize},
12219 {defaultSize, defaultSize, 0}
12220 } // VkOffset3D dstOffset[2];
12221 };
12222
12223 CopyRegion region;
12224 region.imageBlit = imageBlit;
12225 params.regions.push_back(region);
12226 }
12227
12228 addBlittingImageSimpleTests(group, params);
12229 }
12230
addBlittingImageSimpleMirrorSubregionsTests(tcu::TestCaseGroup * group,TestParams params)12231 void addBlittingImageSimpleMirrorSubregionsTests (tcu::TestCaseGroup* group, TestParams params)
12232 {
12233 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12234 const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
12235 params.src.image.extent = defaultExtent;
12236 params.dst.image.extent = defaultExtent;
12237 params.src.image.extent.depth = imageDepth;
12238 params.dst.image.extent.depth = imageDepth;
12239
12240 // No mirroring.
12241 {
12242 const VkImageBlit imageBlit =
12243 {
12244 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
12245 {
12246 {0, 0, 0},
12247 {defaultHalfSize, defaultHalfSize, imageDepth}
12248 }, // VkOffset3D srcOffsets[2];
12249
12250 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
12251 {
12252 {0, 0, 0},
12253 {defaultHalfSize, defaultHalfSize, imageDepth}
12254 } // VkOffset3D dstOffset[2];
12255 };
12256
12257 CopyRegion region;
12258 region.imageBlit = imageBlit;
12259 params.regions.push_back(region);
12260 }
12261
12262 // Flipping y coordinates.
12263 {
12264 const VkImageBlit imageBlit =
12265 {
12266 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
12267 {
12268 {defaultHalfSize, 0, 0},
12269 {defaultSize, defaultHalfSize, imageDepth}
12270 }, // VkOffset3D srcOffsets[2];
12271
12272 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
12273 {
12274 {defaultHalfSize, defaultHalfSize, 0},
12275 {defaultSize, 0, imageDepth}
12276 } // VkOffset3D dstOffset[2];
12277 };
12278 CopyRegion region;
12279 region.imageBlit = imageBlit;
12280 params.regions.push_back(region);
12281 }
12282
12283 // Flipping x coordinates.
12284 {
12285 const VkImageBlit imageBlit =
12286 {
12287 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
12288 {
12289 {0, defaultHalfSize, 0},
12290 {defaultHalfSize, defaultSize, imageDepth}
12291 }, // VkOffset3D srcOffsets[2];
12292
12293 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
12294 {
12295 {defaultHalfSize, defaultHalfSize, 0},
12296 {0, defaultSize, imageDepth}
12297 } // VkOffset3D dstOffset[2];
12298 };
12299
12300 CopyRegion region;
12301 region.imageBlit = imageBlit;
12302 params.regions.push_back(region);
12303 }
12304
12305 // Flipping x and y coordinates.
12306 {
12307 const VkImageBlit imageBlit =
12308 {
12309 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
12310 {
12311 {defaultHalfSize, defaultHalfSize, 0},
12312 {defaultSize, defaultSize, imageDepth}
12313 }, // VkOffset3D srcOffsets[2];
12314
12315 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
12316 {
12317 {defaultSize, defaultSize, 0},
12318 {defaultHalfSize, defaultHalfSize, imageDepth}
12319 } // VkOffset3D dstOffset[2];
12320 };
12321
12322 CopyRegion region;
12323 region.imageBlit = imageBlit;
12324 params.regions.push_back(region);
12325 }
12326
12327 addBlittingImageSimpleTests(group, params);
12328 }
12329
addBlittingImageSimpleScalingWhole1Tests(tcu::TestCaseGroup * group,TestParams params)12330 void addBlittingImageSimpleScalingWhole1Tests (tcu::TestCaseGroup* group, TestParams params)
12331 {
12332 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12333 const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
12334 const deInt32 halfImageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultHalfSize : 1;
12335 params.src.image.extent = defaultExtent;
12336 params.dst.image.extent = defaultHalfExtent;
12337 params.src.image.extent.depth = imageDepth;
12338 params.dst.image.extent.depth = halfImageDepth;
12339
12340 {
12341 const VkImageBlit imageBlit =
12342 {
12343 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
12344 {
12345 {0, 0, 0},
12346 {defaultSize, defaultSize, imageDepth}
12347 }, // VkOffset3D srcOffsets[2];
12348
12349 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
12350 {
12351 {0, 0, 0},
12352 {defaultHalfSize, defaultHalfSize, halfImageDepth}
12353 } // VkOffset3D dstOffset[2];
12354 };
12355
12356 CopyRegion region;
12357 region.imageBlit = imageBlit;
12358 params.regions.push_back(region);
12359 }
12360
12361 addBlittingImageSimpleTests(group, params);
12362 }
12363
addBlittingImageSimpleScalingWhole2Tests(tcu::TestCaseGroup * group,TestParams params)12364 void addBlittingImageSimpleScalingWhole2Tests (tcu::TestCaseGroup* group, TestParams params)
12365 {
12366 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12367 const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
12368 const deInt32 halfImageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultHalfSize : 1;
12369 params.src.image.extent = defaultHalfExtent;
12370 params.dst.image.extent = defaultExtent;
12371 params.src.image.extent.depth = halfImageDepth;
12372 params.dst.image.extent.depth = imageDepth;
12373
12374 {
12375 const VkImageBlit imageBlit =
12376 {
12377 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
12378 {
12379 {0, 0, 0},
12380 {defaultHalfSize, defaultHalfSize, halfImageDepth}
12381 }, // VkOffset3D srcOffsets[2];
12382
12383 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
12384 {
12385 {0, 0, 0},
12386 {defaultSize, defaultSize, imageDepth}
12387 } // VkOffset3D dstOffset[2];
12388 };
12389
12390 CopyRegion region;
12391 region.imageBlit = imageBlit;
12392 params.regions.push_back(region);
12393 }
12394
12395 addBlittingImageSimpleTests(group, params);
12396 }
12397
addBlittingImageSimpleScalingAndOffsetTests(tcu::TestCaseGroup * group,TestParams params)12398 void addBlittingImageSimpleScalingAndOffsetTests (tcu::TestCaseGroup* group, TestParams params)
12399 {
12400 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12401 const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
12402 const deInt32 srcDepthOffset = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultQuarterSize : 0;
12403 const deInt32 srcDepthSize = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultQuarterSize * 3 : 1;
12404 params.src.image.extent = defaultExtent;
12405 params.dst.image.extent = defaultExtent;
12406 params.src.image.extent.depth = imageDepth;
12407 params.dst.image.extent.depth = imageDepth;
12408
12409 {
12410 const VkImageBlit imageBlit =
12411 {
12412 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
12413 {
12414 {defaultQuarterSize, defaultQuarterSize, srcDepthOffset},
12415 {defaultQuarterSize*3, defaultQuarterSize*3, srcDepthSize}
12416 }, // VkOffset3D srcOffsets[2];
12417
12418 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
12419 {
12420 {0, 0, 0},
12421 {defaultSize, defaultSize, imageDepth}
12422 } // VkOffset3D dstOffset[2];
12423 };
12424
12425 CopyRegion region;
12426 region.imageBlit = imageBlit;
12427 params.regions.push_back(region);
12428 }
12429
12430 addBlittingImageSimpleTests(group, params);
12431 }
12432
addBlittingImageSimpleWithoutScalingPartialTests(tcu::TestCaseGroup * group,TestParams params)12433 void addBlittingImageSimpleWithoutScalingPartialTests (tcu::TestCaseGroup* group, TestParams params)
12434 {
12435 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12436 const bool is3dBlit = params.src.image.imageType == VK_IMAGE_TYPE_3D;
12437 params.src.image.extent = defaultExtent;
12438 params.dst.image.extent = defaultExtent;
12439
12440 if (is3dBlit)
12441 {
12442 params.src.image.extent.depth = defaultSize;
12443 params.dst.image.extent.depth = defaultSize;
12444 }
12445
12446 {
12447 CopyRegion region;
12448 for (int i = 0; i < defaultSize; i += defaultQuarterSize)
12449 {
12450 const VkImageBlit imageBlit =
12451 {
12452 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
12453 {
12454 {defaultSize - defaultQuarterSize - i, defaultSize - defaultQuarterSize - i, is3dBlit ? defaultSize - defaultQuarterSize - i : 0},
12455 {defaultSize - i, defaultSize - i, is3dBlit ? defaultSize - i : 1}
12456 }, // VkOffset3D srcOffsets[2];
12457
12458 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
12459 {
12460 {i, i, is3dBlit ? i : 0},
12461 {i + defaultQuarterSize, i + defaultQuarterSize, is3dBlit ? i + defaultQuarterSize : 1}
12462 } // VkOffset3D dstOffset[2];
12463 };
12464 region.imageBlit = imageBlit;
12465 params.regions.push_back(region);
12466 }
12467 }
12468
12469 addBlittingImageSimpleTests(group, params);
12470 }
12471
addBlittingImageSimpleTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)12472 void addBlittingImageSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12473 {
12474 TestParams params;
12475 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12476 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12477 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12478 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12479 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12480 params.allocationKind = allocationKind;
12481 params.extensionUse = extensionUse;
12482 params.src.image.imageType = VK_IMAGE_TYPE_2D;
12483 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
12484 addTestGroup(group, "whole", "Blit without scaling (whole)", addBlittingImageSimpleWholeTests, params);
12485 addTestGroup(group, "mirror_xy", "Flipping x and y coordinates (whole)", addBlittingImageSimpleMirrorXYTests, params);
12486 addTestGroup(group, "mirror_x", "Flipping x coordinates (whole)", addBlittingImageSimpleMirrorXTests, params);
12487 addTestGroup(group, "mirror_y", "Flipping y coordinates (whole)", addBlittingImageSimpleMirrorYTests, params);
12488 addTestGroup(group, "mirror_subregions", "Mirroring subregions in image (no flip, y flip, x flip, xy flip)", addBlittingImageSimpleMirrorSubregionsTests, params);
12489 addTestGroup(group, "scaling_whole1", "Blit with scaling (whole, src extent bigger)", addBlittingImageSimpleScalingWhole1Tests, params);
12490 addTestGroup(group, "scaling_whole2", "Blit with scaling (whole, dst extent bigger)", addBlittingImageSimpleScalingWhole2Tests, params);
12491 addTestGroup(group, "scaling_and_offset", "Blit with scaling and offset (whole, dst extent bigger)", addBlittingImageSimpleScalingAndOffsetTests, params);
12492 addTestGroup(group, "without_scaling_partial", "Blit without scaling (partial)", addBlittingImageSimpleWithoutScalingPartialTests, params);
12493
12494 params.src.image.imageType = VK_IMAGE_TYPE_3D;
12495 params.dst.image.imageType = VK_IMAGE_TYPE_3D;
12496 addTestGroup(group, "whole_3d", "3D blit without scaling (whole)", addBlittingImageSimpleWholeTests, params);
12497 addTestGroup(group, "mirror_xy_3d", "Flipping x and y coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorXYTests, params);
12498 addTestGroup(group, "mirror_x_3d", "Flipping x coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorXTests, params);
12499 addTestGroup(group, "mirror_y_3d", "Flipping y coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorYTests, params);
12500 addTestGroup(group, "mirror_z_3d", "Flipping z coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorZTests, params);
12501 addTestGroup(group, "mirror_subregions_3d", "Mirroring subregions in a 3D image (no flip, y flip, x flip, xy flip)", addBlittingImageSimpleMirrorSubregionsTests, params);
12502 addTestGroup(group, "scaling_whole1_3d", "3D blit a with scaling (whole, src extent bigger)", addBlittingImageSimpleScalingWhole1Tests, params);
12503 addTestGroup(group, "scaling_whole2_3d", "3D blit with scaling (whole, dst extent bigger)", addBlittingImageSimpleScalingWhole2Tests, params);
12504 addTestGroup(group, "scaling_and_offset_3d", "3D blit with scaling and offset (whole, dst extent bigger)", addBlittingImageSimpleScalingAndOffsetTests, params);
12505 addTestGroup(group, "without_scaling_partial_3d", "3D blit without scaling (partial)", addBlittingImageSimpleWithoutScalingPartialTests, params);
12506 }
12507
12508 enum FilterMaskBits
12509 {
12510 FILTER_MASK_NEAREST = 0, // Always tested.
12511 FILTER_MASK_LINEAR = (1u << 0),
12512 FILTER_MASK_CUBIC = (1u << 1),
12513 };
12514
12515 using FilterMask = deUint32;
12516
makeFilterMask(bool onlyNearest,bool discardCubicFilter)12517 FilterMask makeFilterMask (bool onlyNearest, bool discardCubicFilter)
12518 {
12519 FilterMask mask = FILTER_MASK_NEAREST;
12520
12521 if (!onlyNearest)
12522 {
12523 mask |= FILTER_MASK_LINEAR;
12524 if (!discardCubicFilter)
12525 mask |= FILTER_MASK_CUBIC;
12526 }
12527
12528 return mask;
12529 }
12530
12531 struct BlitColorTestParams
12532 {
12533 TestParams params;
12534 const VkFormat* compatibleFormats;
12535 FilterMask testFilters;
12536 };
12537
isAllowedBlittingAllFormatsColorSrcFormatTests(const BlitColorTestParams & testParams)12538 bool isAllowedBlittingAllFormatsColorSrcFormatTests(const BlitColorTestParams& testParams)
12539 {
12540 bool result = true;
12541
12542 if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED)
12543 {
12544 DE_ASSERT(!dedicatedAllocationBlittingFormatsToTestSet.empty());
12545
12546 result =
12547 de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.dst.image.format) ||
12548 de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.src.image.format);
12549 }
12550
12551 return result;
12552 }
12553
12554 const VkFormat linearOtherImageFormatsToTest[] =
12555 {
12556 // From compatibleFormats8Bit
12557 VK_FORMAT_R4G4_UNORM_PACK8,
12558 VK_FORMAT_R8_SRGB,
12559
12560 // From compatibleFormats16Bit
12561 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
12562 VK_FORMAT_R16_SFLOAT,
12563
12564 // From compatibleFormats24Bit
12565 VK_FORMAT_R8G8B8_UNORM,
12566 VK_FORMAT_B8G8R8_SRGB,
12567
12568 // From compatibleFormats32Bit
12569 VK_FORMAT_R8G8B8A8_UNORM,
12570 VK_FORMAT_R32_SFLOAT,
12571
12572 // From compatibleFormats48Bit
12573 VK_FORMAT_R16G16B16_UNORM,
12574 VK_FORMAT_R16G16B16_SFLOAT,
12575
12576 // From compatibleFormats64Bit
12577 VK_FORMAT_R16G16B16A16_UNORM,
12578 VK_FORMAT_R64_SFLOAT,
12579
12580 // From compatibleFormats96Bit
12581 VK_FORMAT_R32G32B32_UINT,
12582 VK_FORMAT_R32G32B32_SFLOAT,
12583
12584 // From compatibleFormats128Bit
12585 VK_FORMAT_R32G32B32A32_UINT,
12586 VK_FORMAT_R64G64_SFLOAT,
12587
12588 // From compatibleFormats192Bit
12589 VK_FORMAT_R64G64B64_UINT,
12590 VK_FORMAT_R64G64B64_SFLOAT,
12591
12592 // From compatibleFormats256Bit
12593 VK_FORMAT_R64G64B64A64_UINT,
12594 VK_FORMAT_R64G64B64A64_SFLOAT,
12595 };
12596
getBlitImageTilingLayoutCaseName(VkImageTiling tiling,VkImageLayout layout)12597 std::string getBlitImageTilingLayoutCaseName (VkImageTiling tiling, VkImageLayout layout)
12598 {
12599 switch (tiling)
12600 {
12601 case VK_IMAGE_TILING_OPTIMAL:
12602 return getImageLayoutCaseName(layout);
12603 case VK_IMAGE_TILING_LINEAR:
12604 return "linear";
12605 default:
12606 DE_ASSERT(false);
12607 return "";
12608 }
12609 }
12610
addBlittingImageAllFormatsColorSrcFormatDstFormatTests(tcu::TestCaseGroup * group,BlitColorTestParams testParams)12611 void addBlittingImageAllFormatsColorSrcFormatDstFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
12612 {
12613 tcu::TestContext& testCtx = group->getTestContext();
12614
12615 FormatSet linearOtherImageFormatsToTestSet;
12616 const int numOfOtherImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(linearOtherImageFormatsToTest);
12617 for (int otherImageFormatsIndex = 0; otherImageFormatsIndex < numOfOtherImageFormatsToTestFilter; ++otherImageFormatsIndex)
12618 linearOtherImageFormatsToTestSet.insert(linearOtherImageFormatsToTest[otherImageFormatsIndex]);
12619
12620 const VkImageTiling blitSrcTilings[] =
12621 {
12622 VK_IMAGE_TILING_OPTIMAL,
12623 VK_IMAGE_TILING_LINEAR,
12624 };
12625 const VkImageLayout blitSrcLayouts[] =
12626 {
12627 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
12628 VK_IMAGE_LAYOUT_GENERAL
12629 };
12630 const VkImageTiling blitDstTilings[] =
12631 {
12632 VK_IMAGE_TILING_OPTIMAL,
12633 VK_IMAGE_TILING_LINEAR,
12634 };
12635 const VkImageLayout blitDstLayouts[] =
12636 {
12637 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
12638 VK_IMAGE_LAYOUT_GENERAL
12639 };
12640
12641 for (int srcTilingNdx = 0u; srcTilingNdx < DE_LENGTH_OF_ARRAY(blitSrcTilings); ++srcTilingNdx)
12642 {
12643 testParams.params.src.image.tiling = blitSrcTilings[srcTilingNdx];
12644
12645 for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
12646 {
12647 testParams.params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx];
12648
12649 // 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
12650 if (testParams.params.src.image.tiling == VK_IMAGE_TILING_LINEAR && testParams.params.src.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)
12651 continue;
12652
12653 for (int dstTilingNdx = 0u; dstTilingNdx < DE_LENGTH_OF_ARRAY(blitDstTilings); ++dstTilingNdx)
12654 {
12655 testParams.params.dst.image.tiling = blitDstTilings[dstTilingNdx];
12656
12657 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
12658 {
12659 testParams.params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx];
12660
12661 // 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
12662 if (testParams.params.dst.image.tiling == VK_IMAGE_TILING_LINEAR && testParams.params.dst.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
12663 continue;
12664
12665 if ((testParams.params.dst.image.tiling == VK_IMAGE_TILING_LINEAR && !de::contains(linearOtherImageFormatsToTestSet, testParams.params.src.image.format)) ||
12666 (testParams.params.src.image.tiling == VK_IMAGE_TILING_LINEAR && !de::contains(linearOtherImageFormatsToTestSet, testParams.params.dst.image.format)))
12667 continue;
12668
12669 testParams.params.filter = VK_FILTER_NEAREST;
12670 const std::string testName = getBlitImageTilingLayoutCaseName(testParams.params.src.image.tiling, testParams.params.src.image.operationLayout) + "_" +
12671 getBlitImageTilingLayoutCaseName(testParams.params.dst.image.tiling, testParams.params.dst.image.operationLayout);
12672 const std::string description = "Blit from layout " + getBlitImageTilingLayoutCaseName(testParams.params.src.image.tiling, testParams.params.src.image.operationLayout) +
12673 " to " + getBlitImageTilingLayoutCaseName(testParams.params.dst.image.tiling, testParams.params.dst.image.operationLayout);
12674 group->addChild(new BlitImageTestCase(testCtx, testName + "_nearest", description, testParams.params));
12675
12676 if (testParams.testFilters & FILTER_MASK_LINEAR)
12677 {
12678 testParams.params.filter = VK_FILTER_LINEAR;
12679 group->addChild(new BlitImageTestCase(testCtx, testName + "_linear", description, testParams.params));
12680 }
12681
12682 if (testParams.testFilters & FILTER_MASK_CUBIC)
12683 {
12684 testParams.params.filter = VK_FILTER_CUBIC_EXT;
12685 group->addChild(new BlitImageTestCase(testCtx, testName + "_cubic", description, testParams.params));
12686 }
12687
12688 if ((testParams.params.src.image.imageType == VK_IMAGE_TYPE_3D) && !isCompressedFormat(testParams.params.src.image.format))
12689 {
12690 const struct
12691 {
12692 FillMode mode;
12693 const char* name;
12694 } modeList[] =
12695 {
12696 { FILL_MODE_BLUE_RED_X, "x" },
12697 { FILL_MODE_BLUE_RED_Y, "y" },
12698 { FILL_MODE_BLUE_RED_Z, "z" },
12699 };
12700
12701 auto otherParams = testParams;
12702 otherParams.params.dst.image.fillMode = FILL_MODE_WHITE;
12703
12704 for (int i = 0; i < DE_LENGTH_OF_ARRAY(modeList); ++i)
12705 {
12706 otherParams.params.src.image.fillMode = modeList[i].mode;
12707
12708 otherParams.params.filter = VK_FILTER_LINEAR;
12709 group->addChild(new BlitImageTestCase(testCtx, testName + "_linear_stripes_" + modeList[i].name, description, otherParams.params));
12710
12711 otherParams.params.filter = VK_FILTER_NEAREST;
12712 group->addChild(new BlitImageTestCase(testCtx, testName + "_nearest_stripes_" + modeList[i].name, description, otherParams.params));
12713 }
12714 }
12715 }
12716 }
12717 }
12718 }
12719 }
12720
addBlittingImageAllFormatsColorSrcFormatTests(tcu::TestCaseGroup * group,BlitColorTestParams testParams)12721 void addBlittingImageAllFormatsColorSrcFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
12722 {
12723 VkFormat srcFormat = testParams.params.src.image.format;
12724
12725 if (testParams.compatibleFormats)
12726 {
12727 for (int dstFormatIndex = 0; testParams.compatibleFormats[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex)
12728 {
12729 testParams.params.dst.image.format = testParams.compatibleFormats[dstFormatIndex];
12730 if (!isSupportedByFramework(testParams.params.dst.image.format))
12731 continue;
12732
12733 if (!isAllowedBlittingAllFormatsColorSrcFormatTests(testParams))
12734 continue;
12735
12736 const std::string description = "Blit destination format " + getFormatCaseName(testParams.params.dst.image.format);
12737 addTestGroup(group, getFormatCaseName(testParams.params.dst.image.format), description, addBlittingImageAllFormatsColorSrcFormatDstFormatTests, testParams);
12738 }
12739 }
12740
12741 // If testParams.compatibleFormats is nullptr, the destination format will be copied from the source format
12742 // When testParams.compatibleFormats is not nullptr but format is compressed we also need to add that format
12743 // as it is not on compatibleFormats list
12744 if (!testParams.compatibleFormats || isCompressedFormat(srcFormat))
12745 {
12746 testParams.params.dst.image.format = srcFormat;
12747
12748 const std::string description = "Blit destination format " + getFormatCaseName(srcFormat);
12749 addTestGroup(group, getFormatCaseName(srcFormat), description, addBlittingImageAllFormatsColorSrcFormatDstFormatTests, testParams);
12750 }
12751 }
12752
12753 const VkFormat compatibleFormatsUInts[] =
12754 {
12755 VK_FORMAT_R8_UINT,
12756 VK_FORMAT_R8G8_UINT,
12757 VK_FORMAT_R8G8B8_UINT,
12758 VK_FORMAT_B8G8R8_UINT,
12759 VK_FORMAT_R8G8B8A8_UINT,
12760 VK_FORMAT_B8G8R8A8_UINT,
12761 VK_FORMAT_A8B8G8R8_UINT_PACK32,
12762 VK_FORMAT_A2R10G10B10_UINT_PACK32,
12763 VK_FORMAT_A2B10G10R10_UINT_PACK32,
12764 VK_FORMAT_R16_UINT,
12765 VK_FORMAT_R16G16_UINT,
12766 VK_FORMAT_R16G16B16_UINT,
12767 VK_FORMAT_R16G16B16A16_UINT,
12768 VK_FORMAT_R32_UINT,
12769 VK_FORMAT_R32G32_UINT,
12770 VK_FORMAT_R32G32B32_UINT,
12771 VK_FORMAT_R32G32B32A32_UINT,
12772 VK_FORMAT_R64_UINT,
12773 VK_FORMAT_R64G64_UINT,
12774 VK_FORMAT_R64G64B64_UINT,
12775 VK_FORMAT_R64G64B64A64_UINT,
12776
12777 VK_FORMAT_UNDEFINED
12778 };
12779 const VkFormat compatibleFormatsSInts[] =
12780 {
12781 VK_FORMAT_R8_SINT,
12782 VK_FORMAT_R8G8_SINT,
12783 VK_FORMAT_R8G8B8_SINT,
12784 VK_FORMAT_B8G8R8_SINT,
12785 VK_FORMAT_R8G8B8A8_SINT,
12786 VK_FORMAT_B8G8R8A8_SINT,
12787 VK_FORMAT_A8B8G8R8_SINT_PACK32,
12788 VK_FORMAT_A2R10G10B10_SINT_PACK32,
12789 VK_FORMAT_A2B10G10R10_SINT_PACK32,
12790 VK_FORMAT_R16_SINT,
12791 VK_FORMAT_R16G16_SINT,
12792 VK_FORMAT_R16G16B16_SINT,
12793 VK_FORMAT_R16G16B16A16_SINT,
12794 VK_FORMAT_R32_SINT,
12795 VK_FORMAT_R32G32_SINT,
12796 VK_FORMAT_R32G32B32_SINT,
12797 VK_FORMAT_R32G32B32A32_SINT,
12798 VK_FORMAT_R64_SINT,
12799 VK_FORMAT_R64G64_SINT,
12800 VK_FORMAT_R64G64B64_SINT,
12801 VK_FORMAT_R64G64B64A64_SINT,
12802
12803 VK_FORMAT_UNDEFINED
12804 };
12805 const VkFormat compatibleFormatsFloats[] =
12806 {
12807 VK_FORMAT_R4G4_UNORM_PACK8,
12808 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
12809 VK_FORMAT_B4G4R4A4_UNORM_PACK16,
12810 VK_FORMAT_R5G6B5_UNORM_PACK16,
12811 VK_FORMAT_B5G6R5_UNORM_PACK16,
12812 VK_FORMAT_R5G5B5A1_UNORM_PACK16,
12813 VK_FORMAT_B5G5R5A1_UNORM_PACK16,
12814 VK_FORMAT_A1R5G5B5_UNORM_PACK16,
12815 VK_FORMAT_R8_UNORM,
12816 VK_FORMAT_R8_SNORM,
12817 VK_FORMAT_R8_USCALED,
12818 VK_FORMAT_R8_SSCALED,
12819 VK_FORMAT_R8G8_UNORM,
12820 VK_FORMAT_R8G8_SNORM,
12821 VK_FORMAT_R8G8_USCALED,
12822 VK_FORMAT_R8G8_SSCALED,
12823 VK_FORMAT_R8G8B8_UNORM,
12824 VK_FORMAT_R8G8B8_SNORM,
12825 VK_FORMAT_R8G8B8_USCALED,
12826 VK_FORMAT_R8G8B8_SSCALED,
12827 VK_FORMAT_B8G8R8_UNORM,
12828 VK_FORMAT_B8G8R8_SNORM,
12829 VK_FORMAT_B8G8R8_USCALED,
12830 VK_FORMAT_B8G8R8_SSCALED,
12831 VK_FORMAT_R8G8B8A8_UNORM,
12832 VK_FORMAT_R8G8B8A8_SNORM,
12833 VK_FORMAT_R8G8B8A8_USCALED,
12834 VK_FORMAT_R8G8B8A8_SSCALED,
12835 VK_FORMAT_B8G8R8A8_UNORM,
12836 VK_FORMAT_B8G8R8A8_SNORM,
12837 VK_FORMAT_B8G8R8A8_USCALED,
12838 VK_FORMAT_B8G8R8A8_SSCALED,
12839 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
12840 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
12841 VK_FORMAT_A8B8G8R8_USCALED_PACK32,
12842 VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
12843 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
12844 VK_FORMAT_A2R10G10B10_SNORM_PACK32,
12845 VK_FORMAT_A2R10G10B10_USCALED_PACK32,
12846 VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
12847 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
12848 VK_FORMAT_A2B10G10R10_SNORM_PACK32,
12849 VK_FORMAT_A2B10G10R10_USCALED_PACK32,
12850 VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
12851 VK_FORMAT_R16_UNORM,
12852 VK_FORMAT_R16_SNORM,
12853 VK_FORMAT_R16_USCALED,
12854 VK_FORMAT_R16_SSCALED,
12855 VK_FORMAT_R16_SFLOAT,
12856 VK_FORMAT_R16G16_UNORM,
12857 VK_FORMAT_R16G16_SNORM,
12858 VK_FORMAT_R16G16_USCALED,
12859 VK_FORMAT_R16G16_SSCALED,
12860 VK_FORMAT_R16G16_SFLOAT,
12861 VK_FORMAT_R16G16B16_UNORM,
12862 VK_FORMAT_R16G16B16_SNORM,
12863 VK_FORMAT_R16G16B16_USCALED,
12864 VK_FORMAT_R16G16B16_SSCALED,
12865 VK_FORMAT_R16G16B16_SFLOAT,
12866 VK_FORMAT_R16G16B16A16_UNORM,
12867 VK_FORMAT_R16G16B16A16_SNORM,
12868 VK_FORMAT_R16G16B16A16_USCALED,
12869 VK_FORMAT_R16G16B16A16_SSCALED,
12870 VK_FORMAT_R16G16B16A16_SFLOAT,
12871 VK_FORMAT_R32_SFLOAT,
12872 VK_FORMAT_R32G32_SFLOAT,
12873 VK_FORMAT_R32G32B32_SFLOAT,
12874 VK_FORMAT_R32G32B32A32_SFLOAT,
12875 VK_FORMAT_R64_SFLOAT,
12876 VK_FORMAT_R64G64_SFLOAT,
12877 VK_FORMAT_R64G64B64_SFLOAT,
12878 VK_FORMAT_R64G64B64A64_SFLOAT,
12879 VK_FORMAT_B10G11R11_UFLOAT_PACK32,
12880 VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
12881
12882 VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
12883 VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
12884
12885 VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
12886
12887 VK_FORMAT_UNDEFINED
12888 };
12889
12890 const VkFormat compressedFormatsFloats[] =
12891 {
12892 VK_FORMAT_BC1_RGB_UNORM_BLOCK,
12893 VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
12894 VK_FORMAT_BC2_UNORM_BLOCK,
12895 VK_FORMAT_BC3_UNORM_BLOCK,
12896 VK_FORMAT_BC4_UNORM_BLOCK,
12897 VK_FORMAT_BC4_SNORM_BLOCK,
12898 VK_FORMAT_BC5_UNORM_BLOCK,
12899 VK_FORMAT_BC5_SNORM_BLOCK,
12900 VK_FORMAT_BC6H_UFLOAT_BLOCK,
12901 VK_FORMAT_BC6H_SFLOAT_BLOCK,
12902 VK_FORMAT_BC7_UNORM_BLOCK,
12903 VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
12904 VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
12905 VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
12906 VK_FORMAT_EAC_R11_UNORM_BLOCK,
12907 VK_FORMAT_EAC_R11_SNORM_BLOCK,
12908 VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
12909 VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
12910 VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
12911 VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
12912 VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
12913 VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
12914 VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
12915 VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
12916 VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
12917 VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
12918 VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
12919 VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
12920 VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
12921 VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
12922 VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
12923 VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
12924
12925 VK_FORMAT_UNDEFINED
12926 };
12927
12928 const VkFormat compatibleFormatsSrgb[] =
12929 {
12930 VK_FORMAT_R8_SRGB,
12931 VK_FORMAT_R8G8_SRGB,
12932 VK_FORMAT_R8G8B8_SRGB,
12933 VK_FORMAT_B8G8R8_SRGB,
12934 VK_FORMAT_R8G8B8A8_SRGB,
12935 VK_FORMAT_B8G8R8A8_SRGB,
12936 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
12937
12938 VK_FORMAT_UNDEFINED
12939 };
12940
12941 const VkFormat compressedFormatsSrgb[] =
12942 {
12943 VK_FORMAT_BC1_RGB_SRGB_BLOCK,
12944 VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
12945 VK_FORMAT_BC2_SRGB_BLOCK,
12946 VK_FORMAT_BC3_SRGB_BLOCK,
12947 VK_FORMAT_BC7_SRGB_BLOCK,
12948 VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
12949 VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
12950 VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
12951 VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
12952 VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
12953 VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
12954 VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
12955 VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
12956 VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
12957 VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
12958 VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
12959 VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
12960 VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
12961 VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
12962 VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
12963 VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
12964 VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
12965
12966 VK_FORMAT_UNDEFINED
12967 };
12968
12969 const VkFormat dedicatedAllocationBlittingFormatsToTest[] =
12970 {
12971 // compatibleFormatsUInts
12972 VK_FORMAT_R8_UINT,
12973 VK_FORMAT_R64G64B64A64_UINT,
12974
12975 // compatibleFormatsSInts
12976 VK_FORMAT_R8_SINT,
12977 VK_FORMAT_R64G64B64A64_SINT,
12978
12979 // compatibleFormatsFloats
12980 VK_FORMAT_R4G4_UNORM_PACK8,
12981 VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
12982
12983 // compatibleFormatsSrgb
12984 VK_FORMAT_R8_SRGB,
12985 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
12986 };
12987
12988 // skip cubic filtering test for the following data formats
12989 const FormatSet onlyNearestAndLinearFormatsToTest =
12990 {
12991 VK_FORMAT_A8B8G8R8_USCALED_PACK32,
12992 VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
12993 VK_FORMAT_A8B8G8R8_UINT_PACK32,
12994 VK_FORMAT_A8B8G8R8_SINT_PACK32
12995 };
12996
12997 // astc formats have diferent block sizes and thus require diferent resolutions for images
12998 enum class AstcImageSizeType
12999 {
13000 SIZE_64_64 = 0,
13001 SIZE_60_64,
13002 SIZE_64_60,
13003 SIZE_60_60,
13004 };
13005
13006 const std::map<VkFormat, AstcImageSizeType> astcSizes
13007 {
13008 { VK_FORMAT_ASTC_4x4_SRGB_BLOCK, AstcImageSizeType::SIZE_64_64 },
13009 { VK_FORMAT_ASTC_4x4_UNORM_BLOCK, AstcImageSizeType::SIZE_64_64 },
13010 { VK_FORMAT_ASTC_5x4_SRGB_BLOCK, AstcImageSizeType::SIZE_60_64 },
13011 { VK_FORMAT_ASTC_5x4_UNORM_BLOCK, AstcImageSizeType::SIZE_60_64 },
13012 { VK_FORMAT_ASTC_5x5_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60 },
13013 { VK_FORMAT_ASTC_5x5_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60 },
13014 { VK_FORMAT_ASTC_6x5_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60 },
13015 { VK_FORMAT_ASTC_6x5_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60 },
13016 { VK_FORMAT_ASTC_6x6_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60 },
13017 { VK_FORMAT_ASTC_6x6_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60 },
13018 { VK_FORMAT_ASTC_8x5_SRGB_BLOCK, AstcImageSizeType::SIZE_64_60 },
13019 { VK_FORMAT_ASTC_8x5_UNORM_BLOCK, AstcImageSizeType::SIZE_64_60 },
13020 { VK_FORMAT_ASTC_8x6_SRGB_BLOCK, AstcImageSizeType::SIZE_64_60 },
13021 { VK_FORMAT_ASTC_8x6_UNORM_BLOCK, AstcImageSizeType::SIZE_64_60 },
13022 { VK_FORMAT_ASTC_8x8_SRGB_BLOCK, AstcImageSizeType::SIZE_64_64 },
13023 { VK_FORMAT_ASTC_8x8_UNORM_BLOCK, AstcImageSizeType::SIZE_64_64 },
13024 { VK_FORMAT_ASTC_10x5_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60 },
13025 { VK_FORMAT_ASTC_10x5_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60 },
13026 { VK_FORMAT_ASTC_10x6_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60 },
13027 { VK_FORMAT_ASTC_10x6_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60 },
13028 { VK_FORMAT_ASTC_10x8_SRGB_BLOCK, AstcImageSizeType::SIZE_60_64 },
13029 { VK_FORMAT_ASTC_10x8_UNORM_BLOCK, AstcImageSizeType::SIZE_60_64 },
13030 { VK_FORMAT_ASTC_10x10_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60 },
13031 { VK_FORMAT_ASTC_10x10_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60 },
13032 { VK_FORMAT_ASTC_12x10_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60 },
13033 { VK_FORMAT_ASTC_12x10_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60 },
13034 { VK_FORMAT_ASTC_12x12_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60 },
13035 { VK_FORMAT_ASTC_12x12_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60 }
13036 };
13037
create2DCopyRegions(deInt32 srcWidth,deInt32 srcHeight,deInt32 dstWidth,deInt32 dstHeight)13038 std::vector<CopyRegion> create2DCopyRegions(deInt32 srcWidth, deInt32 srcHeight, deInt32 dstWidth, deInt32 dstHeight)
13039 {
13040 CopyRegion region;
13041 std::vector<CopyRegion> regionsVector;
13042
13043 deInt32 fourthOfSrcWidth = srcWidth / 4;
13044 deInt32 fourthOfSrcHeight = srcHeight / 4;
13045 deInt32 fourthOfDstWidth = dstWidth / 4;
13046 deInt32 fourthOfDstHeight = dstHeight / 4;
13047
13048 // to the top of resulting image copy whole source image but with increasingly smaller sizes
13049 for (int i = 0, j = 1; (i + fourthOfDstWidth / j < dstWidth) && (fourthOfDstWidth > j); i += fourthOfDstWidth / j++)
13050 {
13051 region.imageBlit =
13052 {
13053 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
13054 {
13055 {0, 0, 0},
13056 {srcWidth, srcHeight, 1}
13057 }, // VkOffset3D srcOffsets[2];
13058
13059 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
13060 {
13061 {i, 0, 0},
13062 {i + fourthOfDstWidth / j, fourthOfDstHeight / j, 1}
13063 } // VkOffset3D dstOffset[2];
13064 };
13065 regionsVector.push_back(region);
13066 }
13067
13068 // to the bottom of resulting image copy parts of source image;
13069 for (int i = 0; i < 4; ++i)
13070 {
13071 int srcX = i * fourthOfSrcWidth;
13072 int srcY = i * fourthOfSrcHeight;
13073 int dstX = i * fourthOfDstWidth;
13074
13075 region.imageBlit =
13076 {
13077 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
13078 {
13079 {srcX, srcY, 0},
13080 {srcX + fourthOfSrcWidth, srcY + fourthOfSrcHeight, 1}
13081 }, // VkOffset3D srcOffsets[2];
13082
13083 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
13084 {
13085 {dstX, 2 * fourthOfDstHeight, 0},
13086 {dstX + fourthOfDstWidth, 3 * fourthOfDstHeight, 1}
13087 } // VkOffset3D dstOffset[2];
13088 };
13089
13090 regionsVector.push_back(region);
13091 }
13092
13093 return regionsVector;
13094 }
13095
addBlittingImageAllFormatsColorTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)13096 void addBlittingImageAllFormatsColorTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
13097 {
13098 const struct {
13099 const VkFormat* sourceFormats;
13100 const VkFormat* destinationFormats;
13101 const bool onlyNearest;
13102 } colorImageFormatsToTestBlit[] =
13103 {
13104 { compatibleFormatsUInts, compatibleFormatsUInts, true },
13105 { compatibleFormatsSInts, compatibleFormatsSInts, true },
13106 { compatibleFormatsFloats, compatibleFormatsFloats, false },
13107 { compressedFormatsFloats, compatibleFormatsFloats, false },
13108 { compatibleFormatsSrgb, compatibleFormatsSrgb, false },
13109 { compressedFormatsSrgb, compatibleFormatsSrgb, false },
13110 };
13111
13112 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
13113
13114 if (allocationKind == ALLOCATION_KIND_DEDICATED)
13115 {
13116 const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
13117 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
13118 dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
13119 }
13120
13121 // 2D tests.
13122 {
13123 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D blitting tests"));
13124
13125 TestParams params;
13126 params.src.image.imageType = VK_IMAGE_TYPE_2D;
13127 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
13128 params.src.image.extent = defaultExtent;
13129 params.dst.image.extent = defaultExtent;
13130 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13131 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13132 params.allocationKind = allocationKind;
13133 params.extensionUse = extensionUse;
13134
13135 // create all required copy regions
13136 const std::map<AstcImageSizeType, std::vector<CopyRegion> > imageRegions
13137 {
13138 { AstcImageSizeType::SIZE_64_64, create2DCopyRegions(64, 64, 64, 64) },
13139 { AstcImageSizeType::SIZE_60_64, create2DCopyRegions(60, 64, 60, 64) },
13140 { AstcImageSizeType::SIZE_64_60, create2DCopyRegions(64, 60, 64, 60) },
13141 { AstcImageSizeType::SIZE_60_60, create2DCopyRegions(60, 60, 60, 60) },
13142 };
13143
13144 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
13145 {
13146 const VkFormat* sourceFormats = colorImageFormatsToTestBlit[compatibleFormatsIndex].sourceFormats;
13147 const VkFormat* destinationFormats = colorImageFormatsToTestBlit[compatibleFormatsIndex].destinationFormats;
13148 const bool onlyNearest = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
13149 for (int srcFormatIndex = 0; sourceFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
13150 {
13151 VkFormat srcFormat = sourceFormats[srcFormatIndex];
13152 params.src.image.format = srcFormat;
13153
13154 const bool onlyNearestAndLinear = de::contains(onlyNearestAndLinearFormatsToTest, params.src.image.format);
13155
13156 // most of tests are using regions caluculated for 64x64 size but astc formats require custom regions
13157 params.regions = imageRegions.at(AstcImageSizeType::SIZE_64_64);
13158 if (isCompressedFormat(srcFormat) && isAstcFormat(mapVkCompressedFormat(srcFormat)))
13159 params.regions = imageRegions.at(astcSizes.at(srcFormat));
13160
13161 // use the fact that first region contains the size of full source image
13162 // and make source and destination the same size - this is needed for astc formats
13163 const VkOffset3D& srcImageSize = params.regions[0].imageBlit.srcOffsets[1];
13164 VkExtent3D& srcImageExtent = params.src.image.extent;
13165 VkExtent3D& dstImageExtent = params.dst.image.extent;
13166 srcImageExtent.width = srcImageSize.x;
13167 srcImageExtent.height = srcImageSize.y;
13168 dstImageExtent.width = srcImageSize.x;
13169 dstImageExtent.height = srcImageSize.y;
13170
13171 BlitColorTestParams testParams
13172 {
13173 params,
13174 destinationFormats,
13175 makeFilterMask(onlyNearest, onlyNearestAndLinear)
13176 };
13177
13178 const std::string description = "Blit source format " + getFormatCaseName(params.src.image.format);
13179 addTestGroup(subGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams);
13180 }
13181 }
13182
13183 group->addChild(subGroup.release());
13184 }
13185
13186 // 1D tests.
13187 {
13188 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D blitting tests"));
13189
13190 TestParams params;
13191 params.src.image.imageType = VK_IMAGE_TYPE_1D;
13192 params.dst.image.imageType = VK_IMAGE_TYPE_1D;
13193 params.src.image.extent = default1dExtent;
13194 params.dst.image.extent = default1dExtent;
13195 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13196 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13197 params.allocationKind = allocationKind;
13198 params.extensionUse = extensionUse;
13199
13200 CopyRegion region;
13201 for (int i = 0; i < defaultSize; i += defaultSize / 2)
13202 {
13203 const VkImageBlit imageBlit =
13204 {
13205 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
13206 {
13207 {0, 0, 0},
13208 {defaultSize, 1, 1}
13209 }, // VkOffset3D srcOffsets[2];
13210
13211 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
13212 {
13213 {i, 0, 0},
13214 {i + defaultQuarterSize, 1, 1}
13215 } // VkOffset3D dstOffset[2];
13216 };
13217 region.imageBlit = imageBlit;
13218 params.regions.push_back(region);
13219 }
13220
13221 {
13222 const VkImageBlit imageBlit =
13223 {
13224 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
13225 {
13226 {0, 0, 0},
13227 {defaultQuarterSize, 1, 1}
13228 }, // VkOffset3D srcOffsets[2];
13229
13230 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
13231 {
13232 {defaultQuarterSize, 0, 0},
13233 {2 * defaultQuarterSize, 1, 1}
13234 } // VkOffset3D dstOffset[2];
13235 };
13236 region.imageBlit = imageBlit;
13237 params.regions.push_back(region);
13238 }
13239
13240 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
13241 {
13242 const VkFormat* sourceFormats = colorImageFormatsToTestBlit[compatibleFormatsIndex].sourceFormats;
13243 const bool onlyNearest = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
13244 for (int srcFormatIndex = 0; sourceFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
13245 {
13246 params.src.image.format = sourceFormats[srcFormatIndex];
13247 if (!isSupportedByFramework(params.src.image.format))
13248 continue;
13249
13250 // Cubic filtering can only be used with 2D images.
13251 const bool onlyNearestAndLinear = true;
13252
13253 BlitColorTestParams testParams
13254 {
13255 params,
13256 nullptr,
13257 makeFilterMask(onlyNearest, onlyNearestAndLinear)
13258 };
13259
13260 const std::string description = "Blit source format " + getFormatCaseName(params.src.image.format);
13261 addTestGroup(subGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams);
13262 }
13263 }
13264
13265 group->addChild(subGroup.release());
13266 }
13267
13268 // 3D tests. Note we use smaller dimensions here for performance reasons.
13269 {
13270 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D blitting tests"));
13271
13272 TestParams params;
13273 params.src.image.imageType = VK_IMAGE_TYPE_3D;
13274 params.dst.image.imageType = VK_IMAGE_TYPE_3D;
13275 params.src.image.extent = default3dExtent;
13276 params.dst.image.extent = default3dExtent;
13277 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13278 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13279 params.allocationKind = allocationKind;
13280 params.extensionUse = extensionUse;
13281
13282 CopyRegion region;
13283 for (int i = 0, j = 1; (i + defaultSixteenthSize / j < defaultQuarterSize) && (defaultSixteenthSize > j); i += defaultSixteenthSize / j++)
13284 {
13285 const VkImageBlit imageBlit =
13286 {
13287 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
13288 {
13289 {0, 0, 0},
13290 {defaultQuarterSize, defaultQuarterSize, defaultQuarterSize}
13291 }, // VkOffset3D srcOffsets[2];
13292
13293 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
13294 {
13295 {i, 0, i},
13296 {i + defaultSixteenthSize / j, defaultSixteenthSize / j, i + defaultSixteenthSize / j}
13297 } // VkOffset3D dstOffset[2];
13298 };
13299 region.imageBlit = imageBlit;
13300 params.regions.push_back(region);
13301 }
13302 for (int i = 0; i < defaultQuarterSize; i += defaultSixteenthSize)
13303 {
13304 const VkImageBlit imageBlit =
13305 {
13306 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
13307 {
13308 {i, i, i},
13309 {i + defaultSixteenthSize, i + defaultSixteenthSize, i + defaultSixteenthSize}
13310 }, // VkOffset3D srcOffsets[2];
13311
13312 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
13313 {
13314 {i, defaultQuarterSize / 2, i},
13315 {i + defaultSixteenthSize, defaultQuarterSize / 2 + defaultSixteenthSize, i + defaultSixteenthSize}
13316 } // VkOffset3D dstOffset[2];
13317 };
13318 region.imageBlit = imageBlit;
13319 params.regions.push_back(region);
13320 }
13321
13322 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
13323 {
13324 const VkFormat* sourceFormats = colorImageFormatsToTestBlit[compatibleFormatsIndex].sourceFormats;
13325 const bool onlyNearest = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
13326 for (int srcFormatIndex = 0; sourceFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
13327 {
13328 params.src.image.format = sourceFormats[srcFormatIndex];
13329 if (!isSupportedByFramework(params.src.image.format))
13330 continue;
13331
13332 // Cubic filtering can only be used with 2D images.
13333 const bool onlyNearestAndLinear = true;
13334
13335 BlitColorTestParams testParams
13336 {
13337 params,
13338 nullptr,
13339 makeFilterMask(onlyNearest, onlyNearestAndLinear)
13340 };
13341
13342 const std::string description = "Blit source format " + getFormatCaseName(params.src.image.format);
13343 addTestGroup(subGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams);
13344 }
13345 }
13346
13347 group->addChild(subGroup.release());
13348 }
13349 }
13350
addBlittingImageAllFormatsDepthStencilFormatsTests(tcu::TestCaseGroup * group,TestParams params)13351 void addBlittingImageAllFormatsDepthStencilFormatsTests (tcu::TestCaseGroup* group, TestParams params)
13352 {
13353 const VkImageLayout blitSrcLayouts[] =
13354 {
13355 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
13356 VK_IMAGE_LAYOUT_GENERAL
13357 };
13358 const VkImageLayout blitDstLayouts[] =
13359 {
13360 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
13361 VK_IMAGE_LAYOUT_GENERAL
13362 };
13363
13364 for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
13365 {
13366 params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx];
13367
13368 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
13369 {
13370 params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx];
13371 params.filter = VK_FILTER_NEAREST;
13372
13373 const std::string testName = getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
13374 getImageLayoutCaseName(params.dst.image.operationLayout);
13375 const std::string description = "Blit from " + getImageLayoutCaseName(params.src.image.operationLayout) +
13376 " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
13377
13378 group->addChild(new BlitImageTestCase(group->getTestContext(), testName + "_nearest", description, params));
13379 }
13380 }
13381 }
13382
addBlittingImageAllFormatsDepthStencilTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)13383 void addBlittingImageAllFormatsDepthStencilTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
13384 {
13385 const VkFormat depthAndStencilFormats[] =
13386 {
13387 VK_FORMAT_D16_UNORM,
13388 VK_FORMAT_X8_D24_UNORM_PACK32,
13389 VK_FORMAT_D32_SFLOAT,
13390 VK_FORMAT_S8_UINT,
13391 VK_FORMAT_D16_UNORM_S8_UINT,
13392 VK_FORMAT_D24_UNORM_S8_UINT,
13393 VK_FORMAT_D32_SFLOAT_S8_UINT,
13394 };
13395
13396 const VkImageSubresourceLayers defaultDepthSourceLayer = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
13397 const VkImageSubresourceLayers defaultStencilSourceLayer = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
13398 const VkImageSubresourceLayers defaultDSSourceLayer = { VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
13399
13400 // 2D tests
13401 {
13402 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D blitting tests"));
13403
13404 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
13405 {
13406 TestParams params;
13407 params.src.image.imageType = VK_IMAGE_TYPE_2D;
13408 params.src.image.extent = defaultExtent;
13409 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13410 params.src.image.format = depthAndStencilFormats[compatibleFormatsIndex];
13411 params.dst.image.extent = defaultExtent;
13412 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
13413 params.dst.image.format = params.src.image.format;
13414 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13415 params.allocationKind = allocationKind;
13416 params.extensionUse = extensionUse;
13417 params.separateDepthStencilLayouts = DE_FALSE;
13418
13419 bool hasDepth = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
13420 bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
13421
13422 CopyRegion region;
13423 for (int i = 0, j = 1; (i + defaultQuarterSize / j < defaultSize) && (defaultQuarterSize > j); i += defaultQuarterSize / j++)
13424 {
13425 const VkOffset3D srcOffset0 = {0, 0, 0};
13426 const VkOffset3D srcOffset1 = {defaultSize, defaultSize, 1};
13427 const VkOffset3D dstOffset0 = {i, 0, 0};
13428 const VkOffset3D dstOffset1 = {i + defaultQuarterSize / j, defaultQuarterSize / j, 1};
13429
13430 if (hasDepth)
13431 {
13432 const VkImageBlit imageBlit =
13433 {
13434 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
13435 { srcOffset0 , srcOffset1 }, // VkOffset3D srcOffsets[2];
13436 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
13437 { dstOffset0 , dstOffset1 }, // VkOffset3D dstOffset[2];
13438 };
13439 region.imageBlit = imageBlit;
13440 params.regions.push_back(region);
13441 }
13442 if (hasStencil)
13443 {
13444 const VkImageBlit imageBlit =
13445 {
13446 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
13447 { srcOffset0 , srcOffset1 }, // VkOffset3D srcOffsets[2];
13448 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
13449 { dstOffset0 , dstOffset1 }, // VkOffset3D dstOffset[2];
13450 };
13451 region.imageBlit = imageBlit;
13452 params.regions.push_back(region);
13453 }
13454 }
13455 for (int i = 0; i < defaultSize; i += defaultQuarterSize)
13456 {
13457 const VkOffset3D srcOffset0 = {i, i, 0};
13458 const VkOffset3D srcOffset1 = {i + defaultQuarterSize, i + defaultQuarterSize, 1};
13459 const VkOffset3D dstOffset0 = {i, defaultSize / 2, 0};
13460 const VkOffset3D dstOffset1 = {i + defaultQuarterSize, defaultSize / 2 + defaultQuarterSize, 1};
13461
13462 if (hasDepth)
13463 {
13464 const VkImageBlit imageBlit =
13465 {
13466 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
13467 { srcOffset0, srcOffset1 }, // VkOffset3D srcOffsets[2];
13468 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
13469 { dstOffset0, dstOffset1 } // VkOffset3D dstOffset[2];
13470 };
13471 region.imageBlit = imageBlit;
13472 params.regions.push_back(region);
13473 }
13474 if (hasStencil)
13475 {
13476 const VkImageBlit imageBlit =
13477 {
13478 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
13479 { srcOffset0, srcOffset1 }, // VkOffset3D srcOffsets[2];
13480 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
13481 { dstOffset0, dstOffset1 } // VkOffset3D dstOffset[2];
13482 };
13483 region.imageBlit = imageBlit;
13484 params.regions.push_back(region);
13485 }
13486 if (hasDepth && hasStencil)
13487 {
13488 const VkOffset3D dstDSOffset0 = {i, 3 * defaultQuarterSize, 0};
13489 const VkOffset3D dstDSOffset1 = {i + defaultQuarterSize, defaultSize, 1};
13490 const VkImageBlit imageBlit =
13491 {
13492 defaultDSSourceLayer, // VkImageSubresourceLayers srcSubresource;
13493 { srcOffset0, srcOffset1 }, // VkOffset3D srcOffsets[2];
13494 defaultDSSourceLayer, // VkImageSubresourceLayers dstSubresource;
13495 { dstDSOffset0, dstDSOffset1 } // VkOffset3D dstOffset[2];
13496 };
13497 region.imageBlit = imageBlit;
13498 params.regions.push_back(region);
13499 }
13500 }
13501
13502 const std::string testName = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
13503 const std::string description = "Blit from " + getFormatCaseName(params.src.image.format) +
13504 " to " + getFormatCaseName(params.dst.image.format);
13505 addTestGroup(subGroup.get(), testName, description, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
13506
13507 if (hasDepth && hasStencil)
13508 {
13509 params.separateDepthStencilLayouts = DE_TRUE;
13510 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" +
13511 getFormatCaseName(params.dst.image.format) + "_separate_layouts";
13512 const std::string description2 = "Blit from " + getFormatCaseName(params.src.image.format) +
13513 " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
13514 addTestGroup(subGroup.get(), testName2, description2, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
13515 }
13516 }
13517
13518 group->addChild(subGroup.release());
13519 }
13520
13521 // 1D tests
13522 {
13523 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D blitting tests"));
13524
13525 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
13526 {
13527 TestParams params;
13528 params.src.image.imageType = VK_IMAGE_TYPE_1D;
13529 params.dst.image.imageType = VK_IMAGE_TYPE_1D;
13530 params.src.image.extent = default1dExtent;
13531 params.dst.image.extent = default1dExtent;
13532 params.src.image.format = depthAndStencilFormats[compatibleFormatsIndex];
13533 params.dst.image.format = params.src.image.format;
13534 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13535 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13536 params.allocationKind = allocationKind;
13537 params.extensionUse = extensionUse;
13538
13539 bool hasDepth = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
13540 bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
13541
13542 CopyRegion region;
13543 for (int i = 0; i < defaultSize; i += defaultSize / 2)
13544 {
13545 const VkOffset3D srcOffset0 = {0, 0, 0};
13546 const VkOffset3D srcOffset1 = {defaultSize, 1, 1};
13547 const VkOffset3D dstOffset0 = {i, 0, 0};
13548 const VkOffset3D dstOffset1 = {i + defaultQuarterSize, 1, 1};
13549
13550 if (hasDepth)
13551 {
13552 const VkImageBlit imageBlit =
13553 {
13554 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
13555 { srcOffset0 , srcOffset1 }, // VkOffset3D srcOffsets[2];
13556 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
13557 { dstOffset0 , dstOffset1 }, // VkOffset3D dstOffset[2];
13558 };
13559 region.imageBlit = imageBlit;
13560 params.regions.push_back(region);
13561 }
13562 if (hasStencil)
13563 {
13564 const VkImageBlit imageBlit =
13565 {
13566 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
13567 { srcOffset0 , srcOffset1 }, // VkOffset3D srcOffsets[2];
13568 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
13569 { dstOffset0 , dstOffset1 }, // VkOffset3D dstOffset[2];
13570 };
13571 region.imageBlit = imageBlit;
13572 params.regions.push_back(region);
13573 }
13574 }
13575
13576 {
13577 const VkOffset3D srcOffset0 = {0, 0, 0};
13578 const VkOffset3D srcOffset1 = {defaultQuarterSize, 1, 1};
13579 const VkOffset3D dstOffset0 = {defaultQuarterSize, 0, 0};
13580 const VkOffset3D dstOffset1 = {2 * defaultQuarterSize, 1, 1};
13581
13582 if (hasDepth)
13583 {
13584 const VkImageBlit imageBlit =
13585 {
13586 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
13587 { srcOffset0, srcOffset1 }, // VkOffset3D srcOffsets[2];
13588 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
13589 { dstOffset0, dstOffset1 } // VkOffset3D dstOffset[2];
13590 };
13591 region.imageBlit = imageBlit;
13592 params.regions.push_back(region);
13593 }
13594 if (hasStencil)
13595 {
13596 const VkImageBlit imageBlit =
13597 {
13598 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
13599 { srcOffset0, srcOffset1 }, // VkOffset3D srcOffsets[2];
13600 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
13601 { dstOffset0, dstOffset1 } // VkOffset3D dstOffset[2];
13602 };
13603 region.imageBlit = imageBlit;
13604 params.regions.push_back(region);
13605 }
13606 if (hasDepth && hasStencil)
13607 {
13608 const VkOffset3D dstDSOffset0 = {3 * defaultQuarterSize, 0, 0};
13609 const VkOffset3D dstDSOffset1 = {3 * defaultQuarterSize + defaultQuarterSize / 2, 1, 1};
13610 const VkImageBlit imageBlit =
13611 {
13612 defaultDSSourceLayer, // VkImageSubresourceLayers srcSubresource;
13613 { srcOffset0, srcOffset1 }, // VkOffset3D srcOffsets[2];
13614 defaultDSSourceLayer, // VkImageSubresourceLayers dstSubresource;
13615 { dstDSOffset0, dstDSOffset1 } // VkOffset3D dstOffset[2];
13616 };
13617 region.imageBlit = imageBlit;
13618 params.regions.push_back(region);
13619 }
13620 }
13621
13622 const std::string testName = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
13623 const std::string description = "Blit from " + getFormatCaseName(params.src.image.format) +
13624 " to " + getFormatCaseName(params.dst.image.format);
13625 addTestGroup(subGroup.get(), testName, description, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
13626
13627 if (hasDepth && hasStencil)
13628 {
13629 params.separateDepthStencilLayouts = DE_TRUE;
13630 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" +
13631 getFormatCaseName(params.dst.image.format) + "_separate_layouts";
13632 const std::string description2 = "Blit from " + getFormatCaseName(params.src.image.format) +
13633 " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
13634 addTestGroup(subGroup.get(), testName2, description2, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
13635 }
13636 }
13637
13638 group->addChild(subGroup.release());
13639 }
13640
13641 // 3D tests. Note we use smaller dimensions here for performance reasons.
13642 {
13643 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D blitting tests"));
13644
13645 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
13646 {
13647 TestParams params;
13648 params.src.image.imageType = VK_IMAGE_TYPE_3D;
13649 params.dst.image.imageType = VK_IMAGE_TYPE_3D;
13650 params.src.image.extent = default3dExtent;
13651 params.dst.image.extent = default3dExtent;
13652 params.src.image.format = depthAndStencilFormats[compatibleFormatsIndex];
13653 params.dst.image.format = params.src.image.format;
13654 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13655 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13656 params.allocationKind = allocationKind;
13657 params.extensionUse = extensionUse;
13658
13659 bool hasDepth = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
13660 bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
13661
13662 CopyRegion region;
13663 for (int i = 0, j = 1; (i + defaultSixteenthSize / j < defaultQuarterSize) && (defaultSixteenthSize > j); i += defaultSixteenthSize / j++)
13664 {
13665 const VkOffset3D srcOffset0 = {0, 0, 0};
13666 const VkOffset3D srcOffset1 = {defaultQuarterSize, defaultQuarterSize, defaultQuarterSize};
13667 const VkOffset3D dstOffset0 = {i, 0, i};
13668 const VkOffset3D dstOffset1 = {i + defaultSixteenthSize / j, defaultSixteenthSize / j, i + defaultSixteenthSize / j};
13669
13670 if (hasDepth)
13671 {
13672 const VkImageBlit imageBlit =
13673 {
13674 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
13675 { srcOffset0 , srcOffset1 }, // VkOffset3D srcOffsets[2];
13676 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
13677 { dstOffset0 , dstOffset1 }, // VkOffset3D dstOffset[2];
13678 };
13679 region.imageBlit = imageBlit;
13680 params.regions.push_back(region);
13681 }
13682 if (hasStencil)
13683 {
13684 const VkImageBlit imageBlit =
13685 {
13686 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
13687 { srcOffset0 , srcOffset1 }, // VkOffset3D srcOffsets[2];
13688 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
13689 { dstOffset0 , dstOffset1 }, // VkOffset3D dstOffset[2];
13690 };
13691 region.imageBlit = imageBlit;
13692 params.regions.push_back(region);
13693 }
13694 }
13695 for (int i = 0; i < defaultQuarterSize; i += defaultSixteenthSize)
13696 {
13697 const VkOffset3D srcOffset0 = {i, i, i};
13698 const VkOffset3D srcOffset1 = {i + defaultSixteenthSize, i + defaultSixteenthSize, i + defaultSixteenthSize};
13699 const VkOffset3D dstOffset0 = {i, defaultQuarterSize / 2, i};
13700 const VkOffset3D dstOffset1 = {i + defaultSixteenthSize, defaultQuarterSize / 2 + defaultSixteenthSize, i + defaultSixteenthSize};
13701
13702 if (hasDepth)
13703 {
13704 const VkImageBlit imageBlit =
13705 {
13706 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
13707 { srcOffset0, srcOffset1 }, // VkOffset3D srcOffsets[2];
13708 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
13709 { dstOffset0, dstOffset1 } // VkOffset3D dstOffset[2];
13710 };
13711 region.imageBlit = imageBlit;
13712 params.regions.push_back(region);
13713 }
13714 if (hasStencil)
13715 {
13716 const VkImageBlit imageBlit =
13717 {
13718 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
13719 { srcOffset0, srcOffset1 }, // VkOffset3D srcOffsets[2];
13720 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
13721 { dstOffset0, dstOffset1 } // VkOffset3D dstOffset[2];
13722 };
13723 region.imageBlit = imageBlit;
13724 params.regions.push_back(region);
13725 }
13726 if (hasDepth && hasStencil)
13727 {
13728 const VkOffset3D dstDSOffset0 = {i, 3 * defaultSixteenthSize, i};
13729 const VkOffset3D dstDSOffset1 = {i + defaultSixteenthSize, defaultQuarterSize, i + defaultSixteenthSize};
13730 const VkImageBlit imageBlit =
13731 {
13732 defaultDSSourceLayer, // VkImageSubresourceLayers srcSubresource;
13733 { srcOffset0, srcOffset1 }, // VkOffset3D srcOffsets[2];
13734 defaultDSSourceLayer, // VkImageSubresourceLayers dstSubresource;
13735 { dstDSOffset0, dstDSOffset1 } // VkOffset3D dstOffset[2];
13736 };
13737 region.imageBlit = imageBlit;
13738 params.regions.push_back(region);
13739 }
13740 }
13741
13742 const std::string testName = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
13743 const std::string description = "Blit from " + getFormatCaseName(params.src.image.format) +
13744 " to " + getFormatCaseName(params.dst.image.format);
13745 addTestGroup(subGroup.get(), testName, description, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
13746
13747 if (hasDepth && hasStencil)
13748 {
13749 params.separateDepthStencilLayouts = DE_TRUE;
13750 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" +
13751 getFormatCaseName(params.dst.image.format) + "_separate_layouts";
13752 const std::string description2 = "Blit from " + getFormatCaseName(params.src.image.format) +
13753 " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
13754 addTestGroup(subGroup.get(), testName2, description2, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
13755 }
13756 }
13757
13758 group->addChild(subGroup.release());
13759 }
13760 }
13761
addBlittingImageAllFormatsMipmapFormatTests(tcu::TestCaseGroup * group,BlitColorTestParams testParams)13762 void addBlittingImageAllFormatsMipmapFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
13763 {
13764 tcu::TestContext& testCtx = group->getTestContext();
13765
13766 const VkImageLayout blitSrcLayouts[] =
13767 {
13768 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
13769 VK_IMAGE_LAYOUT_GENERAL
13770 };
13771 const VkImageLayout blitDstLayouts[] =
13772 {
13773 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
13774 VK_IMAGE_LAYOUT_GENERAL
13775 };
13776
13777 for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
13778 {
13779 testParams.params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx];
13780 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
13781 {
13782 testParams.params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx];
13783
13784 testParams.params.filter = VK_FILTER_NEAREST;
13785 const std::string testName = getImageLayoutCaseName(testParams.params.src.image.operationLayout) + "_" +
13786 getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
13787 const std::string description = "Blit from layout " + getImageLayoutCaseName(testParams.params.src.image.operationLayout) +
13788 " to " + getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
13789 group->addChild(new BlitMipmapTestCase(testCtx, testName + "_nearest", description, testParams.params));
13790
13791 if (testParams.testFilters & FILTER_MASK_LINEAR)
13792 {
13793 testParams.params.filter = VK_FILTER_LINEAR;
13794 group->addChild(new BlitMipmapTestCase(testCtx, testName + "_linear", description, testParams.params));
13795 }
13796
13797 if (testParams.testFilters & FILTER_MASK_CUBIC)
13798 {
13799 testParams.params.filter = VK_FILTER_CUBIC_EXT;
13800 group->addChild(new BlitMipmapTestCase(testCtx, testName + "_cubic", description, testParams.params));
13801 }
13802 }
13803 }
13804 }
13805
addBlittingImageAllFormatsBaseLevelMipmapTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)13806 void addBlittingImageAllFormatsBaseLevelMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
13807 {
13808 const struct
13809 {
13810 const VkFormat* const compatibleFormats;
13811 const bool onlyNearest;
13812 } colorImageFormatsToTestBlit[] =
13813 {
13814 { compatibleFormatsUInts, true },
13815 { compatibleFormatsSInts, true },
13816 { compatibleFormatsFloats, false },
13817 { compatibleFormatsSrgb, false },
13818 };
13819
13820 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
13821
13822 const int layerCountsToTest[] =
13823 {
13824 1,
13825 6
13826 };
13827
13828 TestParams params;
13829 params.src.image.imageType = VK_IMAGE_TYPE_2D;
13830 params.src.image.extent = defaultExtent;
13831 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13832 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
13833 params.dst.image.extent = defaultExtent;
13834 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13835 params.allocationKind = allocationKind;
13836 params.extensionUse = extensionUse;
13837 params.mipLevels = deLog2Floor32(deMaxu32(defaultExtent.width, defaultExtent.height)) + 1u;
13838 params.singleCommand = DE_TRUE;
13839
13840 CopyRegion region;
13841 for (deUint32 mipLevelNdx = 0u; mipLevelNdx < params.mipLevels; mipLevelNdx++)
13842 {
13843 VkImageSubresourceLayers destLayer = defaultSourceLayer;
13844 destLayer.mipLevel = mipLevelNdx;
13845
13846 const VkImageBlit imageBlit =
13847 {
13848 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
13849 {
13850 {0, 0, 0},
13851 {defaultSize, defaultSize, 1}
13852 }, // VkOffset3D srcOffsets[2];
13853
13854 destLayer, // VkImageSubresourceLayers dstSubresource;
13855 {
13856 {0, 0, 0},
13857 {defaultSize >> mipLevelNdx, defaultSize >> mipLevelNdx, 1}
13858 } // VkOffset3D dstOffset[2];
13859 };
13860 region.imageBlit = imageBlit;
13861 params.regions.push_back(region);
13862 }
13863
13864 if (allocationKind == ALLOCATION_KIND_DEDICATED)
13865 {
13866 const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
13867 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
13868 dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
13869 }
13870
13871 for (int layerCountIndex = 0; layerCountIndex < DE_LENGTH_OF_ARRAY(layerCountsToTest); layerCountIndex++)
13872 {
13873 const int layerCount = layerCountsToTest[layerCountIndex];
13874 const std::string layerGroupName = "layercount_" + de::toString(layerCount);
13875 const std::string layerGroupDesc = "Blit mipmaps with layerCount = " + de::toString(layerCount);
13876
13877 de::MovePtr<tcu::TestCaseGroup> layerCountGroup (new tcu::TestCaseGroup(group->getTestContext(), layerGroupName.c_str(), layerGroupDesc.c_str()));
13878
13879 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
13880 {
13881 const VkFormat* compatibleFormats = colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
13882 const bool onlyNearest = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
13883
13884 for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
13885 {
13886 params.src.image.format = compatibleFormats[srcFormatIndex];
13887 params.dst.image.format = compatibleFormats[srcFormatIndex];
13888
13889 if (!isSupportedByFramework(params.src.image.format))
13890 continue;
13891
13892 const bool onlyNearestAndLinear = de::contains(onlyNearestAndLinearFormatsToTest, params.src.image.format);
13893
13894 const std::string description = "Blit source format " + getFormatCaseName(params.src.image.format);
13895
13896 BlitColorTestParams testParams;
13897 testParams.params = params;
13898 testParams.compatibleFormats = compatibleFormats;
13899 testParams.testFilters = makeFilterMask(onlyNearest, onlyNearestAndLinear);
13900
13901 testParams.params.src.image.extent.depth = layerCount;
13902 testParams.params.dst.image.extent.depth = layerCount;
13903
13904 for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
13905 {
13906 testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
13907 testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
13908 }
13909
13910 addTestGroup(layerCountGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams);
13911 }
13912 }
13913 group->addChild(layerCountGroup.release());
13914 }
13915 }
13916
addBlittingImageAllFormatsPreviousLevelMipmapTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)13917 void addBlittingImageAllFormatsPreviousLevelMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
13918 {
13919 const struct
13920 {
13921 const VkFormat* const compatibleFormats;
13922 const bool onlyNearest;
13923 } colorImageFormatsToTestBlit[] =
13924 {
13925 { compatibleFormatsUInts, true },
13926 { compatibleFormatsSInts, true },
13927 { compatibleFormatsFloats, false },
13928 { compatibleFormatsSrgb, false },
13929 };
13930
13931 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
13932
13933 const int layerCountsToTest[] =
13934 {
13935 1,
13936 6
13937 };
13938
13939 TestParams params;
13940 params.src.image.imageType = VK_IMAGE_TYPE_2D;
13941 params.src.image.extent = defaultExtent;
13942 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13943 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
13944 params.dst.image.extent = defaultExtent;
13945 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
13946 params.allocationKind = allocationKind;
13947 params.extensionUse = extensionUse;
13948 params.mipLevels = deLog2Floor32(deMaxu32(defaultExtent.width, defaultExtent.height)) + 1u;
13949 params.singleCommand = DE_FALSE;
13950
13951 CopyRegion region;
13952 for (deUint32 mipLevelNdx = 1u; mipLevelNdx < params.mipLevels; mipLevelNdx++)
13953 {
13954 VkImageSubresourceLayers srcLayer = defaultSourceLayer;
13955 VkImageSubresourceLayers destLayer = defaultSourceLayer;
13956
13957 srcLayer.mipLevel = mipLevelNdx - 1u;
13958 destLayer.mipLevel = mipLevelNdx;
13959
13960 const VkImageBlit imageBlit =
13961 {
13962 srcLayer, // VkImageSubresourceLayers srcSubresource;
13963 {
13964 {0, 0, 0},
13965 {defaultSize >> (mipLevelNdx - 1u), defaultSize >> (mipLevelNdx - 1u), 1}
13966 }, // VkOffset3D srcOffsets[2];
13967
13968 destLayer, // VkImageSubresourceLayers dstSubresource;
13969 {
13970 {0, 0, 0},
13971 {defaultSize >> mipLevelNdx, defaultSize >> mipLevelNdx, 1}
13972 } // VkOffset3D dstOffset[2];
13973 };
13974 region.imageBlit = imageBlit;
13975 params.regions.push_back(region);
13976 }
13977
13978 if (allocationKind == ALLOCATION_KIND_DEDICATED)
13979 {
13980 const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
13981 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
13982 dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
13983 }
13984
13985 for (int layerCountIndex = 0; layerCountIndex < DE_LENGTH_OF_ARRAY(layerCountsToTest); layerCountIndex++)
13986 {
13987 const int layerCount = layerCountsToTest[layerCountIndex];
13988 const std::string layerGroupName = "layercount_" + de::toString(layerCount);
13989 const std::string layerGroupDesc = "Blit mipmaps with layerCount = " + de::toString(layerCount);
13990
13991 de::MovePtr<tcu::TestCaseGroup> layerCountGroup (new tcu::TestCaseGroup(group->getTestContext(), layerGroupName.c_str(), layerGroupDesc.c_str()));
13992
13993 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
13994 {
13995 const VkFormat* compatibleFormats = colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
13996 const bool onlyNearest = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
13997
13998 for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
13999 {
14000 params.src.image.format = compatibleFormats[srcFormatIndex];
14001 params.dst.image.format = compatibleFormats[srcFormatIndex];
14002
14003 if (!isSupportedByFramework(params.src.image.format))
14004 continue;
14005
14006 const bool onlyNearestAndLinear = de::contains(onlyNearestAndLinearFormatsToTest, params.src.image.format);
14007
14008 const std::string description = "Blit source format " + getFormatCaseName(params.src.image.format);
14009
14010 BlitColorTestParams testParams;
14011 testParams.params = params;
14012 testParams.compatibleFormats = compatibleFormats;
14013 testParams.testFilters = makeFilterMask(onlyNearest, onlyNearestAndLinear);
14014
14015 testParams.params.src.image.extent.depth = layerCount;
14016 testParams.params.dst.image.extent.depth = layerCount;
14017
14018 for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
14019 {
14020 testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
14021 testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
14022 }
14023
14024 addTestGroup(layerCountGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams);
14025 }
14026 }
14027 group->addChild(layerCountGroup.release());
14028 }
14029
14030 for (int multiLayer = 0; multiLayer < 2; multiLayer++)
14031 {
14032 const int layerCount = multiLayer ? 6 : 1;
14033
14034 for (int barrierCount = 1; barrierCount < 4; barrierCount++)
14035 {
14036 if (layerCount != 1 || barrierCount != 1)
14037 {
14038 const std::string barrierGroupName = (multiLayer ? "layerbarriercount_" : "mipbarriercount_") + de::toString(barrierCount);
14039 const std::string barrierGroupDesc = "Use " + de::toString(barrierCount) + " image barriers";
14040
14041 de::MovePtr<tcu::TestCaseGroup> barrierCountGroup(new tcu::TestCaseGroup(group->getTestContext(), barrierGroupName.c_str(), barrierGroupDesc.c_str()));
14042
14043 params.barrierCount = barrierCount;
14044
14045 // Only go through a few common formats
14046 for (int srcFormatIndex = 2; srcFormatIndex < 6; ++srcFormatIndex)
14047 {
14048 params.src.image.format = compatibleFormatsUInts[srcFormatIndex];
14049 params.dst.image.format = compatibleFormatsUInts[srcFormatIndex];
14050
14051 if (!isSupportedByFramework(params.src.image.format))
14052 continue;
14053
14054 const std::string description = "Blit source format " + getFormatCaseName(params.src.image.format);
14055
14056 BlitColorTestParams testParams;
14057 testParams.params = params;
14058 testParams.compatibleFormats = compatibleFormatsUInts;
14059 testParams.testFilters = FILTER_MASK_NEAREST;
14060
14061 testParams.params.src.image.extent.depth = layerCount;
14062 testParams.params.dst.image.extent.depth = layerCount;
14063
14064 for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
14065 {
14066 testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
14067 testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
14068 }
14069
14070 addTestGroup(barrierCountGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams);
14071 }
14072 group->addChild(barrierCountGroup.release());
14073 }
14074 }
14075 }
14076 }
14077
addBlittingImageAllFormatsMipmapTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14078 void addBlittingImageAllFormatsMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14079 {
14080 addTestGroup(group, "from_base_level", "Generate all mipmap levels from base level", addBlittingImageAllFormatsBaseLevelMipmapTests, allocationKind, extensionUse);
14081 addTestGroup(group, "from_previous_level", "Generate next mipmap level from previous level", addBlittingImageAllFormatsPreviousLevelMipmapTests, allocationKind, extensionUse);
14082 }
14083
addBlittingImageAllFormatsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14084 void addBlittingImageAllFormatsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14085 {
14086 addTestGroup(group, "color", "Blitting image with color formats", addBlittingImageAllFormatsColorTests, allocationKind, extensionUse);
14087 addTestGroup(group, "depth_stencil", "Blitting image with depth/stencil formats", addBlittingImageAllFormatsDepthStencilTests, allocationKind, extensionUse);
14088 addTestGroup(group, "generate_mipmaps", "Generating mipmaps with vkCmdBlitImage()", addBlittingImageAllFormatsMipmapTests, allocationKind, extensionUse);
14089 }
14090
addBlittingImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14091 void addBlittingImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14092 {
14093 addTestGroup(group, "simple_tests", "Blitting image simple tests", addBlittingImageSimpleTests, allocationKind, extensionUse);
14094 addTestGroup(group, "all_formats", "Blitting image with all compatible formats", addBlittingImageAllFormatsTests, allocationKind, extensionUse);
14095 }
14096
14097 const VkSampleCountFlagBits samples[] =
14098 {
14099 VK_SAMPLE_COUNT_2_BIT,
14100 VK_SAMPLE_COUNT_4_BIT,
14101 VK_SAMPLE_COUNT_8_BIT,
14102 VK_SAMPLE_COUNT_16_BIT,
14103 VK_SAMPLE_COUNT_32_BIT,
14104 VK_SAMPLE_COUNT_64_BIT
14105 };
14106 const VkExtent3D resolveExtent = {256u, 256u, 1};
14107
addResolveImageWholeTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14108 void addResolveImageWholeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14109 {
14110 TestParams params;
14111 params.src.image.imageType = VK_IMAGE_TYPE_2D;
14112 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14113 params.src.image.extent = resolveExtent;
14114 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14115 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14116 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
14117 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14118 params.dst.image.extent = resolveExtent;
14119 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14120 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14121 params.allocationKind = allocationKind;
14122 params.extensionUse = extensionUse;
14123
14124 {
14125 const VkImageSubresourceLayers sourceLayer =
14126 {
14127 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
14128 0u, // deUint32 mipLevel;
14129 0u, // deUint32 baseArrayLayer;
14130 1u // deUint32 layerCount;
14131 };
14132 const VkImageResolve testResolve =
14133 {
14134 sourceLayer, // VkImageSubresourceLayers srcSubresource;
14135 {0, 0, 0}, // VkOffset3D srcOffset;
14136 sourceLayer, // VkImageSubresourceLayers dstSubresource;
14137 {0, 0, 0}, // VkOffset3D dstOffset;
14138 resolveExtent, // VkExtent3D extent;
14139 };
14140
14141 CopyRegion imageResolve;
14142 imageResolve.imageResolve = testResolve;
14143 params.regions.push_back(imageResolve);
14144 }
14145
14146 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14147 {
14148 params.imageOffset = false;
14149 params.samples = samples[samplesIndex];
14150 const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]);
14151 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
14152 params.imageOffset = true;
14153 if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14154 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", description, params));
14155 }
14156 }
14157 }
14158
addResolveImagePartialTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14159 void addResolveImagePartialTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14160 {
14161 TestParams params;
14162 params.src.image.imageType = VK_IMAGE_TYPE_2D;
14163 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14164 params.src.image.extent = resolveExtent;
14165 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14166 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14167 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
14168 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14169 params.dst.image.extent = resolveExtent;
14170 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14171 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14172 params.allocationKind = allocationKind;
14173 params.extensionUse = extensionUse;
14174
14175 {
14176 const VkImageSubresourceLayers sourceLayer =
14177 {
14178 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
14179 0u, // deUint32 mipLevel;
14180 0u, // deUint32 baseArrayLayer;
14181 1u // deUint32 layerCount;
14182 };
14183 const VkImageResolve testResolve =
14184 {
14185 sourceLayer, // VkImageSubresourceLayers srcSubresource;
14186 {0, 0, 0}, // VkOffset3D srcOffset;
14187 sourceLayer, // VkImageSubresourceLayers dstSubresource;
14188 {64u, 64u, 0}, // VkOffset3D dstOffset;
14189 {128u, 128u, 1u}, // VkExtent3D extent;
14190 };
14191
14192 CopyRegion imageResolve;
14193 imageResolve.imageResolve = testResolve;
14194 params.regions.push_back(imageResolve);
14195 }
14196
14197 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14198 {
14199 params.samples = samples[samplesIndex];
14200 const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]);
14201 params.imageOffset = false;
14202 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
14203 params.imageOffset = true;
14204 if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14205 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", description, params));
14206 }
14207 }
14208 }
14209
addResolveImageWithRegionsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14210 void addResolveImageWithRegionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14211 {
14212 TestParams params;
14213 params.src.image.imageType = VK_IMAGE_TYPE_2D;
14214 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14215 params.src.image.extent = resolveExtent;
14216 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14217 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14218 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
14219 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14220 params.dst.image.extent = resolveExtent;
14221 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14222 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14223 params.allocationKind = allocationKind;
14224 params.extensionUse = extensionUse;
14225 params.imageOffset = allocationKind != ALLOCATION_KIND_DEDICATED;
14226
14227 {
14228 const VkImageSubresourceLayers sourceLayer =
14229 {
14230 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
14231 0u, // deUint32 mipLevel;
14232 0u, // deUint32 baseArrayLayer;
14233 1u // deUint32 layerCount;
14234 };
14235
14236 for (int i = 0; i < 256; i += 64)
14237 {
14238 const VkImageResolve testResolve =
14239 {
14240 sourceLayer, // VkImageSubresourceLayers srcSubresource;
14241 {i, i, 0}, // VkOffset3D srcOffset;
14242 sourceLayer, // VkImageSubresourceLayers dstSubresource;
14243 {i, 0, 0}, // VkOffset3D dstOffset;
14244 {64u, 64u, 1u}, // VkExtent3D extent;
14245 };
14246
14247 CopyRegion imageResolve;
14248 imageResolve.imageResolve = testResolve;
14249 params.regions.push_back(imageResolve);
14250 }
14251 }
14252
14253 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14254 {
14255 params.samples = samples[samplesIndex];
14256 const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]);
14257 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
14258 }
14259 }
14260
addResolveImageWholeCopyBeforeResolvingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14261 void addResolveImageWholeCopyBeforeResolvingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14262 {
14263 TestParams params;
14264 params.src.image.imageType = VK_IMAGE_TYPE_2D;
14265 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14266 params.src.image.extent = defaultExtent;
14267 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14268 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14269 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
14270 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14271 params.dst.image.extent = defaultExtent;
14272 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14273 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14274 params.allocationKind = allocationKind;
14275 params.extensionUse = extensionUse;
14276
14277 {
14278 const VkImageSubresourceLayers sourceLayer =
14279 {
14280 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
14281 0u, // deUint32 mipLevel;
14282 0u, // deUint32 baseArrayLayer;
14283 1u // deUint32 layerCount;
14284 };
14285
14286 const VkImageResolve testResolve =
14287 {
14288 sourceLayer, // VkImageSubresourceLayers srcSubresource;
14289 {0, 0, 0}, // VkOffset3D srcOffset;
14290 sourceLayer, // VkImageSubresourceLayers dstSubresource;
14291 {0, 0, 0}, // VkOffset3D dstOffset;
14292 defaultExtent, // VkExtent3D extent;
14293 };
14294
14295 CopyRegion imageResolve;
14296 imageResolve.imageResolve = testResolve;
14297 params.regions.push_back(imageResolve);
14298 }
14299
14300 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14301 {
14302 params.samples = samples[samplesIndex];
14303 const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]);
14304 params.imageOffset = false;
14305 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_MS_IMAGE));
14306 params.imageOffset = true;
14307 if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14308 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", description, params, COPY_MS_IMAGE_TO_MS_IMAGE));
14309 }
14310 }
14311 }
14312
addComputeAndTransferQueueTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14313 void addComputeAndTransferQueueTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14314 {
14315 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)"));
14316 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)"));
14317
14318 TestParams params;
14319 params.src.image.imageType = VK_IMAGE_TYPE_2D;
14320 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14321 params.src.image.extent = defaultExtent;
14322 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14323 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14324 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
14325 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14326 params.dst.image.extent = defaultExtent;
14327 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14328 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14329 params.allocationKind = allocationKind;
14330 params.extensionUse = extensionUse;
14331
14332 {
14333 const VkImageSubresourceLayers sourceLayer =
14334 {
14335 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
14336 0u, // deUint32 mipLevel;
14337 0u, // deUint32 baseArrayLayer;
14338 1u // deUint32 layerCount;
14339 };
14340
14341 const VkImageResolve testResolve =
14342 {
14343 sourceLayer, // VkImageSubresourceLayers srcSubresource;
14344 {0, 0, 0}, // VkOffset3D srcOffset;
14345 sourceLayer, // VkImageSubresourceLayers dstSubresource;
14346 {0, 0, 0}, // VkOffset3D dstOffset;
14347 defaultExtent, // VkExtent3D extent;
14348 };
14349
14350 CopyRegion imageResolve;
14351 imageResolve.imageResolve = testResolve;
14352 params.regions.push_back(imageResolve);
14353 }
14354
14355 for (const auto& sample : samples)
14356 {
14357 params.samples = sample;
14358 const std::string description = "With " + getSampleCountCaseName(sample);
14359 computeGroup->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(sample), description, params, COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE));
14360 transferGroup->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(sample), description, params, COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER));
14361 }
14362
14363 group->addChild(computeGroup.release());
14364 group->addChild(transferGroup.release());
14365 }
14366
addResolveImageWholeCopyWithoutCabBeforeResolvingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14367 void addResolveImageWholeCopyWithoutCabBeforeResolvingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14368 {
14369 TestParams params;
14370 params.src.image.imageType = VK_IMAGE_TYPE_2D;
14371 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14372 params.src.image.extent = defaultExtent;
14373 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14374 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14375 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
14376 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14377 params.dst.image.extent = defaultExtent;
14378 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14379 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14380 params.allocationKind = allocationKind;
14381 params.extensionUse = extensionUse;
14382
14383 {
14384 const VkImageSubresourceLayers sourceLayer =
14385 {
14386 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
14387 0u, // deUint32 mipLevel;
14388 0u, // deUint32 baseArrayLayer;
14389 1u // deUint32 layerCount;
14390 };
14391
14392 const VkImageResolve testResolve =
14393 {
14394 sourceLayer, // VkImageSubresourceLayers srcSubresource;
14395 {0, 0, 0}, // VkOffset3D srcOffset;
14396 sourceLayer, // VkImageSubresourceLayers dstSubresource;
14397 {0, 0, 0}, // VkOffset3D dstOffset;
14398 defaultExtent, // VkExtent3D extent;
14399 };
14400
14401 CopyRegion imageResolve;
14402 imageResolve.imageResolve = testResolve;
14403 params.regions.push_back(imageResolve);
14404 }
14405
14406 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14407 {
14408 params.samples = samples[samplesIndex];
14409 const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]);
14410 params.imageOffset = false;
14411 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB));
14412 params.imageOffset = true;
14413 if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14414 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", description, params, COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB));
14415 }
14416 }
14417 }
14418
addResolveImageWholeCopyDiffLayoutsBeforeResolvingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14419 void addResolveImageWholeCopyDiffLayoutsBeforeResolvingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14420 {
14421 TestParams params;
14422 params.src.image.imageType = VK_IMAGE_TYPE_2D;
14423 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14424 params.src.image.extent = defaultExtent;
14425 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14426 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14427 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
14428 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14429 params.dst.image.extent = defaultExtent;
14430 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14431 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14432 params.allocationKind = allocationKind;
14433 params.extensionUse = extensionUse;
14434
14435 {
14436 const VkImageSubresourceLayers sourceLayer =
14437 {
14438 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
14439 0u, // deUint32 mipLevel;
14440 0u, // deUint32 baseArrayLayer;
14441 1u // deUint32 layerCount;
14442 };
14443
14444 const VkImageResolve testResolve =
14445 {
14446 sourceLayer, // VkImageSubresourceLayers srcSubresource;
14447 {0, 0, 0}, // VkOffset3D srcOffset;
14448 sourceLayer, // VkImageSubresourceLayers dstSubresource;
14449 {0, 0, 0}, // VkOffset3D dstOffset;
14450 defaultExtent, // VkExtent3D extent;
14451 };
14452
14453 CopyRegion imageResolve;
14454 imageResolve.imageResolve = testResolve;
14455 params.regions.push_back(imageResolve);
14456 }
14457
14458 const struct
14459 {
14460 VkImageLayout layout;
14461 std::string name;
14462 } imageLayouts[] =
14463 {
14464 { VK_IMAGE_LAYOUT_GENERAL, "general" },
14465 { VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, "transfer_src_optimal" },
14466 { VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, "transfer_dst_optimal" }
14467 };
14468
14469 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14470 for (int srcLayoutIndex = 0; srcLayoutIndex < DE_LENGTH_OF_ARRAY(imageLayouts); ++srcLayoutIndex)
14471 for (int dstLayoutIndex = 0; dstLayoutIndex < DE_LENGTH_OF_ARRAY(imageLayouts); ++dstLayoutIndex)
14472 {
14473 params.src.image.operationLayout = imageLayouts[srcLayoutIndex].layout;
14474 params.dst.image.operationLayout = imageLayouts[dstLayoutIndex].layout;
14475 if (params.src.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ||
14476 params.dst.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)
14477 continue;
14478 params.samples = samples[samplesIndex];
14479 const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]);
14480 std::string testName = getSampleCountCaseName(samples[samplesIndex]) + "_" + imageLayouts[srcLayoutIndex].name + "_" + imageLayouts[dstLayoutIndex].name;
14481 params.imageOffset = false;
14482 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), testName, description, params, COPY_MS_IMAGE_TO_MS_IMAGE));
14483 params.imageOffset = true;
14484 if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14485 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), testName + "_bind_offset", description, params, COPY_MS_IMAGE_TO_MS_IMAGE));
14486 }
14487 }
14488 }
14489
addResolveImageLayerCopyBeforeResolvingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14490 void addResolveImageLayerCopyBeforeResolvingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14491 {
14492 TestParams params;
14493 params.src.image.imageType = VK_IMAGE_TYPE_2D;
14494 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14495 params.src.image.extent = defaultExtent;
14496 params.src.image.extent.depth = 5u;
14497 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14498 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14499 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
14500 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14501 params.dst.image.extent = defaultExtent;
14502 params.dst.image.extent.depth = 5u;
14503 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14504 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14505 params.allocationKind = allocationKind;
14506 params.extensionUse = extensionUse;
14507
14508 for (deUint32 layerNdx=0; layerNdx < params.src.image.extent.depth; ++layerNdx)
14509 {
14510 const VkImageSubresourceLayers sourceLayer =
14511 {
14512 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
14513 0u, // deUint32 mipLevel;
14514 layerNdx, // deUint32 baseArrayLayer;
14515 1u // deUint32 layerCount;
14516 };
14517
14518 const VkImageResolve testResolve =
14519 {
14520 sourceLayer, // VkImageSubresourceLayers srcSubresource;
14521 {0, 0, 0}, // VkOffset3D srcOffset;
14522 sourceLayer, // VkImageSubresourceLayers dstSubresource;
14523 {0, 0, 0}, // VkOffset3D dstOffset;
14524 defaultExtent, // VkExtent3D extent;
14525 };
14526
14527 CopyRegion imageResolve;
14528 imageResolve.imageResolve = testResolve;
14529 params.regions.push_back(imageResolve);
14530 }
14531
14532 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14533 {
14534 params.samples = samples[samplesIndex];
14535 const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]);
14536 params.imageOffset = false;
14537 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_LAYER_TO_MS_IMAGE));
14538 params.imageOffset = true;
14539 if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14540 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", description, params, COPY_MS_IMAGE_LAYER_TO_MS_IMAGE));
14541 }
14542 }
14543 }
14544
addResolveCopyImageWithRegionsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14545 void addResolveCopyImageWithRegionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14546 {
14547 TestParams params;
14548 params.src.image.imageType = VK_IMAGE_TYPE_2D;
14549 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14550 params.src.image.extent = resolveExtent;
14551 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14552 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14553 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
14554 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14555 params.dst.image.extent = resolveExtent;
14556 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14557 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14558 params.allocationKind = allocationKind;
14559 params.extensionUse = extensionUse;
14560
14561 int32_t imageHalfWidth = getExtent3D(params.src.image).width / 2;
14562 int32_t imageHalfHeight = getExtent3D(params.src.image).height / 2;
14563 VkExtent3D halfImageExtent = {resolveExtent.width / 2, resolveExtent.height / 2, 1u};
14564
14565 // Lower right corner to lower left corner.
14566 {
14567 const VkImageSubresourceLayers sourceLayer =
14568 {
14569 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
14570 0u, // deUint32 mipLevel;
14571 0u, // deUint32 baseArrayLayer;
14572 1u // deUint32 layerCount;
14573 };
14574
14575 const VkImageResolve testResolve =
14576 {
14577 sourceLayer, // VkImageSubresourceLayers srcSubresource;
14578 {imageHalfWidth, imageHalfHeight, 0}, // VkOffset3D srcOffset;
14579 sourceLayer, // VkImageSubresourceLayers dstSubresource;
14580 {0, imageHalfHeight, 0}, // VkOffset3D dstOffset;
14581 halfImageExtent, // VkExtent3D extent;
14582 };
14583
14584 CopyRegion imageResolve;
14585 imageResolve.imageResolve = testResolve;
14586 params.regions.push_back(imageResolve);
14587 }
14588
14589 // Upper right corner to lower right corner.
14590 {
14591 const VkImageSubresourceLayers sourceLayer =
14592 {
14593 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
14594 0u, // deUint32 mipLevel;
14595 0u, // deUint32 baseArrayLayer;
14596 1u // deUint32 layerCount;
14597 };
14598
14599 const VkImageResolve testResolve =
14600 {
14601 sourceLayer, // VkImageSubresourceLayers srcSubresource;
14602 {imageHalfWidth, 0, 0}, // VkOffset3D srcOffset;
14603 sourceLayer, // VkImageSubresourceLayers dstSubresource;
14604 {imageHalfWidth, imageHalfHeight, 0}, // VkOffset3D dstOffset;
14605 halfImageExtent, // VkExtent3D extent;
14606 };
14607
14608 CopyRegion imageResolve;
14609 imageResolve.imageResolve = testResolve;
14610 params.regions.push_back(imageResolve);
14611 }
14612
14613 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14614 {
14615 params.samples = samples[samplesIndex];
14616 const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]);
14617 params.imageOffset = false;
14618 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION));
14619 params.imageOffset = true;
14620 if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14621 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", description, params, COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION));
14622 }
14623 }
14624 }
14625
addResolveImageWholeArrayImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14626 void addResolveImageWholeArrayImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14627 {
14628 TestParams params;
14629 params.src.image.imageType = VK_IMAGE_TYPE_2D;
14630 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14631 params.src.image.extent = defaultExtent;
14632 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14633 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14634 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
14635 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14636 params.dst.image.extent = defaultExtent;
14637 params.dst.image.extent.depth = 5u;
14638 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14639 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14640 params.allocationKind = allocationKind;
14641 params.extensionUse = extensionUse;
14642
14643 for (deUint32 layerNdx=0; layerNdx < params.dst.image.extent.depth; ++layerNdx)
14644 {
14645 const VkImageSubresourceLayers sourceLayer =
14646 {
14647 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
14648 0u, // deUint32 mipLevel;
14649 layerNdx, // deUint32 baseArrayLayer;
14650 1u // deUint32 layerCount;
14651 };
14652
14653 const VkImageResolve testResolve =
14654 {
14655 sourceLayer, // VkImageSubresourceLayers srcSubresource;
14656 {0, 0, 0}, // VkOffset3D srcOffset;
14657 sourceLayer, // VkImageSubresourceLayers dstSubresource;
14658 {0, 0, 0}, // VkOffset3D dstOffset;
14659 defaultExtent, // VkExtent3D extent;
14660 };
14661
14662 CopyRegion imageResolve;
14663 imageResolve.imageResolve = testResolve;
14664 params.regions.push_back(imageResolve);
14665 }
14666
14667 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14668 {
14669 params.samples = samples[samplesIndex];
14670 const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]);
14671 params.imageOffset = false;
14672 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
14673 params.imageOffset = true;
14674 if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14675 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
14676 }
14677 }
14678 }
14679
addResolveImageWholeArrayImageSingleRegionTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14680 void addResolveImageWholeArrayImageSingleRegionTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14681 {
14682 TestParams params;
14683 params.src.image.imageType = VK_IMAGE_TYPE_2D;
14684 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14685 params.src.image.extent = defaultExtent;
14686 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14687 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
14688 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14689 params.dst.image.extent = defaultExtent;
14690 params.dst.image.extent.depth = 5u;
14691 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14692 params.allocationKind = allocationKind;
14693 params.extensionUse = extensionUse;
14694
14695 const VkImageSubresourceLayers sourceLayer =
14696 {
14697 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
14698 0u, // uint32_t mipLevel;
14699 0, // uint32_t baseArrayLayer;
14700 params.dst.image.extent.depth // uint32_t layerCount;
14701 };
14702
14703 const VkImageResolve testResolve =
14704 {
14705 sourceLayer, // VkImageSubresourceLayers srcSubresource;
14706 {0, 0, 0}, // VkOffset3D srcOffset;
14707 sourceLayer, // VkImageSubresourceLayers dstSubresource;
14708 {0, 0, 0}, // VkOffset3D dstOffset;
14709 defaultExtent, // VkExtent3D extent;
14710 };
14711
14712 CopyRegion imageResolve;
14713 imageResolve.imageResolve = testResolve;
14714 params.regions.push_back(imageResolve);
14715
14716 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14717 {
14718 params.samples = samples[samplesIndex];
14719 const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]);
14720 params.imageOffset = false;
14721 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
14722 params.imageOffset = true;
14723 if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14724 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
14725 }
14726 }
14727 }
14728
addResolveImageDiffImageSizeTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14729 void addResolveImageDiffImageSizeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14730 {
14731 tcu::TestContext& testCtx = group->getTestContext();
14732 TestParams params;
14733 params.src.image.imageType = VK_IMAGE_TYPE_2D;
14734 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14735 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14736 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14737 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
14738 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14739 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
14740 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14741 params.allocationKind = allocationKind;
14742 params.extensionUse = extensionUse;
14743
14744 {
14745 const VkImageSubresourceLayers sourceLayer =
14746 {
14747 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
14748 0u, // deUint32 mipLevel;
14749 0u, // deUint32 baseArrayLayer;
14750 1u // deUint32 layerCount;
14751 };
14752 const VkImageResolve testResolve =
14753 {
14754 sourceLayer, // VkImageSubresourceLayers srcSubresource;
14755 {0, 0, 0}, // VkOffset3D srcOffset;
14756 sourceLayer, // VkImageSubresourceLayers dstSubresource;
14757 {0, 0, 0}, // VkOffset3D dstOffset;
14758 resolveExtent, // VkExtent3D extent;
14759 };
14760 CopyRegion imageResolve;
14761 imageResolve.imageResolve = testResolve;
14762 params.regions.push_back(imageResolve);
14763 }
14764
14765 const VkExtent3D imageExtents[] =
14766 {
14767 { resolveExtent.width + 10, resolveExtent.height, resolveExtent.depth },
14768 { resolveExtent.width, resolveExtent.height * 2, resolveExtent.depth },
14769 { resolveExtent.width, resolveExtent.height, resolveExtent.depth + 10 }
14770 };
14771
14772 for (int srcImageExtentIndex = 0; srcImageExtentIndex < DE_LENGTH_OF_ARRAY(imageExtents); ++srcImageExtentIndex)
14773 {
14774 const VkExtent3D& srcImageSize = imageExtents[srcImageExtentIndex];
14775 params.src.image.extent = srcImageSize;
14776 params.dst.image.extent = resolveExtent;
14777 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14778 {
14779 params.samples = samples[samplesIndex];
14780 std::ostringstream testName;
14781 testName << "src_" << srcImageSize.width << "_" << srcImageSize.height << "_" << srcImageSize.depth << "_" << getSampleCountCaseName(samples[samplesIndex]);
14782 std::ostringstream description;
14783 description << "With " << getSampleCountCaseName(samples[samplesIndex]) << " and source image size ("
14784 << srcImageSize.width << ", " << srcImageSize.height << ", " << srcImageSize.depth << ")";
14785 group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str(), description.str(), params));
14786 }
14787 }
14788 for (int dstImageExtentIndex = 0; dstImageExtentIndex < DE_LENGTH_OF_ARRAY(imageExtents); ++dstImageExtentIndex)
14789 {
14790 const VkExtent3D& dstImageSize = imageExtents[dstImageExtentIndex];
14791 params.src.image.extent = resolveExtent;
14792 params.dst.image.extent = dstImageSize;
14793 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14794 {
14795 params.samples = samples[samplesIndex];
14796 std::ostringstream testName;
14797 testName << "dst_" << dstImageSize.width << "_" << dstImageSize.height << "_" << dstImageSize.depth << "_" << getSampleCountCaseName(samples[samplesIndex]);
14798 std::ostringstream description;
14799 description << "With " << getSampleCountCaseName(samples[samplesIndex]) << " and destination image size ("
14800 << dstImageSize.width << ", " << dstImageSize.height << ", " << dstImageSize.depth << ")";
14801 params.imageOffset = false;
14802 group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str(), description.str(), params));
14803 params.imageOffset = true;
14804 if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14805 group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str() + "_bind_offset", description.str(), params));
14806 }
14807 }
14808 }
14809 }
14810
addDepthStencilCopyMSAATest(tcu::TestCaseGroup * group,DepthStencilMSAA::TestParameters testCreateParams)14811 void addDepthStencilCopyMSAATest (tcu::TestCaseGroup* group, DepthStencilMSAA::TestParameters testCreateParams)
14812 {
14813 // Run all the tests with one of the bare depth format and one bare stencil format + mandatory combined formats.
14814 const struct
14815 {
14816 const std::string name;
14817 const VkFormat vkFormat;
14818 } depthAndStencilFormats[] =
14819 {
14820 { "d32_sfloat", VK_FORMAT_D32_SFLOAT },
14821 { "s8_uint", VK_FORMAT_S8_UINT },
14822 { "d16_unorm_s8_uint", VK_FORMAT_D16_UNORM_S8_UINT },
14823 { "d24_unorm_s8_uint", VK_FORMAT_D24_UNORM_S8_UINT },
14824 };
14825
14826 // Both image layouts will be tested only with full image copy tests to limit the number of tests.
14827 const VkImageLayout srcImageLayouts[] =
14828 {
14829 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
14830 VK_IMAGE_LAYOUT_GENERAL
14831 };
14832 const VkImageLayout dstImageLayouts[] =
14833 {
14834 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
14835 VK_IMAGE_LAYOUT_GENERAL
14836 };
14837
14838 for (const auto &srcLayout : srcImageLayouts)
14839 {
14840 for (const auto &dstLayout : dstImageLayouts)
14841 {
14842 testCreateParams.srcImageLayout = srcLayout;
14843 testCreateParams.dstImageLayout = dstLayout;
14844 for (const auto &format : depthAndStencilFormats)
14845 {
14846 testCreateParams.imageFormat = format.vkFormat;
14847 const auto textureFormat = mapVkFormat(format.vkFormat);
14848 bool hasDepth = tcu::hasDepthComponent(textureFormat.order);
14849 bool hasStencil = tcu::hasStencilComponent(textureFormat.order);
14850 std::string testNameBase = format.name + "_" + (testCreateParams.copyOptions == DepthStencilMSAA::COPY_WHOLE_IMAGE ? getImageLayoutCaseName(srcLayout) + "_" + getImageLayoutCaseName(dstLayout) + "_": "");
14851
14852 if (hasDepth)
14853 {
14854 testCreateParams.copyAspect = VK_IMAGE_ASPECT_DEPTH_BIT;
14855 for (auto sample : samples)
14856 {
14857 testCreateParams.samples = sample;
14858 std::string description = "Copy depth component with sample count: " + getSampleCountCaseName(sample);
14859 testCreateParams.imageOffset = false;
14860 group->addChild(new DepthStencilMSAATestCase(group->getTestContext(), testNameBase + "D_" + getSampleCountCaseName(sample), description, testCreateParams));
14861 testCreateParams.imageOffset = true;
14862 if (testCreateParams.allocationKind != ALLOCATION_KIND_DEDICATED) {
14863 group->addChild(new DepthStencilMSAATestCase(group->getTestContext(), testNameBase + "D_" + getSampleCountCaseName(sample) + "_bind_offset", description, testCreateParams));
14864 }
14865 }
14866 }
14867
14868 if (hasStencil)
14869 {
14870 testCreateParams.copyAspect = VK_IMAGE_ASPECT_STENCIL_BIT;
14871 for (auto sample : samples)
14872 {
14873 testCreateParams.samples = sample;
14874 std::string description = "Copy stencil component with sample count: " + getSampleCountCaseName(sample);
14875 testCreateParams.imageOffset = false;
14876 group->addChild(new DepthStencilMSAATestCase(group->getTestContext(), testNameBase + "S_" + getSampleCountCaseName(sample), description, testCreateParams));
14877 testCreateParams.imageOffset = true;
14878 if (testCreateParams.allocationKind != ALLOCATION_KIND_DEDICATED) {
14879 group->addChild(new DepthStencilMSAATestCase(group->getTestContext(), testNameBase + "S_" + getSampleCountCaseName(sample) + "_bind_offset", description, testCreateParams));
14880 }
14881 }
14882 }
14883 }
14884 if (testCreateParams.copyOptions != DepthStencilMSAA::COPY_WHOLE_IMAGE)
14885 break;
14886 }
14887 if (testCreateParams.copyOptions != DepthStencilMSAA::COPY_WHOLE_IMAGE)
14888 break;
14889 }
14890 }
14891
addDepthStencilCopyMSAATestGroup(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14892 void addDepthStencilCopyMSAATestGroup (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14893 {
14894 // Allocation kind, extension use copy option parameters are defined here. Rest of the parameters are defined in `addDepthStencilCopyMSAATest` function.
14895 DepthStencilMSAA::TestParameters testParams = {};
14896 testParams.allocationKind = allocationKind;
14897 testParams.extensionUse = extensionUse;
14898
14899 testParams.copyOptions = DepthStencilMSAA::COPY_WHOLE_IMAGE;
14900 addTestGroup(group, "whole", "Copy from depth stencil to depth stencil with multi sample tests", addDepthStencilCopyMSAATest, testParams);
14901
14902 testParams.copyOptions = DepthStencilMSAA::COPY_PARTIAL;
14903 addTestGroup(group, "partial", "Copy from depth stencil to depth stencil with multi sample tests", addDepthStencilCopyMSAATest, testParams);
14904
14905 testParams.copyOptions = DepthStencilMSAA::COPY_ARRAY_TO_ARRAY;
14906 addTestGroup(group, "array_to_array", "Copy from array layer to array layer", addDepthStencilCopyMSAATest, testParams);
14907 }
14908
addBufferCopyOffsetTests(tcu::TestCaseGroup * group)14909 void addBufferCopyOffsetTests (tcu::TestCaseGroup* group)
14910 {
14911 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"));
14912
14913 for (deUint32 srcOffset = 0u; srcOffset < BufferOffsetParams::kMaxOffset; ++srcOffset)
14914 for (deUint32 dstOffset = 0u; dstOffset < BufferOffsetParams::kMaxOffset; ++dstOffset)
14915 {
14916 BufferOffsetParams params{srcOffset, dstOffset};
14917 addFunctionCase(subGroup.get(), de::toString(srcOffset) + "_" + de::toString(dstOffset), "", bufferOffsetTest, params);
14918 }
14919
14920 group->addChild(subGroup.release());
14921 }
14922
addResolveImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14923 void addResolveImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14924 {
14925 addTestGroup(group, "whole", "Resolve from image to image (whole)", addResolveImageWholeTests, allocationKind, extensionUse);
14926 addTestGroup(group, "partial", "Resolve from image to image (partial)", addResolveImagePartialTests, allocationKind, extensionUse);
14927 addTestGroup(group, "with_regions", "Resolve from image to image (with regions)", addResolveImageWithRegionsTests, allocationKind, extensionUse);
14928 addTestGroup(group, "whole_copy_before_resolving", "Resolve from image to image (whole copy before resolving)", addResolveImageWholeCopyBeforeResolvingTests, allocationKind, extensionUse);
14929 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);
14930 addComputeAndTransferQueueTests(group, allocationKind, extensionUse);
14931 addTestGroup(group, "diff_layout_copy_before_resolving", "Resolve from image to image (whole copy before resolving with different layouts)", addResolveImageWholeCopyDiffLayoutsBeforeResolvingTests, allocationKind, extensionUse);
14932 addTestGroup(group, "layer_copy_before_resolving", "Resolve from image to image (layer copy before resolving)", addResolveImageLayerCopyBeforeResolvingTests, allocationKind, extensionUse);
14933 addTestGroup(group, "copy_with_regions_before_resolving", "Resolve from image to image (region copy before resolving)", addResolveCopyImageWithRegionsTests, allocationKind, extensionUse);
14934 addTestGroup(group, "whole_array_image", "Resolve from image to image (whole array image)", addResolveImageWholeArrayImageTests, allocationKind, extensionUse);
14935 addTestGroup(group, "whole_array_image_one_region", "Resolve from image to image (whole array image with single region)", addResolveImageWholeArrayImageSingleRegionTests, allocationKind, extensionUse);
14936 addTestGroup(group, "diff_image_size", "Resolve from image to image of different size", addResolveImageDiffImageSizeTests, allocationKind, extensionUse);
14937 }
14938
addCopiesAndBlittingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14939 void addCopiesAndBlittingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14940 {
14941 addTestGroup(group, "image_to_image", "Copy from image to image", addImageToImageTests, allocationKind, extensionUse);
14942 addTestGroup(group, "image_to_buffer", "Copy from image to buffer", addImageToBufferTests, allocationKind, extensionUse);
14943 addTestGroup(group, "buffer_to_image", "Copy from buffer to image", addBufferToImageTests, allocationKind, extensionUse);
14944 addTestGroup(group, "buffer_to_depthstencil", "Copy from buffer to depth/Stencil", addBufferToDepthStencilTests, allocationKind, extensionUse);
14945 addTestGroup(group, "buffer_to_buffer", "Copy from buffer to buffer", addBufferToBufferTests, allocationKind, extensionUse);
14946 addTestGroup(group, "blit_image", "Blitting image", addBlittingImageTests, allocationKind, extensionUse);
14947 addTestGroup(group, "resolve_image", "Resolve image", addResolveImageTests, allocationKind, extensionUse);
14948 addTestGroup(group, "depth_stencil_msaa_copy", "Copy depth/stencil with MSAA", addDepthStencilCopyMSAATestGroup, allocationKind, extensionUse);
14949 }
14950
addCoreCopiesAndBlittingTests(tcu::TestCaseGroup * group)14951 void addCoreCopiesAndBlittingTests(tcu::TestCaseGroup* group)
14952 {
14953 addCopiesAndBlittingTests(group, ALLOCATION_KIND_SUBALLOCATED, EXTENSION_USE_NONE);
14954 addBufferCopyOffsetTests(group);
14955 }
14956
14957
addDedicatedAllocationCopiesAndBlittingTests(tcu::TestCaseGroup * group)14958 void addDedicatedAllocationCopiesAndBlittingTests (tcu::TestCaseGroup* group)
14959 {
14960 addCopiesAndBlittingTests(group, ALLOCATION_KIND_DEDICATED, EXTENSION_USE_NONE);
14961 }
14962
14963 #ifndef CTS_USES_VULKANSC
addExtensionCopiesAndBlittingTests(tcu::TestCaseGroup * group)14964 void addExtensionCopiesAndBlittingTests(tcu::TestCaseGroup* group)
14965 {
14966 addCopiesAndBlittingTests(group, ALLOCATION_KIND_DEDICATED, EXTENSION_USE_COPY_COMMANDS2);
14967 }
14968 #endif // CTS_USES_VULKANSC
14969
14970 } // anonymous
14971
createCopiesAndBlittingTests(tcu::TestContext & testCtx)14972 tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx)
14973 {
14974 de::MovePtr<tcu::TestCaseGroup> copiesAndBlittingTests(new tcu::TestCaseGroup(testCtx, "copy_and_blit", "Copies And Blitting Tests"));
14975
14976 copiesAndBlittingTests->addChild(createTestGroup(testCtx, "core", "Core Copies And Blitting Tests", addCoreCopiesAndBlittingTests));
14977 copiesAndBlittingTests->addChild(createTestGroup(testCtx, "dedicated_allocation", "Copies And Blitting Tests For Dedicated Memory Allocation", addDedicatedAllocationCopiesAndBlittingTests));
14978 #ifndef CTS_USES_VULKANSC
14979 copiesAndBlittingTests->addChild(createTestGroup(testCtx, "copy_commands2", "Copies And Blitting Tests using KHR_copy_commands2", addExtensionCopiesAndBlittingTests));
14980 #endif // CTS_USES_VULKANSC
14981
14982 return copiesAndBlittingTests.release();
14983 }
14984
14985 } // api
14986 } // vkt
14987