Just some basic code cleanup in TextureCacheCommon.

This commit is contained in:
Henrik Rydgård committed 2026-06-08 22:51:00 +02:00
1 parent 2360466cc4
commit e0a961ddc5
4 files changed
+51 -61

No files matched your search

+30 -31
View File
@@ -63,6 +63,9 @@
#define TEXCACHE_MIN_PRESSURE 16 * 1024 * 1024 // Total in VRAM
#define TEXCACHE_SECOND_MIN_PRESSURE 4 * 1024 * 1024
static bool MatchFramebuffer(const TextureDefinition &entry, VirtualFramebuffer *framebuffer, u32 texaddrOffset, RasterChannel channel, bool useBufferedRendering, FramebufferMatchInfo *matchInfo);
static bool GetBestFramebufferCandidate(FramebufferManagerCommon *fbManager, const TextureDefinition &entry, u32 texAddrOffset, AttachCandidate *bestCandidate, const char *context);
// Just for reference
// PSP Color formats:
@@ -339,6 +342,7 @@ SamplerCacheKey TextureCacheCommon::GetSamplingParams(int maxLevel, const TexCac
}
SamplerCacheKey TextureCacheCommon::GetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight) {
// TODO: This call is pretty pointless, we overwrite most of it.
SamplerCacheKey key = GetSamplingParams(0, nullptr, true);
// In case auto max quality was on, restore min filt. Another fix for water in Outrun.
@@ -358,6 +362,7 @@ SamplerCacheKey TextureCacheCommon::GetFramebufferSamplingParams(u16 bufferWidth
int w = gstate.getTextureWidth(0);
int h = gstate.getTextureHeight(0);
if (w != bufferWidth || h != bufferHeight) {
// Actually, maybe we should always do this?
key.sClamp = true;
key.tClamp = true;
}
@@ -626,7 +631,7 @@ TexCacheEntry *TextureCacheCommon::SetTexture() {
def.bufw = bufw;
AttachCandidate bestCandidate;
if (GetBestFramebufferCandidate(def, 0, &bestCandidate, "texture")) {
if (GetBestFramebufferCandidate(framebufferManager_, def, 0, &bestCandidate, "texture")) {
// If we had a texture entry here, let's get rid of it.
if (entryIter != cache_.end()) {
DeleteTexture(entryIter);
@@ -709,20 +714,22 @@ TexCacheEntry *TextureCacheCommon::SetTexture() {
return entry;
}
bool TextureCacheCommon::GetBestFramebufferCandidate(const TextureDefinition &entry, u32 texAddrOffset, AttachCandidate *bestCandidate, const char *context) const {
static bool GetBestFramebufferCandidate(FramebufferManagerCommon *fbManager, const TextureDefinition &entry, u32 texAddrOffset, AttachCandidate *bestCandidate, const char *context) {
gpuStats.perFrame.numFramebufferEvaluations++;
TinySet<AttachCandidate, 6> candidates;
const std::vector<VirtualFramebuffer *> &framebuffers = framebufferManager_->Framebuffers();
const std::vector<VirtualFramebuffer *> &framebuffers = fbManager->Framebuffers();
const bool useBufferedRendering = fbManager->UseBufferedRendering();
for (VirtualFramebuffer *framebuffer : framebuffers) {
FramebufferMatchInfo match{};
if (MatchFramebuffer(entry, framebuffer, texAddrOffset, RASTER_COLOR, &match)) {
if (MatchFramebuffer(entry, framebuffer, texAddrOffset, RASTER_COLOR, useBufferedRendering, &match)) {
candidates.push_back(AttachCandidate{ framebuffer, match, RASTER_COLOR });
}
match = {};
if (MatchFramebuffer(entry, framebuffer, texAddrOffset, RASTER_DEPTH, &match)) {
if (MatchFramebuffer(entry, framebuffer, texAddrOffset, RASTER_DEPTH, useBufferedRendering, &match)) {
candidates.push_back(AttachCandidate{ framebuffer, match, RASTER_DEPTH });
}
}
@@ -768,7 +775,7 @@ bool TextureCacheCommon::GetBestFramebufferCandidate(const TextureDefinition &en
// Avoid binding as texture the framebuffer we're rendering to.
// In Killzone, we split the framebuffer but the matching algorithm can still pick the wrong one,
// which this avoids completely.
if (kzCompat && candidate.fb == framebufferManager_->GetCurrentRenderVFB()) {
if (kzCompat && candidate.fb == fbManager->GetCurrentRenderVFB()) {
continue;
}
@@ -853,7 +860,7 @@ void TextureCacheCommon::Decimate(TexCacheEntry *exceptThisOne, bool forcePressu
// In low memory mode, we kill them all since secondary cache is disabled.
if (lowMemoryMode_ || iter->second->lastFrame + TEXTURE_SECOND_KILL_AGE < gpuStats.totals.numFlips) {
ReleaseTexture(iter->second.get(), true);
secondCacheSizeEstimate_ -= EstimateTexMemoryUsage(iter->second.get());
secondCacheSizeEstimate_ -= iter->second->EstimateTexMemoryUsage();
iter = secondCache_.erase(iter);
} else {
++iter;
@@ -863,11 +870,7 @@ void TextureCacheCommon::Decimate(TexCacheEntry *exceptThisOne, bool forcePressu
VERBOSE_LOG(Log::G3D, "Decimated second texture cache, saved %d estimated bytes - now %d bytes", had - secondCacheSizeEstimate_, secondCacheSizeEstimate_);
}
DecimateVideos();
replacer_.Decimate(forcePressure ? ReplacerDecimateMode::FORCE_PRESSURE : ReplacerDecimateMode::NEW_FRAME);
}
void TextureCacheCommon::DecimateVideos() {
// Decimate known videos.
for (auto iter = videos_.begin(); iter != videos_.end(); ) {
if (iter->flips + VIDEO_DECIMATE_AGE < gpuStats.totals.numFlips) {
iter = videos_.erase(iter);
@@ -875,6 +878,8 @@ void TextureCacheCommon::DecimateVideos() {
++iter;
}
}
replacer_.Decimate(forcePressure ? ReplacerDecimateMode::FORCE_PRESSURE : ReplacerDecimateMode::NEW_FRAME);
}
bool TextureCacheCommon::IsVideo(u32 texaddr) const {
@@ -891,7 +896,7 @@ bool TextureCacheCommon::IsVideo(u32 texaddr) const {
}
void TextureCacheCommon::HandleTextureChange(TexCacheEntry *const entry, const char *reason, bool initialMatch, bool doDelete) {
cacheSizeEstimate_ -= EstimateTexMemoryUsage(entry);
cacheSizeEstimate_ -= entry->EstimateTexMemoryUsage();
entry->numInvalidated++;
gpuStats.perFrame.numTextureInvalidations++;
DEBUG_LOG(Log::G3D, "Texture different or overwritten, reloading at %08x: %s", entry->addr, reason);
@@ -980,9 +985,8 @@ void TextureCacheCommon::NotifyFramebuffer(VirtualFramebuffer *framebuffer, Fram
}
}
bool TextureCacheCommon::MatchFramebuffer(
const TextureDefinition &entry,
VirtualFramebuffer *framebuffer, u32 texaddrOffset, RasterChannel channel, FramebufferMatchInfo *matchInfo) const {
static bool MatchFramebuffer(const TextureDefinition &entry,
VirtualFramebuffer *framebuffer, u32 texaddrOffset, RasterChannel channel, bool useBufferedRendering, FramebufferMatchInfo *matchInfo) {
static const u32 MAX_SUBAREA_Y_OFFSET_SAFE = 32;
uint32_t fb_address = channel == RASTER_DEPTH ? framebuffer->z_address : framebuffer->fb_address;
@@ -1052,12 +1056,9 @@ bool TextureCacheCommon::MatchFramebuffer(
// Format incompatible, ignoring without comment. (maybe some really gnarly hacks will end up here...)
return false;
}
} else if (!useBufferedRendering) {
return false;
} else {
// Apply to buffered mode only.
if (!framebufferManager_->UseBufferedRendering()) {
return false;
}
// Check works for D16 too.
// These are combinations that we have special-cased handling for. There are more
// ones possible, but rare - we'll add them as we find them used.
@@ -1275,7 +1276,7 @@ bool TextureCacheCommon::SetOffsetTexture(u32 yOffset) {
def.dim = gstate.getTextureDimension(0);
AttachCandidate bestCandidate;
if (GetBestFramebufferCandidate(def, texaddrOffset, &bestCandidate, "offsetTexture")) {
if (GetBestFramebufferCandidate(framebufferManager_, def, texaddrOffset, &bestCandidate, "offsetTexture")) {
SetTextureFramebuffer(bestCandidate);
return true;
} else {
@@ -1547,14 +1548,13 @@ bool TextureCacheCommon::GetCurrentClutBuffer(GPUDebugBuffer &buffer) {
}
// Host memory usage, not PSP memory usage.
u32 TextureCacheCommon::EstimateTexMemoryUsage(const TexCacheEntry *entry) {
const u16 dim = entry->dim;
u32 TexCacheEntry::EstimateTexMemoryUsage() const {
// TODO: This does not take into account the HD remaster's larger textures.
const u8 dimW = ((dim >> 0) & 0xf);
const u8 dimH = ((dim >> 8) & 0xf);
u32 pixelSize = 2;
switch (entry->format) {
switch (format) {
case GE_TFMT_CLUT4:
case GE_TFMT_CLUT8:
case GE_TFMT_CLUT16:
@@ -2579,7 +2579,7 @@ void TextureCacheCommon::Clear(bool delete_them) {
void TextureCacheCommon::DeleteTexture(TexCache::iterator it) {
ReleaseTexture(it->second.get(), true);
cacheSizeEstimate_ -= EstimateTexMemoryUsage(it->second.get());
cacheSizeEstimate_ -= it->second->EstimateTexMemoryUsage();
cache_.erase(it);
}
@@ -2644,7 +2644,7 @@ bool TextureCacheCommon::CheckFullHash(TexCacheEntry *entry, bool &doDelete) {
// It wasn't found, so we're about to throw away the entry and rebuild a texture.
// Let's save this in the secondary cache in case it gets used again.
secondKey = entry->fullhash | ((u64)entry->cluthash << 32);
secondCacheSizeEstimate_ += EstimateTexMemoryUsage(entry);
secondCacheSizeEstimate_ += entry->EstimateTexMemoryUsage();
// If the entry already exists in the secondary texture cache, drop it nicely.
auto oldIter = secondCache_.find(secondKey);
@@ -2773,7 +2773,7 @@ bool TextureCacheCommon::PrepareBuildTexture(BuildTexturePlan &plan, TexCacheEnt
gpuStats.perFrame.numTexturesDecoded++;
// For the estimate, we assume cluts always point to 8888 for simplicity.
cacheSizeEstimate_ += EstimateTexMemoryUsage(entry);
cacheSizeEstimate_ += entry->EstimateTexMemoryUsage();
plan.badMipSizes = false;
// maxLevel here is the max level to upload. Not the count.
@@ -2912,9 +2912,8 @@ bool TextureCacheCommon::PrepareBuildTexture(BuildTexturePlan &plan, TexCacheEnt
if (plan.scaleFactor > 1) {
plan.levelsToLoad = 1;
bool enableVideoUpscaling = false;
if (!enableVideoUpscaling && plan.isVideo) {
if (plan.isVideo) {
// No upscaling for video textures.
plan.scaleFactor = 1;
plan.levelsToCreate = 1;
}
+3 -7
View File
@@ -235,6 +235,7 @@ struct TexCacheEntry {
bool Matches(u16 dim2, u8 format2, u8 maxLevel2) const;
u64 CacheKey() const;
static u64 CacheKey(u32 addr, u8 format, u16 dim, u32 cluthash);
u32 EstimateTexMemoryUsage() const;
};
std::string TexStatusToString(TexCacheEntry::TexStatus status);
@@ -443,22 +444,17 @@ protected:
return (const T *)clutBufRaw_;
}
static u32 EstimateTexMemoryUsage(const TexCacheEntry *entry);
// These need to be member functions just for IsVideo and Replacer.
SamplerCacheKey GetSamplingParams(int maxLevel, const TexCacheEntry *entry, bool flatZ);
SamplerCacheKey GetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight);
void UpdateMaxSeenV(TexCacheEntry *entry, bool throughMode);
bool MatchFramebuffer(const TextureDefinition &entry, VirtualFramebuffer *framebuffer, u32 texaddrOffset, RasterChannel channel, FramebufferMatchInfo *matchInfo) const;
bool GetBestFramebufferCandidate(const TextureDefinition &entry, u32 texAddrOffset, AttachCandidate *bestCandidate, const char *context) const;
void SetTextureFramebuffer(const AttachCandidate &candidate);
bool GetCurrentFramebufferTextureDebug(GPUDebugBuffer &buffer, bool *isFramebuffer);
virtual void BoundFramebufferTexture() {}
void DecimateVideos();
bool IsVideo(u32 texaddr) const;
static CheckAlphaResult CheckCLUTAlpha(const uint8_t *pixelData, GEPaletteFormat clutFmt, int w);
+18 -21
View File
@@ -570,20 +570,6 @@ void TextureCacheVulkan::ReleaseTexture(TexCacheEntry *entry, bool delete_them)
entry->vkTex = nullptr;
}
VkFormat getClutDestFormatVulkan(GEPaletteFormat format) {
switch (format) {
case GE_CMODE_16BIT_ABGR4444:
return VULKAN_4444_FORMAT;
case GE_CMODE_16BIT_ABGR5551:
return VULKAN_1555_FORMAT;
case GE_CMODE_16BIT_BGR5650:
return VULKAN_565_FORMAT;
case GE_CMODE_32BIT_ABGR8888:
return VULKAN_8888_FORMAT;
}
return VK_FORMAT_UNDEFINED;
}
static const VkFilter MagFiltVK[2] = {
VK_FILTER_NEAREST,
VK_FILTER_LINEAR
@@ -833,18 +819,18 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) {
copyBatch.reserve(levels);
for (int i = 0; i < levels; i++) {
int mipUnscaledWidth = gstate.getTextureWidth(i);
int mipUnscaledHeight = gstate.getTextureHeight(i);
const int mipUnscaledWidth = gstate.getTextureWidth(i);
const int mipUnscaledHeight = gstate.getTextureHeight(i);
int mipWidth;
int mipHeight;
plan.GetMipSize(i, &mipWidth, &mipHeight);
int bpp = VkFormatBytesPerPixel(actualFmt);
const int bpp = VkFormatBytesPerPixel(actualFmt);
// RoundToNextPowerOf2 is probably not necessary as the optimal alignment is gonna be a power of 2.
int optimalStrideAlignment = RoundToNextPowerOf2(std::max(4, (int)vulkan->GetPhysicalDeviceProperties().properties.limits.optimalBufferCopyRowPitchAlignment));
int byteStride = RoundUpToMultipleOf(mipWidth * bpp, optimalStrideAlignment); // output stride
int pixelStride = byteStride / bpp;
const int optimalStrideAlignment = RoundToNextPowerOf2(std::max(4, (int)vulkan->GetPhysicalDeviceProperties().properties.limits.optimalBufferCopyRowPitchAlignment));
const int byteStride = RoundUpToMultipleOf(mipWidth * bpp, optimalStrideAlignment); // output stride
const int pixelStride = byteStride / bpp;
int uploadSize = byteStride * mipHeight;
uint32_t bufferOffset;
@@ -968,7 +954,18 @@ VkFormat TextureCacheVulkan::GetDestFormat(GETextureFormat format, GEPaletteForm
case GE_TFMT_CLUT8:
case GE_TFMT_CLUT16:
case GE_TFMT_CLUT32:
return getClutDestFormatVulkan(clutFormat);
switch (clutFormat) {
case GE_CMODE_16BIT_ABGR4444:
return VULKAN_4444_FORMAT;
case GE_CMODE_16BIT_ABGR5551:
return VULKAN_1555_FORMAT;
case GE_CMODE_16BIT_BGR5650:
return VULKAN_565_FORMAT;
case GE_CMODE_32BIT_ABGR8888:
return VULKAN_8888_FORMAT;
default:
return VK_FORMAT_UNDEFINED;
}
case GE_TFMT_4444:
return VULKAN_4444_FORMAT;
case GE_TFMT_5551:
-2
View File
@@ -154,5 +154,3 @@ private:
VulkanBuffer textureScaleCBuffer_;
bool cbufferInited_ = true;
};
VkFormat getClutDestFormatVulkan(GEPaletteFormat format);