blob: e880c1fe66b4db4e4527cf952665fe9ed5eaa087 [file] [log] [blame]
/*
* Copyright (c) 2015-2025 The Khronos Group Inc.
* Copyright (c) 2015-2025 Valve Corporation
* Copyright (c) 2015-2025 LunarG, Inc.
* Copyright (c) 2015-2025 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 "../framework/layer_validation_tests.h"
#include "../framework/pipeline_helper.h"
#include "../framework/render_pass_helper.h"
class NegativeProtectedMemory : public VkLayerTest {};
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->SetDesiredError("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);
// creates a queue without VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT
RETURN_IF_SKIP(Init());
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->SetDesiredError("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;
CreateBufferTest(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(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->SetDesiredError("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_command_buffer.handle();
m_command_buffer.Begin();
m_command_buffer.End();
m_errorMonitor->SetDesiredError("VUID-vkQueueSubmit-queue-06448");
m_errorMonitor->SetUnexpectedError("VUID-VkSubmitInfo-pNext-04148");
vk::QueueSubmit(m_default_queue->handle(), 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);
AddRequiredFeature(vkt::Feature::sparseBinding);
AddRequiredFeature(vkt::Feature::protectedMemory);
RETURN_IF_SKIP(InitFramework());
RETURN_IF_SKIP(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_PROTECTED_BIT));
bool sparse_support = (m_device->Physical().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;
if (sparse_support == true) {
CreateBufferTest(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(*m_device, buffer_create_info, vkt::no_mem);
buffer_create_info.flags = 0;
vkt::Buffer buffer_unprotected(*m_device, buffer_create_info, vkt::no_mem);
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(image_create_info, "VUID-VkImageCreateInfo-None-01891");
}
// Create actual protected and unprotected images
image_create_info.flags = VK_IMAGE_CREATE_PROTECTED_BIT;
vkt::Image image_protected(*m_device, image_create_info, vkt::no_mem);
image_create_info.flags = 0;
vkt::Image image_unprotected(*m_device, image_create_info, vkt::no_mem);
// 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, &mem_reqs_protected);
vk::GetBufferMemoryRequirements(device(), buffer_protected, &mem_reqs_protected);
VkMemoryRequirements mem_reqs_unprotected;
vk::GetImageMemoryRequirements(device(), image_unprotected, &mem_reqs_unprotected);
vk::GetBufferMemoryRequirements(device(), buffer_unprotected, &mem_reqs_unprotected);
alloc_info.allocationSize = mem_reqs_protected.size;
bool found =
m_device->Physical().SetMemoryType(mem_reqs_unprotected.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_PROTECTED_BIT);
if (!found) {
GTEST_SKIP() << "Memory type not found";
}
vkt::DeviceMemory memory_protected(*m_device, alloc_info);
alloc_info.allocationSize = mem_reqs_unprotected.size;
found = m_device->Physical().SetMemoryType(mem_reqs_unprotected.memoryTypeBits, &alloc_info,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_PROTECTED_BIT);
if (!found) {
GTEST_SKIP() << "Memory type not found";
}
vkt::DeviceMemory memory_unprotected(*m_device, alloc_info);
// Bind protected buffer with unprotected memory
m_errorMonitor->SetDesiredError("VUID-vkBindBufferMemory-None-01898");
m_errorMonitor->SetUnexpectedError("VUID-vkBindBufferMemory-memory-01035");
vk::BindBufferMemory(device(), buffer_protected, memory_unprotected, 0);
m_errorMonitor->VerifyFound();
// Bind unprotected buffer with protected memory
m_errorMonitor->SetDesiredError("VUID-vkBindBufferMemory-None-01899");
m_errorMonitor->SetUnexpectedError("VUID-vkBindBufferMemory-memory-01035");
vk::BindBufferMemory(device(), buffer_unprotected, memory_protected, 0);
m_errorMonitor->VerifyFound();
// Bind protected image with unprotected memory
m_errorMonitor->SetDesiredError("VUID-vkBindImageMemory-None-01901");
m_errorMonitor->SetUnexpectedError("VUID-vkBindImageMemory-memory-01047");
vk::BindImageMemory(device(), image_protected, memory_unprotected, 0);
m_errorMonitor->VerifyFound();
// Bind unprotected image with protected memory
m_errorMonitor->SetDesiredError("VUID-vkBindImageMemory-None-01902");
m_errorMonitor->SetUnexpectedError("VUID-vkBindImageMemory-memory-01047");
vk::BindImageMemory(device(), image_unprotected, memory_protected, 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->SetDesiredError("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->SetDesiredError("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");
all_queue_count_ = true;
SetTargetApiVersion(VK_API_VERSION_1_1);
AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
RETURN_IF_SKIP(InitFramework());
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->SetDesiredError("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->SetDesiredError("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->SetDesiredError("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->SetDesiredError("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->SetDesiredError("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->SetDesiredError("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->SetDesiredError("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->SetDesiredError("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);
AddRequiredFeature(vkt::Feature::protectedMemory);
AddRequiredFeature(vkt::Feature::pipelineProtectedAccess);
RETURN_IF_SKIP(InitFramework());
RETURN_IF_SKIP(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_PROTECTED_BIT));
InitRenderTarget();
CreatePipelineHelper pipe(*this);
pipe.VertexShaderOnly();
pipe.gp_ci_.flags = VK_PIPELINE_CREATE_NO_PROTECTED_ACCESS_BIT | VK_PIPELINE_CREATE_PROTECTED_ACCESS_ONLY_BIT;
m_errorMonitor->SetDesiredError("VUID-VkGraphicsPipelineCreateInfo-flags-07369");
pipe.CreateGraphicsPipeline();
m_errorMonitor->VerifyFound();
pipe.gp_ci_.flags = VK_PIPELINE_CREATE_NO_PROTECTED_ACCESS_BIT;
pipe.CreateGraphicsPipeline();
m_command_buffer.Begin();
m_errorMonitor->SetDesiredError("VUID-vkCmdBindPipeline-pipelineProtectedAccess-07408");
vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
m_errorMonitor->VerifyFound();
CreatePipelineHelper protected_pipe(*this);
protected_pipe.shader_stages_ = {protected_pipe.vs_->GetStageCreateInfo()};
protected_pipe.gp_ci_.flags = VK_PIPELINE_CREATE_PROTECTED_ACCESS_ONLY_BIT;
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->SetDesiredError("VUID-vkCmdBindPipeline-pipelineProtectedAccess-07409");
vk::CmdBindPipeline(unprotected_cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS, protected_pipe);
m_errorMonitor->VerifyFound();
// Create device without protected access features
vkt::Device test_device(Gpu(), m_device_extension_names);
VkShaderObj vs2(*m_device, kVertexMinimalGlsl, VK_SHADER_STAGE_VERTEX_BIT, SPV_ENV_VULKAN_1_0, SPV_SOURCE_GLSL_TRY);
vs2.InitFromGLSLTry(&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->SetDesiredError("VUID-VkGraphicsPipelineCreateInfo-pipelineProtectedAccess-07368");
CreatePipelineHelper featureless_pipe(*this);
featureless_pipe.device_ = &test_device;
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;
featureless_pipe.gp_ci_.layout = test_pipeline_layout;
featureless_pipe.gp_ci_.renderPass = render_pass;
featureless_pipe.CreateGraphicsPipeline();
m_errorMonitor->VerifyFound();
}
TEST_F(NegativeProtectedMemory, PipelineProtectedAccessGPL) {
TEST_DESCRIPTION("Test VUIDs from VK_EXT_pipeline_protected_access");
SetTargetApiVersion(VK_API_VERSION_1_1);
AddRequiredExtensions(VK_EXT_PIPELINE_PROTECTED_ACCESS_EXTENSION_NAME);
AddRequiredExtensions(VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME);
AddRequiredFeature(vkt::Feature::graphicsPipelineLibrary);
AddRequiredFeature(vkt::Feature::protectedMemory);
AddRequiredFeature(vkt::Feature::pipelineProtectedAccess);
RETURN_IF_SKIP(Init());
InitRenderTarget();
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;
ASSERT_EQ(VK_SUCCESS, pre_raster_lib.CreateGraphicsPipeline());
VkPipeline libraries[1] = {
pre_raster_lib,
};
VkPipelineLibraryCreateInfoKHR link_info = vku::InitStructHelper();
link_info.libraryCount = size32(libraries);
link_info.pLibraries = libraries;
m_errorMonitor->SetDesiredError("VUID-VkPipelineLibraryCreateInfoKHR-pipeline-07404");
VkGraphicsPipelineCreateInfo lib_ci = vku::InitStructHelper(&link_info);
lib_ci.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR | VK_PIPELINE_CREATE_NO_PROTECTED_ACCESS_BIT;
lib_ci.renderPass = RenderPass();
lib_ci.layout = pre_raster_lib.gp_ci_.layout;
vkt::Pipeline lib(*m_device, lib_ci);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-VkPipelineLibraryCreateInfoKHR-pipeline-07406");
lib_ci.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR | VK_PIPELINE_CREATE_PROTECTED_ACCESS_ONLY_BIT;
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.gp_ci_.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR | VK_PIPELINE_CREATE_PROTECTED_ACCESS_ONLY_BIT;
ASSERT_EQ(VK_SUCCESS, protected_pre_raster_lib.CreateGraphicsPipeline());
libraries[0] = protected_pre_raster_lib;
VkGraphicsPipelineCreateInfo protected_lib_ci = vku::InitStructHelper(&link_info);
protected_lib_ci.renderPass = RenderPass();
protected_lib_ci.layout = pre_raster_lib.gp_ci_.layout;
m_errorMonitor->SetDesiredError("VUID-VkPipelineLibraryCreateInfoKHR-pipeline-07407");
lib_ci.flags = 0;
protected_lib_ci.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR;
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.gp_ci_.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR | VK_PIPELINE_CREATE_NO_PROTECTED_ACCESS_BIT;
ASSERT_EQ(VK_SUCCESS, unprotected_pre_raster_lib.CreateGraphicsPipeline());
libraries[0] = unprotected_pre_raster_lib;
VkGraphicsPipelineCreateInfo unprotected_lib_ci = vku::InitStructHelper(&link_info);
unprotected_lib_ci.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR;
unprotected_lib_ci.renderPass = RenderPass();
unprotected_lib_ci.layout = pre_raster_lib.gp_ci_.layout;
m_errorMonitor->SetDesiredError("VUID-VkPipelineLibraryCreateInfoKHR-pipeline-07405");
vkt::Pipeline lib4(*m_device, unprotected_lib_ci);
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);
AddRequiredFeature(vkt::Feature::protectedMemory);
RETURN_IF_SKIP(InitFramework());
// Turns m_command_buffer into a protected command buffer
RETURN_IF_SKIP(InitState(nullptr, nullptr, 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.CreateGraphicsPipeline();
vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_OCCLUSION, 1);
m_command_buffer.Begin();
m_command_buffer.BeginRenderPass(m_renderPassBeginInfo);
vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndirect-commandBuffer-02711");
vk::CmdDrawIndirect(m_command_buffer, indirect_buffer, 0, 1, sizeof(VkDrawIndirectCommand));
m_errorMonitor->VerifyFound();
vk::CmdBindIndexBuffer(m_command_buffer, index_buffer, 0, VK_INDEX_TYPE_UINT32);
m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexedIndirect-commandBuffer-02711");
vk::CmdDrawIndexedIndirect(m_command_buffer, indexed_indirect_buffer, 0, 1, sizeof(VkDrawIndexedIndirectCommand));
m_errorMonitor->VerifyFound();
m_command_buffer.EndRenderPass();
// Query should be outside renderpass
vk::CmdResetQueryPool(m_command_buffer, query_pool, 0, 1);
m_errorMonitor->SetDesiredError("VUID-vkCmdBeginQuery-commandBuffer-01885");
vk::CmdBeginQuery(m_command_buffer, query_pool, 0, 0);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkCmdEndQuery-commandBuffer-01886");
m_errorMonitor->SetUnexpectedError("VUID-vkCmdEndQuery-None-01923");
vk::CmdEndQuery(m_command_buffer, query_pool, 0);
m_errorMonitor->VerifyFound();
m_command_buffer.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);
AddRequiredFeature(vkt::Feature::fragmentStoresAndAtomics);
AddRequiredFeature(vkt::Feature::protectedMemory);
RETURN_IF_SKIP(Init());
VkPhysicalDeviceProtectedMemoryProperties protected_memory_properties = vku::InitStructHelper();
GetPhysicalDeviceProperties2(protected_memory_properties);
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.flags = VK_BUFFER_CREATE_PROTECTED_BIT;
vkt::Buffer buffer_protected(*m_device, buffer_create_info, vkt::no_mem);
buffer_create_info.flags = 0;
vkt::Buffer buffer_unprotected(*m_device, buffer_create_info, vkt::no_mem);
// Create actual protected and unprotected images
const VkFormat image_format = VK_FORMAT_R8G8B8A8_UNORM;
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;
vkt::Image image_protected(*m_device, image_create_info, vkt::no_mem);
vkt::Image image_protected_descriptor(*m_device, image_create_info, vkt::no_mem);
image_create_info.flags = 0;
vkt::Image image_unprotected(*m_device, image_create_info, vkt::no_mem);
vkt::Image image_unprotected_descriptor(*m_device, image_create_info, vkt::no_mem);
// 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, &mem_reqs_buffer_protected);
vk::GetBufferMemoryRequirements(device(), buffer_unprotected, &mem_reqs_buffer_unprotected);
VkMemoryRequirements mem_reqs_image_protected;
VkMemoryRequirements mem_reqs_image_unprotected;
vk::GetImageMemoryRequirements(device(), image_protected, &mem_reqs_image_protected);
vk::GetImageMemoryRequirements(device(), image_unprotected, &mem_reqs_image_unprotected);
bool found =
m_device->Physical().SetMemoryType(mem_reqs_buffer_protected.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_PROTECTED_BIT);
if (!found) {
GTEST_SKIP() << "Memory type not found";
}
alloc_info.allocationSize = mem_reqs_buffer_protected.size;
vkt::DeviceMemory memory_buffer_protected(*m_device, alloc_info);
found = m_device->Physical().SetMemoryType(mem_reqs_buffer_unprotected.memoryTypeBits, &alloc_info,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_PROTECTED_BIT);
if (!found) {
GTEST_SKIP() << "Memory type not found";
}
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;
found =
m_device->Physical().SetMemoryType(mem_reqs_image_protected.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_PROTECTED_BIT);
if (!found) {
GTEST_SKIP() << "Memory type not found";
}
vkt::DeviceMemory memory_image_protected(*m_device, alloc_info);
found = m_device->Physical().SetMemoryType(mem_reqs_image_unprotected.memoryTypeBits, &alloc_info,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_PROTECTED_BIT);
if (!found) {
GTEST_SKIP() << "Memory type not found";
}
alloc_info.allocationSize = mem_reqs_image_unprotected.size;
vkt::DeviceMemory memory_image_unprotected(*m_device, alloc_info);
vk::BindBufferMemory(device(), buffer_protected, memory_buffer_protected, 0);
vk::BindBufferMemory(device(), buffer_unprotected, memory_buffer_unprotected, 0);
vk::BindImageMemory(device(), image_protected, memory_image_protected, 0);
vk::BindImageMemory(device(), image_unprotected, memory_image_unprotected, 0);
vk::BindImageMemory(device(), image_protected_descriptor, memory_image_protected, 0);
vk::BindImageMemory(device(), image_unprotected_descriptor, memory_image_unprotected, 0);
// Change layout once memory is bound
image_protected.SetLayout(VK_IMAGE_LAYOUT_GENERAL);
image_protected_descriptor.SetLayout(VK_IMAGE_LAYOUT_GENERAL);
image_unprotected.SetLayout(VK_IMAGE_LAYOUT_GENERAL);
image_unprotected_descriptor.SetLayout(VK_IMAGE_LAYOUT_GENERAL);
// need memory bound at image view creation time
vkt::ImageView view0 = image_protected.CreateView();
vkt::ImageView view1 = image_unprotected.CreateView();
image_views[0] = view0;
image_views[1] = view1;
vkt::ImageView view_descriptor0 = image_protected_descriptor.CreateView();
vkt::ImageView view_descriptor1 = image_unprotected_descriptor.CreateView();
image_views_descriptor[0] = view_descriptor0;
image_views_descriptor[1] = view_descriptor1;
// A renderpass and framebuffer that contains a protected and unprotected image view
RenderPassSingleSubpass rp(*this);
rp.AddAttachmentDescription(image_format, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
rp.AddAttachmentDescription(image_format, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
rp.AddAttachmentReference({0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL});
rp.AddAttachmentReference({1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL});
rp.AddColorAttachment(0);
rp.AddColorAttachment(1);
rp.AddSubpassDependency(VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_SHADER_WRITE_BIT);
rp.CreateRenderPass();
vkt::Framebuffer framebuffer(*m_device, rp, 2, image_views, 8, 8);
// 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}};
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(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);
VkPipelineColorBlendAttachmentState cb_attachments[2] = {};
memset(cb_attachments, 0, sizeof(VkPipelineColorBlendAttachmentState) * 2);
CreatePipelineHelper g_pipe(*this);
g_pipe.gp_ci_.renderPass = rp;
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.cb_ci_.attachmentCount = 2;
g_pipe.cb_ci_.pAttachments = cb_attachments;
g_pipe.CreateGraphicsPipeline();
vkt::Sampler sampler(*m_device, SafeSaneSamplerCreateInfo());
// Use protected resources in unprotected command buffer
g_pipe.descriptor_set_->WriteDescriptorBufferInfo(0, buffer_protected, 0, 1024);
g_pipe.descriptor_set_->WriteDescriptorImageInfo(1, image_views_descriptor[0], sampler, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
VK_IMAGE_LAYOUT_GENERAL);
g_pipe.descriptor_set_->UpdateDescriptorSets();
m_command_buffer.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->SetDesiredError("VUID-vkCmdBlitImage-commandBuffer-01834");
vk::CmdBlitImage(m_command_buffer, image_protected, VK_IMAGE_LAYOUT_GENERAL, image_unprotected, VK_IMAGE_LAYOUT_GENERAL, 1,
&blit_region, VK_FILTER_NEAREST);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkCmdBlitImage-commandBuffer-01835");
vk::CmdBlitImage(m_command_buffer, image_unprotected, VK_IMAGE_LAYOUT_GENERAL, image_protected, VK_IMAGE_LAYOUT_GENERAL, 1,
&blit_region, VK_FILTER_NEAREST);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkCmdClearColorImage-commandBuffer-01805");
vk::CmdClearColorImage(m_command_buffer, image_protected, VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1, &subresource_range);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkCmdCopyBuffer-commandBuffer-01822");
vk::CmdCopyBuffer(m_command_buffer, buffer_protected, buffer_unprotected, 1, &buffer_copy);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkCmdCopyBuffer-commandBuffer-01823");
vk::CmdCopyBuffer(m_command_buffer, buffer_unprotected, buffer_protected, 1, &buffer_copy);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkCmdCopyBufferToImage-commandBuffer-01828");
vk::CmdCopyBufferToImage(m_command_buffer, buffer_protected, image_unprotected, VK_IMAGE_LAYOUT_GENERAL, 1,
&buffer_image_copy);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkCmdCopyBufferToImage-commandBuffer-01829");
vk::CmdCopyBufferToImage(m_command_buffer, buffer_unprotected, image_protected, VK_IMAGE_LAYOUT_GENERAL, 1,
&buffer_image_copy);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkCmdCopyImage-commandBuffer-01825");
vk::CmdCopyImage(m_command_buffer, image_protected, VK_IMAGE_LAYOUT_GENERAL, image_unprotected, VK_IMAGE_LAYOUT_GENERAL, 1,
&image_copy);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkCmdCopyImage-commandBuffer-01826");
vk::CmdCopyImage(m_command_buffer, image_unprotected, VK_IMAGE_LAYOUT_GENERAL, image_protected, VK_IMAGE_LAYOUT_GENERAL, 1,
&image_copy);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkCmdCopyImageToBuffer-commandBuffer-01831");
vk::CmdCopyImageToBuffer(m_command_buffer, image_protected, VK_IMAGE_LAYOUT_GENERAL, buffer_unprotected, 1,
&buffer_image_copy);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkCmdCopyImageToBuffer-commandBuffer-01832");
vk::CmdCopyImageToBuffer(m_command_buffer, image_unprotected, VK_IMAGE_LAYOUT_GENERAL, buffer_protected, 1,
&buffer_image_copy);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkCmdFillBuffer-commandBuffer-01811");
vk::CmdFillBuffer(m_command_buffer, buffer_protected, 0, 4, 0);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkCmdUpdateBuffer-commandBuffer-01813");
vk::CmdUpdateBuffer(m_command_buffer, buffer_protected, 0, 4, (void *)update_data);
m_errorMonitor->VerifyFound();
m_command_buffer.BeginRenderPass(rp, framebuffer, render_area.extent.width, render_area.extent.height);
m_errorMonitor->SetDesiredError("VUID-vkCmdClearAttachments-commandBuffer-02504");
vk::CmdClearAttachments(m_command_buffer, 2, clear_attachments, 2, clear_rect);
m_errorMonitor->VerifyFound();
vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe);
vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_, 0, 1,
&g_pipe.descriptor_set_->set_, 0, nullptr);
VkDeviceSize offset = 0;
vk::CmdBindVertexBuffers(m_command_buffer, 0, 1, &buffer_protected.handle(), &offset);
vk::CmdBindIndexBuffer(m_command_buffer, buffer_protected, 0, VK_INDEX_TYPE_UINT16);
m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexed-commandBuffer-02707"); // color attachment
m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexed-commandBuffer-02707"); // buffer descriptorSet
m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexed-commandBuffer-02707"); // image descriptorSet
m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexed-commandBuffer-02707"); // vertex
m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexed-commandBuffer-02707"); // index
vk::CmdDrawIndexed(m_command_buffer, 1, 0, 0, 0, 0);
m_errorMonitor->VerifyFound();
m_command_buffer.EndRenderPass();
}
m_command_buffer.End();
// Use unprotected resources in protected command buffer
g_pipe.descriptor_set_->WriteDescriptorBufferInfo(0, buffer_unprotected, 0, 1024);
g_pipe.descriptor_set_->WriteDescriptorImageInfo(1, image_views_descriptor[1], sampler, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
VK_IMAGE_LAYOUT_GENERAL);
g_pipe.descriptor_set_->UpdateDescriptorSets();
protectedCommandBuffer.Begin();
if (!protected_memory_properties.protectedNoFault) {
m_errorMonitor->SetDesiredError("VUID-vkCmdBlitImage-commandBuffer-01836");
vk::CmdBlitImage(protectedCommandBuffer, image_protected, VK_IMAGE_LAYOUT_GENERAL, image_unprotected,
VK_IMAGE_LAYOUT_GENERAL, 1, &blit_region, VK_FILTER_NEAREST);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkCmdClearColorImage-commandBuffer-01806");
vk::CmdClearColorImage(protectedCommandBuffer, image_unprotected, VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1,
&subresource_range);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkCmdCopyBuffer-commandBuffer-01824");
vk::CmdCopyBuffer(protectedCommandBuffer, buffer_protected, buffer_unprotected, 1, &buffer_copy);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkCmdCopyBufferToImage-commandBuffer-01830");
vk::CmdCopyBufferToImage(protectedCommandBuffer, buffer_protected, image_unprotected, VK_IMAGE_LAYOUT_GENERAL, 1,
&buffer_image_copy);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkCmdCopyImage-commandBuffer-01827");
vk::CmdCopyImage(protectedCommandBuffer, image_protected, VK_IMAGE_LAYOUT_GENERAL, image_unprotected,
VK_IMAGE_LAYOUT_GENERAL, 1, &image_copy);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkCmdCopyImageToBuffer-commandBuffer-01833");
vk::CmdCopyImageToBuffer(protectedCommandBuffer, image_protected, VK_IMAGE_LAYOUT_GENERAL, buffer_unprotected, 1,
&buffer_image_copy);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkCmdFillBuffer-commandBuffer-01812");
vk::CmdFillBuffer(protectedCommandBuffer, buffer_unprotected, 0, 4, 0);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkCmdUpdateBuffer-commandBuffer-01814");
vk::CmdUpdateBuffer(protectedCommandBuffer, buffer_unprotected, 0, 4, (void *)update_data);
m_errorMonitor->VerifyFound();
protectedCommandBuffer.BeginRenderPass(rp, framebuffer, render_area.extent.width, render_area.extent.height);
m_errorMonitor->SetDesiredError("VUID-vkCmdClearAttachments-commandBuffer-02505");
vk::CmdClearAttachments(protectedCommandBuffer, 2, clear_attachments, 2, clear_rect);
m_errorMonitor->VerifyFound();
vk::CmdBindPipeline(protectedCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe);
vk::CmdBindDescriptorSets(protectedCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_, 0, 1,
&g_pipe.descriptor_set_->set_, 0, nullptr);
VkDeviceSize offset = 0;
vk::CmdBindVertexBuffers(protectedCommandBuffer, 0, 1, &buffer_unprotected.handle(), &offset);
vk::CmdBindIndexBuffer(protectedCommandBuffer, buffer_unprotected, 0, VK_INDEX_TYPE_UINT16);
m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexed-commandBuffer-02712"); // color attachment
m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexed-commandBuffer-02712"); // descriptorSet
vk::CmdDrawIndexed(protectedCommandBuffer, 1, 0, 0, 0, 0);
m_errorMonitor->VerifyFound();
vk::CmdEndRenderPass(protectedCommandBuffer);
}
protectedCommandBuffer.End();
// Try submitting together to test only 1 error occurs for the corresponding command buffer
VkCommandBuffer comman_buffers[2] = {m_command_buffer, protectedCommandBuffer};
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->SetDesiredError("VUID-vkQueueSubmit-queue-06448");
m_errorMonitor->SetDesiredError("VUID-VkSubmitInfo-pNext-04148");
vk::QueueSubmit(m_default_queue->handle(), 1, &submit_info, VK_NULL_HANDLE);
m_errorMonitor->VerifyFound();
protected_submit_info.protectedSubmit = VK_FALSE;
m_errorMonitor->SetDesiredError("VUID-VkSubmitInfo-pNext-04120");
vk::QueueSubmit(m_default_queue->handle(), 1, &submit_info, VK_NULL_HANDLE);
m_errorMonitor->VerifyFound();
// If the VkSubmitInfo::pNext chain does not contain an instance of this structure, the batch is unprotected.
submit_info.pNext = nullptr;
m_errorMonitor->SetDesiredError("VUID-VkSubmitInfo-pNext-04120");
vk::QueueSubmit(m_default_queue->handle(), 1, &submit_info, VK_NULL_HANDLE);
m_errorMonitor->VerifyFound();
}
TEST_F(NegativeProtectedMemory, RayTracingPipeline) {
TEST_DESCRIPTION("Bind ray tracing pipeline in a protected command buffer");
SetTargetApiVersion(VK_API_VERSION_1_3);
AddRequiredExtensions(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME);
AddRequiredExtensions(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME);
AddRequiredExtensions(VK_KHR_RAY_QUERY_EXTENSION_NAME);
AddRequiredExtensions(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
AddRequiredExtensions(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
AddRequiredExtensions(VK_KHR_SPIRV_1_4_EXTENSION_NAME);
AddRequiredExtensions(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME);
AddRequiredExtensions(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME);
AddRequiredFeature(vkt::Feature::protectedMemory);
AddRequiredFeature(vkt::Feature::rayTracingPipeline);
RETURN_IF_SKIP(InitFramework());
RETURN_IF_SKIP(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_PROTECTED_BIT));
const vkt::PipelineLayout empty_pipeline_layout(*m_device, {});
VkShaderObj rgen_shader(*m_device, kRayTracingMinimalGlsl, VK_SHADER_STAGE_RAYGEN_BIT_KHR, SPV_ENV_VULKAN_1_2);
VkShaderObj chit_shader(*m_device, kRayTracingMinimalGlsl, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, SPV_ENV_VULKAN_1_2);
const vkt::PipelineLayout pipeline_layout(*m_device, {});
std::array<VkPipelineShaderStageCreateInfo, 2> shader_stages;
shader_stages[0] = vku::InitStructHelper();
shader_stages[0].stage = VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;
shader_stages[0].module = chit_shader;
shader_stages[0].pName = "main";
shader_stages[1] = vku::InitStructHelper();
shader_stages[1].stage = VK_SHADER_STAGE_RAYGEN_BIT_KHR;
shader_stages[1].module = rgen_shader;
shader_stages[1].pName = "main";
std::array<VkRayTracingShaderGroupCreateInfoKHR, 1> shader_groups;
shader_groups[0] = vku::InitStructHelper();
shader_groups[0].type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR;
shader_groups[0].generalShader = 1;
shader_groups[0].closestHitShader = VK_SHADER_UNUSED_KHR;
shader_groups[0].anyHitShader = VK_SHADER_UNUSED_KHR;
shader_groups[0].intersectionShader = VK_SHADER_UNUSED_KHR;
VkRayTracingPipelineCreateInfoKHR raytracing_pipeline_ci = vku::InitStructHelper();
raytracing_pipeline_ci.flags = 0;
raytracing_pipeline_ci.stageCount = static_cast<uint32_t>(shader_stages.size());
raytracing_pipeline_ci.pStages = shader_stages.data();
raytracing_pipeline_ci.pGroups = shader_groups.data();
raytracing_pipeline_ci.groupCount = shader_groups.size();
raytracing_pipeline_ci.layout = pipeline_layout;
VkPipeline raytracing_pipeline = VK_NULL_HANDLE;
vk::CreateRayTracingPipelinesKHR(*m_device, VK_NULL_HANDLE, VK_NULL_HANDLE, 1, &raytracing_pipeline_ci, nullptr,
&raytracing_pipeline);
m_command_buffer.Begin();
m_errorMonitor->SetDesiredError("VUID-vkCmdBindPipeline-pipelineBindPoint-06721");
vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, raytracing_pipeline);
m_errorMonitor->VerifyFound();
m_command_buffer.End();
vk::DestroyPipeline(device(), raytracing_pipeline, nullptr);
}
TEST_F(NegativeProtectedMemory, RayQuery) {
TEST_DESCRIPTION("Bind ray tracing pipeline in a protected command buffer");
SetTargetApiVersion(VK_API_VERSION_1_1);
AddRequiredExtensions(VK_KHR_RAY_QUERY_EXTENSION_NAME);
AddRequiredFeature(vkt::Feature::rayQuery);
AddRequiredFeature(vkt::Feature::protectedMemory);
RETURN_IF_SKIP(InitFramework());
// Turns m_command_buffer into a protected command buffer
RETURN_IF_SKIP(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_PROTECTED_BIT));
InitRenderTarget();
// kFragmentMinimalGlsl but with added OpCapability RayQueryKHR
const char *spv_source = R"(
OpCapability Shader
OpCapability RayQueryKHR
OpExtension "SPV_KHR_ray_query"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %uFragColor
OpExecutionMode %main OriginUpperLeft
OpDecorate %uFragColor Location 0
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%_ptr_Output_v4float = OpTypePointer Output %v4float
%uFragColor = OpVariable %_ptr_Output_v4float Output
%float_0 = OpConstant %float 0
%float_1 = OpConstant %float 1
%12 = OpConstantComposite %v4float %float_0 %float_1 %float_0 %float_1
%main = OpFunction %void None %3
%5 = OpLabel
OpStore %uFragColor %12
OpReturn
OpFunctionEnd
)";
VkShaderObj fs(*m_device, spv_source, VK_SHADER_STAGE_FRAGMENT_BIT, SPV_ENV_VULKAN_1_0, SPV_SOURCE_ASM);
CreatePipelineHelper pipe(*this);
pipe.shader_stages_ = {pipe.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
pipe.CreateGraphicsPipeline();
m_command_buffer.Begin();
m_command_buffer.BeginRenderPass(m_renderPassBeginInfo);
vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
m_errorMonitor->SetUnexpectedError("VUID-vkCmdDraw-commandBuffer-02712"); // color attachment
m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-commandBuffer-04617"); // rayQuery
vk::CmdDraw(m_command_buffer, 3, 1, 0, 0);
m_errorMonitor->VerifyFound();
m_command_buffer.EndRenderPass();
m_command_buffer.End();
}
TEST_F(NegativeProtectedMemory, Usage) {
SetTargetApiVersion(VK_API_VERSION_1_1);
AddRequiredExtensions(VK_EXT_DESCRIPTOR_BUFFER_EXTENSION_NAME);
AddRequiredFeature(vkt::Feature::descriptorBuffer);
AddRequiredFeature(vkt::Feature::protectedMemory);
RETURN_IF_SKIP(Init());
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 | VK_BUFFER_USAGE_SAMPLER_DESCRIPTOR_BUFFER_BIT_EXT;
CreateBufferTest(buffer_create_info, "VUID-VkBufferCreateInfo-flags-09641");
}
TEST_F(NegativeProtectedMemory, WriteToProtectedStorageBuffer) {
TEST_DESCRIPTION("Test OpStore on protected resources");
SetTargetApiVersion(VK_API_VERSION_1_1);
AddRequiredExtensions(VK_EXT_DESCRIPTOR_BUFFER_EXTENSION_NAME);
AddRequiredFeature(vkt::Feature::descriptorBuffer);
AddRequiredFeature(vkt::Feature::protectedMemory);
AddRequiredFeature(vkt::Feature::fragmentStoresAndAtomics);
RETURN_IF_SKIP(InitFramework());
RETURN_IF_SKIP(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_PROTECTED_BIT));
InitRenderTarget();
VkPhysicalDeviceProtectedMemoryProperties protected_memory_properties = vku::InitStructHelper();
GetPhysicalDeviceProperties2(protected_memory_properties);
if (protected_memory_properties.protectedNoFault) {
GTEST_SKIP() << "protectedNoFault feature is supported";
}
vkt::Buffer buffer_unprotected(*m_device, 256, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
const char fsSource[] = R"glsl(
#version 450
layout(set=0, binding=0) buffer block { vec4 x; };
layout(location=0) out vec4 color;
void main(){
x = gl_FragCoord;
}
)glsl";
VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);
CreatePipelineHelper pipe(*this);
pipe.shader_stages_ = {pipe.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
pipe.dsl_bindings_[0] = {0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
pipe.CreateGraphicsPipeline();
// Use unprotected resources in protected command buffer
pipe.descriptor_set_->WriteDescriptorBufferInfo(0, buffer_unprotected, 0, 256, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
pipe.descriptor_set_->UpdateDescriptorSets();
m_command_buffer.Begin();
vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
vk::CmdBeginRenderPass(m_command_buffer, &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_, 0, 1,
&pipe.descriptor_set_->set_, 0, nullptr);
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-commandBuffer-02712"); // color attachment
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-commandBuffer-02712"); // Write to SSBO
vk::CmdDraw(m_command_buffer, 3, 1, 0, 0);
m_errorMonitor->VerifyFound();
vk::CmdEndRenderPass(m_command_buffer);
m_command_buffer.End();
}
TEST_F(NegativeProtectedMemory, ResolveProtectedImage) {
SetTargetApiVersion(VK_API_VERSION_1_1);
AddRequiredFeature(vkt::Feature::protectedMemory);
RETURN_IF_SKIP(Init());
VkPhysicalDeviceProtectedMemoryProperties prot_mem_props = vku::InitStructHelper();
VkPhysicalDeviceProperties2 props = vku::InitStructHelper(&prot_mem_props);
vk::GetPhysicalDeviceProperties2(Gpu(), &props);
const auto protected_no_fault_supported = (prot_mem_props.protectedNoFault == VK_TRUE);
if (protected_no_fault_supported) {
GTEST_SKIP() << "Test requires protectedMemory support without protectedNoFault support";
}
VkImageFormatProperties2 image_format_prop = vku::InitStructHelper();
VkPhysicalDeviceImageFormatInfo2 image_format_info = vku::InitStructHelper();
image_format_info.tiling = VK_IMAGE_TILING_OPTIMAL;
image_format_info.type = VK_IMAGE_TYPE_2D;
image_format_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
image_format_info.format = VK_FORMAT_R8G8B8A8_UNORM;
VkResult result = vk::GetPhysicalDeviceImageFormatProperties2(m_device->Physical(), &image_format_info, &image_format_prop);
if ((result != VK_SUCCESS) || !(image_format_prop.imageFormatProperties.sampleCounts & VK_SAMPLE_COUNT_4_BIT)) {
GTEST_SKIP() << "Cannot create an image with format VK_FORMAT_R8G8B8A8_UNORM and sample count VK_SAMPLE_COUNT_4_BIT. "
"Skipping remainder of the test";
}
auto image_ci = vkt::Image::ImageCreateInfo2D(32, 32, 1, 1, VK_FORMAT_R8G8B8A8_UNORM,
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
vkt::Image image(*m_device, image_ci);
image_ci.samples = VK_SAMPLE_COUNT_4_BIT;
vkt::Image ms_image(*m_device, image_ci);
image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
image_ci.flags = VK_IMAGE_CREATE_PROTECTED_BIT;
vkt::Image image_protected(*m_device, image_ci, vkt::no_mem);
image_ci.samples = VK_SAMPLE_COUNT_4_BIT;
vkt::Image ms_image_protected(*m_device, image_ci, vkt::no_mem);
VkPhysicalDeviceMemoryProperties phys_mem_props;
vk::GetPhysicalDeviceMemoryProperties(Gpu(), &phys_mem_props);
uint32_t protected_index = phys_mem_props.memoryTypeCount;
for (uint32_t i = 0; i < phys_mem_props.memoryTypeCount; i++) {
if ((phys_mem_props.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_PROTECTED_BIT) != 0) {
protected_index = i;
break;
}
}
VkMemoryRequirements mem_reqs;
vk::GetImageMemoryRequirements(device(), image_protected, &mem_reqs);
VkMemoryRequirements ms_mem_reqs;
vk::GetImageMemoryRequirements(device(), ms_image_protected, &ms_mem_reqs);
VkMemoryAllocateInfo mem_alloc = vku::InitStructHelper();
mem_alloc.allocationSize = mem_reqs.size;
mem_alloc.memoryTypeIndex = protected_index;
vkt::DeviceMemory memory(*m_device, mem_alloc);
vk::BindImageMemory(device(), image_protected, memory, 0);
mem_alloc.allocationSize = ms_mem_reqs.size;
vkt::DeviceMemory ms_memory(*m_device, mem_alloc);
vk::BindImageMemory(device(), ms_image_protected, ms_memory, 0);
m_command_buffer.Begin();
VkImageResolve region;
region.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u};
region.srcOffset = {0, 0, 0};
region.dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u};
region.dstOffset = {0, 0, 0};
region.extent = {1u, 1u, 1u};
m_errorMonitor->SetDesiredError("VUID-vkCmdResolveImage-commandBuffer-01837");
vk::CmdResolveImage(m_command_buffer, ms_image_protected, VK_IMAGE_LAYOUT_GENERAL, image, VK_IMAGE_LAYOUT_GENERAL, 1u, &region);
m_errorMonitor->SetDesiredError("VUID-vkCmdResolveImage-commandBuffer-01838");
vk::CmdResolveImage(m_command_buffer, ms_image, VK_IMAGE_LAYOUT_GENERAL, image_protected, VK_IMAGE_LAYOUT_GENERAL, 1u, &region);
m_errorMonitor->VerifyFound();
}
TEST_F(NegativeProtectedMemory, ResolveImageInProtectedCmdBuffer) {
SetTargetApiVersion(VK_API_VERSION_1_1);
AddRequiredFeature(vkt::Feature::protectedMemory);
RETURN_IF_SKIP(InitFramework());
RETURN_IF_SKIP(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_PROTECTED_BIT));
VkPhysicalDeviceProtectedMemoryProperties prot_mem_props = vku::InitStructHelper();
VkPhysicalDeviceProperties2 props = vku::InitStructHelper(&prot_mem_props);
vk::GetPhysicalDeviceProperties2(Gpu(), &props);
const auto protected_no_fault_supported = (prot_mem_props.protectedNoFault == VK_TRUE);
if (protected_no_fault_supported) {
GTEST_SKIP() << "Test requires protectedMemory support without protectedNoFault support";
}
auto image_ci = vkt::Image::ImageCreateInfo2D(32, 32, 1, 1, VK_FORMAT_R8G8B8A8_UNORM,
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
vkt::Image image(*m_device, image_ci);
image_ci.samples = VK_SAMPLE_COUNT_4_BIT;
vkt::Image ms_image(*m_device, image_ci);
m_command_buffer.Begin();
VkImageResolve region;
region.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u};
region.srcOffset = {0, 0, 0};
region.dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u};
region.dstOffset = {0, 0, 0};
region.extent = {1u, 1u, 1u};
m_errorMonitor->SetDesiredError("VUID-vkCmdResolveImage-commandBuffer-01839");
vk::CmdResolveImage(m_command_buffer, ms_image, VK_IMAGE_LAYOUT_GENERAL, image, VK_IMAGE_LAYOUT_GENERAL, 1u, &region);
m_errorMonitor->VerifyFound();
}
TEST_F(NegativeProtectedMemory, ZeroInitializeDeviceMemory) {
SetTargetApiVersion(VK_API_VERSION_1_1);
AddRequiredExtensions(VK_EXT_ZERO_INITIALIZE_DEVICE_MEMORY_EXTENSION_NAME);
AddRequiredFeature(vkt::Feature::protectedMemory);
AddRequiredFeature(vkt::Feature::zeroInitializeDeviceMemory);
RETURN_IF_SKIP(Init());
VkMemoryAllocateFlagsInfo alloc_flags = vku::InitStructHelper();
alloc_flags.flags = VK_MEMORY_ALLOCATE_ZERO_INITIALIZE_BIT_EXT;
VkMemoryAllocateInfo alloc_info = vku::InitStructHelper(&alloc_flags);
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) {
GTEST_SKIP() << "Protected bit not found";
}
VkDeviceMemory memory_protected = VK_NULL_HANDLE;
m_errorMonitor->SetDesiredError("VUID-VkMemoryAllocateFlagsInfo-flags-10761");
vk::AllocateMemory(device(), &alloc_info, NULL, &memory_protected);
m_errorMonitor->VerifyFound();
}