blob: 9e345789fa3b379d7d2d6a2743918558ae6de1a5 [file] [log] [blame]
/*
* Copyright (c) 2015-2023 The Khronos Group Inc.
* Copyright (c) 2015-2023 Valve Corporation
* Copyright (c) 2015-2023 LunarG, Inc.
* Copyright (c) 2015-2023 Google, Inc.
* Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#include "utils/cast_utils.h"
#include "../framework/layer_validation_tests.h"
#include "../framework/pipeline_helper.h"
TEST_F(NegativeProtectedMemory, Queue) {
TEST_DESCRIPTION("Try creating queue without VK_QUEUE_PROTECTED_BIT capability");
SetTargetApiVersion(VK_API_VERSION_1_1);
AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
RETURN_IF_SKIP(InitFramework())
VkPhysicalDeviceProtectedMemoryFeatures protected_features = vku::InitStructHelper();
GetPhysicalDeviceFeatures2(protected_features);
if (protected_features.protectedMemory == VK_FALSE) {
GTEST_SKIP() << "test requires protectedMemory";
}
// Try to find a protected queue family type
bool unprotected_queue = false;
uint32_t queue_family_index = 0;
uint32_t queue_family_count = 0;
vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_family_count, nullptr);
std::vector<VkQueueFamilyProperties> queue_families(queue_family_count);
vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_family_count, queue_families.data());
// need to find a queue without protected support
for (size_t i = 0; i < queue_families.size(); i++) {
if ((queue_families[i].queueFlags & VK_QUEUE_PROTECTED_BIT) == 0) {
unprotected_queue = true;
queue_family_index = i;
break;
}
}
if (unprotected_queue == false) {
GTEST_SKIP() << "test requires queue without VK_QUEUE_PROTECTED_BIT";
}
float queue_priority = 1.0;
VkDeviceQueueCreateInfo queue_create_info = vku::InitStructHelper();
queue_create_info.flags = VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT;
queue_create_info.queueFamilyIndex = queue_family_index;
queue_create_info.queueCount = 1;
queue_create_info.pQueuePriorities = &queue_priority;
VkDevice test_device = VK_NULL_HANDLE;
VkDeviceCreateInfo device_create_info = vku::InitStructHelper(&protected_features);
device_create_info.flags = 0;
device_create_info.pQueueCreateInfos = &queue_create_info;
device_create_info.queueCreateInfoCount = 1;
device_create_info.pEnabledFeatures = nullptr;
device_create_info.enabledLayerCount = 0;
device_create_info.enabledExtensionCount = 0;
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceQueueCreateInfo-flags-06449");
vk::CreateDevice(gpu(), &device_create_info, nullptr, &test_device);
m_errorMonitor->VerifyFound();
}
TEST_F(NegativeProtectedMemory, Submit) {
TEST_DESCRIPTION("Setting protectedSubmit with a queue not created with VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT");
SetTargetApiVersion(VK_API_VERSION_1_1);
AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
RETURN_IF_SKIP(InitFramework())
// creates a queue without VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT
RETURN_IF_SKIP(InitState())
VkCommandPool command_pool;
VkCommandPoolCreateInfo pool_create_info = vku::InitStructHelper();
pool_create_info.flags = VK_COMMAND_POOL_CREATE_PROTECTED_BIT;
pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCommandPoolCreateInfo-flags-02860");
vk::CreateCommandPool(device(), &pool_create_info, nullptr, &command_pool);
m_errorMonitor->VerifyFound();
VkBufferCreateInfo buffer_create_info = vku::InitStructHelper();
buffer_create_info.flags = VK_BUFFER_CREATE_PROTECTED_BIT;
buffer_create_info.size = 4096;
buffer_create_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
buffer_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
CreateBufferTest(*this, &buffer_create_info, "VUID-VkBufferCreateInfo-flags-01887");
VkImageCreateInfo image_create_info = vku::InitStructHelper();
image_create_info.flags = VK_IMAGE_CREATE_PROTECTED_BIT;
image_create_info.extent = {64, 64, 1};
image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
image_create_info.imageType = VK_IMAGE_TYPE_2D;
image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
image_create_info.arrayLayers = 1;
image_create_info.mipLevels = 1;
CreateImageTest(*this, &image_create_info, "VUID-VkImageCreateInfo-flags-01890");
// Try to find memory with protected bit in it at all
VkDeviceMemory memory_protected = VK_NULL_HANDLE;
VkMemoryAllocateInfo alloc_info = vku::InitStructHelper();
alloc_info.allocationSize = 4096;
VkPhysicalDeviceMemoryProperties phys_mem_props;
vk::GetPhysicalDeviceMemoryProperties(gpu(), &phys_mem_props);
alloc_info.memoryTypeIndex = phys_mem_props.memoryTypeCount + 1;
for (uint32_t i = 0; i < phys_mem_props.memoryTypeCount; i++) {
// Check just protected bit is in type at all
if ((phys_mem_props.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_PROTECTED_BIT) != 0) {
alloc_info.memoryTypeIndex = i;
break;
}
}
if (alloc_info.memoryTypeIndex < phys_mem_props.memoryTypeCount) {
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkMemoryAllocateInfo-memoryTypeIndex-01872");
vk::AllocateMemory(device(), &alloc_info, NULL, &memory_protected);
m_errorMonitor->VerifyFound();
}
VkProtectedSubmitInfo protected_submit_info = vku::InitStructHelper();
protected_submit_info.protectedSubmit = VK_TRUE;
VkSubmitInfo submit_info = vku::InitStructHelper(&protected_submit_info);
submit_info.commandBufferCount = 1;
submit_info.pCommandBuffers = &m_commandBuffer->handle();
m_commandBuffer->begin();
m_commandBuffer->end();
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkQueueSubmit-queue-06448");
m_errorMonitor->SetUnexpectedError("VUID-VkSubmitInfo-pNext-04148");
vk::QueueSubmit(m_default_queue, 1, &submit_info, VK_NULL_HANDLE);
m_errorMonitor->VerifyFound();
}
TEST_F(NegativeProtectedMemory, Memory) {
TEST_DESCRIPTION("Validate cases where protectedMemory feature is enabled and usages are invalid");
SetTargetApiVersion(VK_API_VERSION_1_1);
AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
RETURN_IF_SKIP(InitFramework())
VkPhysicalDeviceProtectedMemoryFeatures protected_memory_features = vku::InitStructHelper();
auto features2 = GetPhysicalDeviceFeatures2(protected_memory_features);
if (protected_memory_features.protectedMemory == VK_FALSE) {
GTEST_SKIP() << "protectedMemory feature not supported";
};
// Turns m_commandBuffer into a protected command buffer
RETURN_IF_SKIP(InitState(nullptr, &features2, VK_COMMAND_POOL_CREATE_PROTECTED_BIT));
bool sparse_support = (m_device->phy().features().sparseBinding == VK_TRUE);
VkBufferCreateInfo buffer_create_info = vku::InitStructHelper();
buffer_create_info.flags = VK_BUFFER_CREATE_PROTECTED_BIT | VK_BUFFER_CREATE_SPARSE_BINDING_BIT;
buffer_create_info.size = 1 << 20; // 1 MB
buffer_create_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
buffer_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
if (sparse_support == true) {
CreateBufferTest(*this, &buffer_create_info, "VUID-VkBufferCreateInfo-None-01888");
}
// Create actual protected and unprotected buffers
buffer_create_info.flags = VK_BUFFER_CREATE_PROTECTED_BIT;
vkt::Buffer buffer_protected;
buffer_protected.init_no_mem(*m_device, buffer_create_info);
buffer_create_info.flags = 0;
vkt::Buffer buffer_unprotected;
buffer_unprotected.init_no_mem(*m_device, buffer_create_info);
VkImageCreateInfo image_create_info = vku::InitStructHelper();
image_create_info.flags = VK_IMAGE_CREATE_PROTECTED_BIT | VK_IMAGE_CREATE_SPARSE_BINDING_BIT;
image_create_info.extent = {8, 8, 1};
image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
image_create_info.imageType = VK_IMAGE_TYPE_2D;
image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
image_create_info.arrayLayers = 1;
image_create_info.mipLevels = 1;
if (sparse_support == true) {
CreateImageTest(*this, &image_create_info, "VUID-VkImageCreateInfo-None-01891");
}
// Create actual protected and unprotected images
VkImageObj image_protected(m_device);
VkImageObj image_unprotected(m_device);
image_create_info.flags = VK_IMAGE_CREATE_PROTECTED_BIT;
image_protected.init_no_mem(*m_device, image_create_info);
image_create_info.flags = 0;
image_unprotected.init_no_mem(*m_device, image_create_info);
// Create protected and unproteced memory
VkMemoryAllocateInfo alloc_info = vku::InitStructHelper();
alloc_info.allocationSize = 0;
// set allocationSize to buffer as it will be larger than the image, but query image to avoid BP warning
VkMemoryRequirements mem_reqs_protected;
vk::GetImageMemoryRequirements(device(), image_protected.handle(), &mem_reqs_protected);
vk::GetBufferMemoryRequirements(device(), buffer_protected.handle(), &mem_reqs_protected);
VkMemoryRequirements mem_reqs_unprotected;
vk::GetImageMemoryRequirements(device(), image_unprotected.handle(), &mem_reqs_unprotected);
vk::GetBufferMemoryRequirements(device(), buffer_unprotected.handle(), &mem_reqs_unprotected);
// Get memory index for a protected and unprotected memory
VkPhysicalDeviceMemoryProperties phys_mem_props;
vk::GetPhysicalDeviceMemoryProperties(gpu(), &phys_mem_props);
uint32_t memory_type_protected = phys_mem_props.memoryTypeCount + 1;
uint32_t memory_type_unprotected = phys_mem_props.memoryTypeCount + 1;
for (uint32_t i = 0; i < phys_mem_props.memoryTypeCount; i++) {
if ((mem_reqs_unprotected.memoryTypeBits & (1 << i)) &&
((phys_mem_props.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) ==
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)) {
memory_type_unprotected = i;
}
// Check just protected bit is in type at all
if ((mem_reqs_protected.memoryTypeBits & (1 << i)) &&
((phys_mem_props.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_PROTECTED_BIT) != 0)) {
memory_type_protected = i;
}
}
if ((memory_type_protected >= phys_mem_props.memoryTypeCount) || (memory_type_unprotected >= phys_mem_props.memoryTypeCount)) {
GTEST_SKIP() << "No valid memory type index could be found";
}
alloc_info.memoryTypeIndex = memory_type_protected;
alloc_info.allocationSize = mem_reqs_protected.size;
vkt::DeviceMemory memory_protected(*m_device, alloc_info);
alloc_info.allocationSize = mem_reqs_unprotected.size;
alloc_info.memoryTypeIndex = memory_type_unprotected;
vkt::DeviceMemory memory_unprotected(*m_device, alloc_info);
// Bind protected buffer with unprotected memory
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkBindBufferMemory-None-01898");
m_errorMonitor->SetUnexpectedError("VUID-vkBindBufferMemory-memory-01035");
vk::BindBufferMemory(device(), buffer_protected.handle(), memory_unprotected.handle(), 0);
m_errorMonitor->VerifyFound();
// Bind unprotected buffer with protected memory
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkBindBufferMemory-None-01899");
m_errorMonitor->SetUnexpectedError("VUID-vkBindBufferMemory-memory-01035");
vk::BindBufferMemory(device(), buffer_unprotected.handle(), memory_protected.handle(), 0);
m_errorMonitor->VerifyFound();
// Bind protected image with unprotected memory
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkBindImageMemory-None-01901");
m_errorMonitor->SetUnexpectedError("VUID-vkBindImageMemory-memory-01047");
vk::BindImageMemory(device(), image_protected.handle(), memory_unprotected.handle(), 0);
m_errorMonitor->VerifyFound();
// Bind unprotected image with protected memory
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkBindImageMemory-None-01902");
m_errorMonitor->SetUnexpectedError("VUID-vkBindImageMemory-memory-01047");
vk::BindImageMemory(device(), image_unprotected.handle(), memory_protected.handle(), 0);
m_errorMonitor->VerifyFound();
}
TEST_F(NegativeProtectedMemory, UniqueQueueDeviceCreationBothProtected) {
TEST_DESCRIPTION("Vulkan 1.1 unique queue detection where both are protected and same queue family");
SetTargetApiVersion(VK_API_VERSION_1_1);
AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
RETURN_IF_SKIP(InitFramework())
// Needed for both protected memory and vkGetDeviceQueue2
VkPhysicalDeviceProtectedMemoryFeatures protected_features = vku::InitStructHelper();
GetPhysicalDeviceFeatures2(protected_features);
if (protected_features.protectedMemory == VK_FALSE) {
GTEST_SKIP() << "test requires protectedMemory";
}
// Try to find a protected queue family type
bool protected_queue = false;
VkQueueFamilyProperties queue_properties; // selected queue family used
uint32_t queue_family_index = 0;
uint32_t queue_family_count = 0;
vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_family_count, nullptr);
std::vector<VkQueueFamilyProperties> queue_families(queue_family_count);
vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_family_count, queue_families.data());
for (size_t i = 0; i < queue_families.size(); i++) {
// need to have at least 2 queues to use
if (((queue_families[i].queueFlags & VK_QUEUE_PROTECTED_BIT) != 0) && (queue_families[i].queueCount > 1)) {
protected_queue = true;
queue_family_index = i;
queue_properties = queue_families[i];
break;
}
}
if (protected_queue == false) {
GTEST_SKIP() << "test requires queue with VK_QUEUE_PROTECTED_BIT with 2 queues, not available";
}
float queue_priority = 1.0;
VkDeviceQueueCreateInfo queue_create_info[2];
queue_create_info[0] = vku::InitStructHelper();
queue_create_info[0].flags = 0;
queue_create_info[0].queueFamilyIndex = queue_family_index;
queue_create_info[0].queueCount = 1;
queue_create_info[0].pQueuePriorities = &queue_priority;
// queueFamilyIndex is the same and both are empty flags
queue_create_info[1] = queue_create_info[0];
VkDevice test_device = VK_NULL_HANDLE;
VkDeviceCreateInfo device_create_info = vku::InitStructHelper(&protected_features);
device_create_info.flags = 0;
device_create_info.pQueueCreateInfos = queue_create_info;
device_create_info.queueCreateInfoCount = 2;
device_create_info.pEnabledFeatures = nullptr;
device_create_info.enabledLayerCount = 0;
device_create_info.enabledExtensionCount = 0;
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceCreateInfo-queueFamilyIndex-02802");
vk::CreateDevice(gpu(), &device_create_info, nullptr, &test_device);
m_errorMonitor->VerifyFound();
// both protected
queue_create_info[0].flags = VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT;
queue_create_info[1].flags = VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT;
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceCreateInfo-queueFamilyIndex-02802");
vk::CreateDevice(gpu(), &device_create_info, nullptr, &test_device);
m_errorMonitor->VerifyFound();
}
TEST_F(NegativeProtectedMemory, GetDeviceQueue) {
TEST_DESCRIPTION("General testing of vkGetDeviceQueue and general Device creation cases");
SetTargetApiVersion(VK_API_VERSION_1_1);
AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
RETURN_IF_SKIP(InitFramework())
// Needed for both protected memory and vkGetDeviceQueue2
if (IsDriver(VK_DRIVER_ID_MESA_RADV)) {
GTEST_SKIP() << "This test should not be run on the RADV driver.";
}
VkDeviceQueueInfo2 queue_info_2 = vku::InitStructHelper();
VkDevice test_device = VK_NULL_HANDLE;
VkQueue test_queue = VK_NULL_HANDLE;
VkResult result;
// Use the first Physical device and queue family
// Makes test more portable as every driver has at least 1 queue with a queueCount of 1
uint32_t queue_family_count = 1;
uint32_t queue_family_index = 0;
VkQueueFamilyProperties queue_properties;
vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_family_count, &queue_properties);
float queue_priority = 1.0;
VkDeviceQueueCreateInfo queue_create_info = vku::InitStructHelper();
queue_create_info.flags = VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT;
queue_create_info.queueFamilyIndex = queue_family_index;
queue_create_info.queueCount = 1;
queue_create_info.pQueuePriorities = &queue_priority;
VkPhysicalDeviceProtectedMemoryFeatures protect_features = vku::InitStructHelper();
protect_features.protectedMemory = VK_FALSE; // Starting with it off
VkDeviceCreateInfo device_create_info = vku::InitStructHelper(&protect_features);
device_create_info.flags = 0;
device_create_info.pQueueCreateInfos = &queue_create_info;
device_create_info.queueCreateInfoCount = 1;
device_create_info.pEnabledFeatures = nullptr;
device_create_info.enabledLayerCount = 0;
device_create_info.enabledExtensionCount = 0;
// Protect feature not set
m_errorMonitor->SetUnexpectedError("VUID-VkDeviceQueueCreateInfo-flags-06449");
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceQueueCreateInfo-flags-02861");
vk::CreateDevice(gpu(), &device_create_info, nullptr, &test_device);
m_errorMonitor->VerifyFound();
GetPhysicalDeviceFeatures2(protect_features);
if (protect_features.protectedMemory == VK_TRUE) {
// Might not have protected queue support
m_errorMonitor->SetUnexpectedError("VUID-VkDeviceQueueCreateInfo-flags-06449");
result = vk::CreateDevice(gpu(), &device_create_info, nullptr, &test_device);
if (result != VK_SUCCESS) {
GTEST_SKIP() << "CreateDevice returned back not VK_SUCCESS";
}
// Try using GetDeviceQueue with a queue that has as flag
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkGetDeviceQueue-flags-01841");
vk::GetDeviceQueue(test_device, queue_family_index, 0, &test_queue);
m_errorMonitor->VerifyFound();
// Test device created with flag and trying to query with no flag
queue_info_2.flags = 0;
queue_info_2.queueFamilyIndex = queue_family_index;
queue_info_2.queueIndex = 0;
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceQueueInfo2-flags-06225");
vk::GetDeviceQueue2(test_device, &queue_info_2, &test_queue);
m_errorMonitor->VerifyFound();
vk::DestroyDevice(test_device, nullptr);
test_device = VK_NULL_HANDLE;
}
// Create device without protected queue
protect_features.protectedMemory = VK_FALSE;
queue_create_info.flags = 0;
result = vk::CreateDevice(gpu(), &device_create_info, nullptr, &test_device);
if (result != VK_SUCCESS) {
GTEST_SKIP() << "CreateDevice returned back not VK_SUCCESS";
}
if (queue_properties.queueCount > 1) {
// Set queueIndex 1 over size of queueCount used to create device
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkGetDeviceQueue-queueIndex-00385");
vk::GetDeviceQueue(test_device, queue_family_index, 1, &test_queue);
m_errorMonitor->VerifyFound();
}
// Use an unknown queue family index
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkGetDeviceQueue-queueFamilyIndex-00384");
vk::GetDeviceQueue(test_device, queue_family_index + 1, 0, &test_queue);
m_errorMonitor->VerifyFound();
queue_info_2.flags = 0; // same as device creation
queue_info_2.queueFamilyIndex = queue_family_index;
queue_info_2.queueIndex = 0;
if (queue_properties.queueCount > 1) {
// Set queueIndex 1 over size of queueCount used to create device
queue_info_2.queueIndex = 1;
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceQueueInfo2-queueIndex-01843");
vk::GetDeviceQueue2(test_device, &queue_info_2, &test_queue);
m_errorMonitor->VerifyFound();
queue_info_2.queueIndex = 0; // reset
}
// Use an unknown queue family index
queue_info_2.queueFamilyIndex = queue_family_index + 1;
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceQueueInfo2-queueFamilyIndex-01842");
vk::GetDeviceQueue2(test_device, &queue_info_2, &test_queue);
m_errorMonitor->VerifyFound();
queue_info_2.queueFamilyIndex = queue_family_index; // reset
// Test device created with no flags and trying to query with flag
queue_info_2.flags = VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT;
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceQueueInfo2-flags-06225");
vk::GetDeviceQueue2(test_device, &queue_info_2, &test_queue);
m_errorMonitor->VerifyFound();
queue_info_2.flags = 0; // reset
// Sanity check can still get the queue
vk::GetDeviceQueue(test_device, queue_family_index, 0, &test_queue);
vk::DestroyDevice(test_device, nullptr);
}
TEST_F(NegativeProtectedMemory, PipelineProtectedAccess) {
TEST_DESCRIPTION("Test VUIDs from VK_EXT_pipeline_protected_access");
SetTargetApiVersion(VK_API_VERSION_1_1);
AddRequiredExtensions(VK_EXT_PIPELINE_PROTECTED_ACCESS_EXTENSION_NAME);
AddOptionalExtensions(VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME);
RETURN_IF_SKIP(InitFramework())
const bool pipeline_libraries = IsExtensionsEnabled(VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME);
VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT gpl_features = vku::InitStructHelper();
VkPhysicalDeviceProtectedMemoryFeatures protected_memory_features = vku::InitStructHelper();
if (pipeline_libraries) protected_memory_features.pNext = &gpl_features;
VkPhysicalDevicePipelineProtectedAccessFeaturesEXT pipeline_protected_access_features =
vku::InitStructHelper(&protected_memory_features);
auto features2 = GetPhysicalDeviceFeatures2(pipeline_protected_access_features);
pipeline_protected_access_features.pipelineProtectedAccess = VK_TRUE;
if (protected_memory_features.protectedMemory == VK_FALSE) {
GTEST_SKIP() << "protectedMemory feature not supported";
};
RETURN_IF_SKIP(InitState(nullptr, &features2, VK_COMMAND_POOL_CREATE_PROTECTED_BIT));
InitRenderTarget();
CreatePipelineHelper pipe(*this);
pipe.InitState();
pipe.shader_stages_ = {pipe.vs_->GetStageCreateInfo()};
pipe.gp_ci_.flags = VK_PIPELINE_CREATE_NO_PROTECTED_ACCESS_BIT_EXT | VK_PIPELINE_CREATE_PROTECTED_ACCESS_ONLY_BIT_EXT;
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkGraphicsPipelineCreateInfo-flags-07369");
pipe.CreateGraphicsPipeline();
m_errorMonitor->VerifyFound();
pipe.gp_ci_.flags = VK_PIPELINE_CREATE_NO_PROTECTED_ACCESS_BIT_EXT;
pipe.CreateGraphicsPipeline();
m_commandBuffer->begin();
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindPipeline-pipelineProtectedAccess-07408");
vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.Handle());
m_errorMonitor->VerifyFound();
CreatePipelineHelper protected_pipe(*this);
protected_pipe.InitState();
protected_pipe.shader_stages_ = {protected_pipe.vs_->GetStageCreateInfo()};
protected_pipe.gp_ci_.flags = VK_PIPELINE_CREATE_PROTECTED_ACCESS_ONLY_BIT_EXT;
protected_pipe.CreateGraphicsPipeline();
vkt::CommandPool command_pool(*m_device, m_device->graphics_queue_node_index_);
vkt::CommandBuffer unprotected_cmdbuf(m_device, &command_pool);
unprotected_cmdbuf.begin();
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindPipeline-pipelineProtectedAccess-07409");
vk::CmdBindPipeline(unprotected_cmdbuf.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, protected_pipe.Handle());
m_errorMonitor->VerifyFound();
if (pipeline_libraries) {
CreatePipelineHelper pre_raster_lib(*this);
const auto vs_spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl);
VkShaderModuleCreateInfo vs_ci = vku::InitStructHelper();
vs_ci.codeSize = vs_spv.size() * sizeof(decltype(vs_spv)::value_type);
vs_ci.pCode = vs_spv.data();
VkPipelineShaderStageCreateInfo stage_ci = vku::InitStructHelper(&vs_ci);
stage_ci.stage = VK_SHADER_STAGE_VERTEX_BIT;
stage_ci.module = VK_NULL_HANDLE;
stage_ci.pName = "main";
pre_raster_lib.InitPreRasterLibInfo(&stage_ci);
pre_raster_lib.pipeline_layout_ci_.flags |= VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT;
pre_raster_lib.InitState();
ASSERT_EQ(VK_SUCCESS, pre_raster_lib.CreateGraphicsPipeline());
VkPipeline libraries[1] = {
pre_raster_lib.pipeline_,
};
VkPipelineLibraryCreateInfoKHR link_info = vku::InitStructHelper();
link_info.libraryCount = size(libraries);
link_info.pLibraries = libraries;
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkPipelineLibraryCreateInfoKHR-pipeline-07404");
VkGraphicsPipelineCreateInfo lib_ci = vku::InitStructHelper(&link_info);
lib_ci.flags = VK_PIPELINE_CREATE_NO_PROTECTED_ACCESS_BIT_EXT;
vkt::Pipeline lib(*m_device, lib_ci);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkPipelineLibraryCreateInfoKHR-pipeline-07406");
lib_ci.flags = VK_PIPELINE_CREATE_PROTECTED_ACCESS_ONLY_BIT_EXT;
vkt::Pipeline lib2(*m_device, lib_ci);
m_errorMonitor->VerifyFound();
CreatePipelineHelper protected_pre_raster_lib(*this);
protected_pre_raster_lib.InitPreRasterLibInfo(&stage_ci);
protected_pre_raster_lib.pipeline_layout_ci_.flags |= VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT;
protected_pre_raster_lib.InitState();
protected_pre_raster_lib.gp_ci_.flags = VK_PIPELINE_CREATE_PROTECTED_ACCESS_ONLY_BIT_EXT;
ASSERT_EQ(VK_SUCCESS, protected_pre_raster_lib.CreateGraphicsPipeline());
libraries[0] = protected_pre_raster_lib.pipeline_;
VkGraphicsPipelineCreateInfo protected_lib_ci = vku::InitStructHelper(&link_info);
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkPipelineLibraryCreateInfoKHR-pipeline-07407");
lib_ci.flags = 0;
vkt::Pipeline lib3(*m_device, protected_lib_ci);
m_errorMonitor->VerifyFound();
CreatePipelineHelper unprotected_pre_raster_lib(*this);
unprotected_pre_raster_lib.InitPreRasterLibInfo(&stage_ci);
unprotected_pre_raster_lib.pipeline_layout_ci_.flags |= VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT;
unprotected_pre_raster_lib.InitState();
unprotected_pre_raster_lib.gp_ci_.flags = VK_PIPELINE_CREATE_NO_PROTECTED_ACCESS_BIT_EXT;
ASSERT_EQ(VK_SUCCESS, unprotected_pre_raster_lib.CreateGraphicsPipeline());
libraries[0] = unprotected_pre_raster_lib.pipeline_;
VkGraphicsPipelineCreateInfo unprotected_lib_ci = vku::InitStructHelper(&link_info);
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkPipelineLibraryCreateInfoKHR-pipeline-07405");
vkt::Pipeline lib4(*m_device, unprotected_lib_ci);
m_errorMonitor->VerifyFound();
}
// Create device without protected access features
vkt::Device test_device(gpu());
VkShaderObj vs2(this, kVertexMinimalGlsl, VK_SHADER_STAGE_VERTEX_BIT, SPV_ENV_VULKAN_1_0, SPV_SOURCE_GLSL_TRY);
vs2.InitFromGLSLTry(false, &test_device);
const vkt::PipelineLayout test_pipeline_layout(test_device);
VkAttachmentReference attach = {};
attach.layout = VK_IMAGE_LAYOUT_GENERAL;
VkSubpassDescription subpass = {};
subpass.pColorAttachments = &attach;
subpass.colorAttachmentCount = 1;
VkAttachmentDescription attach_desc = {};
attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM;
attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
attach_desc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL;
attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
VkRenderPassCreateInfo rpci = vku::InitStructHelper();
rpci.subpassCount = 1;
rpci.pSubpasses = &subpass;
rpci.attachmentCount = 1;
rpci.pAttachments = &attach_desc;
vkt::RenderPass render_pass(test_device, rpci);
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkGraphicsPipelineCreateInfo-pipelineProtectedAccess-07368");
CreatePipelineHelper featureless_pipe(*this);
featureless_pipe.device_ = &test_device;
featureless_pipe.InitState();
featureless_pipe.rs_state_ci_.rasterizerDiscardEnable = VK_TRUE;
featureless_pipe.shader_stages_ = {vs2.GetStageCreateInfo()};
featureless_pipe.gp_ci_.flags = VK_PIPELINE_CREATE_PROTECTED_ACCESS_ONLY_BIT_EXT;
featureless_pipe.gp_ci_.layout = test_pipeline_layout.handle();
featureless_pipe.gp_ci_.renderPass = render_pass.handle();
featureless_pipe.CreateGraphicsPipeline();
m_errorMonitor->VerifyFound();
}
TEST_F(NegativeProtectedMemory, UnprotectedCommands) {
TEST_DESCRIPTION("Test making commands in unprotected command buffers that can't be used");
// protect memory added in VK 1.1
SetTargetApiVersion(VK_API_VERSION_1_1);
AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
RETURN_IF_SKIP(InitFramework())
VkPhysicalDeviceProtectedMemoryFeatures protected_memory_features = vku::InitStructHelper();
auto features2 = GetPhysicalDeviceFeatures2(protected_memory_features);
if (protected_memory_features.protectedMemory == VK_FALSE) {
GTEST_SKIP() << "protectedMemory feature not supported";
};
// Turns m_commandBuffer into a protected command buffer
RETURN_IF_SKIP(InitState(nullptr, &features2, VK_COMMAND_POOL_CREATE_PROTECTED_BIT));
InitRenderTarget();
vkt::Buffer indirect_buffer(*m_device, sizeof(VkDrawIndirectCommand), VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
vkt::Buffer indexed_indirect_buffer(*m_device, sizeof(VkDrawIndexedIndirectCommand), VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
vkt::Buffer index_buffer(*m_device, sizeof(uint32_t), VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
CreatePipelineHelper pipe(*this);
pipe.InitState();
pipe.CreateGraphicsPipeline();
VkQueryPoolCreateInfo query_pool_create_info = vku::InitStructHelper();
query_pool_create_info.queryType = VK_QUERY_TYPE_OCCLUSION;
query_pool_create_info.queryCount = 1;
vkt::QueryPool query_pool(*m_device, query_pool_create_info);
m_commandBuffer->begin();
m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirect-commandBuffer-02711");
vk::CmdDrawIndirect(m_commandBuffer->handle(), indirect_buffer.handle(), 0, 1, sizeof(VkDrawIndirectCommand));
m_errorMonitor->VerifyFound();
vk::CmdBindIndexBuffer(m_commandBuffer->handle(), index_buffer.handle(), 0, VK_INDEX_TYPE_UINT32);
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexedIndirect-commandBuffer-02711");
vk::CmdDrawIndexedIndirect(m_commandBuffer->handle(), indexed_indirect_buffer.handle(), 0, 1,
sizeof(VkDrawIndexedIndirectCommand));
m_errorMonitor->VerifyFound();
m_commandBuffer->EndRenderPass();
// Query should be outside renderpass
vk::CmdResetQueryPool(m_commandBuffer->handle(), query_pool.handle(), 0, 1);
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginQuery-commandBuffer-01885");
vk::CmdBeginQuery(m_commandBuffer->handle(), query_pool.handle(), 0, 0);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdEndQuery-commandBuffer-01886");
m_errorMonitor->SetUnexpectedError("VUID-vkCmdEndQuery-None-01923");
vk::CmdEndQuery(m_commandBuffer->handle(), query_pool.handle(), 0);
m_errorMonitor->VerifyFound();
m_commandBuffer->end();
}
TEST_F(NegativeProtectedMemory, MixingProtectedResources) {
TEST_DESCRIPTION("Test where there is mixing of protectedMemory backed resource in command buffers");
SetTargetApiVersion(VK_API_VERSION_1_1);
AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
RETURN_IF_SKIP(InitFramework())
VkPhysicalDeviceProtectedMemoryFeatures protected_memory_features = vku::InitStructHelper();
auto features2 = GetPhysicalDeviceFeatures2(protected_memory_features);
if (protected_memory_features.protectedMemory == VK_FALSE) {
GTEST_SKIP() << "protectedMemory feature not supported";
};
VkPhysicalDeviceProtectedMemoryProperties protected_memory_properties = vku::InitStructHelper();
GetPhysicalDeviceProperties2(protected_memory_properties);
// Turns m_commandBuffer into a unprotected command buffer without passing in a VkCommandPoolCreateFlags
RETURN_IF_SKIP(InitState(nullptr, &features2))
vkt::CommandPool protectedCommandPool(*m_device, m_device->graphics_queue_node_index_, VK_COMMAND_POOL_CREATE_PROTECTED_BIT);
vkt::CommandBuffer protectedCommandBuffer(m_device, &protectedCommandPool);
// Create actual protected and unprotected buffers
VkBufferCreateInfo buffer_create_info = vku::InitStructHelper();
buffer_create_info.size = 1 << 20; // 1 MB
buffer_create_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT |
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT |
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
buffer_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
buffer_create_info.flags = VK_BUFFER_CREATE_PROTECTED_BIT;
vkt::Buffer buffer_protected;
buffer_protected.init_no_mem(*m_device, buffer_create_info);
buffer_create_info.flags = 0;
vkt::Buffer buffer_unprotected;
buffer_unprotected.init_no_mem(*m_device, buffer_create_info);
// Create actual protected and unprotected images
const VkFormat image_format = VK_FORMAT_R8G8B8A8_UNORM;
VkImageObj image_protected(m_device);
VkImageObj image_unprotected(m_device);
VkImageObj image_protected_descriptor(m_device);
VkImageObj image_unprotected_descriptor(m_device);
VkImageView image_views[2];
VkImageView image_views_descriptor[2];
VkImageCreateInfo image_create_info = vku::InitStructHelper();
image_create_info.extent = {64, 64, 1};
image_create_info.format = image_format;
image_create_info.imageType = VK_IMAGE_TYPE_2D;
image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT;
image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
image_create_info.arrayLayers = 1;
image_create_info.mipLevels = 1;
image_create_info.flags = VK_IMAGE_CREATE_PROTECTED_BIT;
image_protected.init_no_mem(*m_device, image_create_info);
image_protected_descriptor.init_no_mem(*m_device, image_create_info);
image_create_info.flags = 0;
image_unprotected.init_no_mem(*m_device, image_create_info);
image_unprotected_descriptor.init_no_mem(*m_device, image_create_info);
// Create protected and unproteced memory
VkMemoryAllocateInfo alloc_info = vku::InitStructHelper();
alloc_info.allocationSize = 0;
VkMemoryRequirements mem_reqs_buffer_protected;
VkMemoryRequirements mem_reqs_buffer_unprotected;
vk::GetBufferMemoryRequirements(device(), buffer_protected.handle(), &mem_reqs_buffer_protected);
vk::GetBufferMemoryRequirements(device(), buffer_unprotected.handle(), &mem_reqs_buffer_unprotected);
VkMemoryRequirements mem_reqs_image_protected;
VkMemoryRequirements mem_reqs_image_unprotected;
vk::GetImageMemoryRequirements(device(), image_protected.handle(), &mem_reqs_image_protected);
vk::GetImageMemoryRequirements(device(), image_unprotected.handle(), &mem_reqs_image_unprotected);
m_device->phy().set_memory_type(mem_reqs_buffer_protected.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_PROTECTED_BIT);
alloc_info.allocationSize = mem_reqs_buffer_protected.size;
vkt::DeviceMemory memory_buffer_protected(*m_device, alloc_info);
m_device->phy().set_memory_type(mem_reqs_buffer_unprotected.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
VK_MEMORY_PROPERTY_PROTECTED_BIT);
alloc_info.allocationSize = mem_reqs_buffer_unprotected.size;
vkt::DeviceMemory memory_buffer_unprotected(*m_device, alloc_info);
alloc_info.allocationSize = mem_reqs_image_protected.size;
m_device->phy().set_memory_type(mem_reqs_image_protected.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_PROTECTED_BIT);
vkt::DeviceMemory memory_image_protected(*m_device, alloc_info);
m_device->phy().set_memory_type(mem_reqs_image_unprotected.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
VK_MEMORY_PROPERTY_PROTECTED_BIT);
alloc_info.allocationSize = mem_reqs_image_unprotected.size;
vkt::DeviceMemory memory_image_unprotected(*m_device, alloc_info);
vk::BindBufferMemory(device(), buffer_protected.handle(), memory_buffer_protected.handle(), 0);
vk::BindBufferMemory(device(), buffer_unprotected.handle(), memory_buffer_unprotected.handle(), 0);
vk::BindImageMemory(device(), image_protected.handle(), memory_image_protected.handle(), 0);
vk::BindImageMemory(device(), image_unprotected.handle(), memory_image_unprotected.handle(), 0);
vk::BindImageMemory(device(), image_protected_descriptor.handle(), memory_image_protected.handle(), 0);
vk::BindImageMemory(device(), image_unprotected_descriptor.handle(), memory_image_unprotected.handle(), 0);
// Change layout once memory is bound
image_protected.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
image_protected_descriptor.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
image_unprotected.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
image_unprotected_descriptor.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
// need memory bound at image view creation time
image_views[0] = image_protected.targetView(image_format);
image_views[1] = image_unprotected.targetView(image_format);
image_views_descriptor[0] = image_protected_descriptor.targetView(image_format);
image_views_descriptor[1] = image_unprotected_descriptor.targetView(image_format);
// A renderpass and framebuffer that contains a protected and unprotected image view
VkAttachmentDescription attachments[2] = {
{0, image_format, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
{0, image_format, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
};
VkAttachmentReference references[2] = {{0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
{1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}};
VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 2, references, nullptr, nullptr, 0, nullptr};
VkSubpassDependency dependency = {0,
0,
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_ACCESS_SHADER_WRITE_BIT,
VK_ACCESS_SHADER_WRITE_BIT,
VK_DEPENDENCY_BY_REGION_BIT};
VkRenderPassCreateInfo render_pass_create_info = {
VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, attachments, 1, &subpass, 1, &dependency};
vkt::RenderPass render_pass(*m_device, render_pass_create_info);
VkFramebufferCreateInfo framebuffer_create_info = {
VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, render_pass, 2, image_views, 8, 8, 1};
vkt::Framebuffer framebuffer(*m_device, framebuffer_create_info);
// Various structs used for commands
VkImageSubresourceLayers image_subresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
VkImageBlit blit_region = {};
blit_region.srcSubresource = image_subresource;
blit_region.dstSubresource = image_subresource;
blit_region.srcOffsets[0] = {0, 0, 0};
blit_region.srcOffsets[1] = {8, 8, 1};
blit_region.dstOffsets[0] = {0, 8, 0};
blit_region.dstOffsets[1] = {8, 8, 1};
VkClearColorValue clear_color = {{0, 0, 0, 0}};
VkImageSubresourceRange subresource_range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
VkBufferCopy buffer_copy = {0, 0, 64};
VkBufferImageCopy buffer_image_copy = {};
buffer_image_copy.bufferRowLength = 0;
buffer_image_copy.bufferImageHeight = 0;
buffer_image_copy.imageSubresource = image_subresource;
buffer_image_copy.imageOffset = {0, 0, 0};
buffer_image_copy.imageExtent = {1, 1, 1};
buffer_image_copy.bufferOffset = 0;
VkImageCopy image_copy = {};
image_copy.srcSubresource = image_subresource;
image_copy.srcOffset = {0, 0, 0};
image_copy.dstSubresource = image_subresource;
image_copy.dstOffset = {0, 0, 0};
image_copy.extent = {1, 1, 1};
uint32_t update_data[4] = {0, 0, 0, 0};
VkRect2D render_area = {{0, 0}, {8, 8}};
VkRenderPassBeginInfo render_pass_begin =
vku::InitStruct<VkRenderPassBeginInfo>(nullptr, render_pass.handle(), framebuffer.handle(), render_area, 0u, nullptr);
VkClearAttachment clear_attachments[2] = {{VK_IMAGE_ASPECT_COLOR_BIT, 0, {m_clear_color}},
{VK_IMAGE_ASPECT_COLOR_BIT, 1, {m_clear_color}}};
VkClearRect clear_rect[2] = {{render_area, 0, 1}, {render_area, 0, 1}};
const char fsSource[] = R"glsl(
#version 450
layout(set=0, binding=0) uniform foo { int x; int y; } bar;
layout(set=0, binding=1, rgba8) uniform image2D si1;
layout(location=0) out vec4 x;
void main(){
x = vec4(bar.y);
imageStore(si1, ivec2(0), vec4(0));
}
)glsl";
VkShaderObj fs(this, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);
CreatePipelineHelper g_pipe(*this, 2u);
g_pipe.gp_ci_.renderPass = render_pass.handle();
g_pipe.shader_stages_ = {g_pipe.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
g_pipe.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr},
{1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
g_pipe.InitState();
ASSERT_EQ(VK_SUCCESS, g_pipe.CreateGraphicsPipeline());
vkt::Sampler sampler(*m_device, SafeSaneSamplerCreateInfo());
// Use protected resources in unprotected command buffer
g_pipe.descriptor_set_->WriteDescriptorBufferInfo(0, buffer_protected.handle(), 0, 1024);
g_pipe.descriptor_set_->WriteDescriptorImageInfo(1, image_views_descriptor[0], sampler.handle(),
VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_IMAGE_LAYOUT_GENERAL);
g_pipe.descriptor_set_->UpdateDescriptorSets();
m_commandBuffer->begin();
// will get undefined values, but not invalid if protectedNoFault is supported
// Will still create an empty command buffer to test submit VUs if protectedNoFault is supported
if (!protected_memory_properties.protectedNoFault) {
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBlitImage-commandBuffer-01834");
vk::CmdBlitImage(m_commandBuffer->handle(), image_protected.handle(), VK_IMAGE_LAYOUT_GENERAL, image_unprotected.handle(),
VK_IMAGE_LAYOUT_GENERAL, 1, &blit_region, VK_FILTER_NEAREST);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBlitImage-commandBuffer-01835");
vk::CmdBlitImage(m_commandBuffer->handle(), image_unprotected.handle(), VK_IMAGE_LAYOUT_GENERAL, image_protected.handle(),
VK_IMAGE_LAYOUT_GENERAL, 1, &blit_region, VK_FILTER_NEAREST);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearColorImage-commandBuffer-01805");
vk::CmdClearColorImage(m_commandBuffer->handle(), image_protected.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1,
&subresource_range);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBuffer-commandBuffer-01822");
vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_protected.handle(), buffer_unprotected.handle(), 1, &buffer_copy);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBuffer-commandBuffer-01823");
vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_unprotected.handle(), buffer_protected.handle(), 1, &buffer_copy);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-commandBuffer-01828");
vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_protected.handle(), image_unprotected.handle(),
VK_IMAGE_LAYOUT_GENERAL, 1, &buffer_image_copy);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-commandBuffer-01829");
vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_unprotected.handle(), image_protected.handle(),
VK_IMAGE_LAYOUT_GENERAL, 1, &buffer_image_copy);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-commandBuffer-01825");
vk::CmdCopyImage(m_commandBuffer->handle(), image_protected.handle(), VK_IMAGE_LAYOUT_GENERAL, image_unprotected.handle(),
VK_IMAGE_LAYOUT_GENERAL, 1, &image_copy);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-commandBuffer-01826");
vk::CmdCopyImage(m_commandBuffer->handle(), image_unprotected.handle(), VK_IMAGE_LAYOUT_GENERAL, image_protected.handle(),
VK_IMAGE_LAYOUT_GENERAL, 1, &image_copy);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-commandBuffer-01831");
vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_protected.handle(), VK_IMAGE_LAYOUT_GENERAL,
buffer_unprotected.handle(), 1, &buffer_image_copy);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-commandBuffer-01832");
vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_unprotected.handle(), VK_IMAGE_LAYOUT_GENERAL,
buffer_protected.handle(), 1, &buffer_image_copy);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdFillBuffer-commandBuffer-01811");
vk::CmdFillBuffer(m_commandBuffer->handle(), buffer_protected.handle(), 0, 4, 0);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdUpdateBuffer-commandBuffer-01813");
vk::CmdUpdateBuffer(m_commandBuffer->handle(), buffer_protected.handle(), 0, 4, (void *)update_data);
m_errorMonitor->VerifyFound();
vk::CmdBeginRenderPass(m_commandBuffer->handle(), &render_pass_begin, VK_SUBPASS_CONTENTS_INLINE);
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearAttachments-commandBuffer-02504");
vk::CmdClearAttachments(m_commandBuffer->handle(), 2, clear_attachments, 2, clear_rect);
m_errorMonitor->VerifyFound();
vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0,
1, &g_pipe.descriptor_set_->set_, 0, nullptr);
VkDeviceSize offset = 0;
vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &buffer_protected.handle(), &offset);
vk::CmdBindIndexBuffer(m_commandBuffer->handle(), buffer_protected.handle(), 0, VK_INDEX_TYPE_UINT16);
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexed-commandBuffer-02707"); // color attachment
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexed-commandBuffer-02707"); // buffer descriptorSet
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexed-commandBuffer-02707"); // image descriptorSet
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexed-commandBuffer-02707"); // vertex
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexed-commandBuffer-02707"); // index
vk::CmdDrawIndexed(m_commandBuffer->handle(), 1, 0, 0, 0, 0);
m_errorMonitor->VerifyFound();
m_commandBuffer->EndRenderPass();
}
m_commandBuffer->end();
// Use unprotected resources in protected command buffer
g_pipe.descriptor_set_->WriteDescriptorBufferInfo(0, buffer_unprotected.handle(), 0, 1024);
g_pipe.descriptor_set_->WriteDescriptorImageInfo(1, image_views_descriptor[1], sampler.handle(),
VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_IMAGE_LAYOUT_GENERAL);
g_pipe.descriptor_set_->UpdateDescriptorSets();
protectedCommandBuffer.begin();
if (!protected_memory_properties.protectedNoFault) {
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBlitImage-commandBuffer-01836");
vk::CmdBlitImage(protectedCommandBuffer.handle(), image_protected.handle(), VK_IMAGE_LAYOUT_GENERAL,
image_unprotected.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &blit_region, VK_FILTER_NEAREST);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearColorImage-commandBuffer-01806");
vk::CmdClearColorImage(protectedCommandBuffer.handle(), image_unprotected.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color,
1, &subresource_range);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBuffer-commandBuffer-01824");
vk::CmdCopyBuffer(protectedCommandBuffer.handle(), buffer_protected.handle(), buffer_unprotected.handle(), 1, &buffer_copy);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-commandBuffer-01830");
vk::CmdCopyBufferToImage(protectedCommandBuffer.handle(), buffer_protected.handle(), image_unprotected.handle(),
VK_IMAGE_LAYOUT_GENERAL, 1, &buffer_image_copy);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-commandBuffer-01827");
vk::CmdCopyImage(protectedCommandBuffer.handle(), image_protected.handle(), VK_IMAGE_LAYOUT_GENERAL,
image_unprotected.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &image_copy);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-commandBuffer-01833");
vk::CmdCopyImageToBuffer(protectedCommandBuffer.handle(), image_protected.handle(), VK_IMAGE_LAYOUT_GENERAL,
buffer_unprotected.handle(), 1, &buffer_image_copy);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdFillBuffer-commandBuffer-01812");
vk::CmdFillBuffer(protectedCommandBuffer.handle(), buffer_unprotected.handle(), 0, 4, 0);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdUpdateBuffer-commandBuffer-01814");
vk::CmdUpdateBuffer(protectedCommandBuffer.handle(), buffer_unprotected.handle(), 0, 4, (void *)update_data);
m_errorMonitor->VerifyFound();
vk::CmdBeginRenderPass(protectedCommandBuffer.handle(), &render_pass_begin, VK_SUBPASS_CONTENTS_INLINE);
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearAttachments-commandBuffer-02505");
vk::CmdClearAttachments(protectedCommandBuffer.handle(), 2, clear_attachments, 2, clear_rect);
m_errorMonitor->VerifyFound();
vk::CmdBindPipeline(protectedCommandBuffer.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
vk::CmdBindDescriptorSets(protectedCommandBuffer.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS,
g_pipe.pipeline_layout_.handle(), 0, 1, &g_pipe.descriptor_set_->set_, 0, nullptr);
VkDeviceSize offset = 0;
vk::CmdBindVertexBuffers(protectedCommandBuffer.handle(), 0, 1, &buffer_unprotected.handle(), &offset);
vk::CmdBindIndexBuffer(protectedCommandBuffer.handle(), buffer_unprotected.handle(), 0, VK_INDEX_TYPE_UINT16);
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexed-commandBuffer-02712"); // color attachment
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexed-commandBuffer-02712"); // descriptorSet
vk::CmdDrawIndexed(protectedCommandBuffer.handle(), 1, 0, 0, 0, 0);
m_errorMonitor->VerifyFound();
vk::CmdEndRenderPass(protectedCommandBuffer.handle());
}
protectedCommandBuffer.end();
// Try submitting together to test only 1 error occurs for the corresponding command buffer
VkCommandBuffer comman_buffers[2] = {m_commandBuffer->handle(), protectedCommandBuffer.handle()};
VkProtectedSubmitInfo protected_submit_info = vku::InitStructHelper();
VkSubmitInfo submit_info = vku::InitStructHelper(&protected_submit_info);
submit_info.commandBufferCount = 2;
submit_info.pCommandBuffers = comman_buffers;
protected_submit_info.protectedSubmit = VK_TRUE;
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkQueueSubmit-queue-06448");
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubmitInfo-pNext-04148");
vk::QueueSubmit(m_default_queue, 1, &submit_info, VK_NULL_HANDLE);
m_errorMonitor->VerifyFound();
protected_submit_info.protectedSubmit = VK_FALSE;
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubmitInfo-pNext-04120");
vk::QueueSubmit(m_default_queue, 1, &submit_info, VK_NULL_HANDLE);
m_errorMonitor->VerifyFound();
// If the VkSubmitInfo::pNext chain does not include this structure, the batch is unprotected.
submit_info.pNext = nullptr;
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubmitInfo-pNext-04120");
vk::QueueSubmit(m_default_queue, 1, &submit_info, VK_NULL_HANDLE);
m_errorMonitor->VerifyFound();
}