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 memory blit image tests
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktProtectedMemBlitImageTests.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 BlitImageTestInstance : public ProtectedTestInstance
58 {
59 public:
60     BlitImageTestInstance(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 BlitImageTestCase : public TestCase
73 {
74 public:
BlitImageTestCase(tcu::TestContext & testCtx,const std::string & name,vk::VkClearColorValue clearColorValue,ValidationData data,CmdBufferType cmdBufferType)75     BlitImageTestCase(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 
~BlitImageTestCase(void)84     virtual ~BlitImageTestCase(void)
85     {
86     }
createInstance(Context & ctx) const87     virtual TestInstance *createInstance(Context &ctx) const
88     {
89         return new BlitImageTestInstance(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
103     }
104 
105 private:
106     vk::VkClearColorValue m_clearColorValue;
107     ValidationData m_refData;
108     ImageValidator m_validator;
109     CmdBufferType m_cmdBufferType;
110 };
111 
BlitImageTestInstance(Context & ctx,const vk::VkClearColorValue & clearColorValue,const ValidationData & refData,const ImageValidator & validator,const CmdBufferType cmdBufferType)112 BlitImageTestInstance::BlitImageTestInstance(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 BlitImageTestInstance::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     // Blit 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::VkOffset3D imageOffset = {RENDER_WIDTH, RENDER_HEIGHT, 1};
269     const vk::VkImageBlit imageBlit  = {
270         imgSubResCopy, // VkImageSubresourceLayers srcSubresource;
271         {
272             nullOffset,
273             imageOffset,
274         },             // VkOffset3D srcOffsets[2];
275         imgSubResCopy, // VkImageSubresourceLayers dstSubresource;
276         {
277             nullOffset,
278             imageOffset,
279         }, // VkOffset3D dstOffsets[2];
280     };
281     vk.cmdBlitImage(targetCmdBuffer, **colorImageSrc, vk::VK_IMAGE_LAYOUT_GENERAL, **colorImage,
282                     vk::VK_IMAGE_LAYOUT_GENERAL, 1u, &imageBlit, vk::VK_FILTER_NEAREST);
283 
284     // Image barrier to change accessMask to shader read bit for destination image.
285     {
286         const vk::VkImageMemoryBarrier endImgBarrier = {vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,   // sType
287                                                         DE_NULL,                                      // pNext
288                                                         vk::VK_ACCESS_TRANSFER_WRITE_BIT,             // srcAccessMask
289                                                         vk::VK_ACCESS_SHADER_READ_BIT,                // dstAccessMask
290                                                         vk::VK_IMAGE_LAYOUT_GENERAL,                  // oldLayout
291                                                         vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // newLayout
292                                                         queueFamilyIndex, // srcQueueFamilyIndex
293                                                         queueFamilyIndex, // dstQueueFamilyIndex
294                                                         **colorImage,     // image
295                                                         {
296                                                             vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
297                                                             0u,                            // baseMipLevel
298                                                             1u,                            // mipLevels
299                                                             0u,                            // baseArraySlice
300                                                             1u,                            // subresourceRange
301                                                         }};
302         vk.cmdPipelineBarrier(targetCmdBuffer,
303                               vk::VK_PIPELINE_STAGE_TRANSFER_BIT,     // srcStageMask
304                               vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, // dstStageMask
305                               (vk::VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier *)DE_NULL, 0,
306                               (const vk::VkBufferMemoryBarrier *)DE_NULL, 1, &endImgBarrier);
307     }
308 
309     if (m_cmdBufferType == CMD_BUFFER_SECONDARY)
310     {
311         endCommandBuffer(vk, *secondaryCmdBuffer);
312         vk.cmdExecuteCommands(*cmdBuffer, 1u, &secondaryCmdBuffer.get());
313     }
314 
315     endCommandBuffer(vk, *cmdBuffer);
316 
317     // Submit command buffer
318     const vk::Unique<vk::VkFence> fence(vk::createFence(vk, device));
319     VK_CHECK(queueSubmit(ctx, PROTECTION_ENABLED, queue, *cmdBuffer, *fence, ~0ull));
320 
321     // Log out test data
322     ctx.getTestContext().getLog() << tcu::TestLog::Message
323                                   << "Color clear value: " << tcu::Vec4(m_clearColorValue.float32)
324                                   << tcu::TestLog::EndMessage;
325 
326     // Validate resulting image
327     if (m_validator.validateImage(ctx, m_refData, **colorImage, m_imageFormat,
328                                   vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL))
329         return tcu::TestStatus::pass("Everything went OK");
330     else
331         return tcu::TestStatus::fail("Something went really wrong");
332 }
333 
createBlitImageTests(tcu::TestContext & testCtx,CmdBufferType cmdBufferType)334 tcu::TestCaseGroup *createBlitImageTests(tcu::TestContext &testCtx, CmdBufferType cmdBufferType)
335 {
336     struct
337     {
338         const vk::VkClearColorValue clearColorValue;
339         const ValidationData data;
340     } testData[] = {
341         {{{1.0f, 0.0f, 0.0f, 1.0f}},
342          {{
343               tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
344               tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
345               tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f),
346               tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f),
347           },
348           {
349               tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
350               tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
351               tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
352               tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
353           }}},
354         {{{0.0f, 1.0f, 0.0f, 1.0f}},
355          {{
356               tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
357               tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
358               tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f),
359               tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f),
360           },
361           {
362               tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
363               tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
364               tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
365               tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
366           }}},
367         {{{0.0f, 0.0f, 1.0f, 1.0f}},
368          {{
369               tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
370               tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
371               tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f),
372               tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f),
373           },
374           {
375               tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
376               tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
377               tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
378               tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
379           }}},
380         {{{0.0f, 0.0f, 0.0f, 1.0f}},
381          {{
382               tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
383               tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
384               tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f),
385               tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f),
386           },
387           {
388               tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
389               tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
390               tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
391               tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
392           }}},
393         {{{1.0f, 0.0f, 0.0f, 1.0f}},
394          {{
395               tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
396               tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
397               tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f),
398               tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f),
399           },
400           {
401               tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
402               tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
403               tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
404               tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
405           }}},
406         {{{1.0f, 0.0f, 0.0f, 0.0f}},
407          {{
408               tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
409               tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
410               tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f),
411               tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f),
412           },
413           {
414               tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f),
415               tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f),
416               tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f),
417               tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f),
418           }}},
419         {{{0.1f, 0.2f, 0.3f, 0.0f}},
420          {{
421               tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
422               tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
423               tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f),
424               tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f),
425           },
426           {
427               tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f),
428               tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f),
429               tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f),
430               tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f),
431           }}},
432     };
433 
434     // Blit Image Tests with static input
435     de::MovePtr<tcu::TestCaseGroup> blitStaticTests(new tcu::TestCaseGroup(testCtx, "static"));
436 
437     for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(testData); ++ndx)
438     {
439         const std::string name = "blit_" + de::toString(ndx + 1);
440         blitStaticTests->addChild(new BlitImageTestCase(testCtx, name.c_str(), testData[ndx].clearColorValue,
441                                                         testData[ndx].data, cmdBufferType));
442     }
443 
444     /* Add a few randomized tests */
445     // Blit Image Tests with random input
446     de::MovePtr<tcu::TestCaseGroup> blitRandomTests(new tcu::TestCaseGroup(testCtx, "random"));
447     const int testCount = 10;
448     de::Random rnd(testCtx.getCommandLine().getBaseSeed());
449     for (int ndx = 0; ndx < testCount; ++ndx)
450     {
451         const std::string name      = "blit_" + de::toString(ndx + 1);
452         vk::VkClearValue clearValue = vk::makeClearValueColorVec4(tcu::randomVec4(rnd));
453         const tcu::Vec4 refValue(clearValue.color.float32[0], clearValue.color.float32[1], clearValue.color.float32[2],
454                                  clearValue.color.float32[3]);
455         const tcu::Vec4 vec0 = tcu::randomVec4(rnd);
456         const tcu::Vec4 vec1 = tcu::randomVec4(rnd);
457         const tcu::Vec4 vec2 = tcu::randomVec4(rnd);
458         const tcu::Vec4 vec3 = tcu::randomVec4(rnd);
459 
460         ValidationData data = {{vec0, vec1, vec2, vec3}, {refValue, refValue, refValue, refValue}};
461         blitRandomTests->addChild(new BlitImageTestCase(testCtx, name.c_str(), clearValue.color, data, cmdBufferType));
462     }
463 
464     std::string groupName = getCmdBufferTypeStr(cmdBufferType);
465     de::MovePtr<tcu::TestCaseGroup> blitTests(new tcu::TestCaseGroup(testCtx, groupName.c_str()));
466     blitTests->addChild(blitStaticTests.release());
467     blitTests->addChild(blitRandomTests.release());
468     return blitTests.release();
469 }
470 
471 } // namespace
472 
createBlitImageTests(tcu::TestContext & testCtx)473 tcu::TestCaseGroup *createBlitImageTests(tcu::TestContext &testCtx)
474 {
475     de::MovePtr<tcu::TestCaseGroup> blitTests(new tcu::TestCaseGroup(testCtx, "blit"));
476 
477     blitTests->addChild(createBlitImageTests(testCtx, CMD_BUFFER_PRIMARY));
478     blitTests->addChild(createBlitImageTests(testCtx, CMD_BUFFER_SECONDARY));
479 
480     return blitTests.release();
481 }
482 
483 } // namespace ProtectedMem
484 } // namespace vkt
485