From 466a731ece7fd0a8740a04510c8fe59431a6104f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 7 Dec 2021 21:26:14 +0100 Subject: [PATCH 1/4] Detect and specify the max available Vulkan version, up to 1.2. --- Common/GPU/Vulkan/VulkanContext.cpp | 11 ++++++++++- Common/GPU/Vulkan/VulkanLoader.cpp | 2 ++ Common/GPU/Vulkan/VulkanLoader.h | 1 + 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/Common/GPU/Vulkan/VulkanContext.cpp b/Common/GPU/Vulkan/VulkanContext.cpp index 3951e73f766d..94c8bb2b063b 100644 --- a/Common/GPU/Vulkan/VulkanContext.cpp +++ b/Common/GPU/Vulkan/VulkanContext.cpp @@ -162,13 +162,22 @@ VkResult VulkanContext::CreateInstance(const CreateInfo &info) { 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 }; app_info.pApplicationName = info.app_name; app_info.applicationVersion = info.app_ver; app_info.pEngineName = info.app_name; // Let's increment this when we make major engine/context changes. app_info.engineVersion = 2; - app_info.apiVersion = VK_API_VERSION_1_0; + app_info.apiVersion = vulkanApiVersion; VkInstanceCreateInfo inst_info{ VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO }; inst_info.flags = 0; diff --git a/Common/GPU/Vulkan/VulkanLoader.cpp b/Common/GPU/Vulkan/VulkanLoader.cpp index 26391ab62c22..ad285df1ec7b 100644 --- a/Common/GPU/Vulkan/VulkanLoader.cpp +++ b/Common/GPU/Vulkan/VulkanLoader.cpp @@ -32,6 +32,7 @@ namespace PPSSPP_VK { PFN_vkCreateInstance vkCreateInstance; PFN_vkDestroyInstance vkDestroyInstance; PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices; +PFN_vkEnumerateInstanceVersion vkEnumerateInstanceVersion; PFN_vkGetPhysicalDeviceFeatures vkGetPhysicalDeviceFeatures; PFN_vkGetPhysicalDeviceFormatProperties vkGetPhysicalDeviceFormatProperties; PFN_vkGetPhysicalDeviceImageFormatProperties vkGetPhysicalDeviceImageFormatProperties; @@ -485,6 +486,7 @@ bool VulkanLoad() { LOAD_GLOBAL_FUNC(vkGetInstanceProcAddr); LOAD_GLOBAL_FUNC(vkGetDeviceProcAddr); + LOAD_GLOBAL_FUNC(vkEnumerateInstanceVersion); LOAD_GLOBAL_FUNC(vkEnumerateInstanceExtensionProperties); LOAD_GLOBAL_FUNC(vkEnumerateInstanceLayerProperties); diff --git a/Common/GPU/Vulkan/VulkanLoader.h b/Common/GPU/Vulkan/VulkanLoader.h index 5b0cb93b0aa0..7afacacc73e6 100644 --- a/Common/GPU/Vulkan/VulkanLoader.h +++ b/Common/GPU/Vulkan/VulkanLoader.h @@ -38,6 +38,7 @@ namespace PPSSPP_VK { extern PFN_vkCreateInstance vkCreateInstance; extern PFN_vkDestroyInstance vkDestroyInstance; extern PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices; +extern PFN_vkEnumerateInstanceVersion vkEnumerateInstanceVersion; extern PFN_vkGetPhysicalDeviceFeatures vkGetPhysicalDeviceFeatures; extern PFN_vkGetPhysicalDeviceFormatProperties vkGetPhysicalDeviceFormatProperties; extern PFN_vkGetPhysicalDeviceImageFormatProperties vkGetPhysicalDeviceImageFormatProperties; From 0179cb18110f5ab5b32fb060c0d00c2b87c007ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 7 Dec 2021 21:28:39 +0100 Subject: [PATCH 2/4] Very minor logging improvement --- Common/SysError.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Common/SysError.cpp b/Common/SysError.cpp index 2bf17740aae1..c046b8f63b87 100644 --- a/Common/SysError.cpp +++ b/Common/SysError.cpp @@ -50,7 +50,12 @@ std::string GetStringErrorMsg(int errCode) { char err_str[buff_size] = {}; snprintf(err_str, buff_size, "%s", ConvertWStringToUTF8(err_strw).c_str()); - return std::string(err_str); + + std::string err_string = err_str; + if (!err_string.empty() && err_string.back() == '\n') { + err_string.pop_back(); + } + return err_string; #else char err_str[buff_size] = {}; From 05429fc34ffcb4b020300c7c79894c6fa0a57e35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 7 Dec 2021 21:28:58 +0100 Subject: [PATCH 3/4] Vulkan: Correct the max level to generate mipmap calculation --- GPU/Vulkan/TextureCacheVulkan.cpp | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 15cba3afd5ad..606f451be416 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -630,15 +630,6 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) { VkFormat dstFmt = GetDestFormat(GETextureFormat(entry->format), gstate.getClutPaletteFormat()); - // TODO: Really should inspect the format capabilities. - if (g_Config.iTexFiltering == TEX_FILTER_AUTO_MAX_QUALITY) { - // Boost the number of mipmaps. - int maxPossibleMipmaps = log2i(std::min(gstate.getTextureWidth(0), gstate.getTextureHeight(0))); - if (maxPossibleMipmaps > maxLevelToGenerate) { - maxLevelToGenerate = maxPossibleMipmaps; - dstFmt = VK_FORMAT_R8G8B8A8_UNORM; - } - } int scaleFactor = standardScaleFactor_; bool hardwareScaling = g_Config.bTexHardwareScaling && uploadCS_ != VK_NULL_HANDLE; @@ -664,6 +655,7 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) { badMipSizes = false; } + // Don't scale the PPGe texture. if (entry->addr > 0x05000000 && entry->addr < PSP_GetKernelMemoryEnd()) { scaleFactor = 1; @@ -685,12 +677,23 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) { } } - // TODO: Support mip levels for upscaled images. + // TODO: Support reading actual mip levels for upscaled images, instead of just generating them. // Probably can just remove this check? if (scaleFactor > 1) { maxLevel = 0; } + int maxPossibleMipmaps = log2i(std::min(w * scaleFactor, h * scaleFactor)); + + // TODO: Really should inspect the format capabilities. + if (g_Config.iTexFiltering == TEX_FILTER_AUTO_MAX_QUALITY) { + // Boost the number of mipmaps. + if (maxPossibleMipmaps > maxLevelToGenerate) { + dstFmt = VK_FORMAT_R8G8B8A8_UNORM; + } + maxLevelToGenerate = maxPossibleMipmaps; + } + // Any texture scaling is gonna move away from the original 16-bit format, if any. VkFormat actualFmt = scaleFactor > 1 ? VULKAN_8888_FORMAT : dstFmt; if (replaced.Valid()) { From a2f9f68565e52eb1cfd5722fd413de478cfb7cf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 7 Dec 2021 21:46:10 +0100 Subject: [PATCH 4/4] Vulkan: More scissor dimension checks. See #15207 --- Common/GPU/Vulkan/VulkanQueueRunner.cpp | 2 ++ Common/GPU/Vulkan/VulkanRenderManager.h | 9 +++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Common/GPU/Vulkan/VulkanQueueRunner.cpp b/Common/GPU/Vulkan/VulkanQueueRunner.cpp index a44d02167ac2..d6575c4cc69b 100644 --- a/Common/GPU/Vulkan/VulkanQueueRunner.cpp +++ b/Common/GPU/Vulkan/VulkanQueueRunner.cpp @@ -1337,6 +1337,8 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c } else { // Rendering to backbuffer. Might need to rotate. const VkRect2D &rc = c.scissor.scissor; + _dbg_assert_(rc.offset.x >= 0); + _dbg_assert_(rc.offset.y >= 0); DisplayRect rotated_rc{ rc.offset.x, rc.offset.y, (int)rc.extent.width, (int)rc.extent.height }; RotateRectToDisplay(rotated_rc, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight()); _dbg_assert_(rotated_rc.x >= 0); diff --git a/Common/GPU/Vulkan/VulkanRenderManager.h b/Common/GPU/Vulkan/VulkanRenderManager.h index ec4f701d8dd6..d707c5479b79 100644 --- a/Common/GPU/Vulkan/VulkanRenderManager.h +++ b/Common/GPU/Vulkan/VulkanRenderManager.h @@ -291,6 +291,8 @@ class VulkanRenderManager { void SetScissor(VkRect2D rc) { _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER); + _dbg_assert_((int)rc.offset.x >= 0); + _dbg_assert_((int)rc.offset.y >= 0); _dbg_assert_((int)rc.extent.width >= 0); _dbg_assert_((int)rc.extent.height >= 0); @@ -300,7 +302,7 @@ class VulkanRenderManager { rc.extent.width = std::max(1, newWidth); if (rc.offset.x >= curWidth_) { // Fallback. - rc.offset.x = curWidth_ - rc.extent.width; + rc.offset.x = std::max(0, curWidth_ - (int)rc.extent.width); } } @@ -309,9 +311,12 @@ class VulkanRenderManager { rc.extent.height = std::max(1, newHeight); if (rc.offset.y >= curHeight_) { // Fallback. - rc.offset.y = curHeight_ - rc.extent.height; + rc.offset.y = std::max(0, curHeight_ - (int)rc.extent.height); } } + + // TODO: If any of the dimensions are now zero, we should flip a flag and not do draws, probably. + curRenderArea_.Apply(rc); VkRenderData data{ VKRRenderCommand::SCISSOR };