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 ¶meters);
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 ¶meters)
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 ¶meters);
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 ¶meters)
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, ©Barrier, 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 ¶meters);
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 ¶meters)
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, ©Barrier, 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 ¶meters);
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 ¶meters)
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