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