xref: /aosp_15_r20/external/deqp/external/vulkancts/modules/vulkan/image/vktImageTranscodingSupportTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2017 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file  vktImageTranscodingSupportTests.cpp
21  * \brief Transcoding support tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktImageTranscodingSupportTests.hpp"
25 
26 #include "deUniquePtr.hpp"
27 #include "deStringUtil.hpp"
28 #include "deSharedPtr.hpp"
29 #include "deRandom.hpp"
30 
31 #include "vktTestCaseUtil.hpp"
32 #include "vkPrograms.hpp"
33 #include "vkImageUtil.hpp"
34 #include "vktImageTestsUtil.hpp"
35 #include "vkBarrierUtil.hpp"
36 #include "vkBuilderUtil.hpp"
37 #include "vkRef.hpp"
38 #include "vkRefUtil.hpp"
39 #include "vkTypeUtil.hpp"
40 #include "vkQueryUtil.hpp"
41 #include "vkCmdUtil.hpp"
42 #include "vkObjUtil.hpp"
43 #include "vkBufferWithMemory.hpp"
44 
45 #include "tcuTextureUtil.hpp"
46 #include "tcuTexture.hpp"
47 #include "tcuCompressedTexture.hpp"
48 #include "tcuVectorType.hpp"
49 #include "tcuResource.hpp"
50 #include "tcuImageIO.hpp"
51 #include "tcuImageCompare.hpp"
52 #include "tcuTestLog.hpp"
53 #include "tcuRGBA.hpp"
54 #include "tcuSurface.hpp"
55 #include "tcuFloat.hpp"
56 
57 #include <vector>
58 #include <iomanip>
59 
60 using namespace vk;
61 namespace vkt
62 {
63 namespace image
64 {
65 namespace
66 {
67 using de::MovePtr;
68 using de::Random;
69 using de::SharedPtr;
70 using std::string;
71 using std::vector;
72 using tcu::Archive;
73 using tcu::CompressedTexFormat;
74 using tcu::CompressedTexture;
75 using tcu::ConstPixelBufferAccess;
76 using tcu::IVec3;
77 using tcu::Resource;
78 using tcu::TestContext;
79 using tcu::TestStatus;
80 using tcu::UVec3;
81 
82 enum Operation
83 {
84     OPERATION_ATTACHMENT_READ,
85     OPERATION_ATTACHMENT_WRITE,
86     OPERATION_TEXTURE_READ,
87     OPERATION_TEXTURE_WRITE,
88     OPERATION_LAST
89 };
90 
91 struct TestParameters
92 {
93     Operation operation;
94     UVec3 size;
95     ImageType imageType;
96     VkImageUsageFlagBits testedImageUsageFeature;
97     VkFormat featuredFormat;
98     VkFormat featurelessFormat;
99     VkImageUsageFlags testedImageUsage;
100     VkImageUsageFlags pairedImageUsage;
101     const VkFormat *compatibleFormats;
102 };
103 
104 const uint32_t SINGLE_LEVEL = 1u;
105 const uint32_t SINGLE_LAYER = 1u;
106 
107 class BasicTranscodingTestInstance : public TestInstance
108 {
109 public:
110     BasicTranscodingTestInstance(Context &context, const TestParameters &parameters);
111     virtual TestStatus iterate(void) = 0;
112 
113 protected:
114     void generateData(uint8_t *toFill, size_t size, const VkFormat format = VK_FORMAT_UNDEFINED);
115     const TestParameters m_parameters;
116 };
117 
BasicTranscodingTestInstance(Context & context,const TestParameters & parameters)118 BasicTranscodingTestInstance::BasicTranscodingTestInstance(Context &context, const TestParameters &parameters)
119     : TestInstance(context)
120     , m_parameters(parameters)
121 {
122 }
123 
124 // Replace Infs and NaNs with the largest normal value.
125 // Replace denormal numbers with the smallest normal value.
126 // Leave the rest untouched.
127 // T is a tcu::Float specialization.
128 template <class T>
fixFloatIfNeeded(uint8_t * ptr_)129 void fixFloatIfNeeded(uint8_t *ptr_)
130 {
131     T *ptr = reinterpret_cast<T *>(ptr_);
132     if (ptr->isInf() || ptr->isNaN())
133         *ptr = T::largestNormal(ptr->sign());
134     else if (ptr->isDenorm())
135         *ptr = T::smallestNormal(ptr->sign());
136 }
137 
generateData(uint8_t * toFill,size_t size,const VkFormat format)138 void BasicTranscodingTestInstance::generateData(uint8_t *toFill, size_t size, const VkFormat format)
139 {
140     const uint8_t pattern[] = {
141         // 64-bit values
142         0x11,
143         0x11,
144         0x11,
145         0x11,
146         0x22,
147         0x22,
148         0x22,
149         0x22,
150         0x00,
151         0x00,
152         0x00,
153         0x00,
154         0x00,
155         0x00,
156         0x00,
157         0x00,
158         0x00,
159         0x00,
160         0x00,
161         0x00,
162         0x00,
163         0x00,
164         0x00,
165         0x01,
166         0x00,
167         0x00,
168         0x00,
169         0x00,
170         0x00,
171         0x00,
172         0x01,
173         0x00,
174         0x00,
175         0x00,
176         0x00,
177         0x00,
178         0x00,
179         0x01,
180         0x00,
181         0x00,
182         0x00,
183         0x00,
184         0x00,
185         0x00,
186         0x01,
187         0x00,
188         0x00,
189         0x00,
190         0x00,
191         0x00,
192         0x00,
193         0x00,
194         0x00,
195         0x00,
196         0x00,
197         0xFF,
198         0x00,
199         0x00,
200         0x00,
201         0x00,
202         0x00,
203         0x00,
204         0xFF,
205         0x00,
206         0x00,
207         0x00,
208         0x00,
209         0x00,
210         0x00,
211         0xFF,
212         0x00,
213         0x00,
214         0x00,
215         0x00,
216         0x00,
217         0x00,
218         0xFF,
219         0x00,
220         0x00,
221         0x00,
222         0x7F,
223         0xF0,
224         0x00,
225         0x00,
226         0x00,
227         0x00,
228         0x00,
229         0x00, // Positive infinity
230         0xFF,
231         0xF0,
232         0x00,
233         0x00,
234         0x00,
235         0x00,
236         0x00,
237         0x00, // Negative infinity
238         0x7F,
239         0xF0,
240         0x00,
241         0x00,
242         0x00,
243         0x00,
244         0x00,
245         0x01, // Start of a signalling NaN (NANS)
246         0x7F,
247         0xF7,
248         0xFF,
249         0xFF,
250         0xFF,
251         0xFF,
252         0xFF,
253         0xFF, // End of a signalling NaN (NANS)
254         0xFF,
255         0xF0,
256         0x00,
257         0x00,
258         0x00,
259         0x00,
260         0x00,
261         0x01, // Start of a signalling NaN (NANS)
262         0xFF,
263         0xF7,
264         0xFF,
265         0xFF,
266         0xFF,
267         0xFF,
268         0xFF,
269         0xFF, // End of a signalling NaN (NANS)
270         0x7F,
271         0xF8,
272         0x00,
273         0x00,
274         0x00,
275         0x00,
276         0x00,
277         0x00, // Start of a quiet NaN (NANQ)
278         0x7F,
279         0xFF,
280         0xFF,
281         0xFF,
282         0xFF,
283         0xFF,
284         0xFF,
285         0xFF, // End of of a quiet NaN (NANQ)
286         0xFF,
287         0xF8,
288         0x00,
289         0x00,
290         0x00,
291         0x00,
292         0x00,
293         0x00, // Start of a quiet NaN (NANQ)
294         0xFF,
295         0xFF,
296         0xFF,
297         0xFF,
298         0xFF,
299         0xFF,
300         0xFF,
301         0xFF, // End of a quiet NaN (NANQ)
302         // 32-bit values
303         0x7F,
304         0x80,
305         0x00,
306         0x00, // Positive infinity
307         0xFF,
308         0x80,
309         0x00,
310         0x00, // Negative infinity
311         0x7F,
312         0x80,
313         0x00,
314         0x01, // Start of a signalling NaN (NANS)
315         0x7F,
316         0xBF,
317         0xFF,
318         0xFF, // End of a signalling NaN (NANS)
319         0xFF,
320         0x80,
321         0x00,
322         0x01, // Start of a signalling NaN (NANS)
323         0xFF,
324         0xBF,
325         0xFF,
326         0xFF, // End of a signalling NaN (NANS)
327         0x7F,
328         0xC0,
329         0x00,
330         0x00, // Start of a quiet NaN (NANQ)
331         0x7F,
332         0xFF,
333         0xFF,
334         0xFF, // End of of a quiet NaN (NANQ)
335         0xFF,
336         0xC0,
337         0x00,
338         0x00, // Start of a quiet NaN (NANQ)
339         0xFF,
340         0xFF,
341         0xFF,
342         0xFF, // End of a quiet NaN (NANQ)
343         0xAA,
344         0xAA,
345         0xAA,
346         0xAA,
347         0x55,
348         0x55,
349         0x55,
350         0x55,
351     };
352 
353     uint8_t *start   = toFill;
354     size_t sizeToRnd = size;
355 
356     // Pattern part
357     if (size >= 2 * sizeof(pattern))
358     {
359         // Rotated pattern
360         for (size_t i = 0; i < sizeof(pattern); i++)
361             start[sizeof(pattern) - i - 1] = pattern[i];
362 
363         start += sizeof(pattern);
364         sizeToRnd -= sizeof(pattern);
365 
366         // Direct pattern
367         deMemcpy(start, pattern, sizeof(pattern));
368 
369         start += sizeof(pattern);
370         sizeToRnd -= sizeof(pattern);
371     }
372 
373     // Random part
374     {
375         DE_ASSERT(sizeToRnd % sizeof(uint32_t) == 0);
376 
377         uint32_t *start32  = reinterpret_cast<uint32_t *>(start);
378         size_t sizeToRnd32 = sizeToRnd / sizeof(uint32_t);
379         Random rnd(static_cast<uint32_t>(format));
380 
381         for (size_t i = 0; i < sizeToRnd32; i++)
382             start32[i] = rnd.getUint32();
383     }
384 
385     {
386         // Remove certain values that may not be preserved based on the uncompressed view format
387         if (isSnormFormat(m_parameters.featuredFormat))
388         {
389             tcu::TextureFormat textureFormat = mapVkFormat(m_parameters.featuredFormat);
390 
391             if (textureFormat.type == tcu::TextureFormat::SNORM_INT8)
392             {
393                 for (size_t i = 0; i < size; i++)
394                 {
395                     // SNORM fix: due to write operation in SNORM format
396                     // replaces 0x80 to 0x81, remove these values from test
397                     if (toFill[i] == 0x80)
398                         toFill[i] = 0x81;
399                 }
400             }
401             else
402             {
403                 for (size_t i = 0; i < size; i += 2)
404                 {
405                     // SNORM fix: due to write operation in SNORM format
406                     // replaces 0x00 0x80 to 0x01 0x80
407                     if (toFill[i] == 0x00 && toFill[i + 1] == 0x80)
408                         toFill[i + 1] = 0x81;
409                 }
410             }
411         }
412         else if (isFloatFormat(m_parameters.featuredFormat))
413         {
414             tcu::TextureFormat textureFormat = mapVkFormat(m_parameters.featuredFormat);
415 
416             if (textureFormat.type == tcu::TextureFormat::HALF_FLOAT)
417             {
418                 for (size_t i = 0; i < size; i += 2)
419                     fixFloatIfNeeded<tcu::Float16>(toFill + i);
420             }
421             else if (textureFormat.type == tcu::TextureFormat::FLOAT)
422             {
423                 for (size_t i = 0; i < size; i += 4)
424                     fixFloatIfNeeded<tcu::Float16>(toFill + i);
425 
426                 for (size_t i = 0; i < size; i += 4)
427                     fixFloatIfNeeded<tcu::Float32>(toFill + i);
428             }
429         }
430     }
431 }
432 
433 class GraphicsAttachmentsTestInstance : public BasicTranscodingTestInstance
434 {
435 public:
436     GraphicsAttachmentsTestInstance(Context &context, const TestParameters &parameters);
437     virtual TestStatus iterate(void);
438 
439 protected:
440     VkImageCreateInfo makeCreateImageInfo(const VkFormat format, const ImageType type, const UVec3 &size,
441                                           const VkImageUsageFlags usageFlags, const bool extendedImageCreateFlag);
442     VkImageViewUsageCreateInfo makeImageViewUsageCreateInfo(VkImageUsageFlags imageUsageFlags);
443     VkDeviceSize getUncompressedImageData(const VkFormat format, const UVec3 &size, std::vector<uint8_t> &data);
444     virtual void transcode(std::vector<uint8_t> &srcData, std::vector<uint8_t> &dstData,
445                            de::MovePtr<Image> &outputImage);
446     bool compareAndLog(const void *reference, const void *result, size_t size);
447 };
448 
GraphicsAttachmentsTestInstance(Context & context,const TestParameters & parameters)449 GraphicsAttachmentsTestInstance::GraphicsAttachmentsTestInstance(Context &context, const TestParameters &parameters)
450     : BasicTranscodingTestInstance(context, parameters)
451 {
452 }
453 
iterate(void)454 TestStatus GraphicsAttachmentsTestInstance::iterate(void)
455 {
456     std::vector<uint8_t> srcData;
457     std::vector<uint8_t> dstData;
458     de::MovePtr<Image> outputImage;
459 
460     transcode(srcData, dstData, outputImage);
461 
462     DE_ASSERT(srcData.size() > 0 && srcData.size() == dstData.size());
463 
464     if (!compareAndLog(&srcData[0], &dstData[0], srcData.size()))
465         return TestStatus::fail("Output differs from input");
466 
467     return TestStatus::pass("Pass");
468 }
469 
transcode(std::vector<uint8_t> & srcData,std::vector<uint8_t> & dstData,de::MovePtr<Image> & outputImage)470 void GraphicsAttachmentsTestInstance::transcode(std::vector<uint8_t> &srcData, std::vector<uint8_t> &dstData,
471                                                 de::MovePtr<Image> &outputImage)
472 {
473     const DeviceInterface &vk       = m_context.getDeviceInterface();
474     const VkDevice device           = m_context.getDevice();
475     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
476     const VkQueue queue             = m_context.getUniversalQueue();
477     Allocator &allocator            = m_context.getDefaultAllocator();
478 
479     const VkImageSubresourceRange subresourceRange =
480         makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, SINGLE_LEVEL, 0u, SINGLE_LAYER);
481     const VkImageViewUsageCreateInfo *imageViewUsageNull = (VkImageViewUsageCreateInfo *)DE_NULL;
482     const VkImageViewUsageCreateInfo imageViewUsage      = makeImageViewUsageCreateInfo(m_parameters.testedImageUsage);
483 
484     const VkFormat srcFormat = (m_parameters.operation == OPERATION_ATTACHMENT_READ)  ? m_parameters.featurelessFormat :
485                                (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? m_parameters.featuredFormat :
486                                                                                         VK_FORMAT_UNDEFINED;
487     const bool srcExtendedImageCreate = (m_parameters.operation == OPERATION_ATTACHMENT_READ)  ? true :
488                                         (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? false :
489                                                                                                  false;
490     const VkImageUsageFlags srcImageUsageFlags =
491         (m_parameters.operation == OPERATION_ATTACHMENT_READ)  ? m_parameters.testedImageUsage :
492         (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? m_parameters.pairedImageUsage :
493                                                                  0;
494     const VkImageViewUsageCreateInfo *srcImageViewUsageFlags =
495         (m_parameters.operation == OPERATION_ATTACHMENT_READ)  ? &imageViewUsage :
496         (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? imageViewUsageNull :
497                                                                  imageViewUsageNull;
498     const VkDeviceSize srcImageSizeInBytes = getUncompressedImageData(srcFormat, m_parameters.size, srcData);
499 
500     const VkFormat dstFormat = (m_parameters.operation == OPERATION_ATTACHMENT_READ)  ? m_parameters.featuredFormat :
501                                (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? m_parameters.featurelessFormat :
502                                                                                         VK_FORMAT_UNDEFINED;
503     const bool dstExtendedImageCreate = (m_parameters.operation == OPERATION_ATTACHMENT_READ)  ? false :
504                                         (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? true :
505                                                                                                  false;
506     const VkImageUsageFlags dstImageUsageFlags =
507         (m_parameters.operation == OPERATION_ATTACHMENT_READ)  ? m_parameters.pairedImageUsage :
508         (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? m_parameters.testedImageUsage :
509                                                                  0;
510     const VkImageViewUsageCreateInfo *dstImageViewUsageFlags =
511         (m_parameters.operation == OPERATION_ATTACHMENT_READ)  ? imageViewUsageNull :
512         (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? &imageViewUsage :
513                                                                  imageViewUsageNull;
514     const VkDeviceSize dstImageSizeInBytes = getUncompressedImageSizeInBytes(dstFormat, m_parameters.size);
515 
516     const std::vector<tcu::Vec4> vertexArray     = createFullscreenQuad();
517     const uint32_t vertexCount                   = static_cast<uint32_t>(vertexArray.size());
518     const size_t vertexBufferSizeInBytes         = vertexCount * sizeof(vertexArray[0]);
519     const MovePtr<BufferWithMemory> vertexBuffer = MovePtr<BufferWithMemory>(new BufferWithMemory(
520         vk, device, allocator, makeBufferCreateInfo(vertexBufferSizeInBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT),
521         MemoryRequirement::HostVisible));
522     const Allocation &vertexBufferAlloc          = vertexBuffer->getAllocation();
523     const VkDeviceSize vertexBufferOffset[]      = {0};
524 
525     const VkBufferCreateInfo srcImageBufferInfo(
526         makeBufferCreateInfo(srcImageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT));
527     const MovePtr<BufferWithMemory> srcImageBuffer = MovePtr<BufferWithMemory>(
528         new BufferWithMemory(vk, device, allocator, srcImageBufferInfo, MemoryRequirement::HostVisible));
529 
530     const VkImageCreateInfo srcImageCreateInfo = makeCreateImageInfo(
531         srcFormat, m_parameters.imageType, m_parameters.size, srcImageUsageFlags, srcExtendedImageCreate);
532     const MovePtr<Image> srcImage(new Image(vk, device, allocator, srcImageCreateInfo, MemoryRequirement::Any));
533     Move<VkImageView> srcImageView(makeImageView(vk, device, srcImage->get(), mapImageViewType(m_parameters.imageType),
534                                                  m_parameters.featuredFormat, subresourceRange,
535                                                  srcImageViewUsageFlags));
536 
537     const VkImageCreateInfo dstImageCreateInfo = makeCreateImageInfo(
538         dstFormat, m_parameters.imageType, m_parameters.size, dstImageUsageFlags, dstExtendedImageCreate);
539     de::MovePtr<Image> dstImage(new Image(vk, device, allocator, dstImageCreateInfo, MemoryRequirement::Any));
540     Move<VkImageView> dstImageView(makeImageView(vk, device, dstImage->get(), mapImageViewType(m_parameters.imageType),
541                                                  m_parameters.featuredFormat, subresourceRange,
542                                                  dstImageViewUsageFlags));
543 
544     const VkBufferCreateInfo dstImageBufferInfo(
545         makeBufferCreateInfo(dstImageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
546     MovePtr<BufferWithMemory> dstImageBuffer = MovePtr<BufferWithMemory>(
547         new BufferWithMemory(vk, device, allocator, dstImageBufferInfo, MemoryRequirement::HostVisible));
548 
549     const Unique<VkShaderModule> vertShaderModule(
550         createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0));
551     const Unique<VkShaderModule> fragShaderModule(
552         createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0));
553 
554     const Unique<VkRenderPass> renderPass(
555         vkt::image::makeRenderPass(vk, device, m_parameters.featuredFormat, m_parameters.featuredFormat));
556 
557     const Move<VkDescriptorSetLayout> descriptorSetLayout(
558         DescriptorSetLayoutBuilder()
559             .addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT)
560             .build(vk, device));
561     const Move<VkDescriptorPool> descriptorPool(
562         DescriptorPoolBuilder()
563             .addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, SINGLE_LAYER)
564             .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, SINGLE_LAYER));
565     const Move<VkDescriptorSet> descriptorSet(makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
566     const VkDescriptorImageInfo descriptorSrcImageInfo(
567         makeDescriptorImageInfo(DE_NULL, *srcImageView, VK_IMAGE_LAYOUT_GENERAL));
568 
569     const VkExtent2D renderSize(makeExtent2D(m_parameters.size[0], m_parameters.size[1]));
570     const Unique<VkPipelineLayout> pipelineLayout(makePipelineLayout(vk, device, *descriptorSetLayout));
571     const Unique<VkPipeline> pipeline(makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertShaderModule,
572                                                            *fragShaderModule, renderSize, 1u));
573 #ifndef CTS_USES_VULKANSC
574     const Unique<VkCommandPool> cmdPool(
575         createCommandPool(vk, device, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT, queueFamilyIndex));
576 #else
577     const Unique<VkCommandPool> cmdPool(createCommandPool(vk, device, VkCommandPoolCreateFlags(0u), queueFamilyIndex));
578 #endif // CTS_USES_VULKANSC
579     const Unique<VkCommandBuffer> cmdBuffer(
580         allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
581 
582     const VkBufferImageCopy srcCopyRegion = makeBufferImageCopy(m_parameters.size[0], m_parameters.size[1]);
583     const VkBufferMemoryBarrier srcCopyBufferBarrierPre = makeBufferMemoryBarrier(
584         VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, srcImageBuffer->get(), 0ull, srcImageSizeInBytes);
585     const VkImageMemoryBarrier srcCopyImageBarrierPre =
586         makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
587                                VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, srcImage->get(), subresourceRange);
588     const VkImageMemoryBarrier srcCopyImageBarrierPost = makeImageMemoryBarrier(
589         VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
590         VK_IMAGE_LAYOUT_GENERAL, srcImage->get(), subresourceRange);
591     const VkBufferImageCopy dstCopyRegion = makeBufferImageCopy(m_parameters.size[0], m_parameters.size[1]);
592 
593     const VkImageView attachmentBindInfos[] = {*srcImageView, *dstImageView};
594     const Move<VkFramebuffer> framebuffer(makeFramebuffer(vk, device, *renderPass,
595                                                           DE_LENGTH_OF_ARRAY(attachmentBindInfos), attachmentBindInfos,
596                                                           renderSize.width, renderSize.height, SINGLE_LAYER));
597 
598     DE_ASSERT(srcImageSizeInBytes == dstImageSizeInBytes);
599 
600     // Upload vertex data
601     deMemcpy(vertexBufferAlloc.getHostPtr(), &vertexArray[0], vertexBufferSizeInBytes);
602     flushAlloc(vk, device, vertexBufferAlloc);
603 
604     // Upload source image data
605     const Allocation &alloc = srcImageBuffer->getAllocation();
606     deMemcpy(alloc.getHostPtr(), &srcData[0], (size_t)srcImageSizeInBytes);
607     flushAlloc(vk, device, alloc);
608 
609     beginCommandBuffer(vk, *cmdBuffer);
610     vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
611 
612     //Copy buffer to image
613     vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
614                           0, (const VkMemoryBarrier *)DE_NULL, 1u, &srcCopyBufferBarrierPre, 1u,
615                           &srcCopyImageBarrierPre);
616     vk.cmdCopyBufferToImage(*cmdBuffer, srcImageBuffer->get(), srcImage->get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
617                             1u, &srcCopyRegion);
618     vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
619                           (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
620                           (const VkBufferMemoryBarrier *)DE_NULL, 1u, &srcCopyImageBarrierPost);
621 
622     beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderSize);
623 
624     DescriptorSetUpdateBuilder()
625         .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u),
626                      VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &descriptorSrcImageInfo)
627         .update(vk, device);
628 
629     vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(),
630                              0u, DE_NULL);
631     vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &vertexBuffer->get(), vertexBufferOffset);
632     vk.cmdDraw(*cmdBuffer, vertexCount, 1, 0, 0);
633 
634     endRenderPass(vk, *cmdBuffer);
635 
636     const VkImageMemoryBarrier prepareForTransferBarrier =
637         makeImageMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
638                                VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL, dstImage->get(), subresourceRange);
639 
640     const VkBufferMemoryBarrier copyBarrier = makeBufferMemoryBarrier(
641         VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, dstImageBuffer->get(), 0ull, dstImageSizeInBytes);
642 
643     vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
644                           (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
645                           (const VkBufferMemoryBarrier *)DE_NULL, 1, &prepareForTransferBarrier);
646     vk.cmdCopyImageToBuffer(*cmdBuffer, dstImage->get(), VK_IMAGE_LAYOUT_GENERAL, dstImageBuffer->get(), 1u,
647                             &dstCopyRegion);
648     vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0,
649                           0, (const VkMemoryBarrier *)DE_NULL, 1, &copyBarrier, 0,
650                           (const VkImageMemoryBarrier *)DE_NULL);
651 
652     endCommandBuffer(vk, *cmdBuffer);
653 
654     submitCommandsAndWait(vk, device, queue, *cmdBuffer);
655 
656     const Allocation &dstImageBufferAlloc = dstImageBuffer->getAllocation();
657     invalidateAlloc(vk, device, dstImageBufferAlloc);
658     dstData.resize((size_t)dstImageSizeInBytes);
659     deMemcpy(&dstData[0], dstImageBufferAlloc.getHostPtr(), (size_t)dstImageSizeInBytes);
660 
661     outputImage = dstImage;
662 }
663 
makeCreateImageInfo(const VkFormat format,const ImageType type,const UVec3 & size,const VkImageUsageFlags usageFlags,const bool extendedImageCreateFlag)664 VkImageCreateInfo GraphicsAttachmentsTestInstance::makeCreateImageInfo(const VkFormat format, const ImageType type,
665                                                                        const UVec3 &size,
666                                                                        const VkImageUsageFlags usageFlags,
667                                                                        const bool extendedImageCreateFlag)
668 {
669     const VkImageType imageType                    = mapImageType(type);
670     const VkImageCreateFlags imageCreateFlagsBase  = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
671     const VkImageCreateFlags imageCreateFlagsAddOn = extendedImageCreateFlag ? VK_IMAGE_CREATE_EXTENDED_USAGE_BIT : 0;
672     const VkImageCreateFlags imageCreateFlags      = imageCreateFlagsBase | imageCreateFlagsAddOn;
673 
674     const VkImageCreateInfo createImageInfo = {
675         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType sType;
676         DE_NULL,                                // const void* pNext;
677         imageCreateFlags,                       // VkImageCreateFlags flags;
678         imageType,                              // VkImageType imageType;
679         format,                                 // VkFormat format;
680         makeExtent3D(getLayerSize(type, size)), // VkExtent3D extent;
681         1u,                                     // uint32_t mipLevels;
682         1u,                                     // uint32_t arrayLayers;
683         VK_SAMPLE_COUNT_1_BIT,                  // VkSampleCountFlagBits samples;
684         VK_IMAGE_TILING_OPTIMAL,                // VkImageTiling tiling;
685         usageFlags,                             // VkImageUsageFlags usage;
686         VK_SHARING_MODE_EXCLUSIVE,              // VkSharingMode sharingMode;
687         0u,                                     // uint32_t queueFamilyIndexCount;
688         DE_NULL,                                // const uint32_t* pQueueFamilyIndices;
689         VK_IMAGE_LAYOUT_UNDEFINED,              // VkImageLayout initialLayout;
690     };
691 
692     return createImageInfo;
693 }
694 
makeImageViewUsageCreateInfo(VkImageUsageFlags imageUsageFlags)695 VkImageViewUsageCreateInfo GraphicsAttachmentsTestInstance::makeImageViewUsageCreateInfo(
696     VkImageUsageFlags imageUsageFlags)
697 {
698     VkImageViewUsageCreateInfo imageViewUsageCreateInfo = {
699         VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO, //VkStructureType sType;
700         DE_NULL,                                        //const void* pNext;
701         imageUsageFlags,                                //VkImageUsageFlags usage;
702     };
703 
704     return imageViewUsageCreateInfo;
705 }
706 
getUncompressedImageData(const VkFormat format,const UVec3 & size,std::vector<uint8_t> & data)707 VkDeviceSize GraphicsAttachmentsTestInstance::getUncompressedImageData(const VkFormat format, const UVec3 &size,
708                                                                        std::vector<uint8_t> &data)
709 {
710     tcu::IVec3 sizeAsIVec3 =
711         tcu::IVec3(static_cast<int>(size[0]), static_cast<int>(size[1]), static_cast<int>(size[2]));
712     VkDeviceSize sizeBytes = getImageSizeBytes(sizeAsIVec3, format);
713 
714     data.resize((size_t)sizeBytes);
715     generateData(&data[0], data.size(), format);
716 
717     return sizeBytes;
718 }
719 
compareAndLog(const void * reference,const void * result,size_t size)720 bool GraphicsAttachmentsTestInstance::compareAndLog(const void *reference, const void *result, size_t size)
721 {
722     tcu::TestLog &log = m_context.getTestContext().getLog();
723 
724     const uint64_t *ref64 = reinterpret_cast<const uint64_t *>(reference);
725     const uint64_t *res64 = reinterpret_cast<const uint64_t *>(result);
726     const size_t sizew    = size / sizeof(uint64_t);
727     bool equal            = true;
728 
729     DE_ASSERT(size % sizeof(uint64_t) == 0);
730 
731     for (uint32_t ndx = 0u; ndx < static_cast<uint32_t>(sizew); ndx++)
732     {
733         if (ref64[ndx] != res64[ndx])
734         {
735             std::stringstream str;
736 
737             str << "Difference begins near byte " << ndx * sizeof(uint64_t) << "."
738                 << " reference value: 0x" << std::hex << std::setw(2ull * sizeof(uint64_t)) << std::setfill('0')
739                 << ref64[ndx] << " result value: 0x" << std::hex << std::setw(2ull * sizeof(uint64_t))
740                 << std::setfill('0') << res64[ndx];
741 
742             log.writeMessage(str.str().c_str());
743 
744             equal = false;
745 
746             break;
747         }
748     }
749 
750     return equal;
751 }
752 
753 class GraphicsTextureTestInstance : public GraphicsAttachmentsTestInstance
754 {
755 public:
756     GraphicsTextureTestInstance(Context &context, const TestParameters &parameters);
757 
758 protected:
759     void transcode(std::vector<uint8_t> &srcData, std::vector<uint8_t> &dstData, de::MovePtr<Image> &outputImage);
760 };
761 
GraphicsTextureTestInstance(Context & context,const TestParameters & parameters)762 GraphicsTextureTestInstance::GraphicsTextureTestInstance(Context &context, const TestParameters &parameters)
763     : GraphicsAttachmentsTestInstance(context, parameters)
764 {
765 }
766 
transcode(std::vector<uint8_t> & srcData,std::vector<uint8_t> & dstData,de::MovePtr<Image> & outputImage)767 void GraphicsTextureTestInstance::transcode(std::vector<uint8_t> &srcData, std::vector<uint8_t> &dstData,
768                                             de::MovePtr<Image> &outputImage)
769 {
770     const DeviceInterface &vk       = m_context.getDeviceInterface();
771     const VkDevice device           = m_context.getDevice();
772     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
773     const VkQueue queue             = m_context.getUniversalQueue();
774     Allocator &allocator            = m_context.getDefaultAllocator();
775 
776     const VkImageSubresourceRange subresourceRange =
777         makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, SINGLE_LEVEL, 0u, SINGLE_LAYER);
778     const VkImageViewUsageCreateInfo *imageViewUsageNull = (VkImageViewUsageCreateInfo *)DE_NULL;
779     const VkImageViewUsageCreateInfo imageViewUsage      = makeImageViewUsageCreateInfo(m_parameters.testedImageUsage);
780 
781     const VkFormat srcFormat = (m_parameters.operation == OPERATION_TEXTURE_READ)  ? m_parameters.featurelessFormat :
782                                (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? m_parameters.featuredFormat :
783                                                                                      VK_FORMAT_UNDEFINED;
784     const bool srcExtendedImageCreate = (m_parameters.operation == OPERATION_TEXTURE_READ)  ? true :
785                                         (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? false :
786                                                                                               false;
787     const VkImageUsageFlags srcImageUsageFlags =
788         (m_parameters.operation == OPERATION_TEXTURE_READ)  ? m_parameters.testedImageUsage :
789         (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? m_parameters.pairedImageUsage :
790                                                               0;
791     const VkImageViewUsageCreateInfo *srcImageViewUsage =
792         (m_parameters.operation == OPERATION_TEXTURE_READ)  ? &imageViewUsage :
793         (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? imageViewUsageNull :
794                                                               imageViewUsageNull;
795     const VkDeviceSize srcImageSizeInBytes = getUncompressedImageData(srcFormat, m_parameters.size, srcData);
796 
797     const VkFormat dstFormat = (m_parameters.operation == OPERATION_TEXTURE_READ)  ? m_parameters.featuredFormat :
798                                (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? m_parameters.featurelessFormat :
799                                                                                      VK_FORMAT_UNDEFINED;
800     const bool dstExtendedImageCreate = (m_parameters.operation == OPERATION_TEXTURE_READ)  ? false :
801                                         (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? true :
802                                                                                               false;
803     const VkImageUsageFlags dstImageUsageFlags =
804         (m_parameters.operation == OPERATION_TEXTURE_READ)  ? m_parameters.pairedImageUsage :
805         (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? m_parameters.testedImageUsage :
806                                                               0;
807     const VkImageViewUsageCreateInfo *dstImageViewUsage =
808         (m_parameters.operation == OPERATION_TEXTURE_READ)  ? imageViewUsageNull :
809         (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? &imageViewUsage :
810                                                               imageViewUsageNull;
811     const VkDeviceSize dstImageSizeInBytes = getUncompressedImageSizeInBytes(dstFormat, m_parameters.size);
812 
813     const std::vector<tcu::Vec4> vertexArray     = createFullscreenQuad();
814     const uint32_t vertexCount                   = static_cast<uint32_t>(vertexArray.size());
815     const size_t vertexBufferSizeInBytes         = vertexCount * sizeof(vertexArray[0]);
816     const MovePtr<BufferWithMemory> vertexBuffer = MovePtr<BufferWithMemory>(new BufferWithMemory(
817         vk, device, allocator, makeBufferCreateInfo(vertexBufferSizeInBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT),
818         MemoryRequirement::HostVisible));
819     const Allocation &vertexBufferAlloc          = vertexBuffer->getAllocation();
820     const VkDeviceSize vertexBufferOffset[]      = {0};
821 
822     const VkBufferCreateInfo srcImageBufferInfo(
823         makeBufferCreateInfo(srcImageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT));
824     const MovePtr<BufferWithMemory> srcImageBuffer = MovePtr<BufferWithMemory>(
825         new BufferWithMemory(vk, device, allocator, srcImageBufferInfo, MemoryRequirement::HostVisible));
826 
827     const VkImageCreateInfo srcImageCreateInfo = makeCreateImageInfo(
828         srcFormat, m_parameters.imageType, m_parameters.size, srcImageUsageFlags, srcExtendedImageCreate);
829     const MovePtr<Image> srcImage(new Image(vk, device, allocator, srcImageCreateInfo, MemoryRequirement::Any));
830     Move<VkImageView> srcImageView(makeImageView(vk, device, srcImage->get(), mapImageViewType(m_parameters.imageType),
831                                                  m_parameters.featuredFormat, subresourceRange, srcImageViewUsage));
832 
833     const VkImageCreateInfo dstImageCreateInfo = makeCreateImageInfo(
834         dstFormat, m_parameters.imageType, m_parameters.size, dstImageUsageFlags, dstExtendedImageCreate);
835     de::MovePtr<Image> dstImage(new Image(vk, device, allocator, dstImageCreateInfo, MemoryRequirement::Any));
836     Move<VkImageView> dstImageView(makeImageView(vk, device, dstImage->get(), mapImageViewType(m_parameters.imageType),
837                                                  m_parameters.featuredFormat, subresourceRange, dstImageViewUsage));
838     const VkImageMemoryBarrier dstCopyImageBarrier =
839         makeImageMemoryBarrier(0u, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
840                                dstImage->get(), subresourceRange);
841 
842     const VkBufferCreateInfo dstImageBufferInfo(
843         makeBufferCreateInfo(dstImageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
844     MovePtr<BufferWithMemory> dstImageBuffer = MovePtr<BufferWithMemory>(
845         new BufferWithMemory(vk, device, allocator, dstImageBufferInfo, MemoryRequirement::HostVisible));
846 
847     const Unique<VkShaderModule> vertShaderModule(
848         createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0));
849     const Unique<VkShaderModule> fragShaderModule(
850         createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0));
851 
852     const Unique<VkRenderPass> renderPass(makeRenderPass(vk, device));
853 
854     const Move<VkDescriptorSetLayout> descriptorSetLayout(
855         DescriptorSetLayoutBuilder()
856             .addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT)
857             .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT)
858             .build(vk, device));
859     const Move<VkDescriptorPool> descriptorPool(
860         DescriptorPoolBuilder()
861             .addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
862             .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
863             .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
864     const Move<VkDescriptorSet> descriptorSet(makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
865     const VkSamplerCreateInfo srcSamplerInfo(makeSamplerCreateInfo());
866     const Move<VkSampler> srcSampler = vk::createSampler(vk, device, &srcSamplerInfo);
867     const VkDescriptorImageInfo descriptorSrcImage(
868         makeDescriptorImageInfo(*srcSampler, *srcImageView, VK_IMAGE_LAYOUT_GENERAL));
869     const VkDescriptorImageInfo descriptorDstImage(
870         makeDescriptorImageInfo(DE_NULL, *dstImageView, VK_IMAGE_LAYOUT_GENERAL));
871 
872     const VkExtent2D renderSize(makeExtent2D(m_parameters.size[0], m_parameters.size[1]));
873     const Unique<VkPipelineLayout> pipelineLayout(makePipelineLayout(vk, device, *descriptorSetLayout));
874     const Unique<VkPipeline> pipeline(makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertShaderModule,
875                                                            *fragShaderModule, renderSize, 0u));
876 #ifndef CTS_USES_VULKANSC
877     const Unique<VkCommandPool> cmdPool(
878         createCommandPool(vk, device, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT, queueFamilyIndex));
879 #else
880     const Unique<VkCommandPool> cmdPool(createCommandPool(vk, device, VkCommandPoolCreateFlags(0u), queueFamilyIndex));
881 #endif // CTS_USES_VULKANSC
882 
883     const Unique<VkCommandBuffer> cmdBuffer(
884         allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
885 
886     const VkBufferImageCopy srcCopyRegion            = makeBufferImageCopy(m_parameters.size[0], m_parameters.size[1]);
887     const VkBufferMemoryBarrier srcCopyBufferBarrier = makeBufferMemoryBarrier(
888         VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, srcImageBuffer->get(), 0ull, srcImageSizeInBytes);
889     const VkImageMemoryBarrier srcCopyImageBarrier =
890         makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
891                                srcImage->get(), subresourceRange);
892     const VkImageMemoryBarrier srcCopyImageBarrierPost =
893         makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_GENERAL,
894                                VK_IMAGE_LAYOUT_GENERAL, srcImage->get(), subresourceRange);
895 
896     const VkBufferImageCopy dstCopyRegion = makeBufferImageCopy(m_parameters.size[0], m_parameters.size[1]);
897 
898     const VkExtent2D framebufferSize(makeExtent2D(m_parameters.size[0], m_parameters.size[1]));
899     const Move<VkFramebuffer> framebuffer(makeFramebuffer(vk, device, *renderPass, 0, DE_NULL, framebufferSize.width,
900                                                           framebufferSize.height, SINGLE_LAYER));
901 
902     DE_ASSERT(srcImageSizeInBytes == dstImageSizeInBytes);
903 
904     // Upload vertex data
905     deMemcpy(vertexBufferAlloc.getHostPtr(), &vertexArray[0], vertexBufferSizeInBytes);
906     flushAlloc(vk, device, vertexBufferAlloc);
907 
908     // Upload source image data
909     const Allocation &alloc = srcImageBuffer->getAllocation();
910     deMemcpy(alloc.getHostPtr(), &srcData[0], (size_t)srcImageSizeInBytes);
911     flushAlloc(vk, device, alloc);
912 
913     beginCommandBuffer(vk, *cmdBuffer);
914     vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
915 
916     //Copy buffer to image
917     vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
918                           0, (const VkMemoryBarrier *)DE_NULL, 1u, &srcCopyBufferBarrier, 1u, &srcCopyImageBarrier);
919     vk.cmdCopyBufferToImage(*cmdBuffer, srcImageBuffer->get(), srcImage->get(), VK_IMAGE_LAYOUT_GENERAL, 1u,
920                             &srcCopyRegion);
921     vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
922                           (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
923                           (const VkBufferMemoryBarrier *)DE_NULL, 1u, &srcCopyImageBarrierPost);
924 
925     // Make source image readable
926     vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
927                           (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0u, DE_NULL, 1u,
928                           &dstCopyImageBarrier);
929 
930     beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderSize);
931     {
932         DescriptorSetUpdateBuilder()
933             .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u),
934                          VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descriptorSrcImage)
935             .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u),
936                          VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorDstImage)
937             .update(vk, device);
938 
939         vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u,
940                                  &descriptorSet.get(), 0u, DE_NULL);
941         vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &vertexBuffer->get(), vertexBufferOffset);
942         vk.cmdDraw(*cmdBuffer, vertexCount, 1, 0, 0);
943     }
944     endRenderPass(vk, *cmdBuffer);
945 
946     const VkImageMemoryBarrier prepareForTransferBarrier =
947         makeImageMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_GENERAL,
948                                VK_IMAGE_LAYOUT_GENERAL, dstImage->get(), subresourceRange);
949 
950     const VkBufferMemoryBarrier copyBarrier = makeBufferMemoryBarrier(
951         VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, dstImageBuffer->get(), 0ull, dstImageSizeInBytes);
952 
953     vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
954                           (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
955                           (const VkBufferMemoryBarrier *)DE_NULL, 1, &prepareForTransferBarrier);
956     vk.cmdCopyImageToBuffer(*cmdBuffer, dstImage->get(), VK_IMAGE_LAYOUT_GENERAL, dstImageBuffer->get(), 1u,
957                             &dstCopyRegion);
958     vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0,
959                           0, (const VkMemoryBarrier *)DE_NULL, 1, &copyBarrier, 0,
960                           (const VkImageMemoryBarrier *)DE_NULL);
961 
962     endCommandBuffer(vk, *cmdBuffer);
963 
964     submitCommandsAndWait(vk, device, queue, *cmdBuffer);
965 
966     const Allocation &dstImageBufferAlloc = dstImageBuffer->getAllocation();
967     invalidateAlloc(vk, device, dstImageBufferAlloc);
968     dstData.resize((size_t)dstImageSizeInBytes);
969     deMemcpy(&dstData[0], dstImageBufferAlloc.getHostPtr(), (size_t)dstImageSizeInBytes);
970 
971     outputImage = dstImage;
972 }
973 
974 class ImageTranscodingCase : public TestCase
975 {
976 public:
977     ImageTranscodingCase(TestContext &testCtx, const std::string &name, const TestParameters &parameters);
978     void initPrograms(SourceCollections &programCollection) const;
979     TestInstance *createInstance(Context &context) const;
980     virtual void checkSupport(Context &context) const;
981     bool isFormatUsageFlagSupported(Context &context, const VkFormat format, VkImageUsageFlags formatUsageFlags) const;
982 
983 protected:
984     const TestParameters m_parameters;
985 };
986 
ImageTranscodingCase(TestContext & testCtx,const std::string & name,const TestParameters & parameters)987 ImageTranscodingCase::ImageTranscodingCase(TestContext &testCtx, const std::string &name,
988                                            const TestParameters &parameters)
989     : TestCase(testCtx, name)
990     , m_parameters(parameters)
991 {
992 }
993 
initPrograms(vk::SourceCollections & programCollection) const994 void ImageTranscodingCase::initPrograms(vk::SourceCollections &programCollection) const
995 {
996     DE_ASSERT(m_parameters.size.x() > 0);
997     DE_ASSERT(m_parameters.size.y() > 0);
998 
999     ImageType imageTypeForFS = (m_parameters.imageType == IMAGE_TYPE_2D_ARRAY) ? IMAGE_TYPE_2D : m_parameters.imageType;
1000 
1001     // Vertex shader
1002     {
1003         std::ostringstream src;
1004         src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n\n"
1005             << "layout(location = 0) in vec4 v_in_position;\n"
1006             << "\n"
1007             << "void main (void)\n"
1008             << "{\n"
1009             << "    gl_Position = v_in_position;\n"
1010             << "}\n";
1011 
1012         programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
1013     }
1014 
1015     // Fragment shader
1016     {
1017         switch (m_parameters.operation)
1018         {
1019         case OPERATION_ATTACHMENT_READ:
1020         case OPERATION_ATTACHMENT_WRITE:
1021         {
1022             std::ostringstream src;
1023 
1024             const std::string dstTypeStr = getGlslAttachmentType(m_parameters.featuredFormat);
1025             const std::string srcTypeStr = getGlslInputAttachmentType(m_parameters.featuredFormat);
1026 
1027             src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n\n"
1028                 << "precision highp int;\n"
1029                 << "precision highp float;\n"
1030                 << "\n"
1031                 << "layout (location = 0) out highp " << dstTypeStr << " o_color;\n"
1032                 << "layout (input_attachment_index = 0, set = 0, binding = 0) uniform highp " << srcTypeStr
1033                 << " inputImage1;\n"
1034                 << "\n"
1035                 << "void main (void)\n"
1036                 << "{\n"
1037                 << "    o_color = " << dstTypeStr << "(subpassLoad(inputImage1));\n"
1038                 << "}\n";
1039 
1040             programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
1041 
1042             break;
1043         }
1044 
1045         case OPERATION_TEXTURE_READ:
1046         case OPERATION_TEXTURE_WRITE:
1047         {
1048             std::ostringstream src;
1049 
1050             const std::string srcSamplerTypeStr =
1051                 getGlslSamplerType(mapVkFormat(m_parameters.featuredFormat), mapImageViewType(imageTypeForFS));
1052             const std::string dstImageTypeStr =
1053                 getShaderImageType(mapVkFormat(m_parameters.featuredFormat), imageTypeForFS);
1054             const std::string dstFormatQualifierStr =
1055                 getShaderImageFormatQualifier(mapVkFormat(m_parameters.featuredFormat));
1056 
1057             src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n\n"
1058                 << "layout (binding = 0) uniform " << srcSamplerTypeStr << " u_imageIn;\n"
1059                 << "layout (binding = 1, " << dstFormatQualifierStr << ") writeonly uniform " << dstImageTypeStr
1060                 << " u_imageOut;\n"
1061                 << "\n"
1062                 << "void main (void)\n"
1063                 << "{\n"
1064                 << "    const ivec2 out_pos = ivec2(gl_FragCoord.xy);\n"
1065                 << "    const vec2 pixels_resolution = vec2(textureSize(u_imageIn, 0));\n"
1066                 << "    const vec2 in_pos = vec2(gl_FragCoord.xy) / vec2(pixels_resolution);\n"
1067                 << "    imageStore(u_imageOut, out_pos, texture(u_imageIn, in_pos));\n"
1068                 << "}\n";
1069 
1070             programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
1071 
1072             break;
1073         }
1074 
1075         default:
1076             DE_ASSERT(false);
1077         }
1078     }
1079 }
1080 
isFormatUsageFlagSupported(Context & context,const VkFormat format,VkImageUsageFlags formatUsageFlags) const1081 bool ImageTranscodingCase::isFormatUsageFlagSupported(Context &context, const VkFormat format,
1082                                                       VkImageUsageFlags formatUsageFlags) const
1083 {
1084     const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
1085     const InstanceInterface &vk           = context.getInstanceInterface();
1086     VkImageFormatProperties imageFormatProperties;
1087     const VkResult queryResult = vk.getPhysicalDeviceImageFormatProperties(
1088         physicalDevice, format, mapImageType(m_parameters.imageType), VK_IMAGE_TILING_OPTIMAL, formatUsageFlags,
1089         VK_IMAGE_CREATE_EXTENDED_USAGE_BIT, &imageFormatProperties);
1090 
1091     return (queryResult == VK_SUCCESS);
1092 }
1093 
checkSupport(Context & context) const1094 void ImageTranscodingCase::checkSupport(Context &context) const
1095 {
1096     context.requireDeviceFunctionality("VK_KHR_maintenance2");
1097 
1098     if ((m_parameters.operation == OPERATION_TEXTURE_READ || m_parameters.operation == OPERATION_TEXTURE_WRITE) &&
1099         !context.getDeviceFeatures().fragmentStoresAndAtomics)
1100         TCU_THROW(NotSupportedError, "fragmentStoresAndAtomics not supported");
1101 
1102     if (!isFormatUsageFlagSupported(context, m_parameters.featuredFormat, m_parameters.testedImageUsageFeature))
1103         TCU_THROW(NotSupportedError, "Test skipped due to feature is not supported by the format");
1104 
1105     if (!isFormatUsageFlagSupported(context, m_parameters.featuredFormat,
1106                                     m_parameters.testedImageUsage | m_parameters.pairedImageUsage))
1107         TCU_THROW(NotSupportedError, "Required image usage flags are not supported by the format");
1108 }
1109 
createInstance(Context & context) const1110 TestInstance *ImageTranscodingCase::createInstance(Context &context) const
1111 {
1112     VkFormat featurelessFormat = VK_FORMAT_UNDEFINED;
1113     bool differenceFound       = false;
1114 
1115     DE_ASSERT(m_parameters.testedImageUsageFeature != 0);
1116 
1117     for (uint32_t i = 0; m_parameters.compatibleFormats[i] != VK_FORMAT_UNDEFINED; i++)
1118     {
1119         featurelessFormat = m_parameters.compatibleFormats[i];
1120 
1121         if (isSupportedByFramework(featurelessFormat) &&
1122             !isFormatUsageFlagSupported(context, featurelessFormat, m_parameters.testedImageUsageFeature) &&
1123             isFormatUsageFlagSupported(context, featurelessFormat,
1124                                        m_parameters.testedImageUsage & (~m_parameters.testedImageUsageFeature)))
1125         {
1126             differenceFound = true;
1127 
1128             break;
1129         }
1130     }
1131 
1132     if (differenceFound)
1133     {
1134 #ifndef CTS_USES_VULKANSC
1135         if ((context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
1136              !context.getPortabilitySubsetFeatures().imageViewFormatReinterpretation))
1137         {
1138             tcu::TextureFormat textureImageFormat = vk::mapVkFormat(m_parameters.featuredFormat);
1139             tcu::TextureFormat textureViewFormat  = vk::mapVkFormat(featurelessFormat);
1140 
1141             if (tcu::getTextureFormatBitDepth(textureImageFormat) != tcu::getTextureFormatBitDepth(textureViewFormat))
1142                 TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Format must not contain a different number of "
1143                                              "bits in each component, than the format of the VkImage");
1144         }
1145 #endif // CTS_USES_VULKANSC
1146 
1147         TestParameters calculatedParameters = {
1148             m_parameters.operation,               // Operation                operation
1149             m_parameters.size,                    // UVec3                    size
1150             m_parameters.imageType,               // ImageType                imageType
1151             m_parameters.testedImageUsageFeature, // VkImageUsageFlagBits        testedImageUsageFeature
1152             m_parameters.featuredFormat,          // VkFormat                    featuredFormat
1153             featurelessFormat,                    // VkFormat                    featurelessFormat
1154             m_parameters.testedImageUsage,        // VkImageUsageFlags        testedImageUsage
1155             m_parameters.pairedImageUsage,        // VkImageUsageFlags        pairedImageUsage
1156             DE_NULL,                              // const VkFormat*            compatibleFormats
1157         };
1158 
1159         switch (m_parameters.operation)
1160         {
1161         case OPERATION_ATTACHMENT_READ:
1162         case OPERATION_ATTACHMENT_WRITE:
1163             return new GraphicsAttachmentsTestInstance(context, calculatedParameters);
1164 
1165         case OPERATION_TEXTURE_READ:
1166         case OPERATION_TEXTURE_WRITE:
1167             return new GraphicsTextureTestInstance(context, calculatedParameters);
1168 
1169         default:
1170             TCU_THROW(InternalError, "Impossible");
1171         }
1172     }
1173     else
1174         TCU_THROW(NotSupportedError, "All formats in group contain tested feature. Test is impossible.");
1175 }
1176 
1177 } // namespace
1178 
1179 static const VkFormat compatibleFormatList8Bit[] = {
1180     VK_FORMAT_R4G4_UNORM_PACK8, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_SNORM, VK_FORMAT_R8_USCALED,
1181     VK_FORMAT_R8_SSCALED,       VK_FORMAT_R8_UINT,  VK_FORMAT_R8_SINT,  VK_FORMAT_R8_SRGB,
1182 
1183     VK_FORMAT_UNDEFINED};
1184 
1185 static const VkFormat compatibleFormatList16Bit[] = {VK_FORMAT_R4G4B4A4_UNORM_PACK16,
1186                                                      VK_FORMAT_B4G4R4A4_UNORM_PACK16,
1187                                                      VK_FORMAT_R5G6B5_UNORM_PACK16,
1188                                                      VK_FORMAT_B5G6R5_UNORM_PACK16,
1189                                                      VK_FORMAT_R5G5B5A1_UNORM_PACK16,
1190                                                      VK_FORMAT_B5G5R5A1_UNORM_PACK16,
1191                                                      VK_FORMAT_A1R5G5B5_UNORM_PACK16,
1192                                                      VK_FORMAT_R8G8_UNORM,
1193                                                      VK_FORMAT_R8G8_SNORM,
1194                                                      VK_FORMAT_R8G8_USCALED,
1195                                                      VK_FORMAT_R8G8_SSCALED,
1196                                                      VK_FORMAT_R8G8_UINT,
1197                                                      VK_FORMAT_R8G8_SINT,
1198                                                      VK_FORMAT_R8G8_SRGB,
1199                                                      VK_FORMAT_R16_UNORM,
1200                                                      VK_FORMAT_R16_SNORM,
1201                                                      VK_FORMAT_R16_USCALED,
1202                                                      VK_FORMAT_R16_SSCALED,
1203                                                      VK_FORMAT_R16_UINT,
1204                                                      VK_FORMAT_R16_SINT,
1205                                                      VK_FORMAT_R16_SFLOAT,
1206                                                      VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
1207                                                      VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
1208 
1209                                                      VK_FORMAT_UNDEFINED};
1210 
1211 static const VkFormat compatibleFormatList24Bit[] = {
1212     VK_FORMAT_R8G8B8_UNORM, VK_FORMAT_R8G8B8_SNORM,   VK_FORMAT_R8G8B8_USCALED, VK_FORMAT_R8G8B8_SSCALED,
1213     VK_FORMAT_R8G8B8_UINT,  VK_FORMAT_R8G8B8_SINT,    VK_FORMAT_R8G8B8_SRGB,    VK_FORMAT_B8G8R8_UNORM,
1214     VK_FORMAT_B8G8R8_SNORM, VK_FORMAT_B8G8R8_USCALED, VK_FORMAT_B8G8R8_SSCALED, VK_FORMAT_B8G8R8_UINT,
1215     VK_FORMAT_B8G8R8_SINT,  VK_FORMAT_B8G8R8_SRGB,
1216 
1217     VK_FORMAT_UNDEFINED};
1218 
1219 static const VkFormat compatibleFormatList32Bit[] = {VK_FORMAT_R8G8B8A8_UNORM,
1220                                                      VK_FORMAT_R8G8B8A8_SNORM,
1221                                                      VK_FORMAT_R8G8B8A8_USCALED,
1222                                                      VK_FORMAT_R8G8B8A8_SSCALED,
1223                                                      VK_FORMAT_R8G8B8A8_UINT,
1224                                                      VK_FORMAT_R8G8B8A8_SINT,
1225                                                      VK_FORMAT_R8G8B8A8_SRGB,
1226                                                      VK_FORMAT_B8G8R8A8_UNORM,
1227                                                      VK_FORMAT_B8G8R8A8_SNORM,
1228                                                      VK_FORMAT_B8G8R8A8_USCALED,
1229                                                      VK_FORMAT_B8G8R8A8_SSCALED,
1230                                                      VK_FORMAT_B8G8R8A8_UINT,
1231                                                      VK_FORMAT_B8G8R8A8_SINT,
1232                                                      VK_FORMAT_B8G8R8A8_SRGB,
1233                                                      VK_FORMAT_A8B8G8R8_UNORM_PACK32,
1234                                                      VK_FORMAT_A8B8G8R8_SNORM_PACK32,
1235                                                      VK_FORMAT_A8B8G8R8_USCALED_PACK32,
1236                                                      VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
1237                                                      VK_FORMAT_A8B8G8R8_UINT_PACK32,
1238                                                      VK_FORMAT_A8B8G8R8_SINT_PACK32,
1239                                                      VK_FORMAT_A8B8G8R8_SRGB_PACK32,
1240                                                      VK_FORMAT_A2R10G10B10_UNORM_PACK32,
1241                                                      VK_FORMAT_A2R10G10B10_SNORM_PACK32,
1242                                                      VK_FORMAT_A2R10G10B10_USCALED_PACK32,
1243                                                      VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
1244                                                      VK_FORMAT_A2R10G10B10_UINT_PACK32,
1245                                                      VK_FORMAT_A2R10G10B10_SINT_PACK32,
1246                                                      VK_FORMAT_A2B10G10R10_UNORM_PACK32,
1247                                                      VK_FORMAT_A2B10G10R10_SNORM_PACK32,
1248                                                      VK_FORMAT_A2B10G10R10_USCALED_PACK32,
1249                                                      VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
1250                                                      VK_FORMAT_A2B10G10R10_UINT_PACK32,
1251                                                      VK_FORMAT_A2B10G10R10_SINT_PACK32,
1252                                                      VK_FORMAT_R16G16_UNORM,
1253                                                      VK_FORMAT_R16G16_SNORM,
1254                                                      VK_FORMAT_R16G16_USCALED,
1255                                                      VK_FORMAT_R16G16_SSCALED,
1256                                                      VK_FORMAT_R16G16_UINT,
1257                                                      VK_FORMAT_R16G16_SINT,
1258                                                      VK_FORMAT_R16G16_SFLOAT,
1259                                                      VK_FORMAT_R32_UINT,
1260                                                      VK_FORMAT_R32_SINT,
1261                                                      VK_FORMAT_R32_SFLOAT,
1262 
1263                                                      VK_FORMAT_UNDEFINED};
1264 
1265 static const VkFormat compatibleFormatList48Bit[] = {
1266     VK_FORMAT_R16G16B16_UNORM, VK_FORMAT_R16G16B16_SNORM, VK_FORMAT_R16G16B16_USCALED, VK_FORMAT_R16G16B16_SSCALED,
1267     VK_FORMAT_R16G16B16_UINT,  VK_FORMAT_R16G16B16_SINT,  VK_FORMAT_R16G16B16_SFLOAT,
1268 
1269     VK_FORMAT_UNDEFINED};
1270 
1271 static const VkFormat compatibleFormatList64Bit[] = {VK_FORMAT_R16G16B16A16_UNORM,
1272                                                      VK_FORMAT_R16G16B16A16_SNORM,
1273                                                      VK_FORMAT_R16G16B16A16_USCALED,
1274                                                      VK_FORMAT_R16G16B16A16_SSCALED,
1275                                                      VK_FORMAT_R16G16B16A16_UINT,
1276                                                      VK_FORMAT_R16G16B16A16_SINT,
1277                                                      VK_FORMAT_R16G16B16A16_SFLOAT,
1278                                                      VK_FORMAT_R32G32_UINT,
1279                                                      VK_FORMAT_R32G32_SINT,
1280                                                      VK_FORMAT_R32G32_SFLOAT,
1281                                                      VK_FORMAT_R64_UINT,
1282                                                      VK_FORMAT_R64_SINT,
1283                                                      VK_FORMAT_R64_SFLOAT,
1284 
1285                                                      VK_FORMAT_UNDEFINED};
1286 
1287 static const VkFormat compatibleFormatList96Bit[] = {VK_FORMAT_R32G32B32_UINT, VK_FORMAT_R32G32B32_SINT,
1288                                                      VK_FORMAT_R32G32B32_SFLOAT,
1289 
1290                                                      VK_FORMAT_UNDEFINED};
1291 
1292 static const VkFormat compatibleFormatList128Bit[] = {
1293     VK_FORMAT_R32G32B32A32_UINT, VK_FORMAT_R32G32B32A32_SINT, VK_FORMAT_R32G32B32A32_SFLOAT,
1294     VK_FORMAT_R64G64_UINT,       VK_FORMAT_R64G64_SINT,       VK_FORMAT_R64G64_SFLOAT,
1295 
1296     VK_FORMAT_UNDEFINED};
1297 
1298 const VkFormat compatibleFormatList192Bit[] = {VK_FORMAT_R64G64B64_UINT, VK_FORMAT_R64G64B64_SINT,
1299                                                VK_FORMAT_R64G64B64_SFLOAT,
1300 
1301                                                VK_FORMAT_UNDEFINED};
1302 
1303 static const VkFormat compatibleFormatList256Bit[] = {VK_FORMAT_R64G64B64A64_UINT, VK_FORMAT_R64G64B64A64_SINT,
1304                                                       VK_FORMAT_R64G64B64A64_SFLOAT,
1305 
1306                                                       VK_FORMAT_UNDEFINED};
1307 
1308 static const VkFormat *compatibleFormatsList[] = {
1309     compatibleFormatList8Bit,   compatibleFormatList16Bit,  compatibleFormatList24Bit, compatibleFormatList32Bit,
1310     compatibleFormatList48Bit,  compatibleFormatList64Bit,  compatibleFormatList96Bit, compatibleFormatList128Bit,
1311     compatibleFormatList192Bit, compatibleFormatList256Bit,
1312 };
1313 
createImageTranscodingSupportTests(tcu::TestContext & testCtx)1314 tcu::TestCaseGroup *createImageTranscodingSupportTests(tcu::TestContext &testCtx)
1315 {
1316     const std::string operationName[OPERATION_LAST] = {
1317         "attachment_read",
1318         "attachment_write",
1319         "texture_read",
1320         "texture_write",
1321     };
1322     const VkImageUsageFlagBits testedImageUsageFlags[OPERATION_LAST] = {
1323         VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
1324         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
1325         VK_IMAGE_USAGE_SAMPLED_BIT,
1326         VK_IMAGE_USAGE_STORAGE_BIT,
1327     };
1328     const VkImageUsageFlagBits pairedImageUsageFlags[OPERATION_LAST] = {
1329         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
1330         VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
1331         VK_IMAGE_USAGE_STORAGE_BIT,
1332         VK_IMAGE_USAGE_SAMPLED_BIT,
1333     };
1334     VkImageUsageFlags baseFlagsAddOn = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1335 
1336     MovePtr<tcu::TestCaseGroup> imageTranscodingTests(new tcu::TestCaseGroup(testCtx, "extended_usage_bit"));
1337 
1338     for (int operationNdx = OPERATION_ATTACHMENT_READ; operationNdx < OPERATION_LAST; ++operationNdx)
1339     {
1340         MovePtr<tcu::TestCaseGroup> imageOperationGroup(
1341             new tcu::TestCaseGroup(testCtx, operationName[operationNdx].c_str()));
1342 
1343         for (uint32_t groupNdx = 0; groupNdx < DE_LENGTH_OF_ARRAY(compatibleFormatsList); groupNdx++)
1344         {
1345             for (uint32_t featuredFormatNdx = 0;
1346                  compatibleFormatsList[groupNdx][featuredFormatNdx] != VK_FORMAT_UNDEFINED; featuredFormatNdx++)
1347             {
1348                 const VkFormat featuredFormat    = compatibleFormatsList[groupNdx][featuredFormatNdx];
1349                 const VkFormat featurelessFormat = VK_FORMAT_UNDEFINED; // Lookup process is in createInstance()
1350 
1351                 if (!isSupportedByFramework(featuredFormat))
1352                     continue;
1353 
1354                 // Cannot handle SRGB in shader layout classifier
1355                 if (isSrgbFormat(featuredFormat))
1356                     continue;
1357 
1358                 // Cannot handle packed in shader layout classifier
1359                 if (isPackedType(featuredFormat))
1360                     continue;
1361 
1362                 // Cannot handle swizzled component format (i.e. bgr) in shader layout classifier
1363                 if (isComponentSwizzled(featuredFormat))
1364                     continue;
1365 
1366                 // Cannot handle three-component images in shader layout classifier
1367                 if (getNumUsedChannels(featuredFormat) == 3)
1368                     continue;
1369 
1370                 const std::string testName      = getFormatShortString(featuredFormat);
1371                 const TestParameters parameters = {
1372                     static_cast<Operation>(operationNdx), // Operation                operation
1373                     UVec3(16u, 16u, 1u),                  // UVec3                    size
1374                     IMAGE_TYPE_2D,                        // ImageType                imageType
1375                     testedImageUsageFlags[operationNdx],  // VkImageUsageFlagBits        testedImageUsageFeature
1376                     featuredFormat,                       // VkFormat                    featuredFormat
1377                     featurelessFormat,                    // VkFormat                    featurelessFormat
1378                     baseFlagsAddOn | testedImageUsageFlags[operationNdx], // VkImageUsageFlags        testedImageUsage
1379                     baseFlagsAddOn | pairedImageUsageFlags[operationNdx], // VkImageUsageFlags        pairedImageUsage
1380                     compatibleFormatsList[groupNdx] // const VkFormat*            compatibleFormats
1381                 };
1382 
1383                 imageOperationGroup->addChild(new ImageTranscodingCase(testCtx, testName, parameters));
1384             }
1385         }
1386 
1387         imageTranscodingTests->addChild(imageOperationGroup.release());
1388     }
1389 
1390     return imageTranscodingTests.release();
1391 }
1392 
1393 } // namespace image
1394 } // namespace vkt
1395