f5728e0c68ef56d356de77238a54412bbc280639
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / protected_memory / vktProtectedMemUtils.cpp
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 Utility methods
23  *//*--------------------------------------------------------------------*/
24
25 #include "vktProtectedMemUtils.hpp"
26 #include "vktCustomInstancesDevices.hpp"
27
28 #include "deString.h"
29 #include "deRandom.hpp"
30
31 #include "vkDeviceUtil.hpp"
32 #include "vkQueryUtil.hpp"
33 #include "vkTypeUtil.hpp"
34 #include "vkDebugReportUtil.hpp"
35 #include "vkApiVersion.hpp"
36 #include "vkObjUtil.hpp"
37
38 #include "vkPlatform.hpp"
39 #include "vktProtectedMemContext.hpp"
40 #include "vkWsiUtil.hpp"
41 #include "vkObjUtil.hpp"
42
43 namespace vkt
44 {
45
46 using namespace vk;
47
48 namespace ProtectedMem
49 {
50
51 typedef std::vector<vk::VkExtensionProperties> Extensions;
52
53 CustomInstance makeProtectedMemInstance (vkt::Context& context, const std::vector<std::string>& extraExtensions)
54 {
55         const PlatformInterface&        vkp = context.getPlatformInterface();
56         const Extensions                        supportedExtensions(vk::enumerateInstanceExtensionProperties(vkp, DE_NULL));
57         std::vector<std::string>        requiredExtensions = extraExtensions;
58
59         deUint32 apiVersion = context.getUsedApiVersion();
60         if (!isCoreInstanceExtension(apiVersion, "VK_KHR_get_physical_device_properties2"))
61                 requiredExtensions.push_back("VK_KHR_get_physical_device_properties2");
62
63         // extract extension names
64         std::vector<std::string> extensions;
65         for (const auto& e : supportedExtensions)
66                 extensions.push_back(e.extensionName);
67
68         for (const auto& extName : requiredExtensions)
69         {
70                 if (!isInstanceExtensionSupported(apiVersion, extensions, extName))
71                         TCU_THROW(NotSupportedError, (extName + " is not supported").c_str());
72         }
73
74         return createCustomInstanceWithExtensions(context, requiredExtensions);
75 }
76
77 void checkProtectedQueueSupport (Context& context)
78 {
79 #ifdef NOT_PROTECTED
80         return;
81 #endif
82
83         const vk::InstanceInterface&                            vkd                             = context.getInstanceInterface();
84         vk::VkPhysicalDevice                                            physDevice              = context.getPhysicalDevice();
85         std::vector<vk::VkQueueFamilyProperties>        properties;
86         deUint32                                                                        numFamilies             = 0;
87
88         vkd.getPhysicalDeviceQueueFamilyProperties(physDevice, &numFamilies, DE_NULL);
89         DE_ASSERT(numFamilies > 0);
90         properties.resize(numFamilies);
91
92         vkd.getPhysicalDeviceQueueFamilyProperties(physDevice, &numFamilies, properties.data());
93
94         for (auto prop: properties)
95                 if (prop.queueFlags & vk::VK_QUEUE_PROTECTED_BIT)
96                         return;
97
98         TCU_THROW(NotSupportedError, "No protected queue found.");
99 }
100
101 deUint32 chooseProtectedMemQueueFamilyIndex     (const vk::InstanceDriver&      vkd,
102                                                                                          vk::VkPhysicalDevice           physicalDevice,
103                                                                                          vk::VkSurfaceKHR                       surface)
104 {
105         std::vector<vk::VkQueueFamilyProperties>        properties;
106         deUint32                                                                        numFamilies             = 0;
107
108         vkd.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numFamilies, DE_NULL);
109         DE_ASSERT(numFamilies > 0);
110         properties.resize(numFamilies);
111
112         vkd.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numFamilies, properties.data());
113
114         // Get a universal protected queue family index
115         vk::VkQueueFlags        requiredFlags = vk::VK_QUEUE_GRAPHICS_BIT
116                                                                                 | vk::VK_QUEUE_COMPUTE_BIT
117 #ifndef NOT_PROTECTED
118                                                                                 | vk::VK_QUEUE_PROTECTED_BIT
119 #endif
120                                                                                 ;
121         for (size_t idx = 0; idx < properties.size(); ++idx)
122         {
123                 vk::VkQueueFlags        flags = properties[idx].queueFlags;
124
125                 if (surface != DE_NULL
126                         && vk::wsi::getPhysicalDeviceSurfaceSupport(vkd, physicalDevice, (deUint32)idx, surface) == VK_FALSE)
127                         continue; // Skip the queue family index if it does not support the surface
128
129                 if ((flags & requiredFlags) == requiredFlags)
130                         return (deUint32)idx;
131         }
132
133         TCU_THROW(NotSupportedError, "No matching universal protected queue found");
134 }
135
136 vk::Move<vk::VkDevice> makeProtectedMemDevice   (const vk::PlatformInterface&           vkp,
137                                                                                                  vk::VkInstance                                         instance,
138                                                                                                  const vk::InstanceDriver&                      vkd,
139                                                                                                  vk::VkPhysicalDevice                           physicalDevice,
140                                                                                                  const deUint32                                         queueFamilyIndex,
141                                                                                                  const deUint32                                         apiVersion,
142                                                                                                  const std::vector<std::string>&        extraExtensions,
143                                                                                                  bool                                                           validationEnabled)
144 {
145         const Extensions                                        supportedExtensions     (vk::enumerateDeviceExtensionProperties(vkd, physicalDevice, DE_NULL));
146         std::vector<std::string>                        requiredExtensions;
147         std::vector<std::string>                        extensions                      = extraExtensions;
148
149         if (apiVersion < VK_API_VERSION_1_1)
150                 TCU_THROW(NotSupportedError, "Vulkan 1.1 is not supported");
151
152         bool                                                            useYCbCr                        = de::contains(extensions.begin(), extensions.end(), std::string("VK_KHR_sampler_ycbcr_conversion"));
153
154         // Check if the physical device supports the protected memory extension name
155         for (deUint32 ndx = 0; ndx < extensions.size(); ++ndx)
156         {
157                 bool notInCore = !isCoreDeviceExtension(apiVersion, extensions[ndx]);
158                 if (notInCore && !isExtensionSupported(supportedExtensions.begin(), supportedExtensions.end(), RequiredExtension(extensions[ndx])))
159                         TCU_THROW(NotSupportedError, (extensions[ndx] + " is not supported").c_str());
160
161                 if (notInCore)
162                         requiredExtensions.push_back(extensions[ndx]);
163         }
164
165         std::vector<const char*>                        enabledExts                     (requiredExtensions.size());
166         for (size_t idx = 0; idx < requiredExtensions.size(); ++idx)
167         {
168                 enabledExts[idx] = requiredExtensions[idx].c_str();
169         }
170
171         vk::VkPhysicalDeviceSamplerYcbcrConversionFeatures              ycbcrFeature    =
172         {
173                 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES,
174                 DE_NULL,
175                 VK_FALSE
176         };
177         // Check if the protected memory can be enabled on the physical device.
178         vk::VkPhysicalDeviceProtectedMemoryFeatures     protectedFeature =
179         {
180                 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES,        // sType
181                 &ycbcrFeature,                                                                                                          // pNext
182                 VK_FALSE                                                                                                                        // protectedMemory
183         };
184         vk::VkPhysicalDeviceFeatures                                    features;
185         deMemset(&features, 0, sizeof(vk::VkPhysicalDeviceFeatures));
186
187         vk::VkPhysicalDeviceFeatures2                           featuresExt             =
188         {
189                 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,                                       // sType
190                 &protectedFeature,                                                                                                      // pNext
191                 features
192         };
193
194         vkd.getPhysicalDeviceFeatures2(physicalDevice, &featuresExt);
195
196 #ifndef NOT_PROTECTED
197         if (protectedFeature.protectedMemory == VK_FALSE)
198                 TCU_THROW(NotSupportedError, "Protected Memory feature not supported by the device");
199 #endif
200
201         if (useYCbCr && !ycbcrFeature.samplerYcbcrConversion)
202                 TCU_THROW(NotSupportedError, "VK_KHR_sampler_ycbcr_conversion is not supported");
203
204         const float                                                     queuePriorities[]       = { 1.0f };
205         const vk::VkDeviceQueueCreateInfo       queueInfos[]            =
206         {
207                 {
208                         vk::VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
209                         DE_NULL,
210 #ifndef NOT_PROTECTED
211                         (vk::VkDeviceQueueCreateFlags)vk::VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT,
212 #else
213                         (vk::VkDeviceQueueCreateFlags)0u,
214 #endif
215                         queueFamilyIndex,
216                         DE_LENGTH_OF_ARRAY(queuePriorities),
217                         queuePriorities
218                 }
219         };
220
221         const vk::VkDeviceCreateInfo            deviceParams            =
222         {
223                 vk::VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,                                               // sType
224                 &featuresExt,                                                                                                   // pNext
225                 (vk::VkDeviceCreateFlags)0,                                                                             // flags
226                 DE_LENGTH_OF_ARRAY(queueInfos),                                                                 // queueCreateInfosCount
227                 &queueInfos[0],                                                                                                 // pQueueCreateInfos
228                 0u,                                                                                                                             // enabledLayerCount
229                 DE_NULL,                                                                                                                // pEnabledLayerNames
230                 (deUint32)requiredExtensions.size(),                                                    // enabledExtensionCount
231                 requiredExtensions.empty() ? DE_NULL : &enabledExts[0],                 // pEnabledExtensionNames
232                 DE_NULL                                                                                                                 // pEnabledFeatures
233         };
234
235         return createCustomDevice(validationEnabled, vkp, instance, vkd, physicalDevice, &deviceParams, DE_NULL);
236 }
237
238 vk::VkQueue getProtectedQueue   (const vk::DeviceInterface&     vk,
239                                                                  vk::VkDevice                           device,
240                                                                  const deUint32                         queueFamilyIndex,
241                                                                  const deUint32                         queueIdx)
242 {
243         const vk::VkDeviceQueueInfo2    queueInfo       =
244         {
245                 vk::VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2,              // sType
246                 DE_NULL,                                                                                // pNext
247                 vk::VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT,               // flags
248                 queueFamilyIndex,                                                               // queueFamilyIndex
249                 queueIdx,                                                                               // queueIndex
250         };
251
252         (void)queueInfo;
253         vk::VkQueue                                             queue           =
254 #ifndef NOT_PROTECTED
255                                                                                                         vk::getDeviceQueue2(vk, device, &queueInfo);
256 #else
257                                                                                                         vk::getDeviceQueue(vk, device, queueFamilyIndex, 0);
258 #endif
259
260         if (queue == DE_NULL)
261                 TCU_THROW(TestError, "Unable to get a protected queue");
262
263         return queue;
264 }
265
266 de::MovePtr<vk::ImageWithMemory>        createImage2D           (ProtectedContext&              context,
267                                                                                                                  ProtectionMode                 protectionMode,
268                                                                                                                  const deUint32                 queueFamilyIdx,
269                                                                                                                  deUint32                               width,
270                                                                                                                  deUint32                               height,
271                                                                                                                  vk::VkFormat                   format,
272                                                                                                                  vk::VkImageUsageFlags  usageFlags)
273 {
274         const vk::DeviceInterface&      vk                      = context.getDeviceInterface();
275         const vk::VkDevice&                     device          = context.getDevice();
276         vk::Allocator&                          allocator       = context.getDefaultAllocator();
277
278 #ifndef NOT_PROTECTED
279         deUint32                                        flags           = (protectionMode == PROTECTION_ENABLED)
280                                                                                                 ? vk::VK_IMAGE_CREATE_PROTECTED_BIT
281                                                                                                 : (vk::VkImageCreateFlagBits)0u;
282 #else
283         DE_UNREF(protectionMode);
284         deUint32                                        flags           = 0u;
285 #endif
286
287         const vk::VkImageCreateInfo     params          =
288         {
289                 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                // VkStructureType                      stype
290                 DE_NULL,                                                                                // const void*                          pNext
291                 (vk::VkImageCreateFlags)flags,                                  // VkImageCreateFlags           flags
292                 vk::VK_IMAGE_TYPE_2D,                                                   // VkImageType                          imageType
293                 format,                                                                                 // VkFormat                                     format
294                 { width, height, 1 },                                                   // VkExtent3D                           extent
295                 1u,                                                                                             // deUint32                                     mipLevels
296                 1u,                                                                                             // deUint32                                     arrayLayers
297                 vk::VK_SAMPLE_COUNT_1_BIT,                                              // VkSampleCountFlagBits        samples
298                 vk::VK_IMAGE_TILING_OPTIMAL,                                    // VkImageTiling                        tiling
299                 usageFlags,                                                                             // VkImageUsageFlags            usage
300                 vk::VK_SHARING_MODE_EXCLUSIVE,                                  // VkSharingMode                        sharingMode
301                 1u,                                                                                             // deUint32                                     queueFamilyIndexCount
302                 &queueFamilyIdx,                                                                // const deUint32*                      pQueueFamilyIndices
303                 vk::VK_IMAGE_LAYOUT_UNDEFINED,                                  // VkImageLayout                        initialLayout
304         };
305
306 #ifndef NOT_PROTECTED
307         vk::MemoryRequirement           memReq          = (protectionMode == PROTECTION_ENABLED)
308                                                                                                 ? vk::MemoryRequirement::Protected
309                                                                                                 : vk::MemoryRequirement::Any;
310 #else
311         vk::MemoryRequirement           memReq          = vk::MemoryRequirement::Any;
312 #endif
313
314         return de::MovePtr<vk::ImageWithMemory>(new vk::ImageWithMemory(vk, device, allocator, params, memReq));
315 }
316
317 de::MovePtr<vk::BufferWithMemory> makeBuffer (ProtectedContext&                 context,
318                                                                                           ProtectionMode                        protectionMode,
319                                                                                           const deUint32                        queueFamilyIdx,
320                                                                                           deUint32                                      size,
321                                                                                           vk::VkBufferUsageFlags        usageFlags,
322                                                                                           vk::MemoryRequirement         memReq)
323 {
324         const vk::DeviceInterface&              vk                      = context.getDeviceInterface();
325         const vk::VkDevice&                             device          = context.getDevice();
326         vk::Allocator&                                  allocator       = context.getDefaultAllocator();
327
328 #ifndef NOT_PROTECTED
329         deUint32                                                flags           = (protectionMode == PROTECTION_ENABLED)
330                                                                                                         ? vk::VK_BUFFER_CREATE_PROTECTED_BIT
331                                                                                                         : (vk::VkBufferCreateFlagBits)0u;
332         vk::MemoryRequirement                   requirement     = memReq;
333 #else
334         DE_UNREF(protectionMode);
335         deUint32                                                flags           = 0u;
336         vk::MemoryRequirement                   requirement     = memReq & (
337                                                                                                         vk::MemoryRequirement::HostVisible
338                                                                                                         | vk::MemoryRequirement::Coherent
339                                                                                                         | vk::MemoryRequirement::LazilyAllocated);
340 #endif
341
342         const vk::VkBufferCreateInfo    params          =
343         {
344                 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,       // sType
345                 DE_NULL,                                                                        // pNext
346                 (vk::VkBufferCreateFlags)flags,                         // flags
347                 (vk::VkDeviceSize)size,                                         // size
348                 usageFlags,                                                                     // usage
349                 vk::VK_SHARING_MODE_EXCLUSIVE,                          // sharingMode
350                 1u,                                                                                     // queueFamilyCount
351                 &queueFamilyIdx,                                                        // pQueueFamilyIndices
352         };
353
354         return de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(vk, device, allocator, params, requirement));
355 }
356
357 vk::Move<vk::VkImageView> createImageView (ProtectedContext& context, vk::VkImage image, vk::VkFormat format)
358 {
359         const vk::VkImageViewCreateInfo params =
360         {
361                 vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,           // sType
362                 DE_NULL,                                                                                        // pNext
363                 0u,                                                                                                     // flags
364                 image,                                                                                          // image
365                 vk::VK_IMAGE_VIEW_TYPE_2D,                                                      // viewType
366                 format,                                                                                         // format
367                 vk::makeComponentMappingRGBA(),                                         // components
368                 { vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u,1u },       // subresourceRange
369         };
370
371         return vk::createImageView(context.getDeviceInterface(), context.getDevice(), &params);
372 }
373
374 vk::Move<vk::VkRenderPass> createRenderPass (ProtectedContext& context, vk::VkFormat format)
375 {
376         const vk::VkDevice                                      vkDevice                                = context.getDevice();
377         const vk::DeviceInterface&                      vk                                              = context.getDeviceInterface();
378
379         return vk::makeRenderPass(vk, vkDevice, format);
380 }
381
382 vk::Move<vk::VkFramebuffer> createFramebuffer (ProtectedContext& context, deUint32 width, deUint32 height,
383                                                                                                 vk::VkRenderPass renderPass, vk::VkImageView colorImageView)
384 {
385         const vk::VkDevice                                      vkDevice                        = context.getDevice();
386         const vk::DeviceInterface&                      vk                                      = context.getDeviceInterface();
387
388         const vk::VkFramebufferCreateInfo       framebufferParams       =
389         {
390                 vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,  // VkStructureType                      sType;
391                 DE_NULL,                                                                                // const void*                          pNext;
392                 0u,                                                                                             // VkFramebufferCreateFlags     flags;
393                 renderPass,                                                                             // VkRenderPass                         renderPass;
394                 1u,                                                                                             // deUint32                                     attachmentCount;
395                 &colorImageView,                                                                // const VkImageView*           pAttachments;
396                 width,                                                                                  // deUint32                                     width;
397                 height,                                                                                 // deUint32                                     height;
398                 1u                                                                                              // deUint32                                     layers;
399         };
400
401         return vk::createFramebuffer(vk, vkDevice, &framebufferParams);
402 }
403
404
405 vk::Move<vk::VkPipelineLayout> createPipelineLayout (ProtectedContext& context, deUint32 layoutCount, vk::VkDescriptorSetLayout* setLayouts)
406 {
407         const vk::VkPipelineLayoutCreateInfo    params  =
408         {
409                 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,      // sType
410                 DE_NULL,                                                                                        // pNext
411                 0u,                                                                                                     // flags
412                 layoutCount,                                                                            // setLayoutCount
413                 setLayouts,                                                                                     // pSetLayouts
414                 0u,                                                                                                     // pushConstantRangeCount
415                 DE_NULL,                                                                                        // pPushContantRanges
416         };
417
418         return vk::createPipelineLayout(context.getDeviceInterface(), context.getDevice(), &params);
419 }
420
421 void beginSecondaryCommandBuffer (const vk::DeviceInterface&                            vk,
422                                                                   const vk::VkCommandBuffer                                     secondaryCmdBuffer,
423                                                                   const vk::VkCommandBufferInheritanceInfo      bufferInheritanceInfo)
424 {
425         const vk::VkCommandBufferUsageFlags     flags           = bufferInheritanceInfo.renderPass != DE_NULL
426                                                                                                           ? (vk::VkCommandBufferUsageFlags)vk::VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT
427                                                                                                           : (vk::VkCommandBufferUsageFlags)0u;
428         const vk::VkCommandBufferBeginInfo      beginInfo       =
429         {
430                 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                        // sType
431                 DE_NULL,                                                                                                        // pNext
432                 flags,                                                                                                          // flags
433                 &bufferInheritanceInfo,                                                                         // pInheritanceInfo
434         };
435         VK_CHECK(vk.beginCommandBuffer(secondaryCmdBuffer, &beginInfo));
436 }
437
438 vk::VkResult queueSubmit (ProtectedContext&             context,
439                                                   ProtectionMode                protectionMode,
440                                                   vk::VkQueue                   queue,
441                                                   vk::VkCommandBuffer   cmdBuffer,
442                                                   vk::VkFence                   fence,
443                                                   deUint64                              timeout)
444 {
445         const vk::DeviceInterface&                      vk                      = context.getDeviceInterface();
446         const vk::VkDevice&                                     device          = context.getDevice();
447
448         // Basic submit info
449         vk::VkSubmitInfo                                        submitInfo      =
450         {
451                 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,                      // sType
452                 DE_NULL,                                                                        // pNext
453                 0u,                                                                                     // waitSemaphoreCount
454                 DE_NULL,                                                                        // pWaitSempahores
455                 (const vk::VkPipelineStageFlags*)DE_NULL,       // stageFlags
456                 1u,                                                                                     // commandBufferCount
457                 &cmdBuffer,                                                                     // pCommandBuffers
458                 0u,                                                                                     // signalSemaphoreCount
459                 DE_NULL,                                                                        // pSignalSemaphores
460         };
461
462 #ifndef NOT_PROTECTED
463         // Protected extension submit info
464         const vk::VkProtectedSubmitInfo         protectedInfo   =
465         {
466                 vk::VK_STRUCTURE_TYPE_PROTECTED_SUBMIT_INFO,            // sType
467                 DE_NULL,                                                                                        // pNext
468                 VK_TRUE,                                                                                        // protectedSubmit
469         };
470         if (protectionMode == PROTECTION_ENABLED) {
471                 submitInfo.pNext = &protectedInfo;
472         }
473 #else
474         DE_UNREF(protectionMode);
475 #endif
476
477         VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence));
478         return vk.waitForFences(device, 1u, &fence, DE_TRUE, timeout);
479 }
480
481 vk::Move<vk::VkPipeline> makeComputePipeline (const vk::DeviceInterface&                vk,
482                                                                                           const vk::VkDevice                            device,
483                                                                                           const vk::VkPipelineLayout            pipelineLayout,
484                                                                                           const vk::VkShaderModule                      shaderModule,
485                                                                                           const vk::VkSpecializationInfo*       specInfo)
486 {
487         const vk::VkPipelineShaderStageCreateInfo shaderStageInfo =
488         {
489                 vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,        // VkStructureType                                      sType;
490                 DE_NULL,                                                                                                        // const void*                                          pNext;
491                 (vk::VkPipelineShaderStageCreateFlags)0,                                        // VkPipelineShaderStageCreateFlags     flags;
492                 vk::VK_SHADER_STAGE_COMPUTE_BIT,                                                        // VkShaderStageFlagBits                        stage;
493                 shaderModule,                                                                                           // VkShaderModule                                       module;
494                 "main",                                                                                                         // const char*                                          pName;
495                 specInfo,                                                                                                       // const VkSpecializationInfo*          pSpecializationInfo;
496         };
497         const vk::VkComputePipelineCreateInfo pipelineInfo =
498         {
499                 vk::VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,     // VkStructureType                                      sType;
500                 DE_NULL,                                                                                        // const void*                                          pNext;
501                 (vk::VkPipelineCreateFlags)0,                                           // VkPipelineCreateFlags                        flags;
502                 shaderStageInfo,                                                                        // VkPipelineShaderStageCreateInfo      stage;
503                 pipelineLayout,                                                                         // VkPipelineLayout                                     layout;
504                 DE_NULL,                                                                                        // VkPipeline                                           basePipelineHandle;
505                 0,                                                                                                      // deInt32                                                      basePipelineIndex;
506         };
507         return vk::createComputePipeline(vk, device, DE_NULL , &pipelineInfo);
508 }
509
510 vk::Move<vk::VkSampler> makeSampler (const vk::DeviceInterface& vk, const vk::VkDevice& device)
511 {
512         const vk::VkSamplerCreateInfo createInfo =
513         {
514                 vk::VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
515                 DE_NULL,
516                 0u,
517
518                 vk::VK_FILTER_NEAREST,
519                 vk::VK_FILTER_NEAREST,
520
521                 vk::VK_SAMPLER_MIPMAP_MODE_LINEAR,
522                 vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
523                 vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
524                 vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
525                 0.0f,
526                 VK_FALSE,
527                 1.0f,
528                 VK_FALSE,
529                 vk::VK_COMPARE_OP_ALWAYS,
530                 0.0f,
531                 0.0f,
532                 vk::VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,
533                 VK_FALSE
534         };
535
536         return vk::createSampler(vk, device, &createInfo);
537 }
538
539 vk::Move<vk::VkCommandPool> makeCommandPool (const vk::DeviceInterface& vk,
540                                                                                          const vk::VkDevice&            device,
541                                                                                          ProtectionMode                         protectionMode,
542                                                                                          const deUint32                         queueFamilyIdx)
543 {
544         const deUint32  poolFlags       = vk::VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT
545 #ifndef NOT_PROTECTED
546                                                                         | ((protectionMode == PROTECTION_ENABLED) ? vk::VK_COMMAND_POOL_CREATE_PROTECTED_BIT : 0x0)
547 #endif
548                                                                         ;
549 #ifdef NOT_PROTECTED
550         DE_UNREF(protectionMode);
551 #endif
552
553         return vk::createCommandPool(vk, device, poolFlags, queueFamilyIdx);
554 }
555
556 vk::Move<vk::VkPipeline> makeGraphicsPipeline (const vk::DeviceInterface&               vk,
557                                                                                            const vk::VkDevice                           device,
558                                                                                            const vk::VkPipelineLayout           pipelineLayout,
559                                                                                            const vk::VkRenderPass                       renderPass,
560                                                                                            const vk::VkShaderModule                     vertexShaderModule,
561                                                                                            const vk::VkShaderModule                     fragmentShaderModule,
562                                                                                            const VertexBindings&                        vertexBindings,
563                                                                                            const VertexAttribs&                         vertexAttribs,
564                                                                                            const tcu::UVec2&                            renderSize,
565                                                                                            const vk::VkPrimitiveTopology        topology)
566 {
567         const std::vector<VkViewport>                           viewports                                       (1, makeViewport(renderSize));
568         const std::vector<VkRect2D>                                     scissors                                        (1, makeRect2D(renderSize));
569
570         const VkPipelineVertexInputStateCreateInfo      vertexInputStateCreateInfo      =
571         {
572                 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,      // VkStructureType                             sType;
573                 DE_NULL,                                                                                                        // const void*                                 pNext;
574                 (VkPipelineVertexInputStateCreateFlags)0,                                       // VkPipelineVertexInputStateCreateFlags       flags;
575                 (deUint32)vertexBindings.size(),                                                        // deUint32                                    vertexBindingDescriptionCount;
576                 vertexBindings.data(),                                                                          // const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
577                 (deUint32)vertexAttribs.size(),                                                         // deUint32                                    vertexAttributeDescriptionCount;
578                 vertexAttribs.data()                                                                            // const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
579         };
580
581         return vk::makeGraphicsPipeline(vk,                                                                     // const DeviceInterface&                        vk
582                                                                         device,                                                         // const VkDevice                                device
583                                                                         pipelineLayout,                                         // const VkPipelineLayout                        pipelineLayout
584                                                                         vertexShaderModule,                                     // const VkShaderModule                          vertexShaderModule
585                                                                         DE_NULL,                                                        // const VkShaderModule                          tessellationControlModule
586                                                                         DE_NULL,                                                        // const VkShaderModule                          tessellationEvalModule
587                                                                         DE_NULL,                                                        // const VkShaderModule                          geometryShaderModule
588                                                                         fragmentShaderModule,                           // const VkShaderModule                          fragmentShaderModule
589                                                                         renderPass,                                                     // const VkRenderPass                            renderPass
590                                                                         viewports,                                                      // const std::vector<VkViewport>&                viewports
591                                                                         scissors,                                                       // const std::vector<VkRect2D>&                  scissors
592                                                                         topology,                                                       // const VkPrimitiveTopology                     topology
593                                                                         0u,                                                                     // const deUint32                                subpass
594                                                                         0u,                                                                     // const deUint32                                patchControlPoints
595                                                                         &vertexInputStateCreateInfo);           // const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
596 }
597
598 const char* getCmdBufferTypeStr (const CmdBufferType cmdBufferType)
599 {
600         switch (cmdBufferType)
601         {
602                 case CMD_BUFFER_PRIMARY:        return "primary";
603                 case CMD_BUFFER_SECONDARY:      return "secondary";
604
605                 default: DE_FATAL("Invalid command buffer type"); return "";
606         }
607 }
608
609 void clearImage (ProtectedContext& ctx, vk::VkImage image)
610 {
611         const vk::DeviceInterface&                      vk                                      = ctx.getDeviceInterface();
612         const vk::VkDevice                                      device                          = ctx.getDevice();
613         const vk::VkQueue                                       queue                           = ctx.getQueue();
614         const deUint32                                          queueFamilyIndex        = ctx.getQueueFamilyIndex();
615
616         vk::Unique<vk::VkCommandPool>           cmdPool                         (makeCommandPool(vk, device, PROTECTION_ENABLED, queueFamilyIndex));
617         vk::Unique<vk::VkCommandBuffer>         cmdBuffer                       (vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
618
619         const vk::VkClearColorValue                     clearColor                      = { { 0.0f, 0.0f, 0.0f, 0.0f } };
620
621         const vk::VkImageSubresourceRange       subresourceRange        =
622         {
623                 vk::VK_IMAGE_ASPECT_COLOR_BIT,  // VkImageAspectFlags   aspectMask
624                 0u,                                                             // uint32_t                             baseMipLevel
625                 1u,                                                             // uint32_t                             levelCount
626                 0u,                                                             // uint32_t                             baseArrayLayer
627                 1u,                                                             // uint32_t                             layerCount
628         };
629
630         const vk::VkImageMemoryBarrier          preImageBarrier         =
631         {
632                 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,             // VkStructureType                      sType;
633                 DE_NULL,                                                                                // const void*                          pNext;
634                 0u,                                                                                             // VkAccessFlags                        srcAccessMask;
635                 vk::VK_ACCESS_TRANSFER_WRITE_BIT,                               // VkAccessFlags                        dstAccessMask;
636                 vk::VK_IMAGE_LAYOUT_UNDEFINED,                                  // VkImageLayout                        oldLayout;
637                 vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,               // VkImageLayout                        newLayout;
638                 queueFamilyIndex,                                                               // deUint32                                     srcQueueFamilyIndex;
639                 queueFamilyIndex,                                                               // deUint32                                     dstQueueFamilyIndex;
640                 image,                                                                                  // VkImage                                      image;
641                 subresourceRange                                                                // VkImageSubresourceRange      subresourceRange;
642         };
643
644         const vk::VkImageMemoryBarrier          postImageBarrier        =
645         {
646                 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,             // VkStructureType                      sType;
647                 DE_NULL,                                                                                // const void*                          pNext;
648                 vk::VK_ACCESS_TRANSFER_WRITE_BIT,                               // VkAccessFlags                        srcAccessMask;
649                 vk::VK_ACCESS_SHADER_WRITE_BIT,                                 // VkAccessFlags                        dstAccessMask;
650                 vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,               // VkImageLayout                        oldLayout;
651                 vk::VK_IMAGE_LAYOUT_GENERAL,                                    // VkImageLayout                        newLayout;
652                 queueFamilyIndex,                                                               // deUint32                                     srcQueueFamilyIndex;
653                 queueFamilyIndex,                                                               // deUint32                                     dstQueueFamilyIndex;
654                 image,                                                                                  // VkImage                                      image;
655                 subresourceRange                                                                // VkImageSubresourceRange      subresourceRange;
656         };
657
658         beginCommandBuffer(vk, *cmdBuffer);
659         vk.cmdPipelineBarrier(*cmdBuffer,
660                                                   vk::VK_PIPELINE_STAGE_HOST_BIT,
661                                                   vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
662                                                   (vk::VkDependencyFlags)0,
663                                                   0, (const vk::VkMemoryBarrier*)DE_NULL,
664                                                   0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
665                                                   1, &preImageBarrier);
666         vk.cmdClearColorImage(*cmdBuffer, image, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &subresourceRange);
667         vk.cmdPipelineBarrier(*cmdBuffer,
668                                                   vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
669                                                   vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
670                                                   (vk::VkDependencyFlags)0,
671                                                   0, (const vk::VkMemoryBarrier*)DE_NULL,
672                                                   0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
673                                                   1, &postImageBarrier);
674         endCommandBuffer(vk, *cmdBuffer);
675
676         {
677                 const vk::Unique<vk::VkFence>   fence           (createFence(vk, device));
678                 VK_CHECK(queueSubmit(ctx, PROTECTION_ENABLED, queue, *cmdBuffer, *fence, ~0ull));
679         }
680 }
681
682 void uploadImage (ProtectedContext& ctx, vk::VkImage image, const tcu::Texture2D& texture2D)
683 {
684         const vk::DeviceInterface&                      vk                                      = ctx.getDeviceInterface();
685         const vk::VkDevice                                      device                          = ctx.getDevice();
686         const vk::VkQueue                                       queue                           = ctx.getQueue();
687         const deUint32                                          queueFamilyIndex        = ctx.getQueueFamilyIndex();
688
689         vk::Unique<vk::VkCommandPool>           cmdPool                         (makeCommandPool(vk, device, PROTECTION_DISABLED, queueFamilyIndex));
690         vk::Unique<vk::VkCommandBuffer>         cmdBuffer                       (vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
691
692         const deUint32                                          width                           = (deUint32)texture2D.getWidth();
693         const deUint32                                          height                          = (deUint32)texture2D.getHeight();
694         const deUint32                                          stagingBufferSize       = width * height * tcu::getPixelSize(texture2D.getFormat());
695
696         de::UniquePtr<vk::BufferWithMemory>     stagingBuffer           (makeBuffer(ctx,
697                                                                                                                                                 PROTECTION_DISABLED,
698                                                                                                                                                 queueFamilyIndex,
699                                                                                                                                                 stagingBufferSize,
700                                                                                                                                                 vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
701                                                                                                                                                 vk::MemoryRequirement::HostVisible));
702
703         {
704                 const tcu::ConstPixelBufferAccess&      access          = texture2D.getLevel(0);
705                 const tcu::PixelBufferAccess            destAccess      (access.getFormat(), access.getSize(), stagingBuffer->getAllocation().getHostPtr());
706
707                 tcu::copy(destAccess, access);
708
709                 vk::flushMappedMemoryRange(vk, device, stagingBuffer->getAllocation().getMemory(), stagingBuffer->getAllocation().getOffset(), stagingBufferSize);
710         }
711
712         const vk::VkImageSubresourceRange       subresourceRange        =
713         {
714                 vk::VK_IMAGE_ASPECT_COLOR_BIT,  // VkImageAspectFlags   aspectMask
715                 0u,                                                             // uint32_t                             baseMipLevel
716                 1u,                                                             // uint32_t                             levelCount
717                 0u,                                                             // uint32_t                             baseArrayLayer
718                 1u,                                                             // uint32_t                             layerCount
719         };
720
721         const vk::VkImageMemoryBarrier          preCopyBarrier          =
722         {
723                 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,             // VkStructureType                      sType;
724                 DE_NULL,                                                                                // const void*                          pNext;
725                 0u,                                                                                             // VkAccessFlags                        srcAccessMask;
726                 vk::VK_ACCESS_TRANSFER_WRITE_BIT,                               // VkAccessFlags                        dstAccessMask;
727                 vk::VK_IMAGE_LAYOUT_UNDEFINED,                                  // VkImageLayout                        oldLayout;
728                 vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,               // VkImageLayout                        newLayout;
729                 queueFamilyIndex,                                                               // deUint32                                     srcQueueFamilyIndex;
730                 queueFamilyIndex,                                                               // deUint32                                     dstQueueFamilyIndex;
731                 image,                                                                                  // VkImage                                      image;
732                 subresourceRange                                                                // VkImageSubresourceRange      subresourceRange;
733         };
734
735         const vk::VkImageMemoryBarrier          postCopyBarrier         =
736         {
737                 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,             // VkStructureType                      sType;
738                 DE_NULL,                                                                                // const void*                          pNext;
739                 vk::VK_ACCESS_TRANSFER_WRITE_BIT,                               // VkAccessFlags                        srcAccessMask;
740                 vk::VK_ACCESS_TRANSFER_WRITE_BIT,                               // VkAccessFlags                        dstAccessMask;
741                 vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,               // VkImageLayout                        oldLayout;
742                 vk::VK_IMAGE_LAYOUT_GENERAL,                                    // VkImageLayout                        newLayout;
743                 queueFamilyIndex,                                                               // deUint32                                     srcQueueFamilyIndex;
744                 queueFamilyIndex,                                                               // deUint32                                     dstQueueFamilyIndex;
745                 image,                                                                                  // VkImage                                      image;
746                 subresourceRange                                                                // VkImageSubresourceRange      subresourceRange;
747         };
748
749         const vk::VkImageSubresourceLayers      subresourceLayers       =
750         {
751                 vk::VK_IMAGE_ASPECT_COLOR_BIT,  // VkImageAspectFlags   aspectMask;
752                 0u,                                                             // deUint32                             mipLevel;
753                 0u,                                                             // deUint32                             baseArrayLayer;
754                 1u                                                              // deUint32                             layerCount;
755         };
756
757         const vk::VkBufferImageCopy                     copyRegion                      =
758         {
759                 0u,                                                             // VkDeviceSize                                 bufferOffset;
760                 width,                                                  // deUint32                                             bufferRowLength;
761                 height,                                                 // deUint32                                             bufferImageHeight;
762                 subresourceLayers,                              // VkImageSubresourceLayers             imageSubresource;
763                 { 0u, 0u, 0u },                                 // VkOffset3D                                   imageOffset;
764                 { width, height, 1u }                   // VkExtent3D                                   imageExtent;
765         };
766
767         beginCommandBuffer(vk, *cmdBuffer);
768         vk.cmdPipelineBarrier(*cmdBuffer,
769                                                   (vk::VkPipelineStageFlags)vk::VK_PIPELINE_STAGE_HOST_BIT,
770                                                   (vk::VkPipelineStageFlags)vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
771                                                   (vk::VkDependencyFlags)0u,
772                                                   0u, (const vk::VkMemoryBarrier*)DE_NULL,
773                                                   0u, (const vk::VkBufferMemoryBarrier*)DE_NULL,
774                                                   1u, &preCopyBarrier);
775         vk.cmdCopyBufferToImage(*cmdBuffer, **stagingBuffer, image, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &copyRegion);
776         vk.cmdPipelineBarrier(*cmdBuffer,
777                                                   (vk::VkPipelineStageFlags)vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
778                                                   (vk::VkPipelineStageFlags)vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
779                                                   (vk::VkDependencyFlags)0u,
780                                                   0u, (const vk::VkMemoryBarrier*)DE_NULL,
781                                                   0u, (const vk::VkBufferMemoryBarrier*)DE_NULL,
782                                                   1u, &postCopyBarrier);
783         endCommandBuffer(vk, *cmdBuffer);
784
785         {
786                 const vk::Unique<vk::VkFence>   fence           (createFence(vk, device));
787                 VK_CHECK(queueSubmit(ctx, PROTECTION_DISABLED, queue, *cmdBuffer, *fence, ~0ull));
788         }
789 }
790
791 void copyToProtectedImage (ProtectedContext& ctx, vk::VkImage srcImage, vk::VkImage dstImage, vk::VkImageLayout dstImageLayout, deUint32 width, deUint32 height)
792 {
793         const vk::DeviceInterface&                      vk                                      = ctx.getDeviceInterface();
794         const vk::VkDevice                                      device                          = ctx.getDevice();
795         const vk::VkQueue                                       queue                           = ctx.getQueue();
796         const deUint32                                          queueFamilyIndex        = ctx.getQueueFamilyIndex();
797
798         vk::Unique<vk::VkCommandPool>           cmdPool                         (makeCommandPool(vk, device, PROTECTION_ENABLED, queueFamilyIndex));
799         vk::Unique<vk::VkCommandBuffer>         cmdBuffer                       (vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
800
801         const vk::VkImageSubresourceRange       subresourceRange        =
802         {
803                 vk::VK_IMAGE_ASPECT_COLOR_BIT,  // VkImageAspectFlags   aspectMask
804                 0u,                                                             // uint32_t                             baseMipLevel
805                 1u,                                                             // uint32_t                             levelCount
806                 0u,                                                             // uint32_t                             baseArrayLayer
807                 1u,                                                             // uint32_t                             layerCount
808         };
809
810         const vk::VkImageMemoryBarrier          preImageBarriers[]      =
811         {
812                 // source image
813                 {
814                         vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,             // VkStructureType                      sType;
815                         DE_NULL,                                                                                // const void*                          pNext;
816                         vk::VK_ACCESS_TRANSFER_WRITE_BIT,                               // VkAccessFlags                        srcAccessMask;
817                         vk::VK_ACCESS_TRANSFER_READ_BIT,                                // VkAccessFlags                        dstAccessMask;
818                         vk::VK_IMAGE_LAYOUT_GENERAL,                                    // VkImageLayout                        oldLayout;
819                         vk::VK_IMAGE_LAYOUT_GENERAL,                                    // VkImageLayout                        newLayout;
820                         queueFamilyIndex,                                                               // deUint32                                     srcQueueFamilyIndex;
821                         queueFamilyIndex,                                                               // deUint32                                     dstQueueFamilyIndex;
822                         srcImage,                                                                               // VkImage                                      image;
823                         subresourceRange                                                                // VkImageSubresourceRange      subresourceRange;
824                 },
825                 // destination image
826                 {
827                         vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,             // VkStructureType                      sType;
828                         DE_NULL,                                                                                // const void*                          pNext;
829                         0,                                                                                              // VkAccessFlags                        srcAccessMask;
830                         vk::VK_ACCESS_TRANSFER_WRITE_BIT,                               // VkAccessFlags                        dstAccessMask;
831                         vk::VK_IMAGE_LAYOUT_UNDEFINED,                                  // VkImageLayout                        oldLayout;
832                         vk::VK_IMAGE_LAYOUT_GENERAL,                                    // VkImageLayout                        newLayout;
833                         queueFamilyIndex,                                                               // deUint32                                     srcQueueFamilyIndex;
834                         queueFamilyIndex,                                                               // deUint32                                     dstQueueFamilyIndex;
835                         dstImage,                                                                               // VkImage                                      image;
836                         subresourceRange                                                                // VkImageSubresourceRange      subresourceRange;
837                 }
838         };
839
840         const vk::VkImageMemoryBarrier          postImgBarrier          =
841         {
842                 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,             // VkStructureType                      sType;
843                 DE_NULL,                                                                                // const void*                          pNext;
844                 vk::VK_ACCESS_TRANSFER_WRITE_BIT,                               // VkAccessFlags                        srcAccessMask;
845                 vk::VK_ACCESS_SHADER_READ_BIT,                                  // VkAccessFlags                        dstAccessMask;
846                 vk::VK_IMAGE_LAYOUT_GENERAL,                                    // VkImageLayout                        oldLayout;
847                 dstImageLayout,                                                                 // VkImageLayout                        newLayout;
848                 queueFamilyIndex,                                                               // deUint32                                     srcQueueFamilyIndex;
849                 queueFamilyIndex,                                                               // deUint32                                     dstQueueFamilyIndex;
850                 dstImage,                                                                               // VkImage                                      image;
851                 subresourceRange                                                                // VkImageSubresourceRange      subresourceRange;
852         };
853
854         const vk::VkImageSubresourceLayers      subresourceLayers       =
855         {
856                 vk::VK_IMAGE_ASPECT_COLOR_BIT,  // VkImageAspectFlags   aspectMask;
857                 0u,                                                             // deUint32                             mipLevel;
858                 0u,                                                             // deUint32                             baseArrayLayer;
859                 1u                                                              // deUint32                             layerCount;
860         };
861
862         const vk::VkImageCopy                           copyImageRegion         =
863         {
864                 subresourceLayers,              // VkImageSubresourceCopy       srcSubresource;
865                 { 0, 0, 0 },                    // VkOffset3D                           srcOffset;
866                 subresourceLayers,              // VkImageSubresourceCopy       destSubresource;
867                 { 0, 0, 0 },                    // VkOffset3D                           destOffset;
868                 { width, height, 1u },  // VkExtent3D                           extent;
869         };
870
871         beginCommandBuffer(vk, *cmdBuffer);
872         vk.cmdPipelineBarrier(*cmdBuffer,
873                                                   vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
874                                                   vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
875                                                   (vk::VkDependencyFlags)0,
876                                                   0, (const vk::VkMemoryBarrier*)DE_NULL,
877                                                   0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
878                                                   DE_LENGTH_OF_ARRAY(preImageBarriers), preImageBarriers);
879         vk.cmdCopyImage(*cmdBuffer, srcImage, vk::VK_IMAGE_LAYOUT_GENERAL, dstImage, vk::VK_IMAGE_LAYOUT_GENERAL, 1u, &copyImageRegion);
880         vk.cmdPipelineBarrier(*cmdBuffer,
881                                                   vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
882                                                   vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
883                                                   (vk::VkDependencyFlags)0,
884                                                   0, (const vk::VkMemoryBarrier*)DE_NULL,
885                                                   0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
886                                                   1, &postImgBarrier);
887         endCommandBuffer(vk, *cmdBuffer);
888
889         {
890                 const vk::Unique<vk::VkFence>   fence           (createFence(vk, device));
891                 VK_CHECK(queueSubmit(ctx, PROTECTION_ENABLED, queue, *cmdBuffer, *fence, ~0ull));
892         }
893 }
894
895 void fillWithRandomColorTiles (const tcu::PixelBufferAccess& dst, const tcu::Vec4& minVal, const tcu::Vec4& maxVal, deUint32 seed)
896 {
897         const int       numCols         = dst.getWidth()  >= 7 ? 7 : dst.getWidth();
898         const int       numRows         = dst.getHeight() >= 5 ? 5 : dst.getHeight();
899         de::Random      rnd                     (seed);
900
901         for (int slice = 0; slice < dst.getDepth(); slice++)
902         for (int row = 0; row < numRows; row++)
903         for (int col = 0; col < numCols; col++)
904         {
905                 const int       yBegin  = (row + 0)*dst.getHeight() / numRows;
906                 const int       yEnd    = (row + 1)*dst.getHeight() / numRows;
907                 const int       xBegin  = (col + 0)*dst.getWidth() / numCols;
908                 const int       xEnd    = (col + 1)*dst.getWidth() / numCols;
909                 tcu::Vec4       color;
910                 for (int i = 0; i < 4; i++)
911                         color[i] = rnd.getFloat(minVal[i], maxVal[i]);
912                 tcu::clear(tcu::getSubregion(dst, xBegin, yBegin, slice, xEnd - xBegin, yEnd - yBegin, 1), color);
913         }
914 }
915
916 } // ProtectedMem
917 } // vkt