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