diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 81741ed3f4..fa1abdcf49 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -2307,6 +2307,12 @@ bool TextureCacheCommon::PrepareBuildTexture(BuildTexturePlan &plan, TexCacheEnt plan.levelsToLoad = 1; } + if (plan.isVideo || plan.depth != 1) { + plan.maxPossibleLevels = 1; + } else { + plan.maxPossibleLevels = log2i(std::min(plan.w * plan.scaleFactor, plan.h * plan.scaleFactor)) + 1; + } + if (plan.levelsToCreate == 1) { entry->status |= TexCacheEntry::STATUS_NO_MIPS; } else { diff --git a/GPU/Common/TextureCacheCommon.h b/GPU/Common/TextureCacheCommon.h index 781ca3b655..4280848a02 100644 --- a/GPU/Common/TextureCacheCommon.h +++ b/GPU/Common/TextureCacheCommon.h @@ -255,6 +255,9 @@ struct BuildTexturePlan { // the missing levels, or limit itself to levelsToLoad levels. int levelsToCreate; + // The maximum number of mips levels we can create for this texture. + int maxPossibleLevels; + // Load the 0-mip from this PSP texture level instead of 0. // If non-zero, we are only loading one level. int baseLevelSrc; diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index 018d0c7a0e..beb89c6b43 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -282,8 +282,14 @@ void TextureCacheGLES::BuildTexture(TexCacheEntry *const entry) { } if (!gstate_c.Supports(GPU_SUPPORTS_TEXTURE_LOD_CONTROL)) { - // Force no additional mipmaps. - plan.levelsToCreate = plan.levelsToLoad; + // If the mip chain is not full.. + if (plan.levelsToCreate != plan.maxPossibleLevels) { + // We need to avoid creating mips at all, or generate them all - can't be incomplete + // on this hardware (strict OpenGL rules). + plan.levelsToCreate = 1; + plan.levelsToLoad = 1; + entry->status |= TexCacheEntry::STATUS_NO_MIPS; + } } if (plan.depth == 1) { diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index b0eea669f3..eb6ab9507a 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -438,13 +438,6 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) { return; } - int maxPossibleMipLevels; - if (plan.isVideo || plan.depth != 1) { - maxPossibleMipLevels = 1; - } else { - maxPossibleMipLevels = log2i(std::min(plan.w * plan.scaleFactor, plan.h * plan.scaleFactor)) + 1; - } - VkFormat dstFmt = GetDestFormat(GETextureFormat(entry->format), gstate.getClutPaletteFormat()); if (plan.scaleFactor > 1) { @@ -456,11 +449,11 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) { // and similar, which don't really need it. if (g_Config.iTexFiltering == TEX_FILTER_AUTO_MAX_QUALITY && plan.w <= 256 && plan.h <= 256) { // Boost the number of mipmaps. - if (maxPossibleMipLevels > plan.levelsToCreate) { + if (plan.maxPossibleLevels > plan.levelsToCreate) { // We have to generate mips with a shader. This requires decoding to R8G8B8A8_UNORM format to avoid extra complications. dstFmt = VULKAN_8888_FORMAT; } - plan.levelsToCreate = maxPossibleMipLevels; + plan.levelsToCreate = plan.maxPossibleLevels; } // Any texture scaling is gonna move away from the original 16-bit format, if any.