Fix or ignore some various Vulkan validation errors

This commit is contained in:
Henrik Rydgård 2024-04-03 13:37:16 +02:00
parent ed3514f882
commit 32fe47d761
3 changed files with 44 additions and 34 deletions

View file

@ -86,6 +86,15 @@ VkResult VulkanContext::CreateInstance(const CreateInfo &info) {
return VK_ERROR_INITIALIZATION_FAILED; return VK_ERROR_INITIALIZATION_FAILED;
} }
// Check which Vulkan version we should request.
// Our code is fine with any version from 1.0 to 1.2, we don't know about higher versions.
vulkanApiVersion_ = VK_API_VERSION_1_0;
if (vkEnumerateInstanceVersion) {
vkEnumerateInstanceVersion(&vulkanApiVersion_);
vulkanApiVersion_ &= 0xFFFFF000; // Remove patch version.
vulkanApiVersion_ = std::min(VK_API_VERSION_1_3, vulkanApiVersion_);
}
instance_layer_names_.clear(); instance_layer_names_.clear();
device_layer_names_.clear(); device_layer_names_.clear();
@ -167,22 +176,13 @@ VkResult VulkanContext::CreateInstance(const CreateInfo &info) {
WARN_LOG(G3D, "WARNING: Does not seem that instance extension '%s' is available. Trying to proceed anyway.", ext); WARN_LOG(G3D, "WARNING: Does not seem that instance extension '%s' is available. Trying to proceed anyway.", ext);
} }
// Check which Vulkan version we should request.
// Our code is fine with any version from 1.0 to 1.2, we don't know about higher versions.
u32 vulkanApiVersion = VK_API_VERSION_1_0;
if (vkEnumerateInstanceVersion) {
vkEnumerateInstanceVersion(&vulkanApiVersion);
vulkanApiVersion &= 0xFFFFF000; // Remove patch version.
vulkanApiVersion = std::min(VK_API_VERSION_1_2, vulkanApiVersion);
}
VkApplicationInfo app_info{ VK_STRUCTURE_TYPE_APPLICATION_INFO }; VkApplicationInfo app_info{ VK_STRUCTURE_TYPE_APPLICATION_INFO };
app_info.pApplicationName = info.app_name; app_info.pApplicationName = info.app_name;
app_info.applicationVersion = info.app_ver; app_info.applicationVersion = info.app_ver;
app_info.pEngineName = info.app_name; app_info.pEngineName = info.app_name;
// Let's increment this when we make major engine/context changes. // Let's increment this when we make major engine/context changes.
app_info.engineVersion = 2; app_info.engineVersion = 2;
app_info.apiVersion = vulkanApiVersion; app_info.apiVersion = vulkanApiVersion_;
VkInstanceCreateInfo inst_info{ VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO }; VkInstanceCreateInfo inst_info{ VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO };
inst_info.flags = 0; inst_info.flags = 0;
@ -619,7 +619,10 @@ void VulkanContext::ChooseDevice(int physical_device) {
device_extensions_enabled_.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME); device_extensions_enabled_.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
} }
bool VulkanContext::EnableDeviceExtension(const char *extension) { bool VulkanContext::EnableDeviceExtension(const char *extension, uint32_t coreVersion) {
if (coreVersion != 0 && vulkanApiVersion_ >= coreVersion) {
return true;
}
for (auto &iter : device_extension_properties_) { for (auto &iter : device_extension_properties_) {
if (!strcmp(iter.extensionName, extension)) { if (!strcmp(iter.extensionName, extension)) {
device_extensions_enabled_.push_back(extension); device_extensions_enabled_.push_back(extension);
@ -660,30 +663,30 @@ VkResult VulkanContext::CreateDevice() {
_dbg_assert_(found); _dbg_assert_(found);
// TODO: A lot of these are on by default in later Vulkan versions, should check for that, technically. // TODO: A lot of these are on by default in later Vulkan versions, should check for that, technically.
extensionsLookup_.KHR_maintenance1 = EnableDeviceExtension(VK_KHR_MAINTENANCE1_EXTENSION_NAME); extensionsLookup_.KHR_maintenance1 = EnableDeviceExtension(VK_KHR_MAINTENANCE1_EXTENSION_NAME, VK_API_VERSION_1_1);
extensionsLookup_.KHR_maintenance2 = EnableDeviceExtension(VK_KHR_MAINTENANCE2_EXTENSION_NAME); extensionsLookup_.KHR_maintenance2 = EnableDeviceExtension(VK_KHR_MAINTENANCE2_EXTENSION_NAME, VK_API_VERSION_1_1);
extensionsLookup_.KHR_maintenance3 = EnableDeviceExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME); extensionsLookup_.KHR_maintenance3 = EnableDeviceExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME, VK_API_VERSION_1_1);
extensionsLookup_.KHR_multiview = EnableDeviceExtension(VK_KHR_MULTIVIEW_EXTENSION_NAME); extensionsLookup_.KHR_multiview = EnableDeviceExtension(VK_KHR_MULTIVIEW_EXTENSION_NAME, VK_API_VERSION_1_1);
if (EnableDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME)) { if (EnableDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, VK_API_VERSION_1_1)) {
extensionsLookup_.KHR_get_memory_requirements2 = true; extensionsLookup_.KHR_get_memory_requirements2 = true;
extensionsLookup_.KHR_dedicated_allocation = EnableDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME); extensionsLookup_.KHR_dedicated_allocation = EnableDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME, VK_API_VERSION_1_1);
} }
if (EnableDeviceExtension(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME)) { if (EnableDeviceExtension(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME, VK_API_VERSION_1_2)) {
extensionsLookup_.KHR_create_renderpass2 = true; extensionsLookup_.KHR_create_renderpass2 = true;
extensionsLookup_.KHR_depth_stencil_resolve = EnableDeviceExtension(VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME); extensionsLookup_.KHR_depth_stencil_resolve = EnableDeviceExtension(VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME, VK_API_VERSION_1_2);
} }
extensionsLookup_.EXT_shader_stencil_export = EnableDeviceExtension(VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME); extensionsLookup_.EXT_shader_stencil_export = EnableDeviceExtension(VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME, 0);
extensionsLookup_.EXT_fragment_shader_interlock = EnableDeviceExtension(VK_EXT_FRAGMENT_SHADER_INTERLOCK_EXTENSION_NAME); extensionsLookup_.EXT_fragment_shader_interlock = EnableDeviceExtension(VK_EXT_FRAGMENT_SHADER_INTERLOCK_EXTENSION_NAME, 0);
extensionsLookup_.ARM_rasterization_order_attachment_access = EnableDeviceExtension(VK_ARM_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_EXTENSION_NAME); extensionsLookup_.ARM_rasterization_order_attachment_access = EnableDeviceExtension(VK_ARM_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_EXTENSION_NAME, 0);
#if !PPSSPP_PLATFORM(MAC) && !PPSSPP_PLATFORM(IOS) #if !PPSSPP_PLATFORM(MAC) && !PPSSPP_PLATFORM(IOS)
extensionsLookup_.GOOGLE_display_timing = EnableDeviceExtension(VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME); extensionsLookup_.GOOGLE_display_timing = EnableDeviceExtension(VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME, 0);
#endif #endif
if (!extensionsLookup_.GOOGLE_display_timing) { if (!extensionsLookup_.GOOGLE_display_timing) {
extensionsLookup_.KHR_present_id = EnableDeviceExtension(VK_KHR_PRESENT_ID_EXTENSION_NAME); extensionsLookup_.KHR_present_id = EnableDeviceExtension(VK_KHR_PRESENT_ID_EXTENSION_NAME, 0);
extensionsLookup_.KHR_present_wait = EnableDeviceExtension(VK_KHR_PRESENT_WAIT_EXTENSION_NAME); extensionsLookup_.KHR_present_wait = EnableDeviceExtension(VK_KHR_PRESENT_WAIT_EXTENSION_NAME, 0);
} }
deviceFeatures_.enabled = {}; deviceFeatures_.enabled = {};
@ -752,7 +755,7 @@ VkResult VulkanContext::CreateDevice() {
VulkanSetAvailable(true); VulkanSetAvailable(true);
VmaAllocatorCreateInfo allocatorInfo = {}; VmaAllocatorCreateInfo allocatorInfo = {};
allocatorInfo.vulkanApiVersion = VK_API_VERSION_1_0; allocatorInfo.vulkanApiVersion = vulkanApiVersion_;
allocatorInfo.physicalDevice = physical_devices_[physical_device_]; allocatorInfo.physicalDevice = physical_devices_[physical_device_];
allocatorInfo.device = device_; allocatorInfo.device = device_;
allocatorInfo.instance = instance_; allocatorInfo.instance = instance_;

View file

@ -183,7 +183,8 @@ public:
int GetPhysicalDeviceByName(const std::string &name); int GetPhysicalDeviceByName(const std::string &name);
void ChooseDevice(int physical_device); void ChooseDevice(int physical_device);
bool EnableInstanceExtension(const char *extension); bool EnableInstanceExtension(const char *extension);
bool EnableDeviceExtension(const char *extension); // The core version is to avoid enabling extensions that are merged into core Vulkan from a certain version.
bool EnableDeviceExtension(const char *extension, uint32_t coreVersion);
VkResult CreateDevice(); VkResult CreateDevice();
const std::string &InitError() const { return init_error_; } const std::string &InitError() const { return init_error_; }
@ -428,6 +429,7 @@ private:
VkDevice device_ = VK_NULL_HANDLE; VkDevice device_ = VK_NULL_HANDLE;
VkQueue gfx_queue_ = VK_NULL_HANDLE; VkQueue gfx_queue_ = VK_NULL_HANDLE;
VkSurfaceKHR surface_ = VK_NULL_HANDLE; VkSurfaceKHR surface_ = VK_NULL_HANDLE;
u32 vulkanApiVersion_ = 0;
std::string init_error_; std::string init_error_;
std::vector<const char *> instance_layer_names_; std::vector<const char *> instance_layer_names_;

View file

@ -74,25 +74,26 @@ VKAPI_ATTR VkBool32 VKAPI_CALL VulkanDebugUtilsCallback(
// Can happen when VMA aggressively tries to allocate aperture memory for upload. It gracefully // Can happen when VMA aggressively tries to allocate aperture memory for upload. It gracefully
// falls back to regular video memory, so we just ignore this. I'd argue this is a VMA bug, actually. // falls back to regular video memory, so we just ignore this. I'd argue this is a VMA bug, actually.
return false; return false;
case 181611958:
// Extended validation.
// UNASSIGNED-BestPractices-vkCreateDevice-deprecated-extension
// Doing what this one says doesn't seem very reliable - if I rely strictly on the Vulkan version, I don't get some function pointers? Like createrenderpass2.
return false;
case 657182421: case 657182421:
// Extended validation (ARM best practices) // Extended validation (ARM best practices)
// Non-fifo validation not recommended // Non-fifo validation not recommended
return false; return false;
case 672904502:
// ARM best practices: index buffer usage warning (too few indices used compared to value range).
// This should be looked into more - happens even in moppi-flower which is weird.
return false;
case 337425955: case 337425955:
// False positive // False positive
// https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/3615 // https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/3615
return false; return false;
case 227275665:
// PowerVR (and all other) best practices: LOAD_OP_LOAD used in render pass.
return false;
case 1835555994: // [AMD] [NVIDIA] Performance warning : Pipeline VkPipeline 0xa808d50000000033[global_texcolor] was bound twice in the frame. case 1835555994: // [AMD] [NVIDIA] Performance warning : Pipeline VkPipeline 0xa808d50000000033[global_texcolor] was bound twice in the frame.
// Benign perf warnings. // Benign perf warnings.
return false; return false;
case 1810669668: case 1243445977:
// Clear value but no LOAD_OP_CLEAR. Not worth fixing right now. // Clear value but no LOAD_OP_CLEAR. Not worth fixing right now.
return false; return false;
@ -100,6 +101,10 @@ VKAPI_ATTR VkBool32 VKAPI_CALL VulkanDebugUtilsCallback(
// MSAA depth resolve write-after-write?? // MSAA depth resolve write-after-write??
return false; return false;
case -1306653903:
// ARM complaint about non-fifo swapchain
return false;
default: default:
break; break;
} }