mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-07-11 01:25:07 +02:00
In D3D11, force block compressed textures to have dimensions divisible by 4
Fixes #17745 (crash when loading certain texture packs in D3D11) This is an old unfortunate limitation. Only applies to the top mip level, which makes it obvious that it's kinda unnecessary for the hardware and indeed, Vulkan and OpenGL don't have this limitation.
This commit is contained in:
@@ -513,6 +513,10 @@ ReplacedTexture::LoadLevelResult ReplacedTexture::LoadLevelData(VFSFileReference
|
||||
bool bc = Draw::DataFormatIsBlockCompressed(*pixelFormat, &blockSize);
|
||||
_dbg_assert_(bc || *pixelFormat == Draw::DataFormat::R8G8B8A8_UNORM);
|
||||
|
||||
if (bc && (level.w & 3) != 0 || (level.h & 3) != 0) {
|
||||
WARN_LOG(G3D, "Block compressed replacement texture '%s' not divisible by 4x4 (%dx%d). In D3D11 (only!) we will have to expand (potentially causing glitches).", filename.c_str(), level.w, level.h);
|
||||
}
|
||||
|
||||
data_.resize(numMips);
|
||||
|
||||
basist::ktx2_transcoder_state transcodeState; // Each thread needs one of these.
|
||||
@@ -546,6 +550,7 @@ ReplacedTexture::LoadLevelResult ReplacedTexture::LoadLevelData(VFSFileReference
|
||||
}
|
||||
transcoder.clear();
|
||||
vfs_->CloseFile(openFile);
|
||||
|
||||
return LoadLevelResult::DONE; // don't read more levels
|
||||
} else if (imageType == ReplacedImageType::DDS) {
|
||||
// TODO: Do better with alphaStatus, it's possible.
|
||||
@@ -562,6 +567,10 @@ ReplacedTexture::LoadLevelResult ReplacedTexture::LoadLevelData(VFSFileReference
|
||||
bool bc = Draw::DataFormatIsBlockCompressed(*pixelFormat, &blockSize);
|
||||
_dbg_assert_(bc);
|
||||
|
||||
if (bc && (level.w & 3) != 0 || (level.h & 3) != 0) {
|
||||
WARN_LOG(G3D, "Block compressed replacement texture '%s' not divisible by 4x4 (%dx%d). In D3D11 (only!) we will have to expand (potentially causing glitches).", filename.c_str(), level.w, level.h);
|
||||
}
|
||||
|
||||
data_.resize(numMips);
|
||||
|
||||
// A DDS File can contain multiple mipmaps.
|
||||
@@ -583,6 +592,7 @@ ReplacedTexture::LoadLevelResult ReplacedTexture::LoadLevelData(VFSFileReference
|
||||
level.fileRef = nullptr; // We only provide a fileref on level 0 if we have mipmaps.
|
||||
}
|
||||
vfs_->CloseFile(openFile);
|
||||
|
||||
return LoadLevelResult::DONE; // don't read more levels
|
||||
|
||||
} else if (imageType == ReplacedImageType::ZIM) {
|
||||
|
||||
@@ -337,6 +337,9 @@ bool TextureReplacer::LoadIniValues(IniFile &ini, VFSBackend *dir, bool isOverri
|
||||
}
|
||||
}
|
||||
|
||||
auto gr = GetI18NCategory(I18NCat::GRAPHICS);
|
||||
|
||||
g_OSD.Show(OSDType::MESSAGE_SUCCESS, gr->T("Texture replacement pack activated"));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -348,6 +348,14 @@ void TextureCacheD3D11::BuildTexture(TexCacheEntry *const entry) {
|
||||
if (th > 16384)
|
||||
th = 16384;
|
||||
|
||||
// NOTE: For block-compressed textures, we'll force the size up to the closest 4x4. This is due to an
|
||||
// unfortunate restriction in D3D11 (and early D3D12). We'll warn about it in the log to give texture pack
|
||||
// authors notice to fix it.
|
||||
if (plan.doReplace && Draw::DataFormatIsBlockCompressed(plan.replaced->Format(), nullptr)) {
|
||||
tw = (tw + 3) & ~3;
|
||||
th = (th + 3) & ~3;
|
||||
}
|
||||
|
||||
if (plan.depth == 1) {
|
||||
// We don't yet have mip generation, so clamp the number of levels to the ones we can load directly.
|
||||
levels = std::min(plan.levelsToCreate, plan.levelsToLoad);
|
||||
|
||||
@@ -630,6 +630,7 @@ Stereo rendering = Stereo rendering
|
||||
Stretch = Stretch
|
||||
Texture Filter = Texture filtering
|
||||
Texture Filtering = Texture filtering
|
||||
Texture replacement pack activated = Texture replacement pack activated
|
||||
Texture Scaling = Texture scaling
|
||||
Texture Shader = Texture shader
|
||||
Turn off Hardware Tessellation - unsupported = Turn off "hardware tessellation": unsupported
|
||||
|
||||
Reference in New Issue
Block a user