Change from maxLevel to levelsToLoad, for better readability. Cleanup.

This commit is contained in:
Henrik Rydgård 2022-07-29 12:59:43 +02:00
parent 1e9d85cda1
commit d0d53091a8
11 changed files with 66 additions and 75 deletions

View file

@ -376,9 +376,9 @@ void GLQueueRunner::RunInitSteps(const std::vector<GLRInitStep> &steps, bool ski
boundTexture = tex->texture;
}
if (!gl_extensions.IsGLES || gl_extensions.GLES3) {
glTexParameteri(tex->target, GL_TEXTURE_MAX_LEVEL, step.texture_finalize.maxLevel);
glTexParameteri(tex->target, GL_TEXTURE_MAX_LEVEL, step.texture_finalize.loadedLevels - 1);
}
tex->maxLod = (float)step.texture_finalize.maxLevel;
tex->maxLod = (float)step.texture_finalize.loadedLevels - 1;
if (step.texture_finalize.genMips) {
glGenerateMipmap(tex->target);
}

View file

@ -267,7 +267,7 @@ struct GLRInitStep {
} texture_image;
struct {
GLRTexture *texture;
int maxLevel;
int loadedLevels;
bool genMips;
} texture_finalize;
};

View file

@ -565,10 +565,10 @@ public:
curRenderStep_->commands.push_back(_data);
}
void FinalizeTexture(GLRTexture *texture, int maxLevels, bool genMips) {
void FinalizeTexture(GLRTexture *texture, int loadedLevels, bool genMips) {
GLRInitStep step{ GLRInitStepType::TEXTURE_FINALIZE };
step.texture_finalize.texture = texture;
step.texture_finalize.maxLevel = maxLevels;
step.texture_finalize.loadedLevels = loadedLevels;
step.texture_finalize.genMips = genMips;
initSteps_.push_back(step);
}

View file

@ -845,8 +845,8 @@ void ReplacedTexture::Prepare() {
if (cancelPrepare_)
return;
levelData_.resize(MaxLevel() + 1);
for (int i = 0; i <= MaxLevel(); ++i) {
levelData_.resize(NumLevels());
for (int i = 0; i < NumLevels(); ++i) {
if (cancelPrepare_)
break;
PrepareData(i);

View file

@ -60,8 +60,7 @@ struct ReplacementCacheKey {
u64 cachekey;
u32 hash;
ReplacementCacheKey(u64 c, u32 h) : cachekey(c), hash(h) {
}
ReplacementCacheKey(u64 c, u32 h) : cachekey(c), hash(h) { }
bool operator ==(const ReplacementCacheKey &k) const {
return k.cachekey == cachekey && k.hash == hash;
@ -85,8 +84,7 @@ struct ReplacementAliasKey {
};
};
ReplacementAliasKey(u64 c, u32 h, u32 l) : cachekey(c), level(l), hash(h) {
}
ReplacementAliasKey(u64 c, u32 h, u32 l) : cachekey(c), level(l), hash(h) { }
bool operator ==(const ReplacementAliasKey &k) const {
return k.cachekey == cachekey && k.hashAndLevel == hashAndLevel;
@ -119,11 +117,11 @@ namespace std {
struct ReplacedTexture {
~ReplacedTexture();
inline bool Valid() {
inline bool Valid() const {
return !levels_.empty();
}
bool GetSize(int level, int &w, int &h) {
bool GetSize(int level, int &w, int &h) const {
if ((size_t)level < levels_.size()) {
w = levels_[level].w;
h = levels_[level].h;
@ -132,18 +130,18 @@ struct ReplacedTexture {
return false;
}
int MaxLevel() {
return (int)levels_.size() - 1;
int NumLevels() const {
return (int)levels_.size();
}
Draw::DataFormat Format(int level) {
Draw::DataFormat Format(int level) const {
if ((size_t)level < levels_.size()) {
return levels_[level].fmt;
}
return Draw::DataFormat::R8G8B8A8_UNORM;
}
u8 AlphaStatus() {
u8 AlphaStatus() const {
return (u8)alphaStatus_;
}

View file

@ -2020,13 +2020,12 @@ bool TextureCacheCommon::PrepareBuildTexture(BuildTexturePlan &plan, TexCacheEnt
plan.badMipSizes = false;
// maxLevel here is the max level to upload. Not the count.
plan.canAutoGen = false;
plan.maxLevelToLoad = entry->maxLevel;
for (int i = 0; i <= plan.maxLevelToLoad; i++) {
plan.levelsToLoad = entry->maxLevel + 1;
for (int i = 0; i < plan.levelsToLoad; i++) {
// If encountering levels pointing to nothing, adjust max level.
u32 levelTexaddr = gstate.getTextureAddress(i);
if (!Memory::IsValidAddress(levelTexaddr)) {
plan.maxLevelToLoad = i - 1;
plan.levelsToLoad = i;
break;
}
@ -2034,7 +2033,7 @@ bool TextureCacheCommon::PrepareBuildTexture(BuildTexturePlan &plan, TexCacheEnt
int tw = gstate.getTextureWidth(i);
int th = gstate.getTextureHeight(i);
if (tw == 1 || th == 1) {
plan.maxLevelToLoad = i;
plan.levelsToLoad = i + 1; // next level is assumed to be invalid
break;
}
@ -2048,9 +2047,6 @@ bool TextureCacheCommon::PrepareBuildTexture(BuildTexturePlan &plan, TexCacheEnt
else if (th != 1 && th != (lastH >> 1))
plan.badMipSizes = true;
}
if (lastW > tw || lastH > th)
plan.canAutoGen = true;
}
}
@ -2064,7 +2060,7 @@ bool TextureCacheCommon::PrepareBuildTexture(BuildTexturePlan &plan, TexCacheEnt
}
if (plan.badMipSizes) {
plan.maxLevelToLoad = 0;
plan.levelsToLoad = 1;
}
if (plan.hardwareScaling) {
@ -2074,7 +2070,7 @@ bool TextureCacheCommon::PrepareBuildTexture(BuildTexturePlan &plan, TexCacheEnt
// We generate missing mipmaps from maxLevel+1 up to this level. maxLevel can get overwritten below
// such as when using replacement textures - but let's keep the same amount of levels for generation.
// Not all backends will generate mipmaps, and in GL we can't really control the number of levels.
plan.levelsToCreate = plan.maxLevelToLoad + 1;
plan.levelsToCreate = plan.levelsToLoad;
plan.w = gstate.getTextureWidth(0);
plan.h = gstate.getTextureHeight(0);
@ -2083,7 +2079,7 @@ bool TextureCacheCommon::PrepareBuildTexture(BuildTexturePlan &plan, TexCacheEnt
if (plan.replaced->Valid()) {
// We're replacing, so we won't scale.
plan.scaleFactor = 1;
plan.maxLevelToLoad = plan.replaced->MaxLevel();
plan.levelsToLoad = plan.replaced->NumLevels();
plan.badMipSizes = false;
}
@ -2113,7 +2109,7 @@ bool TextureCacheCommon::PrepareBuildTexture(BuildTexturePlan &plan, TexCacheEnt
// TODO: Support reading actual mip levels for upscaled images, instead of just generating them.
// Maybe can just remove this check?
if (plan.scaleFactor > 1) {
plan.maxLevelToLoad = 0;
plan.levelsToLoad = 1;
bool enableVideoUpscaling = false;
@ -2129,7 +2125,7 @@ bool TextureCacheCommon::PrepareBuildTexture(BuildTexturePlan &plan, TexCacheEnt
// NOTE: Since the level is not part of the cache key, we assume it never changes.
plan.baseLevelSrc = std::max(0, gstate.getTexLevelOffset16() / 16);
plan.levelsToCreate = 1;
plan.maxLevelToLoad = 0;
plan.levelsToLoad = 1;
}
if (plan.levelsToCreate == 1) {

View file

@ -240,14 +240,12 @@ struct BuildTexturePlan {
// However, we still respect baseLevelSrc.
bool badMipSizes;
// Set if we can autogenerate mipmaps. Probably redundant.
bool canAutoGen;
// Number of mip levels to load from PSP memory (or replacement).
int levelsToLoad;
// Highest index of a level to load.
int maxLevelToLoad;
// The number of levels in total to create. If more than maxLevelToLoad,
// the backend is expected to either generate the levels, or limit itself to maxLevelToLoad.
// The number of levels in total to create.
// If greater than maxLevelToLoad, the backend is expected to either generate
// the missing levels, or limit itself to levelsToLoad levels.
int levelsToCreate;
// Load the 0-mip from this PSP texture level instead of 0.

View file

@ -472,6 +472,9 @@ void TextureCacheD3D11::BuildTexture(TexCacheEntry *const entry) {
}
}
// We don't yet have mip generation, so clamp the number of levels to the ones we can load directly.
int levels = std::min(plan.levelsToCreate, plan.levelsToLoad);
D3D11_TEXTURE2D_DESC desc{};
desc.CPUAccessFlags = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
@ -480,7 +483,7 @@ void TextureCacheD3D11::BuildTexture(TexCacheEntry *const entry) {
desc.Width = tw;
desc.Height = th;
desc.Format = tfmt;
desc.MipLevels = plan.levelsToCreate;
desc.MipLevels = levels;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
ASSERT_SUCCESS(device_->CreateTexture2D(&desc, nullptr, &texture));
@ -489,10 +492,16 @@ void TextureCacheD3D11::BuildTexture(TexCacheEntry *const entry) {
entry->textureView = view;
// Mipmapping is only enabled when texture scaling is disabled.
for (int i = 0; i < plan.levelsToCreate; i++) {
for (int i = 0; i < levels; i++) {
LoadTextureLevel(*entry, *plan.replaced, (i == 0) ? plan.baseLevelSrc : i, i, plan.scaleFactor, dstFmt);
}
if (levels == 1) {
entry->status |= TexCacheEntry::STATUS_NO_MIPS;
} else {
entry->status &= ~TexCacheEntry::STATUS_NO_MIPS;
}
if (plan.replaced->Valid()) {
entry->SetAlphaStatus(TexCacheEntry::TexStatus(plan.replaced->AlphaStatus()));
}

View file

@ -428,7 +428,10 @@ void TextureCacheDX9::BuildTexture(TexCacheEntry *const entry) {
}
}
HRESULT hr = device_->CreateTexture(tw, th, plan.levelsToCreate, usage, tfmt, pool, &texture, NULL);
// We don't yet have mip generation, so clamp the number of levels to the ones we can load directly.
int levels = std::min(plan.levelsToCreate, plan.levelsToLoad);
HRESULT hr = device_->CreateTexture(tw, th, levels, usage, tfmt, pool, &texture, NULL);
if (FAILED(hr)) {
INFO_LOG(G3D, "Failed to create D3D texture: %dx%d", tw, th);
@ -442,7 +445,7 @@ void TextureCacheDX9::BuildTexture(TexCacheEntry *const entry) {
}
// Mipmapping is only enabled when texture scaling is disabled.
for (int i = 0; i < plan.levelsToCreate; i++) {
for (int i = 0; i < levels; i++) {
int dstLevel = i;
HRESULT result;
uint32_t lockFlag = dstLevel == 0 ? D3DLOCK_DISCARD : 0; // Can only discard the top level

View file

@ -443,47 +443,34 @@ void TextureCacheGLES::BuildTexture(TexCacheEntry *const entry) {
// than determining if we can wrap this texture size, that is, it's pow2 or not on very old hardware, else true.
// This will be easy after .. well, yet another refactoring, where I hoist the size calculation out of LoadTextureLevel
// and unify BuildTexture.
entry->textureName = render_->CreateTexture(GL_TEXTURE_2D, 16, 16, 1);
entry->textureName = render_->CreateTexture(GL_TEXTURE_2D, plan.w, plan.h, plan.levelsToCreate);
Draw::DataFormat dstFmt = GetDestFormat(GETextureFormat(entry->format), gstate.getClutPaletteFormat());
LoadTextureLevel(*entry, *plan.replaced, plan.baseLevelSrc, 0, plan.scaleFactor, dstFmt);
// Mipmapping is only enabled when texture scaling is disabled.
int texMaxLevel = 0;
bool genMips = false;
if (plan.maxLevelToLoad > 0 && plan.scaleFactor == 1) {
if (gstate_c.Supports(GPU_SUPPORTS_TEXTURE_LOD_CONTROL)) {
if (plan.badMipSizes) {
// WARN_LOG(G3D, "Bad mipmap for texture sized %dx%dx%d - autogenerating", w, h, (int)format);
if (plan.canAutoGen) {
genMips = true;
} else {
texMaxLevel = 0;
plan.maxLevelToLoad = 0;
}
} else {
for (int i = 1; i <= plan.maxLevelToLoad; i++) {
LoadTextureLevel(*entry, *plan.replaced, i, i, plan.scaleFactor, dstFmt);
}
texMaxLevel = plan.maxLevelToLoad;
}
// Apply some additional compatibility checks.
if (plan.levelsToLoad > 1) {
// Avoid PowerVR driver bug
if (plan.w > 1 && plan.h > 1 && !(plan.h > plan.w && draw_->GetBugs().Has(Draw::Bugs::PVR_GENMIPMAP_HEIGHT_GREATER))) { // Really! only seems to fail if height > width
// It's ok to generate mipmaps beyond the loaded levels.
} else {
// Avoid PowerVR driver bug
if (plan.canAutoGen && plan.w > 1 && plan.h > 1 && !(plan.h > plan.w && draw_->GetBugs().Has(Draw::Bugs::PVR_GENMIPMAP_HEIGHT_GREATER))) { // Really! only seems to fail if height > width
// NOTICE_LOG(G3D, "Generating mipmap for texture sized %dx%d%d", w, h, (int)format);
genMips = true;
} else {
plan.maxLevelToLoad = 0;
}
plan.levelsToCreate = plan.levelsToLoad;
}
} else if (gstate_c.Supports(GPU_SUPPORTS_TEXTURE_LOD_CONTROL)) {
texMaxLevel = 0;
}
if (!gstate_c.Supports(GPU_SUPPORTS_TEXTURE_LOD_CONTROL)) {
// Force no additional mipmaps.
plan.levelsToCreate = plan.levelsToLoad;
}
render_->FinalizeTexture(entry->textureName, texMaxLevel, genMips);
for (int i = 0; i < plan.levelsToLoad; i++) {
LoadTextureLevel(*entry, *plan.replaced, i == 0 ? plan.baseLevelSrc : i, i, plan.scaleFactor, dstFmt);
}
if (plan.maxLevelToLoad == 0) {
bool genMips = plan.levelsToCreate > plan.levelsToLoad;
render_->FinalizeTexture(entry->textureName, plan.levelsToLoad, genMips);
if (plan.levelsToLoad == 1) {
entry->status |= TexCacheEntry::STATUS_NO_MIPS;
} else {
entry->status &= ~TexCacheEntry::STATUS_NO_MIPS;

View file

@ -649,7 +649,7 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) {
if (replaced.Valid()) {
// We're replacing, so we won't scale.
scaleFactor = 1;
maxLevel = replaced.MaxLevel();
maxLevel = replaced.NumLevels() - 1;
badMipSizes = false;
}