1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2022 Google 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 vktImageTransfer.cpp
21 * \brief Tests for image transfers
22 *//*--------------------------------------------------------------------*/
23
24 #include "vktTestCase.hpp"
25
26 #include "vkImageUtil.hpp"
27 #include "vkBarrierUtil.hpp"
28 #include "vkTypeUtil.hpp"
29 #include "vkCmdUtil.hpp"
30 #include "vkStrUtil.hpp"
31 #include "vkBufferWithMemory.hpp"
32 #include "vkImageWithMemory.hpp"
33
34 #include "tcuTestLog.hpp"
35 #include "vktTestCase.hpp"
36 #include "tcuTextureUtil.hpp"
37 #include "tcuCommandLine.hpp"
38 #include "vktImageTestsUtil.hpp"
39 #include "vkRefUtil.hpp"
40 #include "deRandom.hpp"
41 #include "ycbcr/vktYCbCrUtil.hpp"
42
43 #include <vector>
44 #include <string>
45
46 using namespace vk;
47
48 namespace vkt
49 {
50 using namespace ycbcr;
51 namespace image
52 {
53 namespace
54 {
55
56 class TransferQueueCase : public vkt::TestCase
57 {
58 public:
59 struct TestParams
60 {
61 VkImageType imageType;
62 VkFormat imageFormat;
63 VkExtent3D dimensions; // .depth will be the number of layers for 2D images and the depth for 3D images.
64 };
65
66 TransferQueueCase(tcu::TestContext &testCtx, const std::string &name, const TestParams ¶ms);
~TransferQueueCase(void)67 virtual ~TransferQueueCase(void)
68 {
69 }
70
initPrograms(vk::SourceCollections &) const71 virtual void initPrograms(vk::SourceCollections &) const
72 {
73 }
74 virtual TestInstance *createInstance(Context &context) const;
75 virtual void checkSupport(Context &context) const;
76
77 private:
78 TestParams m_params;
79 };
80
81 class TransferQueueInstance : public vkt::TestInstance
82 {
83 public:
84 TransferQueueInstance(Context &context, const TransferQueueCase::TestParams ¶ms);
~TransferQueueInstance(void)85 virtual ~TransferQueueInstance(void)
86 {
87 }
88
89 virtual tcu::TestStatus iterate(void);
90
91 private:
92 TransferQueueCase::TestParams m_params;
93 Move<VkCommandPool> m_cmdPool;
94 Move<VkCommandBuffer> m_cmdBuffer;
95 };
96
TransferQueueCase(tcu::TestContext & testCtx,const std::string & name,const TestParams & params)97 TransferQueueCase::TransferQueueCase(tcu::TestContext &testCtx, const std::string &name, const TestParams ¶ms)
98 : vkt::TestCase(testCtx, name)
99 , m_params(params)
100 {
101 }
102
createInstance(Context & context) const103 TestInstance *TransferQueueCase::createInstance(Context &context) const
104 {
105 return new TransferQueueInstance(context, m_params);
106 }
107
checkSupport(Context & context) const108 void TransferQueueCase::checkSupport(Context &context) const
109 {
110 const auto &vki = context.getInstanceInterface();
111 const auto physicalDevice = context.getPhysicalDevice();
112
113 #ifndef CTS_USES_VULKANSC
114 if (m_params.imageFormat == VK_FORMAT_A8_UNORM_KHR || m_params.imageFormat == VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR)
115 context.requireDeviceFunctionality("VK_KHR_maintenance5");
116 #endif // CTS_USES_VULKANSC
117
118 VkImageFormatProperties formatProperties;
119 const auto result = vki.getPhysicalDeviceImageFormatProperties(
120 physicalDevice, m_params.imageFormat, m_params.imageType, VK_IMAGE_TILING_OPTIMAL,
121 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0u, &formatProperties);
122 if (result != VK_SUCCESS)
123 {
124 if (result == VK_ERROR_FORMAT_NOT_SUPPORTED)
125 TCU_THROW(NotSupportedError,
126 "format " + de::toString(m_params.imageFormat) + " does not support the required features");
127 else
128 TCU_FAIL("vkGetPhysicalDeviceImageFormatProperties returned unexpected error");
129 }
130 }
131
TransferQueueInstance(Context & context,const TransferQueueCase::TestParams & params)132 TransferQueueInstance::TransferQueueInstance(Context &context, const TransferQueueCase::TestParams ¶ms)
133 : vkt::TestInstance(context)
134 , m_params(params)
135 {
136 const auto &vk = context.getDeviceInterface();
137 const auto &device = context.getDevice();
138 const uint32_t queueFamilyIndex = context.getUniversalQueueFamilyIndex();
139
140 // Create command pool
141 m_cmdPool = createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
142
143 // Create command buffer
144 m_cmdBuffer = allocateCommandBuffer(vk, device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
145 }
146
iterate(void)147 tcu::TestStatus TransferQueueInstance::iterate(void)
148 {
149 // Test every aspect supported by the image format.
150 const auto tcuFormat = mapVkFormat(m_params.imageFormat);
151
152 Allocator &allocator = m_context.getDefaultAllocator();
153 const auto &vk = m_context.getDeviceInterface();
154 const auto device = m_context.getDevice();
155 const auto queue =
156 getDeviceQueue(m_context.getDeviceInterface(), device, m_context.getUniversalQueueFamilyIndex(), 0u);
157
158 const auto width = m_params.dimensions.width;
159 const auto height = m_params.dimensions.height;
160 const auto layers = m_params.imageType == vk::VK_IMAGE_TYPE_3D ? 1u : m_params.dimensions.depth;
161 const auto depth = m_params.imageType == vk::VK_IMAGE_TYPE_3D ? m_params.dimensions.depth : 1u;
162 const uint32_t pixelDataSize = tcuFormat.getPixelSize() * width * height * layers * depth;
163
164 const vk::VkBufferCreateInfo bufferCreateInfo = {
165 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
166 DE_NULL,
167 0u, // flags
168 static_cast<VkDeviceSize>(pixelDataSize), // size
169 vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT | vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT, // usage
170 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
171 0u, // queueFamilyCount
172 DE_NULL, // pQueueFamilyIndices
173 };
174
175 BufferWithMemory srcBuffer(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible);
176 BufferWithMemory dstBuffer(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible);
177
178 vk::VkExtent3D extent = {m_params.dimensions.width, m_params.dimensions.height, depth};
179 const vk::VkImageCreateInfo imageCreateInfo = {
180 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
181 DE_NULL, // const void* pNext;
182 0, // VkImageCreateFlags flags;
183 m_params.imageType, // VkImageType imageType;
184 m_params.imageFormat, // VkFormat format;
185 extent, // VkExtent3D extent;
186 1u, // uint32_t mipLevels;
187 layers, // uint32_t arraySize;
188 VK_SAMPLE_COUNT_1_BIT, // uint32_t samples;
189 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
190 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
191 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
192 0u, // uint32_t queueFamilyIndexCount;
193 (const uint32_t *)DE_NULL, // const uint32_t* pQueueFamilyIndices;
194 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
195 };
196 Image image(vk, device, allocator, imageCreateInfo, MemoryRequirement::Any);
197
198 // Generate data for source buffer and copy it into buffer
199 std::vector<uint8_t> generatedData(pixelDataSize);
200 de::Random randomGen(deInt32Hash((uint32_t)m_params.imageFormat) ^ deInt32Hash((uint32_t)m_params.imageType) ^
201 deInt32Hash((uint32_t)m_params.dimensions.width) ^
202 deInt32Hash((uint32_t)m_params.dimensions.height) ^
203 deInt32Hash((uint32_t)m_params.dimensions.depth));
204 {
205 fillRandomNoNaN(&randomGen, generatedData.data(), (uint32_t)generatedData.size(), m_params.imageFormat);
206 const Allocation &alloc = srcBuffer.getAllocation();
207 deMemcpy(alloc.getHostPtr(), generatedData.data(), generatedData.size());
208 flushAlloc(vk, device, alloc);
209 }
210
211 beginCommandBuffer(vk, *m_cmdBuffer);
212 const VkImageSubresourceRange subresourceRange =
213 makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, layers);
214 const VkImageMemoryBarrier imageBarrier = makeImageMemoryBarrier(
215 0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, *image, subresourceRange);
216 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
217 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
218 (const VkBufferMemoryBarrier *)DE_NULL, 1u, &imageBarrier);
219 // Copy buffer to image
220 {
221 const bool isCompressed = isCompressedFormat(m_params.imageFormat);
222 const uint32_t blockHeight = (isCompressed) ? getBlockHeight(m_params.imageFormat) : 1u;
223 uint32_t imageHeight = ((height + blockHeight - 1) / blockHeight) * blockHeight;
224
225 const vk::VkBufferImageCopy copyRegion = {
226 0u, // VkDeviceSize bufferOffset;
227 0, // uint32_t bufferRowLength;
228 imageHeight, // uint32_t bufferImageHeight;
229 {
230 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect;
231 0, // uint32_t mipLevel;
232 0u, // uint32_t baseArrayLayer;
233 layers, // uint32_t layerCount;
234 }, // VkImageSubresourceLayers imageSubresource;
235 {0, 0, 0}, // VkOffset3D imageOffset;
236 extent // VkExtent3D imageExtent;
237 };
238
239 const VkImageMemoryBarrier postImageBarrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
240 DE_NULL, // const void* pNext;
241 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
242 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
243 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout oldLayout;
244 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout;
245 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
246 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
247 *image, // VkImage image;
248 {
249 // VkImageSubresourceRange subresourceRange;
250 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect;
251 0u, // uint32_t baseMipLevel;
252 1, // uint32_t mipLevels;
253 0u, // uint32_t baseArraySlice;
254 layers, // uint32_t arraySize;
255 }};
256
257 vk.cmdCopyBufferToImage(*m_cmdBuffer, *srcBuffer, *image, VK_IMAGE_LAYOUT_GENERAL, 1, ©Region);
258
259 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
260 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
261 (const VkBufferMemoryBarrier *)DE_NULL, 1, &postImageBarrier);
262
263 vk.cmdCopyImageToBuffer(*m_cmdBuffer, *image, VK_IMAGE_LAYOUT_GENERAL, *dstBuffer, 1, ©Region);
264 }
265 endCommandBuffer(vk, *m_cmdBuffer);
266
267 submitCommandsAndWait(vk, device, queue, *m_cmdBuffer);
268
269 {
270 std::vector<uint8_t> resultData(pixelDataSize);
271 const Allocation &alloc = dstBuffer.getAllocation();
272 invalidateAlloc(vk, device, alloc);
273 deMemcpy(resultData.data(), alloc.getHostPtr(), resultData.size());
274
275 for (uint32_t i = 0; i < pixelDataSize; ++i)
276 {
277 if (resultData[i] != generatedData[i])
278 {
279 return tcu::TestStatus::fail("Transfer queue test");
280 }
281 }
282 }
283
284 return tcu::TestStatus::pass("Pass");
285 }
286
287 } // anonymous namespace
288
getAspectFlags(tcu::TextureFormat format)289 VkImageAspectFlags getAspectFlags(tcu::TextureFormat format)
290 {
291 VkImageAspectFlags aspectFlag = 0;
292 aspectFlag |= (tcu::hasDepthComponent(format.order) ? VK_IMAGE_ASPECT_DEPTH_BIT : 0);
293 aspectFlag |= (tcu::hasStencilComponent(format.order) ? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
294
295 if (!aspectFlag)
296 aspectFlag = VK_IMAGE_ASPECT_COLOR_BIT;
297
298 return aspectFlag;
299 }
300
createTransferQueueImageTests(tcu::TestContext & testCtx)301 tcu::TestCaseGroup *createTransferQueueImageTests(tcu::TestContext &testCtx)
302 {
303 de::MovePtr<tcu::TestCaseGroup> layoutTestGroup(new tcu::TestCaseGroup(testCtx, "queue_transfer"));
304
305 struct
306 {
307 VkImageType type;
308 bool array;
309 const char *name;
310 } imageClass[] = {
311 // 2D images
312 {VK_IMAGE_TYPE_2D, false, "2d"},
313 // 2D images with multiple layers
314 {VK_IMAGE_TYPE_2D, true, "2d_array"},
315 // 3D images
316 {VK_IMAGE_TYPE_3D, false, "3d"},
317 };
318
319 struct
320 {
321 VkExtent3D extent;
322 const char *name;
323 const char *desc;
324 } extents[] = {
325 {{4u, 3u, 1u}, "4x3x1", "4x3x1 extent"}, {{16u, 15u, 1u}, "16x15x1", "16x15x1 extent"},
326 {{64u, 31u, 1u}, "64x31x1", "64x31x1 extent"}, {{4u, 3u, 2u}, "4x3x2", "4x3x2extent"},
327 {{16u, 15u, 16u}, "16x15x16", "16x15x16 extent"},
328 };
329
330 VkFormat testFormats[] = {
331 VK_FORMAT_R4G4_UNORM_PACK8,
332 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
333 VK_FORMAT_B4G4R4A4_UNORM_PACK16,
334 VK_FORMAT_R5G6B5_UNORM_PACK16,
335 VK_FORMAT_B5G6R5_UNORM_PACK16,
336 VK_FORMAT_R5G5B5A1_UNORM_PACK16,
337 VK_FORMAT_B5G5R5A1_UNORM_PACK16,
338 VK_FORMAT_A1R5G5B5_UNORM_PACK16,
339 #ifndef CTS_USES_VULKANSC
340 VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR,
341 #endif // CTS_USES_VULKANSC
342 VK_FORMAT_R8_UNORM,
343 VK_FORMAT_R8_SNORM,
344 VK_FORMAT_R8_USCALED,
345 VK_FORMAT_R8_SSCALED,
346 VK_FORMAT_R8_UINT,
347 VK_FORMAT_R8_SINT,
348 VK_FORMAT_R8_SRGB,
349 #ifndef CTS_USES_VULKANSC
350 VK_FORMAT_A8_UNORM_KHR,
351 #endif // CTS_USES_VULKANSC
352 VK_FORMAT_R8G8_UNORM,
353 VK_FORMAT_R8G8_SNORM,
354 VK_FORMAT_R8G8_USCALED,
355 VK_FORMAT_R8G8_SSCALED,
356 VK_FORMAT_R8G8_UINT,
357 VK_FORMAT_R8G8_SINT,
358 VK_FORMAT_R8G8_SRGB,
359 VK_FORMAT_R8G8B8_UNORM,
360 VK_FORMAT_R8G8B8_SNORM,
361 VK_FORMAT_R8G8B8_USCALED,
362 VK_FORMAT_R8G8B8_SSCALED,
363 VK_FORMAT_R8G8B8_UINT,
364 VK_FORMAT_R8G8B8_SINT,
365 VK_FORMAT_R8G8B8_SRGB,
366 VK_FORMAT_B8G8R8_UNORM,
367 VK_FORMAT_B8G8R8_SNORM,
368 VK_FORMAT_B8G8R8_USCALED,
369 VK_FORMAT_B8G8R8_SSCALED,
370 VK_FORMAT_B8G8R8_UINT,
371 VK_FORMAT_B8G8R8_SINT,
372 VK_FORMAT_B8G8R8_SRGB,
373 VK_FORMAT_R8G8B8A8_UNORM,
374 VK_FORMAT_R8G8B8A8_SNORM,
375 VK_FORMAT_R8G8B8A8_USCALED,
376 VK_FORMAT_R8G8B8A8_SSCALED,
377 VK_FORMAT_R8G8B8A8_UINT,
378 VK_FORMAT_R8G8B8A8_SINT,
379 VK_FORMAT_R8G8B8A8_SRGB,
380 VK_FORMAT_B8G8R8A8_UNORM,
381 VK_FORMAT_B8G8R8A8_SNORM,
382 VK_FORMAT_B8G8R8A8_USCALED,
383 VK_FORMAT_B8G8R8A8_SSCALED,
384 VK_FORMAT_B8G8R8A8_UINT,
385 VK_FORMAT_B8G8R8A8_SINT,
386 VK_FORMAT_B8G8R8A8_SRGB,
387 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
388 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
389 VK_FORMAT_A8B8G8R8_USCALED_PACK32,
390 VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
391 VK_FORMAT_A8B8G8R8_UINT_PACK32,
392 VK_FORMAT_A8B8G8R8_SINT_PACK32,
393 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
394 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
395 VK_FORMAT_A2R10G10B10_SNORM_PACK32,
396 VK_FORMAT_A2R10G10B10_USCALED_PACK32,
397 VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
398 VK_FORMAT_A2R10G10B10_UINT_PACK32,
399 VK_FORMAT_A2R10G10B10_SINT_PACK32,
400 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
401 VK_FORMAT_A2B10G10R10_SNORM_PACK32,
402 VK_FORMAT_A2B10G10R10_USCALED_PACK32,
403 VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
404 VK_FORMAT_A2B10G10R10_UINT_PACK32,
405 VK_FORMAT_A2B10G10R10_SINT_PACK32,
406 VK_FORMAT_R16_UNORM,
407 VK_FORMAT_R16_SNORM,
408 VK_FORMAT_R16_USCALED,
409 VK_FORMAT_R16_SSCALED,
410 VK_FORMAT_R16_UINT,
411 VK_FORMAT_R16_SINT,
412 VK_FORMAT_R16_SFLOAT,
413 VK_FORMAT_R16G16_UNORM,
414 VK_FORMAT_R16G16_SNORM,
415 VK_FORMAT_R16G16_USCALED,
416 VK_FORMAT_R16G16_SSCALED,
417 VK_FORMAT_R16G16_UINT,
418 VK_FORMAT_R16G16_SINT,
419 VK_FORMAT_R16G16_SFLOAT,
420 VK_FORMAT_R16G16B16_UNORM,
421 VK_FORMAT_R16G16B16_SNORM,
422 VK_FORMAT_R16G16B16_USCALED,
423 VK_FORMAT_R16G16B16_SSCALED,
424 VK_FORMAT_R16G16B16_UINT,
425 VK_FORMAT_R16G16B16_SINT,
426 VK_FORMAT_R16G16B16_SFLOAT,
427 VK_FORMAT_R16G16B16A16_UNORM,
428 VK_FORMAT_R16G16B16A16_SNORM,
429 VK_FORMAT_R16G16B16A16_USCALED,
430 VK_FORMAT_R16G16B16A16_SSCALED,
431 VK_FORMAT_R16G16B16A16_UINT,
432 VK_FORMAT_R16G16B16A16_SINT,
433 VK_FORMAT_R16G16B16A16_SFLOAT,
434 VK_FORMAT_R32_UINT,
435 VK_FORMAT_R32_SINT,
436 VK_FORMAT_R32_SFLOAT,
437 VK_FORMAT_R32G32_UINT,
438 VK_FORMAT_R32G32_SINT,
439 VK_FORMAT_R32G32_SFLOAT,
440 VK_FORMAT_R32G32B32_UINT,
441 VK_FORMAT_R32G32B32_SINT,
442 VK_FORMAT_R32G32B32_SFLOAT,
443 VK_FORMAT_R32G32B32A32_UINT,
444 VK_FORMAT_R32G32B32A32_SINT,
445 VK_FORMAT_R32G32B32A32_SFLOAT,
446 VK_FORMAT_R64_UINT,
447 VK_FORMAT_R64_SINT,
448 VK_FORMAT_R64_SFLOAT,
449 VK_FORMAT_R64G64_UINT,
450 VK_FORMAT_R64G64_SINT,
451 VK_FORMAT_R64G64_SFLOAT,
452 VK_FORMAT_R64G64B64_UINT,
453 VK_FORMAT_R64G64B64_SINT,
454 VK_FORMAT_R64G64B64_SFLOAT,
455 VK_FORMAT_R64G64B64A64_UINT,
456 VK_FORMAT_R64G64B64A64_SINT,
457 VK_FORMAT_R64G64B64A64_SFLOAT,
458 };
459
460 for (int classIdx = 0; classIdx < DE_LENGTH_OF_ARRAY(imageClass); ++classIdx)
461 {
462 const auto &imgClass = imageClass[classIdx];
463 de::MovePtr<tcu::TestCaseGroup> classGroup(new tcu::TestCaseGroup(testCtx, imgClass.name));
464
465 for (int extentIdx = 0; extentIdx < DE_LENGTH_OF_ARRAY(extents); ++extentIdx)
466 {
467 const auto &extent = extents[extentIdx];
468 de::MovePtr<tcu::TestCaseGroup> mipGroup(new tcu::TestCaseGroup(testCtx, extent.name));
469
470 for (int formatIdx = 0; formatIdx < DE_LENGTH_OF_ARRAY(testFormats); ++formatIdx)
471 {
472 static const auto prefixLen = std::string("VK_FORMAT_").size();
473 const auto format = testFormats[formatIdx];
474 const auto fmtName = std::string(getFormatName(format));
475 const auto name = de::toLower(fmtName.substr(prefixLen)); // Remove VK_FORMAT_ prefix.
476
477 TransferQueueCase::TestParams params;
478 params.imageFormat = format;
479 params.imageType = imgClass.type;
480 params.dimensions = {extent.extent.width, extent.extent.height, extent.extent.depth};
481
482 mipGroup->addChild(new TransferQueueCase(testCtx, name, params));
483 }
484
485 classGroup->addChild(mipGroup.release());
486 }
487
488 layoutTestGroup->addChild(classGroup.release());
489 }
490
491 return layoutTestGroup.release();
492 }
493
494 } // namespace image
495 } // namespace vkt
496