TextureCache: Fix D3D backends crashing when a game uses multiple 1x1-sized LODs.

This commit is contained in:
NeoBrainX 2013-02-18 17:14:56 +01:00
parent d0ea94a2aa
commit 19ab5bf50d
6 changed files with 13 additions and 3 deletions

View File

@ -318,7 +318,7 @@ static TextureCache::TCacheEntryBase* ReturnEntry(unsigned int stage, TextureCac
TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int const stage, TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int const stage,
u32 const address, unsigned int width, unsigned int height, int const texformat, u32 const address, unsigned int width, unsigned int height, int const texformat,
unsigned int const tlutaddr, int const tlutfmt, bool const use_mipmaps, unsigned int const maxlevel, bool const from_tmem) unsigned int const tlutaddr, int const tlutfmt, bool const use_mipmaps, unsigned int maxlevel, bool const from_tmem)
{ {
if (0 == address) if (0 == address)
return NULL; return NULL;
@ -372,6 +372,11 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int const stage,
tex_hash ^= tlut_hash; tex_hash ^= tlut_hash;
} }
// D3D doesn't like when the specified mipmap count would require more than one 1x1-sized LOD in the mipmap chain
// e.g. 64x64 with 7 LODs would have the mipmap chain 64x64,32x32,16x16,8x8,4x4,2x2,1x1,1x1, so we limit the mipmap count to 6 there
while (g_ActiveConfig.backend_info.bUseMinimalMipCount && max(expandedWidth, expandedHeight) >> maxlevel == 0)
--maxlevel;
TCacheEntryBase *entry = textures[texID]; TCacheEntryBase *entry = textures[texID];
if (entry) if (entry)
{ {
@ -456,7 +461,7 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int const stage,
const bool using_custom_lods = using_custom_texture && CheckForCustomTextureLODs(tex_hash, texformat, texLevels); const bool using_custom_lods = using_custom_texture && CheckForCustomTextureLODs(tex_hash, texformat, texLevels);
// Only load native mips if their dimensions fit to our virtual texture dimensions // Only load native mips if their dimensions fit to our virtual texture dimensions
const bool use_native_mips = use_mipmaps && !using_custom_lods && (width == nativeW && height == nativeH); const bool use_native_mips = use_mipmaps && !using_custom_lods && (width == nativeW && height == nativeH);
texLevels = (use_native_mips || using_custom_lods) ? texLevels : 1; texLevels = (use_native_mips || using_custom_lods) ? texLevels : 1; // TODO: Should be forced to 1 for non-pow2 textures (e.g. efb copies with automatically adjusted IR)
// create the entry/texture // create the entry/texture
if (NULL == entry) if (NULL == entry)

View File

@ -42,6 +42,7 @@ VideoConfig::VideoConfig()
// disable all features by default // disable all features by default
backend_info.APIType = API_NONE; backend_info.APIType = API_NONE;
backend_info.bUseRGBATextures = false; backend_info.bUseRGBATextures = false;
backend_info.bUseMinimalMipCount = false;
backend_info.bSupports3DVision = false; backend_info.bSupports3DVision = false;
} }

View File

@ -157,6 +157,7 @@ struct VideoConfig
std::vector<std::string> PPShaders; // post-processing shaders std::vector<std::string> PPShaders; // post-processing shaders
bool bUseRGBATextures; // used for D3D11 in TextureCache bool bUseRGBATextures; // used for D3D11 in TextureCache
bool bUseMinimalMipCount;
bool bSupports3DVision; bool bSupports3DVision;
bool bSupportsDualSourceBlend; // only supported by D3D11 and OpenGL bool bSupportsDualSourceBlend; // only supported by D3D11 and OpenGL
bool bSupportsFormatReinterpretation; bool bSupportsFormatReinterpretation;

View File

@ -90,6 +90,7 @@ void InitBackendInfo()
g_Config.backend_info.APIType = API_D3D11; g_Config.backend_info.APIType = API_D3D11;
g_Config.backend_info.bUseRGBATextures = true; // the GX formats barely match any D3D11 formats g_Config.backend_info.bUseRGBATextures = true; // the GX formats barely match any D3D11 formats
g_Config.backend_info.bUseMinimalMipCount = true;
g_Config.backend_info.bSupports3DVision = false; g_Config.backend_info.bSupports3DVision = false;
g_Config.backend_info.bSupportsDualSourceBlend = true; g_Config.backend_info.bSupportsDualSourceBlend = true;
g_Config.backend_info.bSupportsFormatReinterpretation = true; g_Config.backend_info.bSupportsFormatReinterpretation = true;

View File

@ -93,6 +93,7 @@ void InitBackendInfo()
const int maxConstants = (shaderModel < 3) ? 32 : ((shaderModel < 4) ? 224 : 65536); const int maxConstants = (shaderModel < 3) ? 32 : ((shaderModel < 4) ? 224 : 65536);
g_Config.backend_info.APIType = shaderModel < 3 ? API_D3D9_SM20 :API_D3D9_SM30; g_Config.backend_info.APIType = shaderModel < 3 ? API_D3D9_SM20 :API_D3D9_SM30;
g_Config.backend_info.bUseRGBATextures = false; g_Config.backend_info.bUseRGBATextures = false;
g_Config.backend_info.bUseMinimalMipCount = true;
g_Config.backend_info.bSupports3DVision = true; g_Config.backend_info.bSupports3DVision = true;
g_Config.backend_info.bSupportsDualSourceBlend = false; g_Config.backend_info.bSupportsDualSourceBlend = false;
g_Config.backend_info.bSupportsFormatReinterpretation = true; g_Config.backend_info.bSupportsFormatReinterpretation = true;

View File

@ -130,6 +130,7 @@ void InitBackendInfo()
{ {
g_Config.backend_info.APIType = API_OPENGL; g_Config.backend_info.APIType = API_OPENGL;
g_Config.backend_info.bUseRGBATextures = false; g_Config.backend_info.bUseRGBATextures = false;
g_Config.backend_info.bUseMinimalMipCount = false;
g_Config.backend_info.bSupports3DVision = false; g_Config.backend_info.bSupports3DVision = false;
g_Config.backend_info.bSupportsDualSourceBlend = false; // supported, but broken g_Config.backend_info.bSupportsDualSourceBlend = false; // supported, but broken
g_Config.backend_info.bSupportsFormatReinterpretation = false; g_Config.backend_info.bSupportsFormatReinterpretation = false;