mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Move framebuf attachment into central code.
It doesn't look like this will be different, and there's a bug in it.
This commit is contained in:
parent
817df153f8
commit
e8c8f19aec
8 changed files with 98 additions and 252 deletions
|
@ -18,6 +18,7 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "Common/MemoryUtil.h"
|
#include "Common/MemoryUtil.h"
|
||||||
#include "Core/Config.h"
|
#include "Core/Config.h"
|
||||||
|
#include "Core/Host.h"
|
||||||
#include "Core/Reporting.h"
|
#include "Core/Reporting.h"
|
||||||
#include "Core/System.h"
|
#include "Core/System.h"
|
||||||
#include "GPU/Common/FramebufferCommon.h"
|
#include "GPU/Common/FramebufferCommon.h"
|
||||||
|
@ -36,7 +37,7 @@
|
||||||
extern int g_iNumVideos;
|
extern int g_iNumVideos;
|
||||||
|
|
||||||
TextureCacheCommon::TextureCacheCommon()
|
TextureCacheCommon::TextureCacheCommon()
|
||||||
: nextTexture_(nullptr),
|
: cacheSizeEstimate_(0), nextTexture_(nullptr),
|
||||||
clutLastFormat_(0xFFFFFFFF), clutTotalBytes_(0), clutMaxBytes_(0), clutRenderAddress_(0xFFFFFFFF) {
|
clutLastFormat_(0xFFFFFFFF), clutTotalBytes_(0), clutMaxBytes_(0), clutRenderAddress_(0xFFFFFFFF) {
|
||||||
// TODO: Clamp down to 256/1KB? Need to check mipmapShareClut and clamp loadclut.
|
// TODO: Clamp down to 256/1KB? Need to check mipmapShareClut and clamp loadclut.
|
||||||
clutBufRaw_ = (u32 *)AllocateAlignedMemory(1024 * sizeof(u32), 16); // 4KB
|
clutBufRaw_ = (u32 *)AllocateAlignedMemory(1024 * sizeof(u32), 16); // 4KB
|
||||||
|
@ -191,6 +192,54 @@ void TextureCacheCommon::NotifyFramebuffer(u32 address, VirtualFramebuffer *fram
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void TextureCacheCommon::AttachFramebufferValid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const AttachedFramebufferInfo &fbInfo) {
|
||||||
|
const bool hasInvalidFramebuffer = entry->framebuffer == nullptr || entry->invalidHint == -1;
|
||||||
|
const bool hasOlderFramebuffer = entry->framebuffer != nullptr && entry->framebuffer->last_frame_render < framebuffer->last_frame_render;
|
||||||
|
bool hasFartherFramebuffer = false;
|
||||||
|
if (!hasInvalidFramebuffer && !hasOlderFramebuffer) {
|
||||||
|
// If it's valid, but the offset is greater, then we still win.
|
||||||
|
if (fbTexInfo_[entry->addr].yOffset == fbInfo.yOffset)
|
||||||
|
hasFartherFramebuffer = fbTexInfo_[entry->addr].xOffset > fbInfo.xOffset;
|
||||||
|
else
|
||||||
|
hasFartherFramebuffer = fbTexInfo_[entry->addr].yOffset > fbInfo.yOffset;
|
||||||
|
}
|
||||||
|
if (hasInvalidFramebuffer || hasOlderFramebuffer || hasFartherFramebuffer) {
|
||||||
|
if (entry->framebuffer == nullptr) {
|
||||||
|
cacheSizeEstimate_ -= EstimateTexMemoryUsage(entry);
|
||||||
|
}
|
||||||
|
entry->framebuffer = framebuffer;
|
||||||
|
entry->invalidHint = 0;
|
||||||
|
entry->status &= ~TextureCacheCommon::TexCacheEntry::STATUS_DEPALETTIZE;
|
||||||
|
entry->maxLevel = 0;
|
||||||
|
fbTexInfo_[entry->addr] = fbInfo;
|
||||||
|
framebuffer->last_frame_attached = gpuStats.numFlips;
|
||||||
|
host->GPUNotifyTextureAttachment(entry->addr);
|
||||||
|
} else if (entry->framebuffer == framebuffer) {
|
||||||
|
framebuffer->last_frame_attached = gpuStats.numFlips;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextureCacheCommon::AttachFramebufferInvalid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const AttachedFramebufferInfo &fbInfo) {
|
||||||
|
if (entry->framebuffer == nullptr || entry->framebuffer == framebuffer) {
|
||||||
|
if (entry->framebuffer == nullptr) {
|
||||||
|
cacheSizeEstimate_ -= EstimateTexMemoryUsage(entry);
|
||||||
|
}
|
||||||
|
entry->framebuffer = framebuffer;
|
||||||
|
entry->invalidHint = -1;
|
||||||
|
entry->status &= ~TextureCacheCommon::TexCacheEntry::STATUS_DEPALETTIZE;
|
||||||
|
entry->maxLevel = 0;
|
||||||
|
fbTexInfo_[entry->addr] = fbInfo;
|
||||||
|
host->GPUNotifyTextureAttachment(entry->addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextureCacheCommon::DetachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer) {
|
||||||
|
if (entry->framebuffer == framebuffer) {
|
||||||
|
cacheSizeEstimate_ += EstimateTexMemoryUsage(entry);
|
||||||
|
entry->framebuffer = 0;
|
||||||
|
host->GPUNotifyTextureAttachment(entry->addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TextureCacheCommon::NotifyConfigChanged() {
|
void TextureCacheCommon::NotifyConfigChanged() {
|
||||||
int scaleFactor;
|
int scaleFactor;
|
||||||
|
@ -386,3 +435,35 @@ bool TextureCacheCommon::GetCurrentClutBuffer(GPUDebugBuffer &buffer) {
|
||||||
memcpy(buffer.GetData(), clutBufRaw_, 1024);
|
memcpy(buffer.GetData(), clutBufRaw_, 1024);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 TextureCacheCommon::EstimateTexMemoryUsage(const TexCacheEntry *entry) {
|
||||||
|
const u16 dim = entry->dim;
|
||||||
|
const u8 dimW = ((dim >> 0) & 0xf);
|
||||||
|
const u8 dimH = ((dim >> 8) & 0xf);
|
||||||
|
|
||||||
|
u32 pixelSize = 2;
|
||||||
|
switch (entry->format) {
|
||||||
|
case GE_TFMT_CLUT4:
|
||||||
|
case GE_TFMT_CLUT8:
|
||||||
|
case GE_TFMT_CLUT16:
|
||||||
|
case GE_TFMT_CLUT32:
|
||||||
|
// We assume cluts always point to 8888 for simplicity.
|
||||||
|
pixelSize = 4;
|
||||||
|
break;
|
||||||
|
case GE_TFMT_4444:
|
||||||
|
case GE_TFMT_5551:
|
||||||
|
case GE_TFMT_5650:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GE_TFMT_8888:
|
||||||
|
case GE_TFMT_DXT1:
|
||||||
|
case GE_TFMT_DXT3:
|
||||||
|
case GE_TFMT_DXT5:
|
||||||
|
default:
|
||||||
|
pixelSize = 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This in other words multiplies by w and h.
|
||||||
|
return pixelSize << (dimW + dimH);
|
||||||
|
}
|
||||||
|
|
|
@ -143,16 +143,27 @@ protected:
|
||||||
void UnswizzleFromMem(u32 *dest, const u8 *texptr, u32 bufw, u32 height, u32 bytesPerPixel);
|
void UnswizzleFromMem(u32 *dest, const u8 *texptr, u32 bufw, u32 height, u32 bytesPerPixel);
|
||||||
void *RearrangeBuf(void *inBuf, u32 inRowBytes, u32 outRowBytes, int h, bool allowInPlace = true);
|
void *RearrangeBuf(void *inBuf, u32 inRowBytes, u32 outRowBytes, int h, bool allowInPlace = true);
|
||||||
|
|
||||||
|
u32 EstimateTexMemoryUsage(const TexCacheEntry *entry);
|
||||||
void GetSamplingParams(int &minFilt, int &magFilt, bool &sClamp, bool &tClamp, float &lodBias, u8 maxLevel);
|
void GetSamplingParams(int &minFilt, int &magFilt, bool &sClamp, bool &tClamp, float &lodBias, u8 maxLevel);
|
||||||
void UpdateMaxSeenV(bool throughMode);
|
void UpdateMaxSeenV(bool throughMode);
|
||||||
|
|
||||||
virtual bool AttachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, u32 texaddrOffset = 0) = 0;
|
virtual bool AttachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, u32 texaddrOffset = 0) = 0;
|
||||||
virtual void DetachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer) = 0;
|
|
||||||
|
|
||||||
virtual void DownloadFramebufferForClut(u32 clutAddr, u32 bytes) = 0;
|
virtual void DownloadFramebufferForClut(u32 clutAddr, u32 bytes) = 0;
|
||||||
|
|
||||||
TexCache cache;
|
TexCache cache;
|
||||||
|
u32 cacheSizeEstimate_;
|
||||||
|
|
||||||
|
// Separate to keep main texture cache size down.
|
||||||
|
struct AttachedFramebufferInfo {
|
||||||
|
u32 xOffset;
|
||||||
|
u32 yOffset;
|
||||||
|
};
|
||||||
std::vector<VirtualFramebuffer *> fbCache_;
|
std::vector<VirtualFramebuffer *> fbCache_;
|
||||||
|
std::map<u32, AttachedFramebufferInfo> fbTexInfo_;
|
||||||
|
void AttachFramebufferValid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const AttachedFramebufferInfo &fbInfo);
|
||||||
|
void AttachFramebufferInvalid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const AttachedFramebufferInfo &fbInfo);
|
||||||
|
void DetachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer);
|
||||||
|
|
||||||
SimpleBuf<u32> tmpTexBuf32;
|
SimpleBuf<u32> tmpTexBuf32;
|
||||||
SimpleBuf<u16> tmpTexBuf16;
|
SimpleBuf<u16> tmpTexBuf16;
|
||||||
|
|
|
@ -63,7 +63,7 @@ namespace DX9 {
|
||||||
#define TEXCACHE_MIN_PRESSURE 16 * 1024 * 1024 // Total in VRAM
|
#define TEXCACHE_MIN_PRESSURE 16 * 1024 * 1024 // Total in VRAM
|
||||||
#define TEXCACHE_SECOND_MIN_PRESSURE 4 * 1024 * 1024
|
#define TEXCACHE_SECOND_MIN_PRESSURE 4 * 1024 * 1024
|
||||||
|
|
||||||
TextureCacheDX9::TextureCacheDX9() : cacheSizeEstimate_(0), secondCacheSizeEstimate_(0), clearCacheNextFrame_(false), lowMemoryMode_(false), clutBuf_(NULL), texelsScaledThisFrame_(0) {
|
TextureCacheDX9::TextureCacheDX9() : secondCacheSizeEstimate_(0), clearCacheNextFrame_(false), lowMemoryMode_(false), clutBuf_(NULL), texelsScaledThisFrame_(0) {
|
||||||
timesInvalidatedAllThisFrame_ = 0;
|
timesInvalidatedAllThisFrame_ = 0;
|
||||||
lastBoundTexture = INVALID_TEX;
|
lastBoundTexture = INVALID_TEX;
|
||||||
decimationCounter_ = TEXCACHE_DECIMATION_INTERVAL;
|
decimationCounter_ = TEXCACHE_DECIMATION_INTERVAL;
|
||||||
|
@ -91,38 +91,6 @@ TextureCacheDX9::~TextureCacheDX9() {
|
||||||
Clear(true);
|
Clear(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 EstimateTexMemoryUsage(const TextureCacheDX9::TexCacheEntry *entry) {
|
|
||||||
const u16 dim = entry->dim;
|
|
||||||
const u8 dimW = ((dim >> 0) & 0xf);
|
|
||||||
const u8 dimH = ((dim >> 8) & 0xf);
|
|
||||||
|
|
||||||
u32 pixelSize = 2;
|
|
||||||
switch (entry->format) {
|
|
||||||
case GE_TFMT_CLUT4:
|
|
||||||
case GE_TFMT_CLUT8:
|
|
||||||
case GE_TFMT_CLUT16:
|
|
||||||
case GE_TFMT_CLUT32:
|
|
||||||
// We assume cluts always point to 8888 for simplicity.
|
|
||||||
pixelSize = 4;
|
|
||||||
break;
|
|
||||||
case GE_TFMT_4444:
|
|
||||||
case GE_TFMT_5551:
|
|
||||||
case GE_TFMT_5650:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GE_TFMT_8888:
|
|
||||||
case GE_TFMT_DXT1:
|
|
||||||
case GE_TFMT_DXT3:
|
|
||||||
case GE_TFMT_DXT5:
|
|
||||||
default:
|
|
||||||
pixelSize = 4;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This in other words multiplies by w and h.
|
|
||||||
return pixelSize << (dimW + dimH);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextureCacheDX9::Clear(bool delete_them) {
|
void TextureCacheDX9::Clear(bool delete_them) {
|
||||||
pD3Ddevice->SetTexture(0, NULL);
|
pD3Ddevice->SetTexture(0, NULL);
|
||||||
lastBoundTexture = INVALID_TEX;
|
lastBoundTexture = INVALID_TEX;
|
||||||
|
@ -273,46 +241,6 @@ void TextureCacheDX9::ClearNextFrame() {
|
||||||
clearCacheNextFrame_ = true;
|
clearCacheNextFrame_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TextureCacheDX9::AttachFramebufferValid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const AttachedFramebufferInfo &fbInfo) {
|
|
||||||
const bool hasInvalidFramebuffer = entry->framebuffer == nullptr || entry->invalidHint == -1;
|
|
||||||
const bool hasOlderFramebuffer = entry->framebuffer != nullptr && entry->framebuffer->last_frame_render < framebuffer->last_frame_render;
|
|
||||||
bool hasFartherFramebuffer = false;
|
|
||||||
if (!hasInvalidFramebuffer && !hasOlderFramebuffer) {
|
|
||||||
// If it's valid, but the offset is greater, then we still win.
|
|
||||||
if (fbTexInfo_[entry->addr].yOffset == fbInfo.yOffset)
|
|
||||||
hasFartherFramebuffer = fbTexInfo_[entry->addr].xOffset > fbInfo.xOffset;
|
|
||||||
else
|
|
||||||
hasFartherFramebuffer = fbTexInfo_[entry->addr].yOffset > fbInfo.yOffset;
|
|
||||||
}
|
|
||||||
if (hasInvalidFramebuffer || hasOlderFramebuffer || hasFartherFramebuffer) {
|
|
||||||
if (entry->framebuffer == nullptr) {
|
|
||||||
cacheSizeEstimate_ -= EstimateTexMemoryUsage(entry);
|
|
||||||
}
|
|
||||||
entry->framebuffer = framebuffer;
|
|
||||||
entry->invalidHint = 0;
|
|
||||||
entry->status &= ~TextureCacheDX9::TexCacheEntry::STATUS_DEPALETTIZE;
|
|
||||||
fbTexInfo_[entry->addr] = fbInfo;
|
|
||||||
framebuffer->last_frame_attached = gpuStats.numFlips;
|
|
||||||
host->GPUNotifyTextureAttachment(entry->addr);
|
|
||||||
} else if (entry->framebuffer == framebuffer) {
|
|
||||||
framebuffer->last_frame_attached = gpuStats.numFlips;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextureCacheDX9::AttachFramebufferInvalid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const AttachedFramebufferInfo &fbInfo) {
|
|
||||||
if (entry->framebuffer == 0 || entry->framebuffer == framebuffer) {
|
|
||||||
if (entry->framebuffer == nullptr) {
|
|
||||||
cacheSizeEstimate_ -= EstimateTexMemoryUsage(entry);
|
|
||||||
}
|
|
||||||
entry->framebuffer = framebuffer;
|
|
||||||
entry->invalidHint = -1;
|
|
||||||
entry->status &= ~TextureCacheDX9::TexCacheEntry::STATUS_DEPALETTIZE;
|
|
||||||
fbTexInfo_[entry->addr] = fbInfo;
|
|
||||||
host->GPUNotifyTextureAttachment(entry->addr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TextureCacheDX9::AttachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, u32 texaddrOffset) {
|
bool TextureCacheDX9::AttachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, u32 texaddrOffset) {
|
||||||
static const u32 MAX_SUBAREA_Y_OFFSET_SAFE = 32;
|
static const u32 MAX_SUBAREA_Y_OFFSET_SAFE = 32;
|
||||||
|
|
||||||
|
@ -420,14 +348,6 @@ bool TextureCacheDX9::AttachFramebuffer(TexCacheEntry *entry, u32 address, Virtu
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void TextureCacheDX9::DetachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer) {
|
|
||||||
if (entry->framebuffer == framebuffer) {
|
|
||||||
cacheSizeEstimate_ += EstimateTexMemoryUsage(entry);
|
|
||||||
entry->framebuffer = 0;
|
|
||||||
host->GPUNotifyTextureAttachment(entry->addr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void *TextureCacheDX9::ReadIndexedTex(int level, const u8 *texptr, int bytesPerIndex, u32 dstFmt, int bufw) {
|
void *TextureCacheDX9::ReadIndexedTex(int level, const u8 *texptr, int bytesPerIndex, u32 dstFmt, int bufw) {
|
||||||
int w = gstate.getTextureWidth(level);
|
int w = gstate.getTextureWidth(level);
|
||||||
int h = gstate.getTextureHeight(level);
|
int h = gstate.getTextureHeight(level);
|
||||||
|
|
|
@ -89,7 +89,6 @@ private:
|
||||||
u32 GetCurrentClutHash();
|
u32 GetCurrentClutHash();
|
||||||
void UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBase, bool clutIndexIsSimple);
|
void UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBase, bool clutIndexIsSimple);
|
||||||
bool AttachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, u32 texaddrOffset = 0) override;
|
bool AttachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, u32 texaddrOffset = 0) override;
|
||||||
void DetachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer) override;
|
|
||||||
void SetTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer);
|
void SetTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer);
|
||||||
void ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer);
|
void ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer);
|
||||||
|
|
||||||
|
@ -105,18 +104,8 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
TexCache secondCache;
|
TexCache secondCache;
|
||||||
u32 cacheSizeEstimate_;
|
|
||||||
u32 secondCacheSizeEstimate_;
|
u32 secondCacheSizeEstimate_;
|
||||||
|
|
||||||
// Separate to keep main texture cache size down.
|
|
||||||
struct AttachedFramebufferInfo {
|
|
||||||
u32 xOffset;
|
|
||||||
u32 yOffset;
|
|
||||||
};
|
|
||||||
std::map<u32, AttachedFramebufferInfo> fbTexInfo_;
|
|
||||||
void AttachFramebufferValid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const AttachedFramebufferInfo &fbInfo);
|
|
||||||
void AttachFramebufferInvalid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const AttachedFramebufferInfo &fbInfo);
|
|
||||||
|
|
||||||
bool clearCacheNextFrame_;
|
bool clearCacheNextFrame_;
|
||||||
bool lowMemoryMode_;
|
bool lowMemoryMode_;
|
||||||
TextureScalerDX9 scaler;
|
TextureScalerDX9 scaler;
|
||||||
|
|
|
@ -74,7 +74,7 @@
|
||||||
// Hack!
|
// Hack!
|
||||||
extern int g_iNumVideos;
|
extern int g_iNumVideos;
|
||||||
|
|
||||||
TextureCache::TextureCache() : cacheSizeEstimate_(0), secondCacheSizeEstimate_(0), clearCacheNextFrame_(false), lowMemoryMode_(false), clutBuf_(NULL), texelsScaledThisFrame_(0) {
|
TextureCache::TextureCache() : secondCacheSizeEstimate_(0), clearCacheNextFrame_(false), lowMemoryMode_(false), clutBuf_(NULL), texelsScaledThisFrame_(0) {
|
||||||
timesInvalidatedAllThisFrame_ = 0;
|
timesInvalidatedAllThisFrame_ = 0;
|
||||||
lastBoundTexture = INVALID_TEX;
|
lastBoundTexture = INVALID_TEX;
|
||||||
decimationCounter_ = TEXCACHE_DECIMATION_INTERVAL;
|
decimationCounter_ = TEXCACHE_DECIMATION_INTERVAL;
|
||||||
|
@ -89,38 +89,6 @@ TextureCache::~TextureCache() {
|
||||||
Clear(true);
|
Clear(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 EstimateTexMemoryUsage(const TextureCache::TexCacheEntry *entry) {
|
|
||||||
const u16 dim = entry->dim;
|
|
||||||
const u8 dimW = ((dim >> 0) & 0xf);
|
|
||||||
const u8 dimH = ((dim >> 8) & 0xf);
|
|
||||||
|
|
||||||
u32 pixelSize = 2;
|
|
||||||
switch (entry->format) {
|
|
||||||
case GE_TFMT_CLUT4:
|
|
||||||
case GE_TFMT_CLUT8:
|
|
||||||
case GE_TFMT_CLUT16:
|
|
||||||
case GE_TFMT_CLUT32:
|
|
||||||
// We assume cluts always point to 8888 for simplicity.
|
|
||||||
pixelSize = 4;
|
|
||||||
break;
|
|
||||||
case GE_TFMT_4444:
|
|
||||||
case GE_TFMT_5551:
|
|
||||||
case GE_TFMT_5650:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GE_TFMT_8888:
|
|
||||||
case GE_TFMT_DXT1:
|
|
||||||
case GE_TFMT_DXT3:
|
|
||||||
case GE_TFMT_DXT5:
|
|
||||||
default:
|
|
||||||
pixelSize = 4;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This in other words multiplies by w and h.
|
|
||||||
return pixelSize << (dimW + dimH);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextureCache::Clear(bool delete_them) {
|
void TextureCache::Clear(bool delete_them) {
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
lastBoundTexture = INVALID_TEX;
|
lastBoundTexture = INVALID_TEX;
|
||||||
|
@ -271,48 +239,6 @@ void TextureCache::ClearNextFrame() {
|
||||||
clearCacheNextFrame_ = true;
|
clearCacheNextFrame_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TextureCache::AttachFramebufferValid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const AttachedFramebufferInfo &fbInfo) {
|
|
||||||
const bool hasInvalidFramebuffer = entry->framebuffer == nullptr || entry->invalidHint == -1;
|
|
||||||
const bool hasOlderFramebuffer = entry->framebuffer != nullptr && entry->framebuffer->last_frame_render < framebuffer->last_frame_render;
|
|
||||||
bool hasFartherFramebuffer = false;
|
|
||||||
if (!hasInvalidFramebuffer && !hasOlderFramebuffer) {
|
|
||||||
// If it's valid, but the offset is greater, then we still win.
|
|
||||||
if (fbTexInfo_[entry->addr].yOffset == fbInfo.yOffset)
|
|
||||||
hasFartherFramebuffer = fbTexInfo_[entry->addr].xOffset > fbInfo.xOffset;
|
|
||||||
else
|
|
||||||
hasFartherFramebuffer = fbTexInfo_[entry->addr].yOffset > fbInfo.yOffset;
|
|
||||||
}
|
|
||||||
if (hasInvalidFramebuffer || hasOlderFramebuffer || hasFartherFramebuffer) {
|
|
||||||
if (entry->framebuffer == nullptr) {
|
|
||||||
cacheSizeEstimate_ -= EstimateTexMemoryUsage(entry);
|
|
||||||
}
|
|
||||||
entry->framebuffer = framebuffer;
|
|
||||||
entry->invalidHint = 0;
|
|
||||||
entry->status &= ~TextureCache::TexCacheEntry::STATUS_DEPALETTIZE;
|
|
||||||
entry->maxLevel = 0;
|
|
||||||
fbTexInfo_[entry->addr] = fbInfo;
|
|
||||||
framebuffer->last_frame_attached = gpuStats.numFlips;
|
|
||||||
host->GPUNotifyTextureAttachment(entry->addr);
|
|
||||||
} else if (entry->framebuffer == framebuffer) {
|
|
||||||
framebuffer->last_frame_attached = gpuStats.numFlips;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextureCache::AttachFramebufferInvalid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const AttachedFramebufferInfo &fbInfo) {
|
|
||||||
if (entry->framebuffer == nullptr || entry->framebuffer == framebuffer) {
|
|
||||||
if (entry->framebuffer == nullptr) {
|
|
||||||
cacheSizeEstimate_ -= EstimateTexMemoryUsage(entry);
|
|
||||||
}
|
|
||||||
entry->framebuffer = framebuffer;
|
|
||||||
entry->invalidHint = -1;
|
|
||||||
entry->status &= ~TextureCache::TexCacheEntry::STATUS_DEPALETTIZE;
|
|
||||||
entry->maxLevel = 0;
|
|
||||||
fbTexInfo_[entry->addr] = fbInfo;
|
|
||||||
host->GPUNotifyTextureAttachment(entry->addr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TextureCache::AttachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, u32 texaddrOffset) {
|
bool TextureCache::AttachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, u32 texaddrOffset) {
|
||||||
static const u32 MAX_SUBAREA_Y_OFFSET_SAFE = 32;
|
static const u32 MAX_SUBAREA_Y_OFFSET_SAFE = 32;
|
||||||
|
|
||||||
|
@ -420,14 +346,6 @@ bool TextureCache::AttachFramebuffer(TexCacheEntry *entry, u32 address, VirtualF
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void TextureCache::DetachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer) {
|
|
||||||
if (entry->framebuffer == framebuffer) {
|
|
||||||
cacheSizeEstimate_ += EstimateTexMemoryUsage(entry);
|
|
||||||
entry->framebuffer = 0;
|
|
||||||
host->GPUNotifyTextureAttachment(entry->addr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void *TextureCache::ReadIndexedTex(int level, const u8 *texptr, int bytesPerIndex, GLuint dstFmt, int bufw) {
|
void *TextureCache::ReadIndexedTex(int level, const u8 *texptr, int bytesPerIndex, GLuint dstFmt, int bufw) {
|
||||||
int w = gstate.getTextureWidth(level);
|
int w = gstate.getTextureWidth(level);
|
||||||
int h = gstate.getTextureHeight(level);
|
int h = gstate.getTextureHeight(level);
|
||||||
|
|
|
@ -104,24 +104,13 @@ private:
|
||||||
u32 GetCurrentClutHash();
|
u32 GetCurrentClutHash();
|
||||||
void UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBase, bool clutIndexIsSimple);
|
void UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBase, bool clutIndexIsSimple);
|
||||||
bool AttachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, u32 texaddrOffset = 0) override;
|
bool AttachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, u32 texaddrOffset = 0) override;
|
||||||
void DetachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer) override;
|
|
||||||
void SetTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer);
|
void SetTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer);
|
||||||
void ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer);
|
void ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer);
|
||||||
|
|
||||||
TexCache secondCache;
|
|
||||||
std::vector<u32> nameCache_;
|
std::vector<u32> nameCache_;
|
||||||
u32 cacheSizeEstimate_;
|
TexCache secondCache;
|
||||||
u32 secondCacheSizeEstimate_;
|
u32 secondCacheSizeEstimate_;
|
||||||
|
|
||||||
// Separate to keep main texture cache size down.
|
|
||||||
struct AttachedFramebufferInfo {
|
|
||||||
u32 xOffset;
|
|
||||||
u32 yOffset;
|
|
||||||
};
|
|
||||||
std::map<u32, AttachedFramebufferInfo> fbTexInfo_;
|
|
||||||
void AttachFramebufferValid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const AttachedFramebufferInfo &fbInfo);
|
|
||||||
void AttachFramebufferInvalid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const AttachedFramebufferInfo &fbInfo);
|
|
||||||
|
|
||||||
bool clearCacheNextFrame_;
|
bool clearCacheNextFrame_;
|
||||||
bool lowMemoryMode_;
|
bool lowMemoryMode_;
|
||||||
|
|
||||||
|
|
|
@ -127,7 +127,7 @@ VkSampler SamplerCache::GetOrCreateSampler(const SamplerCacheKey &key) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureCacheVulkan::TextureCacheVulkan(VulkanContext *vulkan)
|
TextureCacheVulkan::TextureCacheVulkan(VulkanContext *vulkan)
|
||||||
: vulkan_(vulkan), samplerCache_(vulkan), cacheSizeEstimate_(0), secondCacheSizeEstimate_(0),
|
: vulkan_(vulkan), samplerCache_(vulkan), secondCacheSizeEstimate_(0),
|
||||||
clearCacheNextFrame_(false), lowMemoryMode_(false), clutBuf_(NULL), texelsScaledThisFrame_(0),
|
clearCacheNextFrame_(false), lowMemoryMode_(false), clutBuf_(NULL), texelsScaledThisFrame_(0),
|
||||||
clutAlphaLinear_(false) {
|
clutAlphaLinear_(false) {
|
||||||
timesInvalidatedAllThisFrame_ = 0;
|
timesInvalidatedAllThisFrame_ = 0;
|
||||||
|
@ -323,48 +323,6 @@ void TextureCacheVulkan::ClearNextFrame() {
|
||||||
clearCacheNextFrame_ = true;
|
clearCacheNextFrame_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TextureCacheVulkan::AttachFramebufferValid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const AttachedFramebufferInfo &fbInfo) {
|
|
||||||
const bool hasInvalidFramebuffer = entry->framebuffer == nullptr || entry->invalidHint == -1;
|
|
||||||
const bool hasOlderFramebuffer = entry->framebuffer != nullptr && entry->framebuffer->last_frame_render < framebuffer->last_frame_render;
|
|
||||||
bool hasFartherFramebuffer = false;
|
|
||||||
if (!hasInvalidFramebuffer && !hasOlderFramebuffer) {
|
|
||||||
// If it's valid, but the offset is greater, then we still win.
|
|
||||||
if (fbTexInfo_[entry->addr].yOffset == fbInfo.yOffset)
|
|
||||||
hasFartherFramebuffer = fbTexInfo_[entry->addr].xOffset > fbInfo.xOffset;
|
|
||||||
else
|
|
||||||
hasFartherFramebuffer = fbTexInfo_[entry->addr].yOffset > fbInfo.yOffset;
|
|
||||||
}
|
|
||||||
if (hasInvalidFramebuffer || hasOlderFramebuffer || hasFartherFramebuffer) {
|
|
||||||
if (entry->framebuffer == nullptr) {
|
|
||||||
cacheSizeEstimate_ -= EstimateTexMemoryUsage(entry);
|
|
||||||
}
|
|
||||||
entry->framebuffer = framebuffer;
|
|
||||||
entry->invalidHint = 0;
|
|
||||||
entry->status &= ~TextureCacheVulkan::TexCacheEntry::STATUS_DEPALETTIZE;
|
|
||||||
entry->maxLevel = 0;
|
|
||||||
fbTexInfo_[entry->addr] = fbInfo;
|
|
||||||
framebuffer->last_frame_attached = gpuStats.numFlips;
|
|
||||||
host->GPUNotifyTextureAttachment(entry->addr);
|
|
||||||
} else if (entry->framebuffer == framebuffer) {
|
|
||||||
framebuffer->last_frame_attached = gpuStats.numFlips;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextureCacheVulkan::AttachFramebufferInvalid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const AttachedFramebufferInfo &fbInfo) {
|
|
||||||
if (entry->framebuffer == nullptr || entry->framebuffer == framebuffer) {
|
|
||||||
if (entry->framebuffer == nullptr) {
|
|
||||||
cacheSizeEstimate_ -= EstimateTexMemoryUsage(entry);
|
|
||||||
}
|
|
||||||
entry->framebuffer = framebuffer;
|
|
||||||
entry->invalidHint = -1;
|
|
||||||
entry->status &= ~TextureCacheVulkan::TexCacheEntry::STATUS_DEPALETTIZE;
|
|
||||||
entry->maxLevel = 0;
|
|
||||||
fbTexInfo_[entry->addr] = fbInfo;
|
|
||||||
host->GPUNotifyTextureAttachment(entry->addr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TextureCacheVulkan::AttachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, u32 texaddrOffset) {
|
bool TextureCacheVulkan::AttachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, u32 texaddrOffset) {
|
||||||
static const u32 MAX_SUBAREA_Y_OFFSET_SAFE = 32;
|
static const u32 MAX_SUBAREA_Y_OFFSET_SAFE = 32;
|
||||||
|
|
||||||
|
@ -472,14 +430,6 @@ bool TextureCacheVulkan::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void TextureCacheVulkan::DetachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer) {
|
|
||||||
if (entry->framebuffer == framebuffer) {
|
|
||||||
cacheSizeEstimate_ += EstimateTexMemoryUsage(entry);
|
|
||||||
entry->framebuffer = 0;
|
|
||||||
host->GPUNotifyTextureAttachment(entry->addr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void *TextureCacheVulkan::ReadIndexedTex(int level, const u8 *texptr, int bytesPerIndex, VkFormat dstFmt, int bufw) {
|
void *TextureCacheVulkan::ReadIndexedTex(int level, const u8 *texptr, int bytesPerIndex, VkFormat dstFmt, int bufw) {
|
||||||
int w = gstate.getTextureWidth(level);
|
int w = gstate.getTextureWidth(level);
|
||||||
int h = gstate.getTextureHeight(level);
|
int h = gstate.getTextureHeight(level);
|
||||||
|
|
|
@ -135,7 +135,6 @@ private:
|
||||||
u32 GetCurrentClutHash();
|
u32 GetCurrentClutHash();
|
||||||
void UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBase, bool clutIndexIsSimple);
|
void UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBase, bool clutIndexIsSimple);
|
||||||
bool AttachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, u32 texaddrOffset = 0) override;
|
bool AttachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, u32 texaddrOffset = 0) override;
|
||||||
void DetachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer) override;
|
|
||||||
void SetTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer);
|
void SetTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer);
|
||||||
void ApplyTextureFramebuffer(VkCommandBuffer cmd, TexCacheEntry *entry, VirtualFramebuffer *framebuffer, VkImageView &image, VkSampler &sampler);
|
void ApplyTextureFramebuffer(VkCommandBuffer cmd, TexCacheEntry *entry, VirtualFramebuffer *framebuffer, VkImageView &image, VkSampler &sampler);
|
||||||
void SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, SamplerCacheKey &key);
|
void SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, SamplerCacheKey &key);
|
||||||
|
@ -143,19 +142,8 @@ private:
|
||||||
VulkanContext *vulkan_;
|
VulkanContext *vulkan_;
|
||||||
|
|
||||||
TexCache secondCache;
|
TexCache secondCache;
|
||||||
std::vector<u32> nameCache_;
|
|
||||||
u32 cacheSizeEstimate_;
|
|
||||||
u32 secondCacheSizeEstimate_;
|
u32 secondCacheSizeEstimate_;
|
||||||
|
|
||||||
// Separate to keep main texture cache size down.
|
|
||||||
struct AttachedFramebufferInfo {
|
|
||||||
u32 xOffset;
|
|
||||||
u32 yOffset;
|
|
||||||
};
|
|
||||||
std::map<u32, AttachedFramebufferInfo> fbTexInfo_;
|
|
||||||
void AttachFramebufferValid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const AttachedFramebufferInfo &fbInfo);
|
|
||||||
void AttachFramebufferInvalid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const AttachedFramebufferInfo &fbInfo);
|
|
||||||
|
|
||||||
bool clearCacheNextFrame_;
|
bool clearCacheNextFrame_;
|
||||||
bool lowMemoryMode_;
|
bool lowMemoryMode_;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue