mirror of
https://github.com/libretro/ppsspp.git
synced 2024-11-28 02:41:18 +00:00
Fix fake mipmap issue related #5350
This commit is contained in:
parent
cbf24a9d78
commit
945e603072
@ -90,7 +90,7 @@ void TextureCacheCommon::GetSamplingParams(int &minFilt, int &magFilt, bool &sCl
|
|||||||
sClamp = gstate.isTexCoordClampedS();
|
sClamp = gstate.isTexCoordClampedS();
|
||||||
tClamp = gstate.isTexCoordClampedT();
|
tClamp = gstate.isTexCoordClampedT();
|
||||||
|
|
||||||
bool noMip = (gstate.texlevel & 0xFFFFFF) == 0x000001 || (gstate.texlevel & 0xFFFFFF) == 0x100001 ; // Fix texlevel at 0
|
bool noMip = gstate.getTexLevelMode() == GE_TEXLEVEL_MODE_CONST;
|
||||||
|
|
||||||
if (maxLevel == 0) {
|
if (maxLevel == 0) {
|
||||||
// Enforce no mip filtering, for safety.
|
// Enforce no mip filtering, for safety.
|
||||||
|
@ -100,7 +100,7 @@ static const CommandTableEntry commandTable[] = {
|
|||||||
{ GE_CMD_TEXSIZE6, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS },
|
{ GE_CMD_TEXSIZE6, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS },
|
||||||
{ GE_CMD_TEXSIZE7, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS },
|
{ GE_CMD_TEXSIZE7, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS },
|
||||||
{ GE_CMD_TEXFORMAT, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_IMAGE },
|
{ GE_CMD_TEXFORMAT, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_IMAGE },
|
||||||
{ GE_CMD_TEXLEVEL, 0, DIRTY_TEXTURE_PARAMS }, // Flushing on this is EXPENSIVE in Gran Turismo and of little use
|
{ GE_CMD_TEXLEVEL, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, // Allow flushing only (Mode == 1 && Level > 0)
|
||||||
{ GE_CMD_TEXADDR0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_IMAGE | DIRTY_UVSCALEOFFSET },
|
{ GE_CMD_TEXADDR0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_IMAGE | DIRTY_UVSCALEOFFSET },
|
||||||
{ GE_CMD_TEXADDR1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS },
|
{ GE_CMD_TEXADDR1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS },
|
||||||
{ GE_CMD_TEXADDR2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS },
|
{ GE_CMD_TEXADDR2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS },
|
||||||
@ -662,7 +662,8 @@ void GPU_DX9::FastRunLoop(DisplayList &list) {
|
|||||||
const u8 cmdFlags = info.flags; // If we stashed the cmdFlags in the top bits of the cmdmem, we could get away with one table lookup instead of two
|
const u8 cmdFlags = info.flags; // If we stashed the cmdFlags in the top bits of the cmdmem, we could get away with one table lookup instead of two
|
||||||
const u32 diff = op ^ gstate.cmdmem[cmd];
|
const u32 diff = op ^ gstate.cmdmem[cmd];
|
||||||
// Inlined CheckFlushOp here to get rid of the dumpThisFrame_ check.
|
// Inlined CheckFlushOp here to get rid of the dumpThisFrame_ check.
|
||||||
if ((cmdFlags & FLAG_FLUSHBEFORE) || (diff && (cmdFlags & FLAG_FLUSHBEFOREONCHANGE))) {
|
if ((cmdFlags & FLAG_FLUSHBEFORE) || (diff && (cmdFlags & FLAG_FLUSHBEFOREONCHANGE)
|
||||||
|
&& (cmd != 0xc8 || (gstate.getTexLevelMode() == GE_TEXLEVEL_MODE_CONST && (0x00FF0000 & gstate.texlevel) != 0)))) { // Avoid always flushing when texlevel(0xc8).
|
||||||
drawEngine_.Flush();
|
drawEngine_.Flush();
|
||||||
}
|
}
|
||||||
gstate.cmdmem[cmd] = op; // TODO: no need to write if diff==0...
|
gstate.cmdmem[cmd] = op; // TODO: no need to write if diff==0...
|
||||||
@ -684,7 +685,8 @@ void GPU_DX9::FinishDeferred() {
|
|||||||
|
|
||||||
inline void GPU_DX9::CheckFlushOp(int cmd, u32 diff) {
|
inline void GPU_DX9::CheckFlushOp(int cmd, u32 diff) {
|
||||||
const u8 cmdFlags = cmdInfo_[cmd].flags;
|
const u8 cmdFlags = cmdInfo_[cmd].flags;
|
||||||
if ((cmdFlags & FLAG_FLUSHBEFORE) || (diff && (cmdFlags & FLAG_FLUSHBEFOREONCHANGE))) {
|
if ((cmdFlags & FLAG_FLUSHBEFORE) || (diff && (cmdFlags & FLAG_FLUSHBEFOREONCHANGE)
|
||||||
|
&& (cmd != 0xc8 || (gstate.getTexLevelMode() == GE_TEXLEVEL_MODE_CONST && (0x00FF0000 & gstate.texlevel) != 0)))) { // Avoid always flushing when texlevel(0xc8).
|
||||||
if (dumpThisFrame_) {
|
if (dumpThisFrame_) {
|
||||||
NOTICE_LOG(G3D, "================ FLUSH ================");
|
NOTICE_LOG(G3D, "================ FLUSH ================");
|
||||||
}
|
}
|
||||||
|
@ -604,7 +604,10 @@ void TextureCacheDX9::SetTexture(bool force) {
|
|||||||
lastBoundTexture = INVALID_TEX;
|
lastBoundTexture = INVALID_TEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 texaddr = gstate.getTextureAddress(0);
|
u8 level = 0;
|
||||||
|
if (gstate.getTexLevelMode() == GE_TEXLEVEL_MODE_CONST)
|
||||||
|
level = (gstate.texlevel >> 20) & 0xF;
|
||||||
|
u32 texaddr = gstate.getTextureAddress(level);
|
||||||
if (!Memory::IsValidAddress(texaddr)) {
|
if (!Memory::IsValidAddress(texaddr)) {
|
||||||
// Bind a null texture and return.
|
// Bind a null texture and return.
|
||||||
pD3Ddevice->SetTexture(0, NULL);
|
pD3Ddevice->SetTexture(0, NULL);
|
||||||
@ -612,9 +615,9 @@ void TextureCacheDX9::SetTexture(bool force) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const u16 dim = gstate.getTextureDimension(0);
|
const u16 dim = gstate.getTextureDimension(level);
|
||||||
int w = gstate.getTextureWidth(0);
|
int w = gstate.getTextureWidth(level);
|
||||||
int h = gstate.getTextureHeight(0);
|
int h = gstate.getTextureHeight(level);
|
||||||
|
|
||||||
GETextureFormat format = gstate.getTextureFormat();
|
GETextureFormat format = gstate.getTextureFormat();
|
||||||
if (format >= 11) {
|
if (format >= 11) {
|
||||||
@ -1011,7 +1014,11 @@ void TextureCacheDX9::BuildTexture(TexCacheEntry *const entry, bool replaceImage
|
|||||||
maxLevel = 0;
|
maxLevel = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadTextureLevel(*entry, replaced, 0, maxLevel, replaceImages, scaleFactor, dstFmt);
|
if (gstate.getTexLevelMode() == GE_TEXLEVEL_MODE_CONST) {
|
||||||
|
u8 level = (gstate.texlevel >> 20) & 0xF;
|
||||||
|
LoadTextureLevel(*entry, replaced, level, maxLevel, replaceImages, scaleFactor, dstFmt);
|
||||||
|
} else
|
||||||
|
LoadTextureLevel(*entry, replaced, 0, maxLevel, replaceImages, scaleFactor, dstFmt);
|
||||||
LPDIRECT3DTEXTURE9 &texture = DxTex(entry);
|
LPDIRECT3DTEXTURE9 &texture = DxTex(entry);
|
||||||
if (!texture) {
|
if (!texture) {
|
||||||
return;
|
return;
|
||||||
@ -1095,7 +1102,7 @@ void TextureCacheDX9::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &re
|
|||||||
int h = gstate.getTextureHeight(level);
|
int h = gstate.getTextureHeight(level);
|
||||||
|
|
||||||
LPDIRECT3DTEXTURE9 &texture = DxTex(&entry);
|
LPDIRECT3DTEXTURE9 &texture = DxTex(&entry);
|
||||||
if (level == 0 && (!replaceImages || texture == nullptr)) {
|
if ((level == 0 || gstate.getTexLevelMode() == GE_TEXLEVEL_MODE_CONST) && (!replaceImages || texture == nullptr)) {
|
||||||
// Create texture
|
// Create texture
|
||||||
D3DPOOL pool = D3DPOOL_MANAGED;
|
D3DPOOL pool = D3DPOOL_MANAGED;
|
||||||
int usage = 0;
|
int usage = 0;
|
||||||
@ -1115,7 +1122,11 @@ void TextureCacheDX9::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &re
|
|||||||
tfmt = D3DFMT_A8R8G8B8;
|
tfmt = D3DFMT_A8R8G8B8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HRESULT hr = pD3Ddevice->CreateTexture(tw, th, levels, usage, tfmt, pool, &texture, NULL);
|
HRESULT hr;
|
||||||
|
if (gstate.getTexLevelMode() == GE_TEXLEVEL_MODE_CONST)
|
||||||
|
hr = pD3Ddevice->CreateTexture(tw, th, 1, usage, tfmt, pool, &texture, NULL);
|
||||||
|
else
|
||||||
|
hr = pD3Ddevice->CreateTexture(tw, th, levels, usage, tfmt, pool, &texture, NULL);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
INFO_LOG(G3D, "Failed to create D3D texture");
|
INFO_LOG(G3D, "Failed to create D3D texture");
|
||||||
ReleaseTexture(&entry);
|
ReleaseTexture(&entry);
|
||||||
@ -1124,7 +1135,10 @@ void TextureCacheDX9::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &re
|
|||||||
}
|
}
|
||||||
|
|
||||||
D3DLOCKED_RECT rect;
|
D3DLOCKED_RECT rect;
|
||||||
texture->LockRect(level, &rect, NULL, 0);
|
if (gstate.getTexLevelMode() == GE_TEXLEVEL_MODE_CONST)
|
||||||
|
texture->LockRect(0, &rect, NULL, 0);
|
||||||
|
else
|
||||||
|
texture->LockRect(level, &rect, NULL, 0);
|
||||||
|
|
||||||
gpuStats.numTexturesDecoded++;
|
gpuStats.numTexturesDecoded++;
|
||||||
if (replaced.GetSize(level, w, h)) {
|
if (replaced.GetSize(level, w, h)) {
|
||||||
@ -1191,7 +1205,10 @@ void TextureCacheDX9::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &re
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
texture->UnlockRect(level);
|
if (gstate.getTexLevelMode() == GE_TEXLEVEL_MODE_CONST)
|
||||||
|
texture->UnlockRect(0);
|
||||||
|
else
|
||||||
|
texture->UnlockRect(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TextureCacheDX9::DecodeTexture(u8 *output, const GPUgstate &state)
|
bool TextureCacheDX9::DecodeTexture(u8 *output, const GPUgstate &state)
|
||||||
|
@ -104,7 +104,7 @@ static const CommandTableEntry commandTable[] = {
|
|||||||
{GE_CMD_TEXSIZE6, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS},
|
{GE_CMD_TEXSIZE6, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS},
|
||||||
{GE_CMD_TEXSIZE7, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS},
|
{GE_CMD_TEXSIZE7, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS},
|
||||||
{GE_CMD_TEXFORMAT, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_IMAGE},
|
{GE_CMD_TEXFORMAT, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_IMAGE},
|
||||||
{GE_CMD_TEXLEVEL, 0, DIRTY_TEXTURE_PARAMS}, // Flushing on this is EXPENSIVE in Gran Turismo and of little use
|
{GE_CMD_TEXLEVEL, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS}, // Allow flushing only (Mode == 1 && Level > 0)
|
||||||
{GE_CMD_TEXADDR0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_IMAGE|DIRTY_UVSCALEOFFSET},
|
{GE_CMD_TEXADDR0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_IMAGE|DIRTY_UVSCALEOFFSET},
|
||||||
{GE_CMD_TEXADDR1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS},
|
{GE_CMD_TEXADDR1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS},
|
||||||
{GE_CMD_TEXADDR2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS},
|
{GE_CMD_TEXADDR2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS},
|
||||||
@ -876,7 +876,8 @@ void GPU_GLES::FastRunLoop(DisplayList &list) {
|
|||||||
const u8 cmdFlags = info.flags; // If we stashed the cmdFlags in the top bits of the cmdmem, we could get away with one table lookup instead of two
|
const u8 cmdFlags = info.flags; // If we stashed the cmdFlags in the top bits of the cmdmem, we could get away with one table lookup instead of two
|
||||||
const u32 diff = op ^ gstate.cmdmem[cmd];
|
const u32 diff = op ^ gstate.cmdmem[cmd];
|
||||||
// Inlined CheckFlushOp here to get rid of the dumpThisFrame_ check.
|
// Inlined CheckFlushOp here to get rid of the dumpThisFrame_ check.
|
||||||
if ((cmdFlags & FLAG_FLUSHBEFORE) || (diff && (cmdFlags & FLAG_FLUSHBEFOREONCHANGE))) {
|
if ((cmdFlags & FLAG_FLUSHBEFORE) || (diff && (cmdFlags & FLAG_FLUSHBEFOREONCHANGE)
|
||||||
|
&& (cmd != 0xc8 || (gstate.getTexLevelMode() == GE_TEXLEVEL_MODE_CONST && (0x00FF0000 & gstate.texlevel) != 0)))) { // Avoid always flushing when texlevel(0xc8).
|
||||||
drawEngine_.Flush();
|
drawEngine_.Flush();
|
||||||
}
|
}
|
||||||
gstate.cmdmem[cmd] = op; // TODO: no need to write if diff==0...
|
gstate.cmdmem[cmd] = op; // TODO: no need to write if diff==0...
|
||||||
@ -901,7 +902,8 @@ void GPU_GLES::FinishDeferred() {
|
|||||||
|
|
||||||
inline void GPU_GLES::CheckFlushOp(int cmd, u32 diff) {
|
inline void GPU_GLES::CheckFlushOp(int cmd, u32 diff) {
|
||||||
const u8 cmdFlags = cmdInfo_[cmd].flags;
|
const u8 cmdFlags = cmdInfo_[cmd].flags;
|
||||||
if ((cmdFlags & FLAG_FLUSHBEFORE) || (diff && (cmdFlags & FLAG_FLUSHBEFOREONCHANGE))) {
|
if ((cmdFlags & FLAG_FLUSHBEFORE) || (diff && (cmdFlags & FLAG_FLUSHBEFOREONCHANGE)
|
||||||
|
&& (cmd != 0xc8 || (gstate.getTexLevelMode() == GE_TEXLEVEL_MODE_CONST && (0x00FF0000 & gstate.texlevel) != 0)))) { // Avoid always flushing when texlevel(0xc8).
|
||||||
if (dumpThisFrame_) {
|
if (dumpThisFrame_) {
|
||||||
NOTICE_LOG(G3D, "================ FLUSH ================");
|
NOTICE_LOG(G3D, "================ FLUSH ================");
|
||||||
}
|
}
|
||||||
|
@ -686,7 +686,10 @@ void TextureCacheGLES::SetTexture(bool force) {
|
|||||||
lastBoundTexture = INVALID_TEX;
|
lastBoundTexture = INVALID_TEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 texaddr = gstate.getTextureAddress(0);
|
u8 level = 0;
|
||||||
|
if (gstate.getTexLevelMode() == GE_TEXLEVEL_MODE_CONST)
|
||||||
|
level = (gstate.texlevel >> 20) & 0xF;
|
||||||
|
u32 texaddr = gstate.getTextureAddress(level);
|
||||||
if (!Memory::IsValidAddress(texaddr)) {
|
if (!Memory::IsValidAddress(texaddr)) {
|
||||||
// Bind a null texture and return.
|
// Bind a null texture and return.
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
@ -694,9 +697,9 @@ void TextureCacheGLES::SetTexture(bool force) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const u16 dim = gstate.getTextureDimension(0);
|
const u16 dim = gstate.getTextureDimension(level);
|
||||||
int w = gstate.getTextureWidth(0);
|
int w = gstate.getTextureWidth(level);
|
||||||
int h = gstate.getTextureHeight(0);
|
int h = gstate.getTextureHeight(level);
|
||||||
|
|
||||||
GETextureFormat format = gstate.getTextureFormat();
|
GETextureFormat format = gstate.getTextureFormat();
|
||||||
if (format >= 11) {
|
if (format >= 11) {
|
||||||
@ -1055,7 +1058,11 @@ void TextureCacheGLES::BuildTexture(TexCacheEntry *const entry, bool replaceImag
|
|||||||
// be as good quality as the game's own (might even be better in some cases though).
|
// be as good quality as the game's own (might even be better in some cases though).
|
||||||
|
|
||||||
// Always load base level texture here
|
// Always load base level texture here
|
||||||
LoadTextureLevel(*entry, replaced, 0, replaceImages, scaleFactor, dstFmt);
|
if (gstate.getTexLevelMode() == GE_TEXLEVEL_MODE_CONST) {
|
||||||
|
u8 level = (gstate.texlevel >> 20) & 0xF;
|
||||||
|
LoadTextureLevel(*entry, replaced, level, replaceImages, scaleFactor, dstFmt);
|
||||||
|
} else
|
||||||
|
LoadTextureLevel(*entry, replaced, 0, replaceImages, scaleFactor, dstFmt);
|
||||||
|
|
||||||
// Mipmapping only enable when texture scaling disable
|
// Mipmapping only enable when texture scaling disable
|
||||||
if (maxLevel > 0 && scaleFactor == 1) {
|
if (maxLevel > 0 && scaleFactor == 1) {
|
||||||
@ -1271,7 +1278,10 @@ void TextureCacheGLES::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &r
|
|||||||
glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, w, h, components2, dstFmt, pixelData);
|
glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, w, h, components2, dstFmt, pixelData);
|
||||||
} else {
|
} else {
|
||||||
PROFILE_THIS_SCOPE("loadtex");
|
PROFILE_THIS_SCOPE("loadtex");
|
||||||
glTexImage2D(GL_TEXTURE_2D, level, components, w, h, 0, components2, dstFmt, pixelData);
|
if (gstate.getTexLevelMode() == GE_TEXLEVEL_MODE_CONST)
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, components, w, h, 0, components2, dstFmt, pixelData);
|
||||||
|
else
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, level, components, w, h, 0, components2, dstFmt, pixelData);
|
||||||
if (!lowMemoryMode_) {
|
if (!lowMemoryMode_) {
|
||||||
GLenum err = glGetError();
|
GLenum err = glGetError();
|
||||||
if (err == GL_OUT_OF_MEMORY) {
|
if (err == GL_OUT_OF_MEMORY) {
|
||||||
|
@ -100,7 +100,7 @@ static const CommandTableEntry commandTable[] = {
|
|||||||
{ GE_CMD_TEXSIZE6, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS },
|
{ GE_CMD_TEXSIZE6, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS },
|
||||||
{ GE_CMD_TEXSIZE7, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS },
|
{ GE_CMD_TEXSIZE7, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS },
|
||||||
{ GE_CMD_TEXFORMAT, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_IMAGE },
|
{ GE_CMD_TEXFORMAT, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_IMAGE },
|
||||||
{ GE_CMD_TEXLEVEL, 0, DIRTY_TEXTURE_PARAMS }, // Flushing on this is EXPENSIVE in Gran Turismo and of little use
|
{ GE_CMD_TEXLEVEL, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, // Allow flushing only (Mode == 1 && Level > 0)
|
||||||
{ GE_CMD_TEXADDR0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_IMAGE | DIRTY_UVSCALEOFFSET },
|
{ GE_CMD_TEXADDR0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_IMAGE | DIRTY_UVSCALEOFFSET },
|
||||||
{ GE_CMD_TEXADDR1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS },
|
{ GE_CMD_TEXADDR1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS },
|
||||||
{ GE_CMD_TEXADDR2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS },
|
{ GE_CMD_TEXADDR2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS },
|
||||||
@ -710,7 +710,8 @@ void GPU_Vulkan::FastRunLoop(DisplayList &list) {
|
|||||||
const u8 cmdFlags = info.flags; // If we stashed the cmdFlags in the top bits of the cmdmem, we could get away with one table lookup instead of two
|
const u8 cmdFlags = info.flags; // If we stashed the cmdFlags in the top bits of the cmdmem, we could get away with one table lookup instead of two
|
||||||
const u32 diff = op ^ gstate.cmdmem[cmd];
|
const u32 diff = op ^ gstate.cmdmem[cmd];
|
||||||
// Inlined CheckFlushOp here to get rid of the dumpThisFrame_ check.
|
// Inlined CheckFlushOp here to get rid of the dumpThisFrame_ check.
|
||||||
if ((cmdFlags & FLAG_FLUSHBEFORE) || (diff && (cmdFlags & FLAG_FLUSHBEFOREONCHANGE))) {
|
if ((cmdFlags & FLAG_FLUSHBEFORE) || (diff && (cmdFlags & FLAG_FLUSHBEFOREONCHANGE)
|
||||||
|
&& (cmd != 0xc8 || (gstate.getTexLevelMode() == GE_TEXLEVEL_MODE_CONST && (0x00FF0000 & gstate.texlevel) != 0)))) { // Avoid always flushing when texlevel(0xc8).
|
||||||
drawEngine_.Flush(curCmd_);
|
drawEngine_.Flush(curCmd_);
|
||||||
}
|
}
|
||||||
gstate.cmdmem[cmd] = op; // TODO: no need to write if diff==0...
|
gstate.cmdmem[cmd] = op; // TODO: no need to write if diff==0...
|
||||||
@ -733,7 +734,8 @@ void GPU_Vulkan::FinishDeferred() {
|
|||||||
|
|
||||||
inline void GPU_Vulkan::CheckFlushOp(int cmd, u32 diff) {
|
inline void GPU_Vulkan::CheckFlushOp(int cmd, u32 diff) {
|
||||||
const u8 cmdFlags = cmdInfo_[cmd].flags;
|
const u8 cmdFlags = cmdInfo_[cmd].flags;
|
||||||
if ((cmdFlags & FLAG_FLUSHBEFORE) || (diff && (cmdFlags & FLAG_FLUSHBEFOREONCHANGE))) {
|
if ((cmdFlags & FLAG_FLUSHBEFORE) || (diff && (cmdFlags & FLAG_FLUSHBEFOREONCHANGE)
|
||||||
|
&& (cmd != 0xc8 || (gstate.getTexLevelMode() == GE_TEXLEVEL_MODE_CONST && (0x00FF0000 & gstate.texlevel) != 0)))) { // Avoid always flushing when texlevel(0xc8).
|
||||||
if (dumpThisFrame_) {
|
if (dumpThisFrame_) {
|
||||||
NOTICE_LOG(G3D, "================ FLUSH ================");
|
NOTICE_LOG(G3D, "================ FLUSH ================");
|
||||||
}
|
}
|
||||||
|
@ -623,16 +623,19 @@ void TextureCacheVulkan::SetTexture() {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
u32 texaddr = gstate.getTextureAddress(0);
|
u8 level = 0;
|
||||||
|
if (gstate.getTexLevelMode() == GE_TEXLEVEL_MODE_CONST)
|
||||||
|
level = (gstate.texlevel >> 20) & 0xF;
|
||||||
|
u32 texaddr = gstate.getTextureAddress(level);
|
||||||
if (!Memory::IsValidAddress(texaddr)) {
|
if (!Memory::IsValidAddress(texaddr)) {
|
||||||
// Bind a null texture and return.
|
// Bind a null texture and return.
|
||||||
lastBoundTexture = nullptr;
|
lastBoundTexture = nullptr;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const u16 dim = gstate.getTextureDimension(0);
|
const u16 dim = gstate.getTextureDimension(level);
|
||||||
int w = gstate.getTextureWidth(0);
|
int w = gstate.getTextureWidth(level);
|
||||||
int h = gstate.getTextureHeight(0);
|
int h = gstate.getTextureHeight(level);
|
||||||
if (texaddr == 0x04000000 && w == 2 && h == 2) {
|
if (texaddr == 0x04000000 && w == 2 && h == 2) {
|
||||||
// Nonsense bootup texture. Discard.
|
// Nonsense bootup texture. Discard.
|
||||||
}
|
}
|
||||||
@ -1082,6 +1085,8 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry, VulkanPushBuff
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (entry->vkTex) {
|
if (entry->vkTex) {
|
||||||
|
u8 level = (gstate.texlevel >> 20) & 0xF;
|
||||||
|
bool fakeMipmap = gstate.getTexLevelMode() == GE_TEXLEVEL_MODE_CONST && level > 0;
|
||||||
// Upload the texture data.
|
// Upload the texture data.
|
||||||
for (int i = 0; i <= maxLevel; i++) {
|
for (int i = 0; i <= maxLevel; i++) {
|
||||||
int mipWidth = gstate.getTextureWidth(i) * scaleFactor;
|
int mipWidth = gstate.getTextureWidth(i) * scaleFactor;
|
||||||
@ -1098,7 +1103,12 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry, VulkanPushBuff
|
|||||||
if (replaced.Valid()) {
|
if (replaced.Valid()) {
|
||||||
replaced.Load(i, data, stride);
|
replaced.Load(i, data, stride);
|
||||||
} else {
|
} else {
|
||||||
LoadTextureLevel(*entry, (uint8_t *)data, stride, i, scaleFactor, dstFmt);
|
if (fakeMipmap) {
|
||||||
|
LoadTextureLevel(*entry, (uint8_t *)data, stride, level, scaleFactor, dstFmt);
|
||||||
|
entry->vkTex->texture_->UploadMip(0, mipWidth, mipHeight, texBuf, bufferOffset, stride / bpp);
|
||||||
|
break;
|
||||||
|
} else
|
||||||
|
LoadTextureLevel(*entry, (uint8_t *)data, stride, i, scaleFactor, dstFmt);
|
||||||
if (replacer.Enabled()) {
|
if (replacer.Enabled()) {
|
||||||
replacer.NotifyTextureDecoded(replacedInfo, data, stride, i, mipWidth, mipHeight);
|
replacer.NotifyTextureDecoded(replacedInfo, data, stride, i, mipWidth, mipHeight);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user