blob: 16375f6133849b450461c62877597f8beacc32e8 [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-2021 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 <vulkan/vulkan_core.h>
#include "../framework/layer_validation_tests.h"
#include "../framework/pipeline_helper.h"
#include "utils/hash_util.h"
#include "generated/vk_validation_error_messages.h"
TEST_F(VkLayerTest, VersionCheckPromotedAPIs) {
TEST_DESCRIPTION("Validate that promoted APIs are not valid in old versions.");
SetTargetApiVersion(VK_API_VERSION_1_0);
RETURN_IF_SKIP(Init());
// TODO - Currently not working on MockICD with Profiles using 1.0
// Seems API version is not being passed through correctly
if (IsPlatformMockICD()) {
GTEST_SKIP() << "Test not supported by MockICD";
}
const auto vkGetPhysicalDeviceProperties2 =
GetInstanceProcAddr<PFN_vkGetPhysicalDeviceProperties2>("vkGetPhysicalDeviceProperties2");
VkPhysicalDeviceProperties2 phys_dev_props_2 = vku::InitStructHelper();
m_errorMonitor->SetDesiredError("UNASSIGNED-API-Version-Violation");
vkGetPhysicalDeviceProperties2(Gpu(), &phys_dev_props_2);
m_errorMonitor->VerifyFound();
}
TEST_F(VkLayerTest, UnsupportedPnextApiVersion) {
TEST_DESCRIPTION("Validate that newer pnext structs are not valid for old Vulkan versions.");
SetTargetApiVersion(VK_API_VERSION_1_1);
RETURN_IF_SKIP(Init());
// 1.1 context, VK_KHR_depth_stencil_resolve is NOT enabled, but using its struct is valid
if (DeviceExtensionSupported(VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME)) {
VkPhysicalDeviceDepthStencilResolveProperties unenabled_device_ext_struct = vku::InitStructHelper();
VkPhysicalDeviceProperties2 phys_dev_props_2 = vku::InitStructHelper(&unenabled_device_ext_struct);
if (DeviceValidationVersion() >= VK_API_VERSION_1_1) {
vk::GetPhysicalDeviceProperties2(Gpu(), &phys_dev_props_2);
} else {
m_errorMonitor->SetDesiredError("UNASSIGNED-API-Version-Violation");
vk::GetPhysicalDeviceProperties2(Gpu(), &phys_dev_props_2);
m_errorMonitor->VerifyFound();
}
}
}
TEST_F(VkLayerTest, VuidCheckForHashCollisions) {
TEST_DESCRIPTION("Ensure there are no VUID hash collisions");
constexpr uint64_t num_vuids = sizeof(vuid_spec_text) / sizeof(vuid_spec_text[0]);
std::vector<uint32_t> hashes;
hashes.reserve(num_vuids);
for (const auto &vuid_spec_text_pair : vuid_spec_text) {
const uint32_t hash = hash_util::VuidHash(vuid_spec_text_pair.vuid);
hashes.push_back(hash);
}
std::sort(hashes.begin(), hashes.end());
const auto it = std::adjacent_find(hashes.begin(), hashes.end());
ASSERT_TRUE(it == hashes.end());
}
TEST_F(VkLayerTest, VuidHashStability) {
TEST_DESCRIPTION("Ensure stability of VUID hashes clients rely on for filtering");
ASSERT_TRUE(hash_util::VuidHash("VUID-VkRenderPassCreateInfo-pNext-01963") == 0xa19880e3);
ASSERT_TRUE(hash_util::VuidHash("VUID-BaryCoordKHR-BaryCoordKHR-04154") == 0xcc72e520);
ASSERT_TRUE(hash_util::VuidHash("VUID-FragDepth-FragDepth-04213") == 0x840af838);
ASSERT_TRUE(hash_util::VuidHash("VUID-RayTmaxKHR-RayTmaxKHR-04349") == 0x8e67514c);
ASSERT_TRUE(hash_util::VuidHash("VUID-RuntimeSpirv-SubgroupUniformControlFlowKHR-06379") == 0x2f574188);
}
TEST_F(VkLayerTest, RequiredParameter) {
TEST_DESCRIPTION("Specify VK_NULL_HANDLE, NULL, and 0 for required handle, pointer, array, and array count parameters");
RETURN_IF_SKIP(Init());
m_errorMonitor->SetDesiredError("VUID-vkGetPhysicalDeviceFeatures-pFeatures-parameter");
// Specify NULL for a pointer to a handle
// Expected to trigger an error with
// StatelessValidation::ValidateRequiredPointer
vk::GetPhysicalDeviceFeatures(Gpu(), NULL);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkGetPhysicalDeviceQueueFamilyProperties-pQueueFamilyPropertyCount-parameter");
// Specify NULL for pointer to array count
// Expected to trigger an error with StatelessValidation::ValidateArray
vk::GetPhysicalDeviceQueueFamilyProperties(Gpu(), NULL, NULL);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkCmdSetViewport-viewportCount-arraylength");
// Specify 0 for a required array count
// Expected to trigger an error with StatelessValidation::ValidateArray
VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
vk::CmdSetViewport(m_command_buffer.handle(), 0, 0, &viewport);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkCmdSetViewport-pViewports-parameter");
// Specify NULL for a required array
// Expected to trigger an error with StatelessValidation::ValidateArray
vk::CmdSetViewport(m_command_buffer.handle(), 0, 1, NULL);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("UNASSIGNED-GeneralParameterError-RequiredHandle");
// Specify VK_NULL_HANDLE for a required handle
// Expected to trigger an error with
// StatelessValidation::ValidateRequiredHandle
vk::UnmapMemory(device(), VK_NULL_HANDLE);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("UNASSIGNED-GeneralParameterError-RequiredHandleArray");
// Specify VK_NULL_HANDLE for a required handle array entry
// Expected to trigger an error with
// StatelessValidation::ValidateRequiredHandleArray
VkFence fence = VK_NULL_HANDLE;
vk::ResetFences(device(), 1, &fence);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkAllocateMemory-pAllocateInfo-parameter");
// Specify NULL for a required struct pointer
// Expected to trigger an error with
// StatelessValidation::ValidateStructType
VkDeviceMemory memory = VK_NULL_HANDLE;
vk::AllocateMemory(device(), NULL, NULL, &memory);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkCmdSetStencilReference-faceMask-requiredbitmask");
// Specify 0 for a required VkFlags parameter
// Expected to trigger an error with StatelessValidation::ValidateFlags
vk::CmdSetStencilReference(m_command_buffer.handle(), 0, 0);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-VkSubmitInfo-sType-sType");
// Set a bogus sType and see what happens
VkSemaphore semaphore = VK_NULL_HANDLE;
VkPipelineStageFlags stageFlags = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
VkSubmitInfo submitInfo = vku::InitStructHelper();
submitInfo.waitSemaphoreCount = 1;
submitInfo.pWaitSemaphores = &semaphore;
submitInfo.pWaitDstStageMask = &stageFlags;
submitInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
vk::QueueSubmit(m_default_queue->handle(), 1, &submitInfo, VK_NULL_HANDLE);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-VkSubmitInfo-pWaitSemaphores-parameter");
stageFlags = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.waitSemaphoreCount = 1;
// Set a null pointer for pWaitSemaphores
submitInfo.pWaitSemaphores = nullptr;
submitInfo.pWaitDstStageMask = &stageFlags;
vk::QueueSubmit(m_default_queue->handle(), 1, &submitInfo, VK_NULL_HANDLE);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-VkSubmitInfo-pWaitDstStageMask-parameter");
submitInfo.pWaitSemaphores = &semaphore;
submitInfo.pWaitDstStageMask = nullptr;
vk::QueueSubmit(m_default_queue->handle(), 1, &submitInfo, VK_NULL_HANDLE);
m_errorMonitor->VerifyFound();
}
#ifdef ANNOTATED_SPEC_LINK
TEST_F(VkLayerTest, SpecLinksImplicit) {
TEST_DESCRIPTION("Test that spec links in a typical error message are well-formed");
RETURN_IF_SKIP(Init());
std::string spec_url_base = ANNOTATED_SPEC_LINK;
std::string spec_version =
spec_url_base + "chapters/features.html#" + std::string("VUID-vkGetPhysicalDeviceFeatures-pFeatures-parameter");
m_errorMonitor->SetDesiredError(spec_version.c_str());
vk::GetPhysicalDeviceFeatures(Gpu(), nullptr);
m_errorMonitor->VerifyFound();
}
TEST_F(VkLayerTest, SpecLinksExplicit) {
TEST_DESCRIPTION("Test that spec links in a typical error message are well-formed");
RETURN_IF_SKIP(Init());
std::string spec_url_base = ANNOTATED_SPEC_LINK;
std::string spec_version = spec_url_base + "chapters/resources.html#" + std::string("VUID-VkBufferCreateInfo-size-00912");
VkBufferCreateInfo info = vku::InitStructHelper();
info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
info.size = 0;
m_errorMonitor->SetDesiredError(spec_version.c_str());
vkt::Buffer buffer(*m_device, info, vkt::no_mem);
m_errorMonitor->VerifyFound();
}
#else // ANNOTATED_SPEC_LINK
TEST_F(VkLayerTest, SpecLinksImplicit) {
TEST_DESCRIPTION("Test that spec links in a typical error message are well-formed");
RETURN_IF_SKIP(Init());
// keep VUID seperate otherwise vk_validation_stats.py will get confused
std::string spec_version = "https://docs.vulkan.org/spec/latest/chapters/features.html#" +
std::string("VUID-vkGetPhysicalDeviceFeatures-pFeatures-parameter");
m_errorMonitor->SetDesiredError(spec_version.c_str());
vk::GetPhysicalDeviceFeatures(Gpu(), nullptr);
m_errorMonitor->VerifyFound();
}
TEST_F(VkLayerTest, SpecLinksExplicit) {
TEST_DESCRIPTION("Test that spec links in a typical error message are well-formed");
RETURN_IF_SKIP(Init());
// keep VUID seperate otherwise vk_validation_stats.py will get confused
std::string spec_version =
"https://docs.vulkan.org/spec/latest/chapters/resources.html#" + std::string("VUID-VkBufferCreateInfo-size-00912");
VkBufferCreateInfo info = vku::InitStructHelper();
info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
info.size = 0;
m_errorMonitor->SetDesiredError(spec_version.c_str());
vkt::Buffer buffer(*m_device, info, vkt::no_mem);
m_errorMonitor->VerifyFound();
}
#endif // ANNOTATED_SPEC_LINK
TEST_F(VkLayerTest, DeviceIDPropertiesUnsupported) {
TEST_DESCRIPTION("VkPhysicalDeviceIDProperties cannot be used without extensions in 1.0");
SetTargetApiVersion(VK_API_VERSION_1_0);
AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
RETURN_IF_SKIP(InitFramework());
if (DeviceValidationVersion() != VK_API_VERSION_1_0) {
GTEST_SKIP() << "Test's for 1.0 only";
}
VkPhysicalDeviceIDProperties id_props = vku::InitStructHelper();
VkPhysicalDeviceProperties2 props2 = vku::InitStructHelper(&id_props);
m_errorMonitor->SetDesiredError("VUID-VkPhysicalDeviceProperties2-pNext-pNext");
vk::GetPhysicalDeviceProperties2KHR(Gpu(), &props2);
m_errorMonitor->VerifyFound();
}
TEST_F(VkLayerTest, UsePnextOnlyStructWithoutExtensionEnabled) {
TEST_DESCRIPTION(
"Validate that using VkPipelineTessellationDomainOriginStateCreateInfo in VkPipelineTessellationStateCreateInfo.pNext "
"in a 1.0 context will generate an error message.");
SetTargetApiVersion(VK_API_VERSION_1_0);
AddRequiredFeature(vkt::Feature::tessellationShader);
RETURN_IF_SKIP(Init());
InitRenderTarget();
VkShaderObj vs(this, kVertexMinimalGlsl, VK_SHADER_STAGE_VERTEX_BIT);
VkShaderObj tcs(this, kTessellationControlMinimalGlsl, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
VkShaderObj tes(this, kTessellationEvalMinimalGlsl, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
VkShaderObj fs(this, kFragmentMinimalGlsl, VK_SHADER_STAGE_FRAGMENT_BIT);
VkPipelineInputAssemblyStateCreateInfo iasci{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0,
VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE};
VkPipelineTessellationDomainOriginStateCreateInfo tessellationDomainOriginStateInfo = {
VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO, VK_NULL_HANDLE,
VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT};
VkPipelineTessellationStateCreateInfo tsci{VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,
&tessellationDomainOriginStateInfo, 0, 3};
CreatePipelineHelper pipe(*this);
pipe.gp_ci_.pTessellationState = &tsci;
pipe.gp_ci_.pInputAssemblyState = &iasci;
pipe.shader_stages_ = {vs.GetStageCreateInfo(), tcs.GetStageCreateInfo(), tes.GetStageCreateInfo(), fs.GetStageCreateInfo()};
// one for each struct
m_errorMonitor->SetDesiredError("VUID-VkPipelineTessellationStateCreateInfo-pNext-pNext");
m_errorMonitor->SetDesiredError("VUID-VkPipelineTessellationStateCreateInfo-pNext-pNext");
pipe.CreateGraphicsPipeline();
m_errorMonitor->VerifyFound();
}
TEST_F(VkLayerTest, PnextOnlyStructValidation) {
TEST_DESCRIPTION("See if checks occur on structs ONLY used in pnext chains.");
AddRequiredExtensions(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
RETURN_IF_SKIP(InitFramework());
// Create a device passing in a bad PdevFeatures2 value
VkPhysicalDeviceDescriptorIndexingFeaturesEXT indexing_features = vku::InitStructHelper();
auto features2 = GetPhysicalDeviceFeatures2(indexing_features);
// Set one of the features values to an invalid boolean value
indexing_features.descriptorBindingUniformBufferUpdateAfterBind = 800;
uint32_t queue_node_count;
vk::GetPhysicalDeviceQueueFamilyProperties(Gpu(), &queue_node_count, NULL);
std::vector<VkQueueFamilyProperties> queue_props;
queue_props.resize(queue_node_count);
vk::GetPhysicalDeviceQueueFamilyProperties(Gpu(), &queue_node_count, queue_props.data());
float priorities[] = {1.0f};
VkDeviceQueueCreateInfo queue_info = vku::InitStructHelper();
queue_info.flags = 0;
queue_info.queueFamilyIndex = 0;
queue_info.queueCount = 1;
queue_info.pQueuePriorities = &priorities[0];
VkDeviceCreateInfo dev_info = vku::InitStructHelper();
dev_info.queueCreateInfoCount = 1;
dev_info.pQueueCreateInfos = &queue_info;
dev_info.enabledLayerCount = 0;
dev_info.ppEnabledLayerNames = NULL;
dev_info.enabledExtensionCount = m_device_extension_names.size();
dev_info.ppEnabledExtensionNames = m_device_extension_names.data();
dev_info.pNext = &features2;
VkDevice dev;
m_errorMonitor->SetDesiredError("is neither VK_TRUE nor VK_FALSE");
m_errorMonitor->SetUnexpectedError("Failed to create");
vk::CreateDevice(Gpu(), &dev_info, NULL, &dev);
m_errorMonitor->VerifyFound();
}
TEST_F(VkLayerTest, ReservedParameter) {
TEST_DESCRIPTION("Specify a non-zero value for a reserved parameter");
RETURN_IF_SKIP(Init());
m_errorMonitor->SetDesiredError(" must be 0");
// Specify 0 for a reserved VkFlags parameter
// Expected to trigger an error with
// StatelessValidation::ValidateReservedFlags
VkSemaphore sem_handle = VK_NULL_HANDLE;
VkSemaphoreCreateInfo sem_info = vku::InitStructHelper();
sem_info.flags = 1;
vk::CreateSemaphore(device(), &sem_info, NULL, &sem_handle);
m_errorMonitor->VerifyFound();
}
TEST_F(VkLayerTest, InvalidStructSType) {
TEST_DESCRIPTION("Specify an invalid VkStructureType for a Vulkan structure's sType field");
RETURN_IF_SKIP(Init());
m_errorMonitor->SetDesiredError("VUID-VkMemoryAllocateInfo-sType-sType");
// Zero struct memory, effectively setting sType to
// VK_STRUCTURE_TYPE_APPLICATION_INFO
// Expected to trigger an error with
// StatelessValidation::ValidateStructType
VkMemoryAllocateInfo alloc_info = {};
VkDeviceMemory memory = VK_NULL_HANDLE;
vk::AllocateMemory(device(), &alloc_info, NULL, &memory);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-VkSubmitInfo-sType-sType");
// Zero struct memory, effectively setting sType to
// VK_STRUCTURE_TYPE_APPLICATION_INFO
// Expected to trigger an error with
// StatelessValidation::ValidateStructTypeArray
VkSubmitInfo submit_info = {};
vk::QueueSubmit(m_default_queue->handle(), 1, &submit_info, VK_NULL_HANDLE);
m_errorMonitor->VerifyFound();
}
TEST_F(VkLayerTest, InvalidStructPNext) {
TEST_DESCRIPTION("Specify an invalid value for a Vulkan structure's pNext field");
AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
RETURN_IF_SKIP(Init());
m_errorMonitor->SetDesiredError("VUID-VkCommandPoolCreateInfo-pNext-pNext");
// Set VkCommandPoolCreateInfo::pNext to a non-NULL value, when pNext must be NULL.
// Need to pick a function that has no allowed pNext structure types.
// Expected to trigger an error with StatelessValidation::ValidateStructPnext
VkCommandPool pool = VK_NULL_HANDLE;
VkCommandPoolCreateInfo pool_ci = vku::InitStructHelper();
VkApplicationInfo app_info = vku::InitStructHelper();
pool_ci.pNext = &app_info;
vk::CreateCommandPool(device(), &pool_ci, NULL, &pool);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError(" chain includes a structure with unexpected VkStructureType ");
// Set VkMemoryAllocateInfo::pNext to a non-NULL value, but use
// a function that has allowed pNext structure types and specify
// a structure type that is not allowed.
// Expected to trigger an error with StatelessValidation::ValidateStructPnext
VkDeviceMemory memory = VK_NULL_HANDLE;
VkMemoryAllocateInfo memory_alloc_info = vku::InitStructHelper(&app_info);
vk::AllocateMemory(device(), &memory_alloc_info, NULL, &memory);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError(" chain includes a structure with unexpected VkStructureType ");
// Same concept as above, but unlike vkAllocateMemory where VkMemoryAllocateInfo is a const
// in vkGetPhysicalDeviceProperties2, VkPhysicalDeviceProperties2 is not a const
VkPhysicalDeviceProperties2 physical_device_properties2 = vku::InitStructHelper(&app_info);
vk::GetPhysicalDeviceProperties2KHR(Gpu(), &physical_device_properties2);
m_errorMonitor->VerifyFound();
}
TEST_F(VkLayerTest, UnrecognizedEnumOutOfRange) {
RETURN_IF_SKIP(Init());
if (DeviceExtensionSupported(Gpu(), nullptr, VK_KHR_MAINTENANCE_5_EXTENSION_NAME)) {
GTEST_SKIP() << "VK_KHR_maintenance5 is supported";
}
m_errorMonitor->SetDesiredError("VUID-vkGetPhysicalDeviceFormatProperties-format-parameter");
// Specify an invalid VkFormat value
// Expected to trigger an error with
// StatelessValidation::ValidateRangedEnum
VkFormatProperties format_properties;
vk::GetPhysicalDeviceFormatProperties(Gpu(), static_cast<VkFormat>(8000), &format_properties);
m_errorMonitor->VerifyFound();
}
TEST_F(VkLayerTest, UnrecognizedEnumOutOfRange2) {
SetTargetApiVersion(VK_API_VERSION_1_1);
RETURN_IF_SKIP(Init());
if (DeviceExtensionSupported(Gpu(), nullptr, VK_KHR_MAINTENANCE_5_EXTENSION_NAME)) {
GTEST_SKIP() << "VK_KHR_maintenance5 is supported";
}
m_errorMonitor->SetDesiredError("VUID-vkGetPhysicalDeviceFormatProperties2-format-parameter");
VkFormatProperties2 format_properties = vku::InitStructHelper();
vk::GetPhysicalDeviceFormatProperties2(Gpu(), static_cast<VkFormat>(8000), &format_properties);
m_errorMonitor->VerifyFound();
}
TEST_F(VkLayerTest, UnrecognizedFlagOutOfRange) {
RETURN_IF_SKIP(Init());
if (DeviceExtensionSupported(Gpu(), nullptr, VK_KHR_MAINTENANCE_5_EXTENSION_NAME)) {
GTEST_SKIP() << "VK_KHR_maintenance5 is supported";
}
m_errorMonitor->SetDesiredError("VUID-vkGetPhysicalDeviceImageFormatProperties-usage-parameter");
VkImageFormatProperties format_properties;
vk::GetPhysicalDeviceImageFormatProperties(Gpu(), VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TYPE_1D, VK_IMAGE_TILING_OPTIMAL,
static_cast<VkImageUsageFlags>(0xffffffff), 0, &format_properties);
m_errorMonitor->VerifyFound();
}
TEST_F(VkLayerTest, UnrecognizedFlagOutOfRange2) {
SetTargetApiVersion(VK_API_VERSION_1_1);
RETURN_IF_SKIP(Init());
if (DeviceExtensionSupported(Gpu(), nullptr, VK_KHR_MAINTENANCE_5_EXTENSION_NAME)) {
GTEST_SKIP() << "VK_KHR_maintenance5 is supported";
}
m_errorMonitor->SetDesiredError("VUID-VkPhysicalDeviceImageFormatInfo2-usage-parameter");
VkImageFormatProperties2 format_properties = vku::InitStructHelper();
VkPhysicalDeviceImageFormatInfo2 format_info = vku::InitStructHelper();
format_info.format = VK_FORMAT_R8G8B8A8_UNORM;
format_info.flags = 0;
format_info.tiling = VK_IMAGE_TILING_OPTIMAL;
format_info.type = VK_IMAGE_TYPE_1D;
format_info.usage = static_cast<VkImageUsageFlags>(0xffffffff);
vk::GetPhysicalDeviceImageFormatProperties2(Gpu(), &format_info, &format_properties);
m_errorMonitor->VerifyFound();
}
TEST_F(VkLayerTest, UnrecognizedValueBadMask) {
RETURN_IF_SKIP(Init());
if (DeviceExtensionSupported(Gpu(), nullptr, VK_KHR_MAINTENANCE_5_EXTENSION_NAME)) {
GTEST_SKIP() << "VK_KHR_maintenance5 is supported";
}
m_errorMonitor->SetDesiredError("VUID-vkGetPhysicalDeviceImageFormatProperties-usage-parameter");
// Specify an invalid VkFlags bitmask value
// Expected to trigger an error with StatelessValidation::ValidateFlags
VkImageFormatProperties image_format_properties;
vk::GetPhysicalDeviceImageFormatProperties(Gpu(), VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
static_cast<VkImageUsageFlags>(1 << 31), 0, &image_format_properties);
m_errorMonitor->VerifyFound();
}
TEST_F(VkLayerTest, UnrecognizedValueBadFlag) {
RETURN_IF_SKIP(Init());
m_errorMonitor->SetDesiredError("VUID-VkSubmitInfo-pWaitDstStageMask-parameter");
// Specify an invalid VkFlags array entry
// Expected to trigger an error with StatelessValidation::ValidateFlagsArray
vkt::Semaphore semaphore(*m_device);
// `stage_flags` is set to a value which, currently, is not a defined stage flag
// `VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM` works well for this
VkPipelineStageFlags stage_flags = VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM;
// `waitSemaphoreCount` *must* be greater than 0 to perform this check
VkSubmitInfo submit_info = vku::InitStructHelper();
submit_info.waitSemaphoreCount = 1;
submit_info.pWaitSemaphores = &semaphore.handle();
submit_info.pWaitDstStageMask = &stage_flags;
vk::QueueSubmit(m_default_queue->handle(), 1, &submit_info, VK_NULL_HANDLE);
m_errorMonitor->VerifyFound();
}
TEST_F(VkLayerTest, UnrecognizedValueBadBool) {
// Make sure using VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE doesn't trigger a false positive.
AddRequiredExtensions(VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME);
RETURN_IF_SKIP(Init());
// Specify an invalid VkBool32 value, expecting a warning with StatelessValidation::ValidateBool32
VkSamplerCreateInfo sampler_info = SafeSaneSamplerCreateInfo();
sampler_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
sampler_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
sampler_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
// Not VK_TRUE or VK_FALSE
sampler_info.anisotropyEnable = 3;
CreateSamplerTest(*this, &sampler_info, "UNASSIGNED-GeneralParameterError-UnrecognizedBool32");
}
TEST_F(VkLayerTest, UnrecognizedValueMaxEnum) {
RETURN_IF_SKIP(Init());
if (DeviceExtensionSupported(Gpu(), nullptr, VK_KHR_MAINTENANCE_5_EXTENSION_NAME)) {
GTEST_SKIP() << "VK_KHR_maintenance5 is supported";
}
// Specify MAX_ENUM
VkFormatProperties format_properties;
m_errorMonitor->SetDesiredError("does not fall within the begin..end range");
vk::GetPhysicalDeviceFormatProperties(Gpu(), VK_FORMAT_MAX_ENUM, &format_properties);
m_errorMonitor->VerifyFound();
}
TEST_F(VkLayerTest, UseObjectWithWrongDevice) {
TEST_DESCRIPTION(
"Try to destroy a render pass object using a device other than the one it was created on. This should generate a distinct "
"error from the invalid handle error.");
// Create first device and renderpass
RETURN_IF_SKIP(Init());
InitRenderTarget();
// Create second device
float priorities[] = {1.0f};
VkDeviceQueueCreateInfo queue_info = vku::InitStructHelper();
queue_info.flags = 0;
queue_info.queueFamilyIndex = 0;
queue_info.queueCount = 1;
queue_info.pQueuePriorities = &priorities[0];
VkDeviceCreateInfo device_create_info = vku::InitStructHelper();
auto features = m_device->Physical().Features();
device_create_info.queueCreateInfoCount = 1;
device_create_info.pQueueCreateInfos = &queue_info;
device_create_info.enabledLayerCount = 0;
device_create_info.ppEnabledLayerNames = NULL;
device_create_info.pEnabledFeatures = &features;
VkDevice second_device;
ASSERT_EQ(VK_SUCCESS, vk::CreateDevice(Gpu(), &device_create_info, NULL, &second_device));
// Try to destroy the renderpass from the first device using the second device
m_errorMonitor->SetDesiredError("VUID-vkDestroyRenderPass-renderPass-parent");
vk::DestroyRenderPass(second_device, m_renderPass, NULL);
m_errorMonitor->VerifyFound();
vk::DestroyDevice(second_device, NULL);
}
TEST_F(VkLayerTest, InvalidAllocationCallbacks) {
TEST_DESCRIPTION("Test with invalid VkAllocationCallbacks");
RETURN_IF_SKIP(Init());
const std::optional queueFamilyIndex = DeviceObj()->QueueFamily(VK_QUEUE_GRAPHICS_BIT);
if (!queueFamilyIndex) {
GTEST_SKIP() << "Required queue families not present";
}
// vk::CreateInstance, and vk::CreateDevice tend to crash in the Loader Trampoline ATM, so choosing vk::CreateCommandPool
const VkCommandPoolCreateInfo cpci = {VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, nullptr, 0, queueFamilyIndex.value()};
VkCommandPool cmdPool;
struct Alloc {
static VKAPI_ATTR void *VKAPI_CALL alloc(void *, size_t, size_t, VkSystemAllocationScope) { return nullptr; };
static VKAPI_ATTR void *VKAPI_CALL realloc(void *, void *, size_t, size_t, VkSystemAllocationScope) { return nullptr; };
static VKAPI_ATTR void VKAPI_CALL free(void *, void *){};
static VKAPI_ATTR void VKAPI_CALL internalAlloc(void *, size_t, VkInternalAllocationType, VkSystemAllocationScope){};
static VKAPI_ATTR void VKAPI_CALL internalFree(void *, size_t, VkInternalAllocationType, VkSystemAllocationScope){};
};
{
m_errorMonitor->SetDesiredError("VUID-VkAllocationCallbacks-pfnAllocation-00632");
const VkAllocationCallbacks allocator = {nullptr, nullptr, Alloc::realloc, Alloc::free, nullptr, nullptr};
vk::CreateCommandPool(device(), &cpci, &allocator, &cmdPool);
m_errorMonitor->VerifyFound();
}
{
m_errorMonitor->SetDesiredError("VUID-VkAllocationCallbacks-pfnReallocation-00633");
const VkAllocationCallbacks allocator = {nullptr, Alloc::alloc, nullptr, Alloc::free, nullptr, nullptr};
vk::CreateCommandPool(device(), &cpci, &allocator, &cmdPool);
m_errorMonitor->VerifyFound();
}
{
m_errorMonitor->SetDesiredError("VUID-VkAllocationCallbacks-pfnFree-00634");
const VkAllocationCallbacks allocator = {nullptr, Alloc::alloc, Alloc::realloc, nullptr, nullptr, nullptr};
vk::CreateCommandPool(device(), &cpci, &allocator, &cmdPool);
m_errorMonitor->VerifyFound();
}
{
m_errorMonitor->SetDesiredError("VUID-VkAllocationCallbacks-pfnInternalAllocation-00635");
const VkAllocationCallbacks allocator = {nullptr, Alloc::alloc, Alloc::realloc, Alloc::free, nullptr, Alloc::internalFree};
vk::CreateCommandPool(device(), &cpci, &allocator, &cmdPool);
m_errorMonitor->VerifyFound();
}
{
m_errorMonitor->SetDesiredError("VUID-VkAllocationCallbacks-pfnInternalAllocation-00635");
const VkAllocationCallbacks allocator = {nullptr, Alloc::alloc, Alloc::realloc, Alloc::free, Alloc::internalAlloc, nullptr};
vk::CreateCommandPool(device(), &cpci, &allocator, &cmdPool);
m_errorMonitor->VerifyFound();
}
}
TEST_F(VkLayerTest, ValidationCacheTestBadMerge) {
AddRequiredExtensions(VK_EXT_VALIDATION_CACHE_EXTENSION_NAME);
RETURN_IF_SKIP(Init());
VkValidationCacheCreateInfoEXT validationCacheCreateInfo = vku::InitStructHelper();
validationCacheCreateInfo.initialDataSize = 0;
validationCacheCreateInfo.pInitialData = NULL;
validationCacheCreateInfo.flags = 0;
VkValidationCacheEXT validationCache = VK_NULL_HANDLE;
VkResult res = vk::CreateValidationCacheEXT(device(), &validationCacheCreateInfo, nullptr, &validationCache);
ASSERT_EQ(VK_SUCCESS, res);
m_errorMonitor->SetDesiredError("VUID-vkMergeValidationCachesEXT-dstCache-01536");
res = vk::MergeValidationCachesEXT(device(), validationCache, 1, &validationCache);
m_errorMonitor->VerifyFound();
vk::DestroyValidationCacheEXT(device(), validationCache, nullptr);
}
TEST_F(VkLayerTest, UnclosedAndDuplicateQueries) {
TEST_DESCRIPTION("End a command buffer with a query still in progress, create nested queries.");
RETURN_IF_SKIP(Init());
VkQueue queue = VK_NULL_HANDLE;
vk::GetDeviceQueue(device(), m_device->graphics_queue_node_index_, 0, &queue);
vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_OCCLUSION, 5);
m_command_buffer.Begin();
vk::CmdResetQueryPool(m_command_buffer.handle(), query_pool.handle(), 0, 5);
m_errorMonitor->SetDesiredError("VUID-vkCmdBeginQuery-queryPool-01922");
vk::CmdBeginQuery(m_command_buffer.handle(), query_pool.handle(), 1, 0);
// Attempt to begin a query that has the same type as an active query
vk::CmdBeginQuery(m_command_buffer.handle(), query_pool.handle(), 3, 0);
vk::CmdEndQuery(m_command_buffer.handle(), query_pool.handle(), 1);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkEndCommandBuffer-commandBuffer-00061");
vk::CmdBeginQuery(m_command_buffer.handle(), query_pool.handle(), 0, 0);
vk::EndCommandBuffer(m_command_buffer.handle());
m_errorMonitor->VerifyFound();
}
TEST_F(VkLayerTest, ExecuteUnrecordedCB) {
TEST_DESCRIPTION("Attempt vkQueueSubmit with a CB in the initial state");
RETURN_IF_SKIP(Init());
// never record m_command_buffer
m_errorMonitor->SetDesiredError("VUID-vkQueueSubmit-pCommandBuffers-00070");
m_default_queue->Submit(m_command_buffer);
m_errorMonitor->VerifyFound();
// Testing an "unfinished secondary CB" crashes on some HW/drivers (notably Pixel 3 and RADV)
// vkt::CommandBuffer cb(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
// m_command_buffer.Begin();
// vk::CmdExecuteCommands(m_command_buffer.handle(), 1u, &cb.handle());
// m_command_buffer.End();
// m_errorMonitor->SetDesiredError("VUID-vkQueueSubmit-pCommandBuffers-00072");
// vk::QueueSubmit(m_default_queue->handle(), 1, &si, VK_NULL_HANDLE);
// m_errorMonitor->VerifyFound();
}
TEST_F(VkLayerTest, ValidateArrayLength) {
TEST_DESCRIPTION("Validate arraylength VUs");
RETURN_IF_SKIP(Init());
InitRenderTarget();
// Used to have a valid pointed to set object too
VkCommandBuffer unused_command_buffer;
VkDescriptorSet unused_descriptor_set;
OneOffDescriptorSet descriptor_set(m_device, {
{0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
});
vkt::PipelineLayout pipeline_layout(*m_device, {&descriptor_set.layout_});
vkt::Fence fence(*m_device);
vkt::Event event(*m_device);
m_errorMonitor->SetDesiredError("VUID-vkAllocateCommandBuffers-pAllocateInfo::commandBufferCount-arraylength");
{
VkCommandBufferAllocateInfo info = vku::InitStructHelper();
info.commandPool = m_command_pool.handle();
info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
info.commandBufferCount = 0; // invalid
vk::AllocateCommandBuffers(device(), &info, &unused_command_buffer);
}
m_errorMonitor->VerifyFound();
// One exception in spec where the size of a field is used in both the function call it and the struct
m_errorMonitor->SetDesiredError("VUID-vkAllocateDescriptorSets-pAllocateInfo::descriptorSetCount-arraylength");
m_errorMonitor->SetDesiredError("VUID-VkDescriptorSetAllocateInfo-descriptorSetCount-arraylength");
{
VkDescriptorSetAllocateInfo info = vku::InitStructHelper();
info.descriptorPool = descriptor_set.pool_;
info.descriptorSetCount = 0; // invalid
info.pSetLayouts = &descriptor_set.layout_.handle();
vk::AllocateDescriptorSets(device(), &info, &unused_descriptor_set);
}
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkFreeCommandBuffers-commandBufferCount-arraylength");
vk::FreeCommandBuffers(device(), m_command_pool.handle(), 0, &unused_command_buffer);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkFreeDescriptorSets-descriptorSetCount-arraylength");
vk::FreeDescriptorSets(device(), descriptor_set.pool_, 0, &descriptor_set.set_);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkResetFences-fenceCount-arraylength");
vk::ResetFences(device(), 0, &fence.handle());
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkWaitForFences-fenceCount-arraylength");
vk::WaitForFences(device(), 0, &fence.handle(), true, 1);
m_errorMonitor->VerifyFound();
vkt::CommandBuffer command_buffer(*m_device, m_command_pool);
command_buffer.Begin();
m_errorMonitor->SetDesiredError("VUID-vkCmdBindDescriptorSets-descriptorSetCount-arraylength");
vk::CmdBindDescriptorSets(command_buffer.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 0,
&descriptor_set.set_, 0, nullptr);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-commandBufferCount-arraylength");
vk::CmdExecuteCommands(command_buffer.handle(), 0, &unused_command_buffer);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkCmdWaitEvents-eventCount-arraylength");
vk::CmdWaitEvents(command_buffer.handle(), 0, &event.handle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
0, nullptr, 0, nullptr, 0, nullptr);
m_errorMonitor->VerifyFound();
command_buffer.End();
}
TEST_F(VkLayerTest, DuplicatePhysicalDevices) {
TEST_DESCRIPTION("Duplicated physical devices in DeviceGroupDeviceCreateInfo.");
SetTargetApiVersion(VK_API_VERSION_1_1);
RETURN_IF_SKIP(InitFramework());
uint32_t physical_device_group_count = 0;
vk::EnumeratePhysicalDeviceGroups(instance(), &physical_device_group_count, nullptr);
if (physical_device_group_count == 0) {
GTEST_SKIP() << "physical_device_group_count is 0";
}
std::vector<VkPhysicalDeviceGroupProperties> physical_device_group(physical_device_group_count,
{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES});
vk::EnumeratePhysicalDeviceGroups(instance(), &physical_device_group_count, physical_device_group.data());
VkPhysicalDevice physicalDevices[2] = {physical_device_group[0].physicalDevices[0],
physical_device_group[0].physicalDevices[0]};
VkDeviceGroupDeviceCreateInfo create_device_pnext = vku::InitStructHelper();
create_device_pnext.physicalDeviceCount = 2;
create_device_pnext.pPhysicalDevices = physicalDevices;
RETURN_IF_SKIP(InitState());
vkt::QueueCreateInfoArray queue_info(m_device->Physical().queue_properties_);
VkDeviceCreateInfo create_info = vku::InitStructHelper();
create_info.pNext = &create_device_pnext;
create_info.queueCreateInfoCount = queue_info.Size();
create_info.pQueueCreateInfos = queue_info.Data();
create_info.enabledLayerCount = 0;
create_info.ppEnabledLayerNames = nullptr;
create_info.enabledExtensionCount = m_device_extension_names.size();
create_info.ppEnabledExtensionNames = m_device_extension_names.data();
VkDevice device;
m_errorMonitor->SetDesiredError("VUID-VkDeviceGroupDeviceCreateInfo-pPhysicalDevices-00375");
vk::CreateDevice(Gpu(), &create_info, nullptr, &device);
m_errorMonitor->VerifyFound();
}
TEST_F(VkLayerTest, InvalidImageCreateFlagWithPhysicalDeviceCount) {
TEST_DESCRIPTION("Test for invalid imageCreate flags bit with physicalDeviceCount.");
SetTargetApiVersion(VK_API_VERSION_1_1);
RETURN_IF_SKIP(InitFramework());
uint32_t physical_device_group_count = 0;
vk::EnumeratePhysicalDeviceGroups(instance(), &physical_device_group_count, nullptr);
if (physical_device_group_count == 0) {
GTEST_SKIP() << "physical_device_group_count is 0";
}
std::vector<VkPhysicalDeviceGroupProperties> physical_device_group(physical_device_group_count,
{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES});
vk::EnumeratePhysicalDeviceGroups(instance(), &physical_device_group_count, physical_device_group.data());
VkDeviceGroupDeviceCreateInfo create_device_pnext = vku::InitStructHelper();
create_device_pnext.physicalDeviceCount = 1;
create_device_pnext.pPhysicalDevices = physical_device_group[0].physicalDevices;
RETURN_IF_SKIP(InitState(nullptr, &create_device_pnext));
VkImageCreateInfo ici = vku::InitStructHelper();
ici.flags = VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT;
ici.imageType = VK_IMAGE_TYPE_2D;
ici.arrayLayers = 1;
ici.extent = {64, 64, 1};
ici.format = VK_FORMAT_R8G8B8A8_UNORM;
ici.mipLevels = 1;
ici.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
ici.samples = VK_SAMPLE_COUNT_1_BIT;
ici.tiling = VK_IMAGE_TILING_OPTIMAL;
ici.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
VkImageFormatProperties imageFormatProperties;
VkResult result =
vk::GetPhysicalDeviceImageFormatProperties(physical_device_group[0].physicalDevices[0], ici.format, ici.imageType,
ici.tiling, ici.usage, ici.flags, &imageFormatProperties);
if (result == VK_ERROR_FORMAT_NOT_SUPPORTED) {
GTEST_SKIP() << "image format is not supported";
}
CreateImageTest(*this, &ici, "VUID-VkImageCreateInfo-physicalDeviceCount-01421");
}
TEST_F(VkLayerTest, ZeroBitmask) {
TEST_DESCRIPTION("Test a reserved flags field set to a non-zero value");
RETURN_IF_SKIP(Init());
m_errorMonitor->SetDesiredError("VUID-VkSemaphoreCreateInfo-flags-zerobitmask");
VkSemaphoreCreateInfo semaphore_ci = vku::InitStructHelper();
semaphore_ci.flags = 1;
VkSemaphore semaphore = VK_NULL_HANDLE;
vk::CreateSemaphore(device(), &semaphore_ci, nullptr, &semaphore);
m_errorMonitor->VerifyFound();
}
TEST_F(VkLayerTest, InvalidExtEnum) {
TEST_DESCRIPTION("Use an enum from an extension that is not enabled.");
RETURN_IF_SKIP(Init());
VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
sampler_ci.magFilter = VK_FILTER_CUBIC_EXT;
m_errorMonitor->SetDesiredError("VUID-VkSamplerCreateInfo-magFilter-parameter");
vkt::Sampler sampler(*m_device, sampler_ci);
m_errorMonitor->VerifyFound();
}
TEST_F(VkLayerTest, ExtensionNotEnabledYCbCr) {
TEST_DESCRIPTION("Validate that using an API from an unenabled extension returns an error");
SetTargetApiVersion(VK_API_VERSION_1_1);
AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
AddRequiredExtensions(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
AddRequiredExtensions(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
AddRequiredExtensions(VK_KHR_MAINTENANCE_1_EXTENSION_NAME);
AddRequiredExtensions(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
RETURN_IF_SKIP(Init());
// The feature bit samplerYcbcrConversion prevents the function from being called even in Vulkan 1.0
m_errorMonitor->SetDesiredError("VUID-vkCreateSamplerYcbcrConversion-None-01648");
VkSamplerYcbcrConversionCreateInfo ycbcr_create_info = vku::InitStructHelper();
ycbcr_create_info.format = VK_FORMAT_UNDEFINED;
ycbcr_create_info.ycbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY;
ycbcr_create_info.ycbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
ycbcr_create_info.components = {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
VK_COMPONENT_SWIZZLE_IDENTITY};
ycbcr_create_info.xChromaOffset = VK_CHROMA_LOCATION_COSITED_EVEN;
ycbcr_create_info.yChromaOffset = VK_CHROMA_LOCATION_COSITED_EVEN;
ycbcr_create_info.chromaFilter = VK_FILTER_NEAREST;
ycbcr_create_info.forceExplicitReconstruction = false;
VkSamplerYcbcrConversion conversion;
vk::CreateSamplerYcbcrConversionKHR(m_device->handle(), &ycbcr_create_info, nullptr, &conversion);
m_errorMonitor->VerifyFound();
}
TEST_F(VkLayerTest, DuplicateValidPNextStructures) {
TEST_DESCRIPTION("Create a pNext chain containing valid structures, but with a duplicate structure type");
// VK_KHR_get_physical_device_properties2 promoted to 1.1
SetTargetApiVersion(VK_API_VERSION_1_1);
RETURN_IF_SKIP(Init());
m_errorMonitor->SetDesiredError("VUID-VkPhysicalDeviceProperties2-sType-unique");
// in VkPhysicalDeviceProperties2 create a chain of pNext of type A -> B -> A
// Also using different instance of struct to not trip the cycle checkings
VkPhysicalDeviceProtectedMemoryProperties protected_memory_properties_0 =
vku::InitStructHelper();
VkPhysicalDeviceIDProperties id_properties = vku::InitStructHelper(&protected_memory_properties_0);
VkPhysicalDeviceProtectedMemoryProperties protected_memory_properties_1 =
vku::InitStructHelper(&id_properties);
VkPhysicalDeviceProperties2 physical_device_properties2 =
vku::InitStructHelper(&protected_memory_properties_1);
vk::GetPhysicalDeviceProperties2(Gpu(), &physical_device_properties2);
m_errorMonitor->VerifyFound();
}
TEST_F(VkLayerTest, GetPhysicalDeviceImageFormatPropertiesFlags) {
RETURN_IF_SKIP(Init());
if (DeviceExtensionSupported(Gpu(), nullptr, VK_KHR_MAINTENANCE_5_EXTENSION_NAME)) {
GTEST_SKIP() << "VK_KHR_maintenance5 is supported";
}
VkImageFormatProperties dummy_props;
m_errorMonitor->SetDesiredError("VUID-vkGetPhysicalDeviceImageFormatProperties-usage-requiredbitmask");
vk::GetPhysicalDeviceImageFormatProperties(m_device->Physical().handle(), VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TYPE_2D,
VK_IMAGE_TILING_OPTIMAL, 0, 0, &dummy_props);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkGetPhysicalDeviceImageFormatProperties-flags-parameter");
vk::GetPhysicalDeviceImageFormatProperties(m_device->Physical().handle(), VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TYPE_2D,
VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0xBAD00000, &dummy_props);
m_errorMonitor->VerifyFound();
}
TEST_F(VkLayerTest, GetCalibratedTimestampsDuplicate) {
TEST_DESCRIPTION("vkGetCalibratedTimestampsEXT with duplicated timeDomain.");
SetTargetApiVersion(VK_API_VERSION_1_1);
AddRequiredExtensions(VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME);
RETURN_IF_SKIP(Init());
uint32_t count = 0;
vk::GetPhysicalDeviceCalibrateableTimeDomainsEXT(Gpu(), &count, nullptr);
std::vector<VkTimeDomainEXT> time_domains(count);
vk::GetPhysicalDeviceCalibrateableTimeDomainsEXT(Gpu(), &count, time_domains.data());
VkCalibratedTimestampInfoEXT timestamp_infos[2];
timestamp_infos[0] = vku::InitStructHelper();
timestamp_infos[0].timeDomain = time_domains[0];
timestamp_infos[1] = vku::InitStructHelper();
timestamp_infos[1].timeDomain = time_domains[0];
uint64_t timestamps[2];
uint64_t max_deviation;
m_errorMonitor->SetDesiredError("VUID-vkGetCalibratedTimestampsEXT-timeDomain-09246");
vk::GetCalibratedTimestampsEXT(device(), 2, timestamp_infos, timestamps, &max_deviation);
m_errorMonitor->VerifyFound();
}
TEST_F(VkLayerTest, GetCalibratedTimestampsDuplicateKHR) {
TEST_DESCRIPTION("vkGetCalibratedTimestampsKHR with duplicated timeDomain.");
SetTargetApiVersion(VK_API_VERSION_1_1);
AddRequiredExtensions(VK_KHR_CALIBRATED_TIMESTAMPS_EXTENSION_NAME);
RETURN_IF_SKIP(Init());
uint32_t count = 0;
vk::GetPhysicalDeviceCalibrateableTimeDomainsKHR(Gpu(), &count, nullptr);
std::vector<VkTimeDomainKHR> time_domains(count);
vk::GetPhysicalDeviceCalibrateableTimeDomainsKHR(Gpu(), &count, time_domains.data());
VkCalibratedTimestampInfoEXT timestamp_infos[2];
timestamp_infos[0] = vku::InitStructHelper();
timestamp_infos[0].timeDomain = time_domains[0];
timestamp_infos[1] = vku::InitStructHelper();
timestamp_infos[1].timeDomain = time_domains[0];
uint64_t timestamps[2];
uint64_t max_deviation;
m_errorMonitor->SetDesiredError("VUID-vkGetCalibratedTimestampsEXT-timeDomain-09246");
vk::GetCalibratedTimestampsKHR(device(), 2, timestamp_infos, timestamps, &max_deviation);
m_errorMonitor->VerifyFound();
}
TEST_F(VkLayerTest, GetCalibratedTimestampsQuery) {
TEST_DESCRIPTION("vkGetCalibratedTimestampsEXT with invalid timeDomain.");
SetTargetApiVersion(VK_API_VERSION_1_1);
AddRequiredExtensions(VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME);
RETURN_IF_SKIP(Init());
uint32_t count = 0;
vk::GetPhysicalDeviceCalibrateableTimeDomainsEXT(Gpu(), &count, nullptr);
std::vector<VkTimeDomainEXT> time_domains(count);
vk::GetPhysicalDeviceCalibrateableTimeDomainsEXT(Gpu(), &count, time_domains.data());
for (uint32_t i = 0; i < count; i++) {
if (time_domains[i] == VK_TIME_DOMAIN_QUERY_PERFORMANCE_COUNTER_KHR) {
GTEST_SKIP() << "Support for VK_TIME_DOMAIN_QUERY_PERFORMANCE_COUNTER_KHR";
}
}
VkCalibratedTimestampInfoEXT timestamp_info = vku::InitStructHelper();
timestamp_info.timeDomain = VK_TIME_DOMAIN_QUERY_PERFORMANCE_COUNTER_KHR;
uint64_t timestamp;
uint64_t max_deviation;
m_errorMonitor->SetDesiredError("VUID-VkCalibratedTimestampInfoKHR-timeDomain-02354");
vk::GetCalibratedTimestampsEXT(device(), 1, &timestamp_info, &timestamp, &max_deviation);
m_errorMonitor->VerifyFound();
}
TEST_F(VkLayerTest, RayTracingStageFlagWithoutFeature) {
TEST_DESCRIPTION("Test using the ray tracing stage flag without enabling any of ray tracing features");
SetTargetApiVersion(VK_API_VERSION_1_1);
AddRequiredExtensions(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME);
RETURN_IF_SKIP(Init());
vkt::Semaphore semaphore(*m_device);
VkPipelineStageFlags stage = VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR;
VkSubmitInfo submit_info = vku::InitStructHelper();
submit_info.signalSemaphoreCount = 1u;
submit_info.pSignalSemaphores = &semaphore.handle();
vk::QueueSubmit(m_default_queue->handle(), 1u, &submit_info, VK_NULL_HANDLE);
submit_info.signalSemaphoreCount = 0u;
submit_info.waitSemaphoreCount = 1u;
submit_info.pWaitSemaphores = &semaphore.handle();
submit_info.pWaitDstStageMask = &stage;
m_errorMonitor->SetDesiredError("VUID-VkSubmitInfo-pWaitDstStageMask-07949");
vk::QueueSubmit(m_default_queue->handle(), 1u, &submit_info, VK_NULL_HANDLE);
m_errorMonitor->VerifyFound();
vkt::Event event(*m_device);
m_command_buffer.Begin();
m_errorMonitor->SetDesiredError("VUID-vkCmdSetEvent-stageMask-07949");
vk::CmdSetEvent(m_command_buffer.handle(), event.handle(), stage);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkCmdResetEvent-stageMask-07949");
vk::CmdResetEvent(m_command_buffer.handle(), event.handle(), stage);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkCmdWaitEvents-srcStageMask-07949");
vk::CmdWaitEvents(m_command_buffer.handle(), 1u, &event.handle(), stage, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0u, nullptr, 0u,
nullptr, 0u, nullptr);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkCmdWaitEvents-dstStageMask-07949");
vk::CmdWaitEvents(m_command_buffer.handle(), 1u, &event.handle(), VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, stage, 0u, nullptr, 0u,
nullptr, 0u, nullptr);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkCmdPipelineBarrier-srcStageMask-07949");
vk::CmdPipelineBarrier(m_command_buffer.handle(), stage, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0u, 0u, nullptr, 0u, nullptr, 0u,
nullptr);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkCmdPipelineBarrier-dstStageMask-07949");
vk::CmdPipelineBarrier(m_command_buffer.handle(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, stage, 0u, 0u, nullptr, 0u, nullptr, 0u,
nullptr);
m_errorMonitor->VerifyFound();
m_command_buffer.End();
m_default_queue->Wait();
}
TEST_F(VkLayerTest, ExtensionXmlDependsLogic) {
TEST_DESCRIPTION("Make sure the OR in 'depends' from XML is observed correctly");
// VK_KHR_buffer_device_address requires
// (VK_KHR_get_physical_device_properties2 AND VK_KHR_device_group) OR VK_VERSION_1_1
// If Vulkan 1.1 is not supported, should still be valid
SetTargetApiVersion(VK_API_VERSION_1_0);
if (!InstanceExtensionSupported(VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME) ||
!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
GTEST_SKIP() << "Did not find the required instance extensions";
}
m_instance_extension_names.push_back(VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME);
m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
RETURN_IF_SKIP(InitFramework());
if (!DeviceExtensionSupported(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME) ||
!DeviceExtensionSupported(VK_KHR_DEVICE_GROUP_EXTENSION_NAME)) {
GTEST_SKIP() << "Did not find the required device extensions";
}
m_device_extension_names.push_back(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
// missing VK_KHR_device_group
float priority = 1.0f;
VkDeviceQueueCreateInfo queue_info = vku::InitStructHelper();
queue_info.queueFamilyIndex = 0;
queue_info.queueCount = 1;
queue_info.pQueuePriorities = &priority;
VkDeviceCreateInfo dev_info = vku::InitStructHelper();
dev_info.queueCreateInfoCount = 1;
dev_info.pQueueCreateInfos = &queue_info;
dev_info.enabledLayerCount = 0;
dev_info.ppEnabledLayerNames = nullptr;
dev_info.enabledExtensionCount = static_cast<uint32_t>(m_device_extension_names.size());
dev_info.ppEnabledExtensionNames = m_device_extension_names.data();
m_errorMonitor->SetDesiredError("VUID-vkCreateDevice-ppEnabledExtensionNames-01387");
VkDevice device;
vk::CreateDevice(gpu_, &dev_info, nullptr, &device);
m_errorMonitor->VerifyFound();
}
TEST_F(VkLayerTest, ExtensionXmlDependsLogic2) {
// VK_KHR_shared_presentable_image requires
// VK_KHR_swapchain
// and
// VK_KHR_get_surface_capabilities2 (missing)
// and
// VK_KHR_get_physical_device_properties2
// or
// Version 1.1
SetTargetApiVersion(VK_API_VERSION_1_0);
if (!InstanceExtensionSupported(VK_KHR_SURFACE_EXTENSION_NAME) ||
!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
GTEST_SKIP() << "Did not find the required instance extensions";
}
m_instance_extension_names.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
RETURN_IF_SKIP(InitFramework());
if (!DeviceExtensionSupported(VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME) ||
!DeviceExtensionSupported(VK_KHR_SWAPCHAIN_EXTENSION_NAME)) {
GTEST_SKIP() << "Did not find the required device extensions";
}
m_device_extension_names.push_back(VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME);
m_device_extension_names.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
float priority = 1.0f;
VkDeviceQueueCreateInfo queue_info = vku::InitStructHelper();
queue_info.queueFamilyIndex = 0;
queue_info.queueCount = 1;
queue_info.pQueuePriorities = &priority;
VkDeviceCreateInfo dev_info = vku::InitStructHelper();
dev_info.queueCreateInfoCount = 1;
dev_info.pQueueCreateInfos = &queue_info;
dev_info.enabledLayerCount = 0;
dev_info.ppEnabledLayerNames = nullptr;
dev_info.enabledExtensionCount = static_cast<uint32_t>(m_device_extension_names.size());
dev_info.ppEnabledExtensionNames = m_device_extension_names.data();
m_errorMonitor->SetDesiredError("VUID-vkCreateDevice-ppEnabledExtensionNames-01387");
VkDevice device;
vk::CreateDevice(gpu_, &dev_info, nullptr, &device);
m_errorMonitor->VerifyFound();
}
TEST_F(VkLayerTest, ExtensionXmlDependsLogic3) {
// VK_KHR_shared_presentable_image requires
// VK_KHR_swapchain
// and
// VK_KHR_get_surface_capabilities2
// and
// VK_KHR_get_physical_device_properties2 (missing)
// or
// Version 1.1 (missing)
SetTargetApiVersion(VK_API_VERSION_1_0);
if (!InstanceExtensionSupported(VK_KHR_SURFACE_EXTENSION_NAME) ||
!InstanceExtensionSupported(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME)) {
GTEST_SKIP() << "Did not find the required instance extensions";
}
m_instance_extension_names.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
m_instance_extension_names.push_back(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME);
RETURN_IF_SKIP(InitFramework());
if (!DeviceExtensionSupported(VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME) ||
!DeviceExtensionSupported(VK_KHR_SWAPCHAIN_EXTENSION_NAME)) {
GTEST_SKIP() << "Did not find the required device extensions";
}
m_device_extension_names.push_back(VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME);
m_device_extension_names.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
float priority = 1.0f;
VkDeviceQueueCreateInfo queue_info = vku::InitStructHelper();
queue_info.queueFamilyIndex = 0;
queue_info.queueCount = 1;
queue_info.pQueuePriorities = &priority;
VkDeviceCreateInfo dev_info = vku::InitStructHelper();
dev_info.queueCreateInfoCount = 1;
dev_info.pQueueCreateInfos = &queue_info;
dev_info.enabledLayerCount = 0;
dev_info.ppEnabledLayerNames = nullptr;
dev_info.enabledExtensionCount = static_cast<uint32_t>(m_device_extension_names.size());
dev_info.ppEnabledExtensionNames = m_device_extension_names.data();
m_errorMonitor->SetDesiredError("VUID-vkCreateDevice-ppEnabledExtensionNames-01387");
VkDevice device;
vk::CreateDevice(gpu_, &dev_info, nullptr, &device);
m_errorMonitor->VerifyFound();
}
TEST_F(VkLayerTest, MissingExtensionPhysicalDeviceProperties) {
TEST_DESCRIPTION("Don't enable instance extension needed");
AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
RETURN_IF_SKIP(Init());
// requires VK_KHR_external_fence_capabilities
VkPhysicalDeviceIDPropertiesKHR id_properties = vku::InitStructHelper();
VkPhysicalDeviceProperties2 properties2 = vku::InitStructHelper(&id_properties);
m_errorMonitor->SetDesiredError("VUID-VkPhysicalDeviceProperties2-pNext-pNext");
vk::GetPhysicalDeviceProperties2KHR(Gpu(), &properties2);
m_errorMonitor->VerifyFound();
}
TEST_F(VkLayerTest, InvalidGetExternalBufferPropertiesUsage) {
TEST_DESCRIPTION("Call vkGetPhysicalDeviceExternalBufferProperties with invalid usage");
AddRequiredExtensions(VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME);
RETURN_IF_SKIP(Init());
#ifdef _WIN32
const auto handle_type = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT;
#else
const auto handle_type = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
#endif
VkPhysicalDeviceExternalBufferInfo externalBufferInfo = vku::InitStructHelper();
externalBufferInfo.usage = 0x80000000;
externalBufferInfo.handleType = handle_type;
VkExternalBufferProperties externalBufferProperties = vku::InitStructHelper();
m_errorMonitor->SetDesiredError("VUID-VkPhysicalDeviceExternalBufferInfo-None-09499");
vk::GetPhysicalDeviceExternalBufferPropertiesKHR(Gpu(), &externalBufferInfo, &externalBufferProperties);
m_errorMonitor->VerifyFound();
externalBufferInfo.usage = 0u;
m_errorMonitor->SetDesiredError("VUID-VkPhysicalDeviceExternalBufferInfo-None-09500");
vk::GetPhysicalDeviceExternalBufferPropertiesKHR(Gpu(), &externalBufferInfo, &externalBufferProperties);
m_errorMonitor->VerifyFound();
}
TEST_F(VkLayerTest, DescriptorBufferNoExtension) {
TEST_DESCRIPTION("Create VkBuffer without the extension.");
SetTargetApiVersion(VK_API_VERSION_1_2);
RETURN_IF_SKIP(Init());
VkBuffer buffer = VK_NULL_HANDLE;
VkBufferCreateInfo buffer_ci = vku::InitStructHelper();
buffer_ci.size = 64;
buffer_ci.usage = VK_BUFFER_USAGE_SAMPLER_DESCRIPTOR_BUFFER_BIT_EXT;
m_errorMonitor->SetDesiredError("VUID-VkBufferCreateInfo-None-09499");
vk::CreateBuffer(*m_device, &buffer_ci, nullptr, &buffer);
m_errorMonitor->VerifyFound();
}
TEST_F(VkLayerTest, MissingExtensionStruct) {
TEST_DESCRIPTION("Don't add extension but use extended structure");
SetTargetApiVersion(VK_API_VERSION_1_1);
RETURN_IF_SKIP(Init());
if (!DeviceExtensionSupported(VK_KHR_MAINTENANCE_5_EXTENSION_NAME)) {
GTEST_SKIP() << "VK_KHR_maintenance5 not supported";
}
vkt::Buffer buffer(*m_device, 32, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT);
// added in VK_KHR_maintenance5
VkBufferUsageFlags2CreateInfo buffer_usage_flags = vku::InitStructHelper();
buffer_usage_flags.usage = VK_BUFFER_USAGE_2_UNIFORM_TEXEL_BUFFER_BIT;
VkBufferViewCreateInfo buffer_view_ci = vku::InitStructHelper(&buffer_usage_flags);
buffer_view_ci.format = VK_FORMAT_R8G8B8A8_UNORM;
buffer_view_ci.range = VK_WHOLE_SIZE;
buffer_view_ci.buffer = buffer.handle();
m_errorMonitor->SetDesiredError("VUID-VkBufferViewCreateInfo-pNext-pNext");
m_errorMonitor->SetDesiredError("VUID-VkBufferViewCreateInfo-pNext-pNext");
vkt::BufferView view(*m_device, buffer_view_ci);
m_errorMonitor->VerifyFound();
}
TEST_F(VkLayerTest, MissingCreateInfo) {
RETURN_IF_SKIP(Init());
VkBuffer buffer;
m_errorMonitor->SetDesiredError("VUID-vkCreateBuffer-pCreateInfo-parameter");
vk::CreateBuffer(device(), nullptr, nullptr, &buffer);
m_errorMonitor->VerifyFound();
VkImage image;
m_errorMonitor->SetDesiredError("VUID-vkCreateImage-pCreateInfo-parameter");
vk::CreateImage(device(), nullptr, nullptr, &image);
m_errorMonitor->VerifyFound();
VkBufferView buffer_view;
m_errorMonitor->SetDesiredError("VUID-vkCreateBufferView-pCreateInfo-parameter");
vk::CreateBufferView(device(), nullptr, nullptr, &buffer_view);
m_errorMonitor->VerifyFound();
VkImageView image_view;
m_errorMonitor->SetDesiredError("VUID-vkCreateImageView-pCreateInfo-parameter");
vk::CreateImageView(device(), nullptr, nullptr, &image_view);
m_errorMonitor->VerifyFound();
VkRenderPass render_pass;
m_errorMonitor->SetDesiredError("VUID-vkCreateRenderPass-pCreateInfo-parameter");
vk::CreateRenderPass(device(), nullptr, nullptr, &render_pass);
m_errorMonitor->VerifyFound();
VkFramebuffer framebuffer;
m_errorMonitor->SetDesiredError("VUID-vkCreateFramebuffer-pCreateInfo-parameter");
vk::CreateFramebuffer(device(), nullptr, nullptr, &framebuffer);
m_errorMonitor->VerifyFound();
VkQueryPool query_pool;
m_errorMonitor->SetDesiredError("VUID-vkCreateQueryPool-pCreateInfo-parameter");
vk::CreateQueryPool(device(), nullptr, nullptr, &query_pool);
m_errorMonitor->VerifyFound();
VkPipelineLayout pipeline_layout;
m_errorMonitor->SetDesiredError("VUID-vkCreatePipelineLayout-pCreateInfo-parameter");
vk::CreatePipelineLayout(device(), nullptr, nullptr, &pipeline_layout);
m_errorMonitor->VerifyFound();
VkPipelineCache pipeline_cache;
m_errorMonitor->SetDesiredError("VUID-vkCreatePipelineCache-pCreateInfo-parameter");
vk::CreatePipelineCache(device(), nullptr, nullptr, &pipeline_cache);
m_errorMonitor->VerifyFound();
VkShaderModule shader_module;
m_errorMonitor->SetDesiredError("VUID-vkCreateShaderModule-pCreateInfo-parameter");
vk::CreateShaderModule(device(), nullptr, nullptr, &shader_module);
m_errorMonitor->VerifyFound();
VkFence fence;
m_errorMonitor->SetDesiredError("VUID-vkCreateFence-pCreateInfo-parameter");
vk::CreateFence(device(), nullptr, nullptr, &fence);
m_errorMonitor->VerifyFound();
VkSemaphore semaphore;
m_errorMonitor->SetDesiredError("VUID-vkCreateSemaphore-pCreateInfo-parameter");
vk::CreateSemaphore(device(), nullptr, nullptr, &semaphore);
m_errorMonitor->VerifyFound();
VkEvent event;
m_errorMonitor->SetDesiredError("VUID-vkCreateEvent-pCreateInfo-parameter");
vk::CreateEvent(device(), nullptr, nullptr, &event);
m_errorMonitor->VerifyFound();
VkSampler sampler;
m_errorMonitor->SetDesiredError("VUID-vkCreateSampler-pCreateInfo-parameter");
vk::CreateSampler(device(), nullptr, nullptr, &sampler);
m_errorMonitor->VerifyFound();
VkCommandPool command_pool;
m_errorMonitor->SetDesiredError("VUID-vkCreateCommandPool-pCreateInfo-parameter");
vk::CreateCommandPool(device(), nullptr, nullptr, &command_pool);
m_errorMonitor->VerifyFound();
VkDescriptorSetLayout set_layout;
m_errorMonitor->SetDesiredError("VUID-vkCreateDescriptorSetLayout-pCreateInfo-parameter");
vk::CreateDescriptorSetLayout(device(), nullptr, nullptr, &set_layout);
m_errorMonitor->VerifyFound();
VkDescriptorPool descriptor_pool;
m_errorMonitor->SetDesiredError("VUID-vkCreateDescriptorPool-pCreateInfo-parameter");
vk::CreateDescriptorPool(device(), nullptr, nullptr, &descriptor_pool);
m_errorMonitor->VerifyFound();
VkCommandBuffer command_buffer;
m_errorMonitor->SetDesiredError("VUID-vkAllocateCommandBuffers-pAllocateInfo-parameter");
vk::AllocateCommandBuffers(device(), nullptr, &command_buffer);
m_errorMonitor->VerifyFound();
// TODO - vvl::AllocateDescriptorSetsData currently doesn't null check pAllocateInfo
// VkDescriptorSet descriptor_set;
// m_errorMonitor->SetDesiredError("VUID-vkAllocateDescriptorSets-pAllocateInfo-parameter");
// vk::AllocateDescriptorSets(device(), nullptr, &descriptor_set);
// m_errorMonitor->VerifyFound();
VkDeviceMemory device_memory;
m_errorMonitor->SetDesiredError("VUID-vkAllocateMemory-pAllocateInfo-parameter");
vk::AllocateMemory(device(), nullptr, nullptr, &device_memory);
m_errorMonitor->VerifyFound();
VkPipeline pipeline;
m_errorMonitor->SetDesiredError("VUID-vkCreateGraphicsPipelines-pCreateInfos-parameter");
vk::CreateGraphicsPipelines(device(), VK_NULL_HANDLE, 1, nullptr, nullptr, &pipeline);
m_errorMonitor->VerifyFound();
m_errorMonitor->SetDesiredError("VUID-vkCreateComputePipelines-pCreateInfos-parameter");
vk::CreateComputePipelines(device(), VK_NULL_HANDLE, 1, nullptr, nullptr, &pipeline);
m_errorMonitor->VerifyFound();
}
// Android loader returns an error in this case, so never makes it to the VVL
#if !defined(VK_USE_PLATFORM_ANDROID_KHR)
TEST_F(VkLayerTest, GetDeviceProcAddrInstance) {
TEST_DESCRIPTION("Call GetDeviceProcAddr on an instance function");
RETURN_IF_SKIP(Init());
m_errorMonitor->SetDesiredWarning("WARNING-vkGetDeviceProcAddr-device");
vk::GetDeviceProcAddr(device(), "vkGetPhysicalDeviceProperties");
m_errorMonitor->VerifyFound();
}
#endif
// TODO - Can reproduce locally when setting VK_LAYER_MESSAGE_FORMAT_DISPLAY_APPLICATION_NAME
// but need to unset variable and make sure works on Android before having CI run this
TEST_F(VkLayerTest, DISABLED_DisplayApplicationName) {
TEST_DESCRIPTION("Test message_format_display_application_name");
const char *name_0 = "first instance";
app_info_.pApplicationName = name_0;
RETURN_IF_SKIP(Init());
const char *name_1 = "second instance";
app_info_.pApplicationName = name_1;
const auto instance_create_info = GetInstanceCreateInfo();
VkInstance instance2;
ASSERT_EQ(VK_SUCCESS, vk::CreateInstance(&instance_create_info, nullptr, &instance2));
uint32_t gpu_count = 0;
vk::EnumeratePhysicalDevices(instance2, &gpu_count, nullptr);
std::vector<VkPhysicalDevice> physical_devices(gpu_count);
vk::EnumeratePhysicalDevices(instance2, &gpu_count, physical_devices.data());
VkPhysicalDevice instance2_physical_device = physical_devices[0];
// scope so device is destroyed before instance
{
vkt::Device device2(instance2_physical_device, m_device_extension_names);
// VUID-vkCreateImage-pCreateInfo-parameter
VkImage image;
m_errorMonitor->SetDesiredError("AppName: first instance");
vk::CreateImage(device(), nullptr, nullptr, &image);
m_errorMonitor->VerifyFound();
// TODO - The second instance is not hooked up to the callback so will crash in corecheck or the driver
m_errorMonitor->SetDesiredError("AppName: second instance");
vk::CreateImage(device2.handle(), nullptr, nullptr, &image);
m_errorMonitor->VerifyFound();
}
ASSERT_NO_FATAL_FAILURE(vk::DestroyInstance(instance2, nullptr));
}
TEST_F(VkLayerTest, GetDeviceFaultInfoEXT) {
TEST_DESCRIPTION("Call vkGetDeviceFaultInfoEXT when no device is lost");
AddRequiredExtensions(VK_EXT_DEVICE_FAULT_EXTENSION_NAME);
AddRequiredFeature(vkt::Feature::deviceFault);
RETURN_IF_SKIP(Init());
VkDeviceFaultCountsEXT fault_count = vku::InitStructHelper();
VkDeviceFaultInfoEXT fault_info = vku::InitStructHelper();
m_errorMonitor->SetDesiredError("VUID-vkGetDeviceFaultInfoEXT-device-07336");
vk::GetDeviceFaultInfoEXT(device(), &fault_count, &fault_info);
m_errorMonitor->VerifyFound();
}
TEST_F(VkLayerTest, PhysicalDeviceLayeredApiVulkanPropertiesKHR) {
SetTargetApiVersion(VK_API_VERSION_1_2);
AddRequiredExtensions(VK_KHR_MAINTENANCE_7_EXTENSION_NAME);
AddRequiredFeature(vkt::Feature::maintenance7);
RETURN_IF_SKIP(Init());
VkPhysicalDeviceVulkan12Properties vulkan_12_props = vku::InitStructHelper(); // not allowed
VkPhysicalDeviceDriverProperties driver_props = vku::InitStructHelper(&vulkan_12_props);
VkPhysicalDeviceLayeredApiVulkanPropertiesKHR api_vulkan_props = vku::InitStructHelper();
api_vulkan_props.properties.pNext = &driver_props;
VkPhysicalDeviceLayeredApiPropertiesKHR api_props = vku::InitStructHelper(&api_vulkan_props);
VkPhysicalDeviceLayeredApiPropertiesListKHR api_prop_lists = vku::InitStructHelper();
api_prop_lists.layeredApiCount = 1;
api_prop_lists.pLayeredApis = &api_props;
VkPhysicalDeviceProperties2 phys_dev_props_2 = vku::InitStructHelper(&api_prop_lists);
m_errorMonitor->SetDesiredError("VUID-VkPhysicalDeviceLayeredApiVulkanPropertiesKHR-pNext-10011");
vk::GetPhysicalDeviceProperties2(Gpu(), &phys_dev_props_2);
m_errorMonitor->VerifyFound();
}
// stype-check off
// TODO - https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/9185
TEST_F(VkLayerTest, DISABLED_PhysicalDeviceLayeredApiVulkanPropertiesPNext) {
SetTargetApiVersion(VK_API_VERSION_1_2);
AddRequiredExtensions(VK_KHR_MAINTENANCE_7_EXTENSION_NAME);
AddRequiredFeature(vkt::Feature::maintenance7);
RETURN_IF_SKIP(Init());
VkPhysicalDeviceDriverProperties driver_props = vku::InitStructHelper();
VkPhysicalDeviceLayeredApiPropertiesKHR api_props = vku::InitStructHelper(&driver_props);
VkPhysicalDeviceLayeredApiPropertiesListKHR api_prop_lists = vku::InitStructHelper();
api_prop_lists.layeredApiCount = 1;
api_prop_lists.pLayeredApis = &api_props;
VkPhysicalDeviceProperties2 phys_dev_props_2 = vku::InitStructHelper(&api_prop_lists);
m_errorMonitor->SetDesiredError("VUID-VkPhysicalDeviceLayeredApiPropertiesKHR-pNext-pNext");
m_errorMonitor->SetDesiredError("VUID-VkPhysicalDeviceLayeredApiPropertiesKHR-sType-sType");
api_props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES;
vk::GetPhysicalDeviceProperties2(Gpu(), &phys_dev_props_2);
m_errorMonitor->VerifyFound();
}
// stype-check on
TEST_F(VkLayerTest, UnrecognizedEnumExtension) {
RETURN_IF_SKIP(Init());
m_errorMonitor->SetDesiredError("VUID-VkImageCreateInfo-format-parameter");
vkt::Image image(*m_device, 4, 4, 1, VK_FORMAT_A4B4G4R4_UNORM_PACK16, VK_IMAGE_USAGE_SAMPLED_BIT);
m_errorMonitor->VerifyFound();
}