1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2017 The Khronos Group Inc.
6  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief Protected content copy image tests
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktProtectedMemCopyImageTests.hpp"
26 
27 #include "deRandom.hpp"
28 #include "tcuTestLog.hpp"
29 #include "tcuVector.hpp"
30 #include "tcuVectorUtil.hpp"
31 
32 #include "vkPrograms.hpp"
33 #include "vktTestCase.hpp"
34 #include "vktTestGroupUtil.hpp"
35 #include "vkTypeUtil.hpp"
36 #include "vkBuilderUtil.hpp"
37 #include "vkCmdUtil.hpp"
38 
39 #include "vktProtectedMemContext.hpp"
40 #include "vktProtectedMemUtils.hpp"
41 #include "vktProtectedMemImageValidator.hpp"
42 
43 namespace vkt
44 {
45 namespace ProtectedMem
46 {
47 
48 namespace
49 {
50 
51 enum
52 {
53     RENDER_WIDTH  = 128,
54     RENDER_HEIGHT = 128,
55 };
56 
57 class CopyImageTestInstance : public ProtectedTestInstance
58 {
59 public:
60     CopyImageTestInstance(Context &ctx, const vk::VkClearColorValue &clearColorValue, const ValidationData &refData,
61                           const ImageValidator &validator, const CmdBufferType cmdBufferType);
62     virtual tcu::TestStatus iterate(void);
63 
64 private:
65     const vk::VkFormat m_imageFormat;
66     const vk::VkClearColorValue &m_clearColorValue;
67     const ValidationData &m_refData;
68     const ImageValidator &m_validator;
69     const CmdBufferType m_cmdBufferType;
70 };
71 
72 class CopyImageTestCase : public TestCase
73 {
74 public:
CopyImageTestCase(tcu::TestContext & testCtx,const std::string & name,vk::VkClearColorValue clearColorValue,ValidationData data,CmdBufferType cmdBufferType)75     CopyImageTestCase(tcu::TestContext &testCtx, const std::string &name, vk::VkClearColorValue clearColorValue,
76                       ValidationData data, CmdBufferType cmdBufferType)
77         : TestCase(testCtx, name)
78         , m_clearColorValue(clearColorValue)
79         , m_refData(data)
80         , m_cmdBufferType(cmdBufferType)
81     {
82     }
83 
~CopyImageTestCase(void)84     virtual ~CopyImageTestCase(void)
85     {
86     }
createInstance(Context & ctx) const87     virtual TestInstance *createInstance(Context &ctx) const
88     {
89         return new CopyImageTestInstance(ctx, m_clearColorValue, m_refData, m_validator, m_cmdBufferType);
90     }
initPrograms(vk::SourceCollections & programCollection) const91     virtual void initPrograms(vk::SourceCollections &programCollection) const
92     {
93         m_validator.initPrograms(programCollection);
94     }
checkSupport(Context & context) const95     virtual void checkSupport(Context &context) const
96     {
97         checkProtectedQueueSupport(context);
98 #ifdef CTS_USES_VULKANSC
99         if (m_cmdBufferType == CMD_BUFFER_SECONDARY &&
100             context.getDeviceVulkanSC10Properties().secondaryCommandBufferNullOrImagelessFramebuffer == VK_FALSE)
101             TCU_THROW(NotSupportedError, "secondaryCommandBufferNullFramebuffer is not supported");
102 #endif // CTS_USES_VULKANSC
103     }
104 
105 private:
106     vk::VkClearColorValue m_clearColorValue;
107     ValidationData m_refData;
108     ImageValidator m_validator;
109     CmdBufferType m_cmdBufferType;
110 };
111 
CopyImageTestInstance(Context & ctx,const vk::VkClearColorValue & clearColorValue,const ValidationData & refData,const ImageValidator & validator,const CmdBufferType cmdBufferType)112 CopyImageTestInstance::CopyImageTestInstance(Context &ctx, const vk::VkClearColorValue &clearColorValue,
113                                              const ValidationData &refData, const ImageValidator &validator,
114                                              const CmdBufferType cmdBufferType)
115     : ProtectedTestInstance(ctx)
116     , m_imageFormat(vk::VK_FORMAT_R8G8B8A8_UNORM)
117     , m_clearColorValue(clearColorValue)
118     , m_refData(refData)
119     , m_validator(validator)
120     , m_cmdBufferType(cmdBufferType)
121 {
122 }
123 
iterate()124 tcu::TestStatus CopyImageTestInstance::iterate()
125 {
126     ProtectedContext &ctx(m_protectedContext);
127     const vk::DeviceInterface &vk   = ctx.getDeviceInterface();
128     const vk::VkDevice device       = ctx.getDevice();
129     const vk::VkQueue queue         = ctx.getQueue();
130     const uint32_t queueFamilyIndex = ctx.getQueueFamilyIndex();
131 
132     // Create images
133     de::MovePtr<vk::ImageWithMemory> colorImage =
134         createImage2D(ctx, PROTECTION_ENABLED, queueFamilyIndex, RENDER_WIDTH, RENDER_HEIGHT, m_imageFormat,
135                       vk::VK_IMAGE_USAGE_SAMPLED_BIT | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
136     de::MovePtr<vk::ImageWithMemory> colorImageSrc = createImage2D(
137         ctx, PROTECTION_ENABLED, queueFamilyIndex, RENDER_WIDTH, RENDER_HEIGHT, m_imageFormat,
138         vk::VK_IMAGE_USAGE_SAMPLED_BIT | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
139 
140     vk::Unique<vk::VkPipelineLayout> pipelineLayout(createPipelineLayout(ctx, 0u, DE_NULL));
141 
142     vk::Unique<vk::VkCommandPool> cmdPool(makeCommandPool(vk, device, PROTECTION_ENABLED, queueFamilyIndex));
143     vk::Unique<vk::VkCommandBuffer> cmdBuffer(
144         vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
145     vk::Unique<vk::VkCommandBuffer> secondaryCmdBuffer(
146         vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_SECONDARY));
147     vk::VkCommandBuffer targetCmdBuffer = (m_cmdBufferType == CMD_BUFFER_SECONDARY) ? *secondaryCmdBuffer : *cmdBuffer;
148 
149     // Begin cmd buffer
150     beginCommandBuffer(vk, *cmdBuffer);
151 
152     if (m_cmdBufferType == CMD_BUFFER_SECONDARY)
153     {
154         // Begin secondary command buffer
155         const vk::VkCommandBufferInheritanceInfo secCmdBufInheritInfo = {
156             vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
157             DE_NULL,
158             (vk::VkRenderPass)0u,                  // renderPass
159             0u,                                    // subpass
160             (vk::VkFramebuffer)0u,                 // framebuffer
161             VK_FALSE,                              // occlusionQueryEnable
162             (vk::VkQueryControlFlags)0u,           // queryFlags
163             (vk::VkQueryPipelineStatisticFlags)0u, // pipelineStatistics
164         };
165         beginSecondaryCommandBuffer(vk, *secondaryCmdBuffer, secCmdBufInheritInfo);
166     }
167 
168     // Start image barrier for source image.
169     {
170         const vk::VkImageMemoryBarrier startImgBarrier = {vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
171                                                           DE_NULL,                                    // pNext
172                                                           0,                                          // srcAccessMask
173                                                           vk::VK_ACCESS_TRANSFER_WRITE_BIT,           // dstAccessMask
174                                                           vk::VK_IMAGE_LAYOUT_UNDEFINED,              // oldLayout
175                                                           vk::VK_IMAGE_LAYOUT_GENERAL,                // newLayout
176                                                           queueFamilyIndex, // srcQueueFamilyIndex
177                                                           queueFamilyIndex, // dstQueueFamilyIndex
178                                                           **colorImageSrc,  // image
179                                                           {
180                                                               vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
181                                                               0u,                            // baseMipLevel
182                                                               1u,                            // mipLevels
183                                                               0u,                            // baseArraySlice
184                                                               1u,                            // subresourceRange
185                                                           }};
186 
187         vk.cmdPipelineBarrier(
188             targetCmdBuffer,                               // commandBuffer
189             vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,         // srcStageMask
190             vk::VK_PIPELINE_STAGE_TRANSFER_BIT,            // dstStageMask
191             (vk::VkDependencyFlags)0,                      // dependencyFlags
192             0, (const vk::VkMemoryBarrier *)DE_NULL,       // memoryBarrierCount, pMemoryBarriers
193             0, (const vk::VkBufferMemoryBarrier *)DE_NULL, // bufferMemoryBarrierCount, pBufferMemoryBarriers
194             1, &startImgBarrier);                          // imageMemoryBarrierCount, pImageMemoryBarriers
195     }
196 
197     // Image clear
198     const vk::VkImageSubresourceRange subresourceRange = {
199         vk::VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags    aspectMask
200         0u,                            // uint32_t                baseMipLevel
201         1u,                            // uint32_t                levelCount
202         0u,                            // uint32_t                baseArrayLayer
203         1u,                            // uint32_t                layerCount
204     };
205     vk.cmdClearColorImage(targetCmdBuffer, **colorImageSrc, vk::VK_IMAGE_LAYOUT_GENERAL, &m_clearColorValue, 1,
206                           &subresourceRange);
207 
208     // Image barrier to change accessMask to transfer read bit for source image.
209     {
210         const vk::VkImageMemoryBarrier initializeBarrier = {vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
211                                                             DE_NULL,                                    // pNext
212                                                             vk::VK_ACCESS_TRANSFER_WRITE_BIT,           // srcAccessMask
213                                                             vk::VK_ACCESS_TRANSFER_READ_BIT,            // dstAccessMask
214                                                             vk::VK_IMAGE_LAYOUT_GENERAL,                // oldLayout
215                                                             vk::VK_IMAGE_LAYOUT_GENERAL,                // newLayout
216                                                             queueFamilyIndex, // srcQueueFamilyIndex
217                                                             queueFamilyIndex, // dstQueueFamilyIndex
218                                                             **colorImageSrc,  // image
219                                                             {
220                                                                 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
221                                                                 0u,                            // baseMipLevel
222                                                                 1u,                            // mipLevels
223                                                                 0u,                            // baseArraySlice
224                                                                 1u,                            // subresourceRange
225                                                             }};
226 
227         vk.cmdPipelineBarrier(targetCmdBuffer,
228                               vk::VK_PIPELINE_STAGE_TRANSFER_BIT, // srcStageMask
229                               vk::VK_PIPELINE_STAGE_TRANSFER_BIT, // dstStageMask
230                               (vk::VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier *)DE_NULL, 0,
231                               (const vk::VkBufferMemoryBarrier *)DE_NULL, 1, &initializeBarrier);
232     }
233 
234     // Image barrier for destination image.
235     {
236         const vk::VkImageMemoryBarrier initializeBarrier = {vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
237                                                             DE_NULL,                                    // pNext
238                                                             0,                                          // srcAccessMask
239                                                             vk::VK_ACCESS_TRANSFER_WRITE_BIT,           // dstAccessMask
240                                                             vk::VK_IMAGE_LAYOUT_UNDEFINED,              // oldLayout
241                                                             vk::VK_IMAGE_LAYOUT_GENERAL,                // newLayout
242                                                             queueFamilyIndex, // srcQueueFamilyIndex
243                                                             queueFamilyIndex, // dstQueueFamilyIndex
244                                                             **colorImage,     // image
245                                                             {
246                                                                 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
247                                                                 0u,                            // baseMipLevel
248                                                                 1u,                            // mipLevels
249                                                                 0u,                            // baseArraySlice
250                                                                 1u,                            // subresourceRange
251                                                             }};
252 
253         vk.cmdPipelineBarrier(targetCmdBuffer,
254                               vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // srcStageMask
255                               vk::VK_PIPELINE_STAGE_TRANSFER_BIT,    // dstStageMask
256                               (vk::VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier *)DE_NULL, 0,
257                               (const vk::VkBufferMemoryBarrier *)DE_NULL, 1, &initializeBarrier);
258     }
259 
260     // Copy image
261     const vk::VkImageSubresourceLayers imgSubResCopy = {
262         vk::VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
263         0u,                            // uint32_t mipLevel;
264         0u,                            // uint32_t baseArrayLayer;
265         1u,                            // uint32_t layerCount;
266     };
267     const vk::VkOffset3D nullOffset       = {0u, 0u, 0u};
268     const vk::VkExtent3D imageExtent      = {(uint32_t)RENDER_WIDTH, (uint32_t)RENDER_HEIGHT, 1u};
269     const vk::VkImageCopy copyImageRegion = {
270         imgSubResCopy, // VkImageSubresourceCopy srcSubresource;
271         nullOffset,    // VkOffset3D srcOffset;
272         imgSubResCopy, // VkImageSubresourceCopy destSubresource;
273         nullOffset,    // VkOffset3D destOffset;
274         imageExtent,   // VkExtent3D extent;
275 
276     };
277     vk.cmdCopyImage(targetCmdBuffer, **colorImageSrc, vk::VK_IMAGE_LAYOUT_GENERAL, // srcImageLayout
278                     **colorImage, vk::VK_IMAGE_LAYOUT_GENERAL,                     // dstImageLayout
279                     1u, &copyImageRegion);
280 
281     // Image barrier to change accessMask for destination image.
282     {
283         const vk::VkImageMemoryBarrier endImgBarrier = {vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,   // sType
284                                                         DE_NULL,                                      // pNext
285                                                         vk::VK_ACCESS_TRANSFER_WRITE_BIT,             // srcAccessMask
286                                                         vk::VK_ACCESS_SHADER_READ_BIT,                // dstAccessMask
287                                                         vk::VK_IMAGE_LAYOUT_GENERAL,                  // oldLayout
288                                                         vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // newLayout
289                                                         queueFamilyIndex, // srcQueueFamilyIndex
290                                                         queueFamilyIndex, // dstQueueFamilyIndex
291                                                         **colorImage,     // image
292                                                         {
293                                                             vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
294                                                             0u,                            // baseMipLevel
295                                                             1u,                            // mipLevels
296                                                             0u,                            // baseArraySlice
297                                                             1u,                            // subresourceRange
298                                                         }};
299         vk.cmdPipelineBarrier(targetCmdBuffer,
300                               vk::VK_PIPELINE_STAGE_TRANSFER_BIT,     // srcStageMask
301                               vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, // dstStageMask
302                               (vk::VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier *)DE_NULL, 0,
303                               (const vk::VkBufferMemoryBarrier *)DE_NULL, 1, &endImgBarrier);
304     }
305 
306     if (m_cmdBufferType == CMD_BUFFER_SECONDARY)
307     {
308         endCommandBuffer(vk, *secondaryCmdBuffer);
309         vk.cmdExecuteCommands(*cmdBuffer, 1u, &secondaryCmdBuffer.get());
310     }
311 
312     endCommandBuffer(vk, *cmdBuffer);
313 
314     // Submit command buffer
315     const vk::Unique<vk::VkFence> fence(vk::createFence(vk, device));
316     VK_CHECK(queueSubmit(ctx, PROTECTION_ENABLED, queue, *cmdBuffer, *fence, ~0ull));
317 
318     // Log out test data
319     ctx.getTestContext().getLog() << tcu::TestLog::Message
320                                   << "Color clear value: " << tcu::Vec4(m_clearColorValue.float32)
321                                   << tcu::TestLog::EndMessage;
322 
323     // Validate resulting image
324     if (m_validator.validateImage(ctx, m_refData, **colorImage, m_imageFormat,
325                                   vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL))
326         return tcu::TestStatus::pass("Everything went OK");
327     else
328         return tcu::TestStatus::fail("Something went really wrong");
329 }
330 
createCopyImageTests(tcu::TestContext & testCtx,CmdBufferType cmdBufferType)331 tcu::TestCaseGroup *createCopyImageTests(tcu::TestContext &testCtx, CmdBufferType cmdBufferType)
332 {
333     struct
334     {
335         const vk::VkClearColorValue clearColorValue;
336         const ValidationData data;
337     } testData[] = {
338         {{{1.0f, 0.0f, 0.0f, 1.0f}},
339          {{
340               tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
341               tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
342               tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f),
343               tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f),
344           },
345           {
346               tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
347               tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
348               tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
349               tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
350           }}},
351         {{{0.0f, 1.0f, 0.0f, 1.0f}},
352          {{
353               tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
354               tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
355               tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f),
356               tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f),
357           },
358           {
359               tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
360               tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
361               tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
362               tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
363           }}},
364         {{{0.0f, 0.0f, 1.0f, 1.0f}},
365          {{
366               tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
367               tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
368               tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f),
369               tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f),
370           },
371           {
372               tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
373               tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
374               tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
375               tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
376           }}},
377         {{{0.0f, 0.0f, 0.0f, 1.0f}},
378          {{
379               tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
380               tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
381               tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f),
382               tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f),
383           },
384           {
385               tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
386               tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
387               tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
388               tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
389           }}},
390         {{{1.0f, 0.0f, 0.0f, 1.0f}},
391          {{
392               tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
393               tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
394               tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f),
395               tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f),
396           },
397           {
398               tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
399               tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
400               tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
401               tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
402           }}},
403         {{{1.0f, 0.0f, 0.0f, 0.0f}},
404          {{
405               tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
406               tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
407               tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f),
408               tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f),
409           },
410           {
411               tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f),
412               tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f),
413               tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f),
414               tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f),
415           }}},
416         {{{0.1f, 0.2f, 0.3f, 0.0f}},
417          {{
418               tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
419               tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
420               tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f),
421               tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f),
422           },
423           {
424               tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f),
425               tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f),
426               tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f),
427               tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f),
428           }}},
429     };
430 
431     // Copy Image Tests with static input
432     de::MovePtr<tcu::TestCaseGroup> copyStaticTests(new tcu::TestCaseGroup(testCtx, "static"));
433 
434     for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(testData); ++ndx)
435     {
436         const std::string name = "copy_" + de::toString(ndx + 1);
437         copyStaticTests->addChild(new CopyImageTestCase(testCtx, name.c_str(), testData[ndx].clearColorValue,
438                                                         testData[ndx].data, cmdBufferType));
439     }
440 
441     /* Add a few randomized tests */
442     // Copy Image Tests with random input
443     de::MovePtr<tcu::TestCaseGroup> copyRandomTests(new tcu::TestCaseGroup(testCtx, "random"));
444     const int testCount = 10;
445     de::Random rnd(testCtx.getCommandLine().getBaseSeed());
446     for (int ndx = 0; ndx < testCount; ++ndx)
447     {
448         const std::string name      = "copy_" + de::toString(ndx + 1);
449         vk::VkClearValue clearValue = vk::makeClearValueColorVec4(tcu::randomVec4(rnd));
450         const tcu::Vec4 refValue(clearValue.color.float32[0], clearValue.color.float32[1], clearValue.color.float32[2],
451                                  clearValue.color.float32[3]);
452         const tcu::Vec4 vec0 = tcu::randomVec4(rnd);
453         const tcu::Vec4 vec1 = tcu::randomVec4(rnd);
454         const tcu::Vec4 vec2 = tcu::randomVec4(rnd);
455         const tcu::Vec4 vec3 = tcu::randomVec4(rnd);
456 
457         ValidationData data = {{vec0, vec1, vec2, vec3}, {refValue, refValue, refValue, refValue}};
458         copyRandomTests->addChild(new CopyImageTestCase(testCtx, name.c_str(), clearValue.color, data, cmdBufferType));
459     }
460 
461     std::string groupName = getCmdBufferTypeStr(cmdBufferType);
462     de::MovePtr<tcu::TestCaseGroup> copyTests(new tcu::TestCaseGroup(testCtx, groupName.c_str()));
463     copyTests->addChild(copyStaticTests.release());
464     copyTests->addChild(copyRandomTests.release());
465     return copyTests.release();
466 }
467 
468 } // namespace
469 
createCopyImageTests(tcu::TestContext & testCtx)470 tcu::TestCaseGroup *createCopyImageTests(tcu::TestContext &testCtx)
471 {
472     de::MovePtr<tcu::TestCaseGroup> copyTests(new tcu::TestCaseGroup(testCtx, "copy"));
473 
474     copyTests->addChild(createCopyImageTests(testCtx, CMD_BUFFER_PRIMARY));
475     copyTests->addChild(createCopyImageTests(testCtx, CMD_BUFFER_SECONDARY));
476 
477     return copyTests.release();
478 }
479 
480 } // namespace ProtectedMem
481 } // namespace vkt
482