1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2017 The Khronos Group Inc.
6 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 * \brief Protected Memory Utility methods
23 *//*--------------------------------------------------------------------*/
25 #include "vktProtectedMemUtils.hpp"
26 #include "vktCustomInstancesDevices.hpp"
29 #include "deRandom.hpp"
31 #include "vkDeviceUtil.hpp"
32 #include "vkQueryUtil.hpp"
33 #include "vkTypeUtil.hpp"
34 #include "vkDebugReportUtil.hpp"
35 #include "vkApiVersion.hpp"
36 #include "vkObjUtil.hpp"
38 #include "vkPlatform.hpp"
39 #include "vktProtectedMemContext.hpp"
40 #include "vkWsiUtil.hpp"
41 #include "vkObjUtil.hpp"
48 namespace ProtectedMem
51 typedef std::vector<vk::VkExtensionProperties> Extensions;
53 CustomInstance makeProtectedMemInstance (vkt::Context& context, const std::vector<std::string>& extraExtensions)
55 const PlatformInterface& vkp = context.getPlatformInterface();
56 const Extensions supportedExtensions(vk::enumerateInstanceExtensionProperties(vkp, DE_NULL));
57 std::vector<std::string> requiredExtensions = extraExtensions;
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");
63 // extract extension names
64 std::vector<std::string> extensions;
65 for (const auto& e : supportedExtensions)
66 extensions.push_back(e.extensionName);
68 for (const auto& extName : requiredExtensions)
70 if (!isInstanceExtensionSupported(apiVersion, extensions, extName))
71 TCU_THROW(NotSupportedError, (extName + " is not supported").c_str());
74 return createCustomInstanceWithExtensions(context, requiredExtensions);
77 void checkProtectedQueueSupport (Context& context)
83 const vk::InstanceInterface& vkd = context.getInstanceInterface();
84 vk::VkPhysicalDevice physDevice = context.getPhysicalDevice();
85 std::vector<vk::VkQueueFamilyProperties> properties;
86 deUint32 numFamilies = 0;
88 vkd.getPhysicalDeviceQueueFamilyProperties(physDevice, &numFamilies, DE_NULL);
89 DE_ASSERT(numFamilies > 0);
90 properties.resize(numFamilies);
92 vkd.getPhysicalDeviceQueueFamilyProperties(physDevice, &numFamilies, properties.data());
94 for (auto prop: properties)
95 if (prop.queueFlags & vk::VK_QUEUE_PROTECTED_BIT)
98 TCU_THROW(NotSupportedError, "No protected queue found.");
101 deUint32 chooseProtectedMemQueueFamilyIndex (const vk::InstanceDriver& vkd,
102 vk::VkPhysicalDevice physicalDevice,
103 vk::VkSurfaceKHR surface)
105 std::vector<vk::VkQueueFamilyProperties> properties;
106 deUint32 numFamilies = 0;
108 vkd.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numFamilies, DE_NULL);
109 DE_ASSERT(numFamilies > 0);
110 properties.resize(numFamilies);
112 vkd.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numFamilies, properties.data());
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
121 for (size_t idx = 0; idx < properties.size(); ++idx)
123 vk::VkQueueFlags flags = properties[idx].queueFlags;
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
129 if ((flags & requiredFlags) == requiredFlags)
130 return (deUint32)idx;
133 TCU_THROW(NotSupportedError, "No matching universal protected queue found");
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)
145 const Extensions supportedExtensions (vk::enumerateDeviceExtensionProperties(vkd, physicalDevice, DE_NULL));
146 std::vector<std::string> requiredExtensions;
147 std::vector<std::string> extensions = extraExtensions;
149 if (apiVersion < VK_API_VERSION_1_1)
150 TCU_THROW(NotSupportedError, "Vulkan 1.1 is not supported");
152 bool useYCbCr = de::contains(extensions.begin(), extensions.end(), std::string("VK_KHR_sampler_ycbcr_conversion"));
154 // Check if the physical device supports the protected memory extension name
155 for (deUint32 ndx = 0; ndx < extensions.size(); ++ndx)
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());
162 requiredExtensions.push_back(extensions[ndx]);
165 std::vector<const char*> enabledExts (requiredExtensions.size());
166 for (size_t idx = 0; idx < requiredExtensions.size(); ++idx)
168 enabledExts[idx] = requiredExtensions[idx].c_str();
171 vk::VkPhysicalDeviceSamplerYcbcrConversionFeatures ycbcrFeature =
173 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES,
177 // Check if the protected memory can be enabled on the physical device.
178 vk::VkPhysicalDeviceProtectedMemoryFeatures protectedFeature =
180 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES, // sType
181 &ycbcrFeature, // pNext
182 VK_FALSE // protectedMemory
184 vk::VkPhysicalDeviceFeatures features;
185 deMemset(&features, 0, sizeof(vk::VkPhysicalDeviceFeatures));
187 vk::VkPhysicalDeviceFeatures2 featuresExt =
189 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, // sType
190 &protectedFeature, // pNext
194 vkd.getPhysicalDeviceFeatures2(physicalDevice, &featuresExt);
196 #ifndef NOT_PROTECTED
197 if (protectedFeature.protectedMemory == VK_FALSE)
198 TCU_THROW(NotSupportedError, "Protected Memory feature not supported by the device");
201 if (useYCbCr && !ycbcrFeature.samplerYcbcrConversion)
202 TCU_THROW(NotSupportedError, "VK_KHR_sampler_ycbcr_conversion is not supported");
204 const float queuePriorities[] = { 1.0f };
205 const vk::VkDeviceQueueCreateInfo queueInfos[] =
208 vk::VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
210 #ifndef NOT_PROTECTED
211 (vk::VkDeviceQueueCreateFlags)vk::VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT,
213 (vk::VkDeviceQueueCreateFlags)0u,
216 DE_LENGTH_OF_ARRAY(queuePriorities),
221 const vk::VkDeviceCreateInfo deviceParams =
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
235 return createCustomDevice(validationEnabled, vkp, instance, vkd, physicalDevice, &deviceParams, DE_NULL);
238 vk::VkQueue getProtectedQueue (const vk::DeviceInterface& vk,
240 const deUint32 queueFamilyIndex,
241 const deUint32 queueIdx)
243 const vk::VkDeviceQueueInfo2 queueInfo =
245 vk::VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2, // sType
247 vk::VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT, // flags
248 queueFamilyIndex, // queueFamilyIndex
249 queueIdx, // queueIndex
254 #ifndef NOT_PROTECTED
255 vk::getDeviceQueue2(vk, device, &queueInfo);
257 vk::getDeviceQueue(vk, device, queueFamilyIndex, 0);
260 if (queue == DE_NULL)
261 TCU_THROW(TestError, "Unable to get a protected queue");
266 de::MovePtr<vk::ImageWithMemory> createImage2D (ProtectedContext& context,
267 ProtectionMode protectionMode,
268 const deUint32 queueFamilyIdx,
272 vk::VkImageUsageFlags usageFlags)
274 const vk::DeviceInterface& vk = context.getDeviceInterface();
275 const vk::VkDevice& device = context.getDevice();
276 vk::Allocator& allocator = context.getDefaultAllocator();
278 #ifndef NOT_PROTECTED
279 deUint32 flags = (protectionMode == PROTECTION_ENABLED)
280 ? vk::VK_IMAGE_CREATE_PROTECTED_BIT
281 : (vk::VkImageCreateFlagBits)0u;
283 DE_UNREF(protectionMode);
287 const vk::VkImageCreateInfo params =
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
306 #ifndef NOT_PROTECTED
307 vk::MemoryRequirement memReq = (protectionMode == PROTECTION_ENABLED)
308 ? vk::MemoryRequirement::Protected
309 : vk::MemoryRequirement::Any;
311 vk::MemoryRequirement memReq = vk::MemoryRequirement::Any;
314 return de::MovePtr<vk::ImageWithMemory>(new vk::ImageWithMemory(vk, device, allocator, params, memReq));
317 de::MovePtr<vk::BufferWithMemory> makeBuffer (ProtectedContext& context,
318 ProtectionMode protectionMode,
319 const deUint32 queueFamilyIdx,
321 vk::VkBufferUsageFlags usageFlags,
322 vk::MemoryRequirement memReq)
324 const vk::DeviceInterface& vk = context.getDeviceInterface();
325 const vk::VkDevice& device = context.getDevice();
326 vk::Allocator& allocator = context.getDefaultAllocator();
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;
334 DE_UNREF(protectionMode);
336 vk::MemoryRequirement requirement = memReq & (
337 vk::MemoryRequirement::HostVisible
338 | vk::MemoryRequirement::Coherent
339 | vk::MemoryRequirement::LazilyAllocated);
342 const vk::VkBufferCreateInfo params =
344 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // sType
346 (vk::VkBufferCreateFlags)flags, // flags
347 (vk::VkDeviceSize)size, // size
349 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
350 1u, // queueFamilyCount
351 &queueFamilyIdx, // pQueueFamilyIndices
354 return de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(vk, device, allocator, params, requirement));
357 vk::Move<vk::VkImageView> createImageView (ProtectedContext& context, vk::VkImage image, vk::VkFormat format)
359 const vk::VkImageViewCreateInfo params =
361 vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // sType
365 vk::VK_IMAGE_VIEW_TYPE_2D, // viewType
367 vk::makeComponentMappingRGBA(), // components
368 { vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u,1u }, // subresourceRange
371 return vk::createImageView(context.getDeviceInterface(), context.getDevice(), ¶ms);
374 vk::Move<vk::VkRenderPass> createRenderPass (ProtectedContext& context, vk::VkFormat format)
376 const vk::VkDevice vkDevice = context.getDevice();
377 const vk::DeviceInterface& vk = context.getDeviceInterface();
379 return vk::makeRenderPass(vk, vkDevice, format);
382 vk::Move<vk::VkFramebuffer> createFramebuffer (ProtectedContext& context, deUint32 width, deUint32 height,
383 vk::VkRenderPass renderPass, vk::VkImageView colorImageView)
385 const vk::VkDevice vkDevice = context.getDevice();
386 const vk::DeviceInterface& vk = context.getDeviceInterface();
388 const vk::VkFramebufferCreateInfo framebufferParams =
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;
401 return vk::createFramebuffer(vk, vkDevice, &framebufferParams);
405 vk::Move<vk::VkPipelineLayout> createPipelineLayout (ProtectedContext& context, deUint32 layoutCount, vk::VkDescriptorSetLayout* setLayouts)
407 const vk::VkPipelineLayoutCreateInfo params =
409 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType
412 layoutCount, // setLayoutCount
413 setLayouts, // pSetLayouts
414 0u, // pushConstantRangeCount
415 DE_NULL, // pPushContantRanges
418 return vk::createPipelineLayout(context.getDeviceInterface(), context.getDevice(), ¶ms);
421 void beginSecondaryCommandBuffer (const vk::DeviceInterface& vk,
422 const vk::VkCommandBuffer secondaryCmdBuffer,
423 const vk::VkCommandBufferInheritanceInfo bufferInheritanceInfo)
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 =
430 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // sType
433 &bufferInheritanceInfo, // pInheritanceInfo
435 VK_CHECK(vk.beginCommandBuffer(secondaryCmdBuffer, &beginInfo));
438 vk::VkResult queueSubmit (ProtectedContext& context,
439 ProtectionMode protectionMode,
441 vk::VkCommandBuffer cmdBuffer,
445 const vk::DeviceInterface& vk = context.getDeviceInterface();
446 const vk::VkDevice& device = context.getDevice();
449 vk::VkSubmitInfo submitInfo =
451 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType
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
462 #ifndef NOT_PROTECTED
463 // Protected extension submit info
464 const vk::VkProtectedSubmitInfo protectedInfo =
466 vk::VK_STRUCTURE_TYPE_PROTECTED_SUBMIT_INFO, // sType
468 VK_TRUE, // protectedSubmit
470 if (protectionMode == PROTECTION_ENABLED) {
471 submitInfo.pNext = &protectedInfo;
474 DE_UNREF(protectionMode);
477 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence));
478 return vk.waitForFences(device, 1u, &fence, DE_TRUE, timeout);
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)
487 const vk::VkPipelineShaderStageCreateInfo shaderStageInfo =
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;
497 const vk::VkComputePipelineCreateInfo pipelineInfo =
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;
507 return vk::createComputePipeline(vk, device, DE_NULL , &pipelineInfo);
510 vk::Move<vk::VkSampler> makeSampler (const vk::DeviceInterface& vk, const vk::VkDevice& device)
512 const vk::VkSamplerCreateInfo createInfo =
514 vk::VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
518 vk::VK_FILTER_NEAREST,
519 vk::VK_FILTER_NEAREST,
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,
529 vk::VK_COMPARE_OP_ALWAYS,
532 vk::VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,
536 return vk::createSampler(vk, device, &createInfo);
539 vk::Move<vk::VkCommandPool> makeCommandPool (const vk::DeviceInterface& vk,
540 const vk::VkDevice& device,
541 ProtectionMode protectionMode,
542 const deUint32 queueFamilyIdx)
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)
550 DE_UNREF(protectionMode);
553 return vk::createCommandPool(vk, device, poolFlags, queueFamilyIdx);
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)
567 const std::vector<VkViewport> viewports (1, makeViewport(renderSize));
568 const std::vector<VkRect2D> scissors (1, makeRect2D(renderSize));
570 const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo =
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;
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
598 const char* getCmdBufferTypeStr (const CmdBufferType cmdBufferType)
600 switch (cmdBufferType)
602 case CMD_BUFFER_PRIMARY: return "primary";
603 case CMD_BUFFER_SECONDARY: return "secondary";
605 default: DE_FATAL("Invalid command buffer type"); return "";
609 void clearImage (ProtectedContext& ctx, vk::VkImage image)
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();
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));
619 const vk::VkClearColorValue clearColor = { { 0.0f, 0.0f, 0.0f, 0.0f } };
621 const vk::VkImageSubresourceRange subresourceRange =
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
630 const vk::VkImageMemoryBarrier preImageBarrier =
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;
644 const vk::VkImageMemoryBarrier postImageBarrier =
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;
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);
677 const vk::Unique<vk::VkFence> fence (createFence(vk, device));
678 VK_CHECK(queueSubmit(ctx, PROTECTION_ENABLED, queue, *cmdBuffer, *fence, ~0ull));
682 void uploadImage (ProtectedContext& ctx, vk::VkImage image, const tcu::Texture2D& texture2D)
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();
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));
692 const deUint32 width = (deUint32)texture2D.getWidth();
693 const deUint32 height = (deUint32)texture2D.getHeight();
694 const deUint32 stagingBufferSize = width * height * tcu::getPixelSize(texture2D.getFormat());
696 de::UniquePtr<vk::BufferWithMemory> stagingBuffer (makeBuffer(ctx,
700 vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
701 vk::MemoryRequirement::HostVisible));
704 const tcu::ConstPixelBufferAccess& access = texture2D.getLevel(0);
705 const tcu::PixelBufferAccess destAccess (access.getFormat(), access.getSize(), stagingBuffer->getAllocation().getHostPtr());
707 tcu::copy(destAccess, access);
709 vk::flushMappedMemoryRange(vk, device, stagingBuffer->getAllocation().getMemory(), stagingBuffer->getAllocation().getOffset(), stagingBufferSize);
712 const vk::VkImageSubresourceRange subresourceRange =
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
721 const vk::VkImageMemoryBarrier preCopyBarrier =
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;
735 const vk::VkImageMemoryBarrier postCopyBarrier =
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;
749 const vk::VkImageSubresourceLayers subresourceLayers =
751 vk::VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
752 0u, // deUint32 mipLevel;
753 0u, // deUint32 baseArrayLayer;
754 1u // deUint32 layerCount;
757 const vk::VkBufferImageCopy copyRegion =
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;
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, ©Region);
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);
786 const vk::Unique<vk::VkFence> fence (createFence(vk, device));
787 VK_CHECK(queueSubmit(ctx, PROTECTION_DISABLED, queue, *cmdBuffer, *fence, ~0ull));
791 void copyToProtectedImage (ProtectedContext& ctx, vk::VkImage srcImage, vk::VkImage dstImage, vk::VkImageLayout dstImageLayout, deUint32 width, deUint32 height)
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();
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));
801 const vk::VkImageSubresourceRange subresourceRange =
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
810 const vk::VkImageMemoryBarrier preImageBarriers[] =
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;
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;
840 const vk::VkImageMemoryBarrier postImgBarrier =
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;
854 const vk::VkImageSubresourceLayers subresourceLayers =
856 vk::VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
857 0u, // deUint32 mipLevel;
858 0u, // deUint32 baseArrayLayer;
859 1u // deUint32 layerCount;
862 const vk::VkImageCopy copyImageRegion =
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;
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, ©ImageRegion);
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,
887 endCommandBuffer(vk, *cmdBuffer);
890 const vk::Unique<vk::VkFence> fence (createFence(vk, device));
891 VK_CHECK(queueSubmit(ctx, PROTECTION_ENABLED, queue, *cmdBuffer, *fence, ~0ull));
895 void fillWithRandomColorTiles (const tcu::PixelBufferAccess& dst, const tcu::Vec4& minVal, const tcu::Vec4& maxVal, deUint32 seed)
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);
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++)
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;
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);
916 void fillWithUniqueColors (const tcu::PixelBufferAccess& dst, deUint32 seed)
918 // This is an implementation of linear congruential generator.
919 // The A and M are prime numbers, thus allowing to generate unique number sequence of length genM-1.
920 // The generator uses C constant as 0, thus value of 0 is not allowed as a seed.
921 const deUint64 genA = 1573051ull;
922 const deUint64 genM = 2097023ull;
923 deUint64 genX = seed % genM;
925 DE_ASSERT(deUint64(dst.getWidth()) * deUint64(dst.getHeight()) * deUint64(dst.getDepth()) < genM - 1);
930 const int numCols = dst.getWidth();
931 const int numRows = dst.getHeight();
932 const int numSlices = dst.getDepth();
934 for (int z = 0; z < numSlices; z++)
935 for (int y = 0; y < numRows; y++)
936 for (int x = 0; x < numCols; x++)
938 genX = (genA * genX) % genM;
940 DE_ASSERT(genX != seed);
942 const float r = float(deUint32((genX >> 0) & 0x7F)) / 127.0f;
943 const float g = float(deUint32((genX >> 7) & 0x7F)) / 127.0f;
944 const float b = float(deUint32((genX >> 14) & 0x7F)) / 127.0f;
945 const tcu::Vec4 color = tcu::Vec4(r, g, b, 1.0f);
947 dst.setPixel(color, x, y, z);