Determine scaleFactor once per frame.

This way, for auto, we can properly treat it like scaleFactor = 1 when the
resolution is small.
This commit is contained in:
Unknown W. Brackets 2016-01-03 23:06:15 -08:00
parent abc0f27c95
commit e427d09628
6 changed files with 55 additions and 42 deletions

View File

@ -19,6 +19,7 @@
#include "Common/MemoryUtil.h"
#include "Core/Config.h"
#include "Core/Reporting.h"
#include "Core/System.h"
#include "GPU/Common/FramebufferCommon.h"
#include "GPU/Common/TextureCacheCommon.h"
#include "GPU/Common/TextureDecoder.h"
@ -164,6 +165,46 @@ void TextureCacheCommon::NotifyFramebuffer(u32 address, VirtualFramebuffer *fram
}
}
void TextureCacheCommon::NotifyConfigChanged() {
int scaleFactor;
// 0 means automatic texture scaling, up to 5x, based on resolution.
if (g_Config.iTexScalingLevel == 0) {
scaleFactor = g_Config.iInternalResolution;
// Automatic resolution too? Okay.
if (scaleFactor == 0) {
if (!g_Config.IsPortrait()) {
scaleFactor = (PSP_CoreParameter().pixelWidth + 479) / 480;
} else {
scaleFactor = (PSP_CoreParameter().pixelHeight + 479) / 480;
}
}
// Mobile devices don't get the higher scale factors, too expensive. Very rough way to decide though...
if (!gstate_c.Supports(GPU_IS_MOBILE)) {
scaleFactor = std::min(5, scaleFactor);
} else {
scaleFactor = std::min(3, scaleFactor);
}
} else {
scaleFactor = g_Config.iTexScalingLevel;
}
if (!gstate_c.Supports(GPU_SUPPORTS_OES_TEXTURE_NPOT)) {
// Reduce the scale factor to a power of two (e.g. 2 or 4) if textures must be a power of two.
while ((scaleFactor & (scaleFactor - 1)) != 0) {
--scaleFactor;
}
}
// Just in case, small display with auto resolution or something.
if (scaleFactor <= 0) {
scaleFactor = 1;
}
standardScaleFactor_ = scaleFactor;
}
void TextureCacheCommon::LoadClut(u32 clutAddr, u32 loadBytes) {
clutTotalBytes_ = loadBytes;
clutRenderAddress_ = 0xFFFFFFFF;

View File

@ -45,6 +45,7 @@ public:
// FramebufferManager keeps TextureCache updated about what regions of memory are being rendered to.
void NotifyFramebuffer(u32 address, VirtualFramebuffer *framebuffer, FramebufferNotification msg);
void NotifyConfigChanged();
int AttachedDrawingHeight();
@ -154,6 +155,7 @@ protected:
u32 clutTotalBytes_;
u32 clutMaxBytes_;
u32 clutRenderAddress_;
int standardScaleFactor_;
};
inline bool TextureCacheCommon::TexCacheEntry::Matches(u16 dim2, u8 format2, u8 maxLevel2) {

View File

@ -444,6 +444,7 @@ DIRECTX9_GPU::DIRECTX9_GPU()
// Some of our defaults are different from hw defaults, let's assert them.
// We restore each frame anyway, but here is convenient for tests.
dxstate.Restore();
textureCache_.NotifyConfigChanged();
}
void DIRECTX9_GPU::UpdateCmdInfo() {
@ -537,6 +538,7 @@ void DIRECTX9_GPU::BeginFrameInternal() {
if (resized_) {
UpdateCmdInfo();
transformDraw_.Resized();
textureCache_.NotifyConfigChanged();
resized_ = false;
}

View File

@ -1145,7 +1145,7 @@ void TextureCacheDX9::SetTexture(bool force) {
}
}
if (match && (entry->status & TexCacheEntry::STATUS_TO_SCALE) && g_Config.iTexScalingLevel != 1 && texelsScaledThisFrame_ < TEXCACHE_MAX_TEXELS_SCALED) {
if (match && (entry->status & TexCacheEntry::STATUS_TO_SCALE) && standardScaleFactor_ != 1 && texelsScaledThisFrame_ < TEXCACHE_MAX_TEXELS_SCALED) {
if ((entry->status & TexCacheEntry::STATUS_CHANGE_FREQUENT) == 0) {
// INFO_LOG(G3D, "Reloading texture to do the scaling we skipped..");
match = false;
@ -1172,7 +1172,7 @@ void TextureCacheDX9::SetTexture(bool force) {
gpuStats.numTextureInvalidations++;
DEBUG_LOG(G3D, "Texture different or overwritten, reloading at %08x: %s", texaddr, reason);
if (doDelete) {
if (entry->maxLevel == maxLevel && entry->dim == gstate.getTextureDimension(0) && entry->format == format && g_Config.iTexScalingLevel == 1) {
if (entry->maxLevel == maxLevel && entry->dim == gstate.getTextureDimension(0) && entry->format == format && standardScaleFactor_ == 1) {
// Actually, if size and number of levels match, let's try to avoid deleting and recreating.
// Instead, let's use glTexSubImage to replace the images.
replaceImages = true;
@ -1291,21 +1291,7 @@ void TextureCacheDX9::SetTexture(bool force) {
// If GLES3 is available, we can preallocate the storage, which makes texture loading more efficient.
D3DFORMAT dstFmt = GetDestFormat(format, gstate.getClutPaletteFormat());
int scaleFactor;
// Auto-texture scale upto 5x rendering resolution
if (g_Config.iTexScalingLevel == 0) {
scaleFactor = g_Config.iInternalResolution;
if (scaleFactor == 0) {
scaleFactor = (PSP_CoreParameter().renderWidth + 479) / 480;
}
scaleFactor = std::min(4, scaleFactor);
if (scaleFactor == 3) {
scaleFactor = 2;
}
} else {
scaleFactor = g_Config.iTexScalingLevel;
}
int scaleFactor = standardScaleFactor_;
// Rachet down scale factor in low-memory mode.
if (lowMemoryMode_) {
@ -1585,7 +1571,7 @@ void *TextureCacheDX9::DecodeTextureLevel(GETextureFormat format, GEPaletteForma
ERROR_LOG_REPORT(G3D, "NO finalbuf! Will crash!");
}
if (!(g_Config.iTexScalingLevel == 1 && gstate_c.Supports(GPU_SUPPORTS_UNPACK_SUBIMAGE)) && w != bufw) {
if (!(standardScaleFactor_ == 1 && gstate_c.Supports(GPU_SUPPORTS_UNPACK_SUBIMAGE)) && w != bufw) {
int pixelSize;
switch (dstFmt) {
case D3DFMT_A4R4G4B4:

View File

@ -454,8 +454,9 @@ GLES_GPU::GLES_GPU(GraphicsContext *ctx)
// Some of our defaults are different from hw defaults, let's assert them.
// We restore each frame anyway, but here is convenient for tests.
transformDraw_.RestoreVAO();
glstate.Restore();
transformDraw_.RestoreVAO();
textureCache_.NotifyConfigChanged();
}
GLES_GPU::~GLES_GPU() {
@ -715,6 +716,7 @@ void GLES_GPU::BeginFrameInternal() {
CheckGPUFeatures();
UpdateCmdInfo();
transformDraw_.Resized();
textureCache_.NotifyConfigChanged();
}
UpdateVsyncInterval(resized_);
resized_ = false;

View File

@ -1230,7 +1230,7 @@ void TextureCache::SetTexture(bool force) {
}
}
if (match && (entry->status & TexCacheEntry::STATUS_TO_SCALE) && g_Config.iTexScalingLevel != 1 && texelsScaledThisFrame_ < TEXCACHE_MAX_TEXELS_SCALED) {
if (match && (entry->status & TexCacheEntry::STATUS_TO_SCALE) && standardScaleFactor_ != 1 && texelsScaledThisFrame_ < TEXCACHE_MAX_TEXELS_SCALED) {
if ((entry->status & TexCacheEntry::STATUS_CHANGE_FREQUENT) == 0) {
// INFO_LOG(G3D, "Reloading texture to do the scaling we skipped..");
match = false;
@ -1255,7 +1255,7 @@ void TextureCache::SetTexture(bool force) {
gpuStats.numTextureInvalidations++;
DEBUG_LOG(G3D, "Texture different or overwritten, reloading at %08x: %s", texaddr, reason);
if (doDelete) {
if (entry->maxLevel == maxLevel && entry->dim == gstate.getTextureDimension(0) && entry->format == format && g_Config.iTexScalingLevel == 1) {
if (entry->maxLevel == maxLevel && entry->dim == gstate.getTextureDimension(0) && entry->format == format && standardScaleFactor_ == 1) {
// Actually, if size and number of levels match, let's try to avoid deleting and recreating.
// Instead, let's use glTexSubImage to replace the images.
replaceImages = true;
@ -1380,27 +1380,7 @@ void TextureCache::SetTexture(bool force) {
// If GLES3 is available, we can preallocate the storage, which makes texture loading more efficient.
GLenum dstFmt = GetDestFormat(format, gstate.getClutPaletteFormat());
int scaleFactor;
// Auto-texture scale upto 5x rendering resolution
if (g_Config.iTexScalingLevel == 0) {
scaleFactor = g_Config.iInternalResolution;
if (scaleFactor == 0) {
scaleFactor = (PSP_CoreParameter().renderWidth + 479) / 480;
}
// Mobile devices don't get the higher scale factors, too expensive. Very rough way to decide though...
if (!gstate_c.Supports(GPU_IS_MOBILE)) {
bool supportNpot = gstate_c.Supports(GPU_SUPPORTS_OES_TEXTURE_NPOT);
scaleFactor = std::min(supportNpot ? 5 : 4, scaleFactor);
if (!supportNpot && scaleFactor == 3) {
scaleFactor = 2;
}
} else {
scaleFactor = std::min(gstate_c.Supports(GPU_SUPPORTS_OES_TEXTURE_NPOT) ? 3 : 2, scaleFactor);
}
} else {
scaleFactor = g_Config.iTexScalingLevel;
}
int scaleFactor = standardScaleFactor_;
// Rachet down scale factor in low-memory mode.
if (lowMemoryMode_) {