Merge pull request #13429 from hrydgard/more-tex-filtering-cleanups

More tex filtering code cleanups
This commit is contained in:
Henrik Rydgård authored and GitHub committed 2020-09-14 07:37:48 +02:00
commit 0b65809fd4
16 files changed
+144 -310

No files matched your search

+77 -66
View File
@@ -146,19 +146,23 @@ static int TexLog2(float delta) {
return useful - 127 * 256;
}
void TextureCacheCommon::GetSamplingParams(int &minFilt, int &magFilt, bool &sClamp, bool &tClamp, float &lodBias, int maxLevel, u32 addr, GETexLevelMode &mode) {
minFilt = gstate.texfilter & 0x7;
magFilt = gstate.isMagnifyFilteringEnabled();
sClamp = gstate.isTexCoordClampedS();
tClamp = gstate.isTexCoordClampedT();
SamplerCacheKey TextureCacheCommon::GetSamplingParams(int maxLevel, u32 texAddr) {
SamplerCacheKey key;
int minFilt = gstate.texfilter & 0x7;
key.minFilt = minFilt & 1;
key.mipEnable = (minFilt >> 2) & 1;
key.mipFilt = (minFilt >> 1) & 1;
key.magFilt = gstate.isMagnifyFilteringEnabled();
key.sClamp = gstate.isTexCoordClampedS();
key.tClamp = gstate.isTexCoordClampedT();
key.aniso = false;
GETexLevelMode mipMode = gstate.getTexLevelMode();
mode = mipMode;
bool autoMip = mipMode == GE_TEXLEVEL_MODE_AUTO;
// TODO: Slope mipmap bias is still not well understood.
lodBias = (float)gstate.getTexLevelOffset16() * (1.0f / 16.0f);
float lodBias = (float)gstate.getTexLevelOffset16() * (1.0f / 16.0f);
if (mipMode == GE_TEXLEVEL_MODE_SLOPE) {
lodBias += 1.0f + TexLog2(gstate.getTextureLodSlope()) * (1.0f / 256.0f);
}
@@ -171,72 +175,18 @@ void TextureCacheCommon::GetSamplingParams(int &minFilt, int &magFilt, bool &sCl
if (noMip) {
// Enforce no mip filtering, for safety.
minFilt &= 1; // no mipmaps yet
key.mipEnable = false;
key.mipFilt = 0;
lodBias = 0.0f;
}
if (!(magFilt & 1) && addr != 0 && g_Config.iTexFiltering != TEX_FILTER_FORCE_NEAREST) {
if (videos_.find(addr & 0x3FFFFFFF) != videos_.end()) {
// Enforce bilinear filtering on magnification.
magFilt |= 1;
}
}
// Filtering overrides
switch (g_Config.iTexFiltering) {
case TEX_FILTER_AUTO:
// Follow what the game wants. We just do a single heuristic change to avoid bleeding of wacky color test colors
// in higher resolution (used by some games for sprites, and they accidentally have linear filter on).
if (gstate.isModeThrough() && g_Config.iInternalResolution != 1) {
bool uglyColorTest = gstate.isColorTestEnabled() && !IsColorTestTriviallyTrue() && gstate.getColorTestRef() != 0;
if (uglyColorTest) {
// Force to nearest.
magFilt &= ~1;
minFilt &= ~1;
}
}
break;
case TEX_FILTER_FORCE_LINEAR:
// Override to linear filtering if there's no alpha or color testing going on.
if ((!gstate.isColorTestEnabled() || IsColorTestTriviallyTrue()) &&
(!gstate.isAlphaTestEnabled() || IsAlphaTestTriviallyTrue())) {
magFilt |= 1;
minFilt |= 1;
}
break;
case TEX_FILTER_FORCE_NEAREST:
default:
// Just force to nearest without checks. Safe (but ugly).
magFilt &= ~1;
minFilt &= ~1;
break;
}
}
void TextureCacheCommon::UpdateSamplingParams(int maxLevel, u32 texAddr, SamplerCacheKey &key) {
// TODO: Make GetSamplingParams write SamplerCacheKey directly
int minFilt;
int magFilt;
bool sClamp;
bool tClamp;
float lodBias;
GETexLevelMode mode;
GetSamplingParams(minFilt, magFilt, sClamp, tClamp, lodBias, maxLevel, texAddr, mode);
key.minFilt = minFilt & 1;
key.mipEnable = (minFilt >> 2) & 1;
key.mipFilt = (minFilt >> 1) & 1;
key.magFilt = magFilt & 1;
key.sClamp = sClamp;
key.tClamp = tClamp;
key.aniso = false;
if (!key.mipEnable) {
key.maxLevel = 0;
key.minLevel = 0;
key.lodBias = 0;
key.mipFilt = 0;
} else {
switch (mode) {
switch (mipMode) {
case GE_TEXLEVEL_MODE_AUTO:
key.maxLevel = maxLevel * 256;
key.minLevel = 0;
@@ -261,6 +211,67 @@ void TextureCacheCommon::UpdateSamplingParams(int maxLevel, u32 texAddr, Sampler
break;
}
}
// Video bilinear override
if (!key.magFilt && texAddr != 0) {
if (videos_.find(texAddr & 0x3FFFFFFF) != videos_.end()) {
// Enforce bilinear filtering on magnification.
key.magFilt = 1;
}
}
// Filtering overrides
switch (g_Config.iTexFiltering) {
case TEX_FILTER_AUTO:
// Follow what the game wants. We just do a single heuristic change to avoid bleeding of wacky color test colors
// in higher resolution (used by some games for sprites, and they accidentally have linear filter on).
if (gstate.isModeThrough() && g_Config.iInternalResolution != 1) {
bool uglyColorTest = gstate.isColorTestEnabled() && !IsColorTestTriviallyTrue() && gstate.getColorTestRef() != 0;
if (uglyColorTest) {
// Force to nearest.
key.magFilt = 0;
key.minFilt = 0;
}
}
break;
case TEX_FILTER_FORCE_LINEAR:
// Override to linear filtering if there's no alpha or color testing going on.
if ((!gstate.isColorTestEnabled() || IsColorTestTriviallyTrue()) &&
(!gstate.isAlphaTestEnabled() || IsAlphaTestTriviallyTrue())) {
key.magFilt = 1;
key.minFilt = 1;
key.mipFilt = 1;
}
break;
case TEX_FILTER_FORCE_NEAREST:
default:
// Just force to nearest without checks. Safe (but ugly).
key.magFilt = 0;
key.minFilt = 0;
break;
}
return key;
}
SamplerCacheKey TextureCacheCommon::GetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight) {
SamplerCacheKey key = GetSamplingParams(0, 0);
// Kill any mipmapping settings.
key.mipEnable = false;
key.minFilt &= 1;
key.mipFilt = 0;
key.magFilt &= 1;
key.aniso = 0.0;
// Often the framebuffer will not match the texture size. We'll wrap/clamp in the shader in that case.
int w = gstate.getTextureWidth(0);
int h = gstate.getTextureHeight(0);
if (w != bufferWidth || h != bufferHeight) {
key.sClamp = true;
key.tClamp = true;
}
return key;
}
void TextureCacheCommon::UpdateMaxSeenV(TexCacheEntry *entry, bool throughMode) {
+3 -2
View File
@@ -284,8 +284,9 @@ protected:
}
u32 EstimateTexMemoryUsage(const TexCacheEntry *entry);
void GetSamplingParams(int &minFilt, int &magFilt, bool &sClamp, bool &tClamp, float &lodBias, int maxLevel, u32 addr, GETexLevelMode &mode);
void UpdateSamplingParams(int maxLevel, u32 texAddr, SamplerCacheKey &key); // Used by D3D11 and Vulkan.
SamplerCacheKey GetSamplingParams(int maxLevel, u32 texAddr);
SamplerCacheKey GetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight);
void UpdateMaxSeenV(TexCacheEntry *entry, bool throughMode);
FramebufferMatchInfo MatchFramebuffer(const TextureDefinition &entry, VirtualFramebuffer *framebuffer, u32 texaddrOffset, FramebufferNotificationChannel channel) const;
+3 -3
View File
@@ -17,19 +17,19 @@
#pragma once
#include <list>
#include <deque>
#include <string>
#include <vector>
#include <d3d11.h>
#include "GPU/GPUCommon.h"
#include "GPU/D3D11/DrawEngineD3D11.h"
#include "GPU/D3D11/TextureCacheD3D11.h"
#include "GPU/D3D11/DepalettizeShaderD3D11.h"
#include "GPU/Common/VertexDecoderCommon.h"
class FramebufferManagerD3D11;
class ShaderManagerD3D11;
class LinkedShaderD3D11;
class TextureCacheD3D11;
class GPU_D3D11 : public GPUCommon {
public:
+4 -30
View File
@@ -156,31 +156,6 @@ void TextureCacheD3D11::InvalidateLastTexture(TexCacheEntry *entry) {
}
}
void TextureCacheD3D11::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, SamplerCacheKey &key) {
int minFilt;
int magFilt;
bool sClamp;
bool tClamp;
float lodBias;
GETexLevelMode mode;
GetSamplingParams(minFilt, magFilt, sClamp, tClamp, lodBias, 0, 0, mode);
key.minFilt = minFilt & 1;
key.mipFilt = 0;
key.magFilt = magFilt & 1;
key.sClamp = sClamp;
key.tClamp = tClamp;
// Often the framebuffer will not match the texture size. We'll wrap/clamp in the shader in that case.
// This happens whether we have OES_texture_npot or not.
int w = gstate.getTextureWidth(0);
int h = gstate.getTextureHeight(0);
if (w != bufferWidth || h != bufferHeight) {
key.sClamp = true;
key.tClamp = true;
}
}
void TextureCacheD3D11::StartFrame() {
InvalidateLastTexture();
timesInvalidatedAllThisFrame_ = 0;
@@ -239,10 +214,9 @@ void TextureCacheD3D11::BindTexture(TexCacheEntry *entry) {
context_->PSSetShaderResources(0, 1, &textureView);
lastBoundTexture = textureView;
}
SamplerCacheKey key{};
int maxLevel = (entry->status & TexCacheEntry::STATUS_BAD_MIPS) ? 0 : entry->maxLevel;
UpdateSamplingParams(maxLevel, entry->addr, key);
ID3D11SamplerState *state = samplerCache_.GetOrCreateSampler(device_, key);
SamplerCacheKey samplerKey = GetSamplingParams(maxLevel, entry->addr);
ID3D11SamplerState *state = samplerCache_.GetOrCreateSampler(device_, samplerKey);
context_->PSSetSamplers(0, 1, &state);
}
@@ -428,8 +402,8 @@ void TextureCacheD3D11::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer,
gstate_c.SetTextureFullAlpha(gstate.getTextureFormat() == GE_TFMT_5650);
framebufferManagerD3D11_->RebindFramebuffer("RebindFramebuffer - ApplyTextureFramebuffer"); // Probably not necessary.
}
SamplerCacheKey samplerKey{};
SetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight, samplerKey);
SamplerCacheKey samplerKey = GetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight);
ID3D11SamplerState *state = samplerCache_.GetOrCreateSampler(device_, samplerKey);
context_->PSSetSamplers(0, 1, &state);
-1
View File
@@ -60,7 +60,6 @@ public:
void ForgetLastTexture() override;
void InvalidateLastTexture(TexCacheEntry *entry = nullptr) override;
void SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, SamplerCacheKey &key);
bool GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) override;
protected:
+3 -3
View File
@@ -17,13 +17,12 @@
#pragma once
#include <list>
#include <deque>
#include <string>
#include <vector>
#include "GPU/GPUCommon.h"
#include "GPU/Directx9/FramebufferManagerDX9.h"
#include "GPU/Directx9/DrawEngineDX9.h"
#include "GPU/Directx9/TextureCacheDX9.h"
#include "GPU/Directx9/DepalettizeShaderDX9.h"
#include "GPU/Common/VertexDecoderCommon.h"
@@ -31,6 +30,7 @@ namespace DX9 {
class ShaderManagerDX9;
class LinkedShaderDX9;
class TextureCacheDX9;
class GPU_DX9 : public GPUCommon {
public:
+19 -93
View File
@@ -119,101 +119,24 @@ D3DFORMAT getClutDestFormat(GEPaletteFormat format) {
return D3DFMT_A8R8G8B8;
}
static const u8 MinFilt[8] = {
D3DTEXF_POINT,
D3DTEXF_LINEAR,
D3DTEXF_POINT,
D3DTEXF_LINEAR,
D3DTEXF_POINT, // GL_NEAREST_MIPMAP_NEAREST,
D3DTEXF_LINEAR, // GL_LINEAR_MIPMAP_NEAREST,
D3DTEXF_POINT, // GL_NEAREST_MIPMAP_LINEAR,
D3DTEXF_LINEAR, // GL_LINEAR_MIPMAP_LINEAR,
};
void TextureCacheDX9::ApplySamplingParams(const SamplerCacheKey &key) {
dxstate.texMinFilter.set(key.minFilt ? D3DTEXF_LINEAR : D3DTEXF_POINT);
dxstate.texMipFilter.set(key.mipFilt ? D3DTEXF_LINEAR : D3DTEXF_POINT);
dxstate.texMagFilter.set(key.magFilt ? D3DTEXF_LINEAR : D3DTEXF_POINT);
static const u8 MipFilt[8] = {
D3DTEXF_NONE,
D3DTEXF_NONE,
D3DTEXF_NONE,
D3DTEXF_NONE,
D3DTEXF_POINT, // GL_NEAREST_MIPMAP_NEAREST,
D3DTEXF_POINT, // GL_LINEAR_MIPMAP_NEAREST,
D3DTEXF_LINEAR, // GL_NEAREST_MIPMAP_LINEAR,
D3DTEXF_LINEAR, // GL_LINEAR_MIPMAP_LINEAR,
};
// DX9 mip levels are .. odd. The "max level" sets the LARGEST mip to use.
// We can enforce only the top mip level by setting a massive negative lod bias.
static const u8 MagFilt[2] = {
D3DTEXF_POINT,
D3DTEXF_LINEAR
};
void TextureCacheDX9::UpdateSamplingParams(TexCacheEntry &entry, bool force) {
int minFilt;
int magFilt;
bool sClamp;
bool tClamp;
float lodBias;
GETexLevelMode mode;
u8 maxLevel = (entry.status & TexCacheEntry::STATUS_BAD_MIPS) ? 0 : entry.maxLevel;
GetSamplingParams(minFilt, magFilt, sClamp, tClamp, lodBias, maxLevel, entry.addr, mode);
if (maxLevel != 0) {
if (mode == GE_TEXLEVEL_MODE_AUTO) {
dxstate.texMaxMipLevel.set(0);
dxstate.texMipLodBias.set(lodBias);
} else if (mode == GE_TEXLEVEL_MODE_CONST) {
// TODO: This is just an approximation - texMaxMipLevel sets the lowest numbered mip to use.
// Unfortunately, this doesn't support a const 1.5 or etc.
dxstate.texMaxMipLevel.set(std::max(0, std::min((int)maxLevel, (int)lodBias)));
dxstate.texMipLodBias.set(-1000.0f);
} else { // if (mode == GE_TEXLEVEL_MODE_SLOPE{
dxstate.texMaxMipLevel.set(0);
dxstate.texMipLodBias.set(0.0f);
}
} else {
if (!key.mipEnable) {
dxstate.texMaxMipLevel.set(0);
dxstate.texMipLodBias.set(0.0f);
dxstate.texMipLodBias.set(-100.0f);
} else {
dxstate.texMipLodBias.set((float)key.lodBias / 256.0f);
dxstate.texMaxMipLevel.set(key.minLevel / 256);
}
D3DTEXTUREFILTERTYPE minf = (D3DTEXTUREFILTERTYPE)MinFilt[minFilt];
D3DTEXTUREFILTERTYPE mipf = (D3DTEXTUREFILTERTYPE)MipFilt[minFilt];
D3DTEXTUREFILTERTYPE magf = (D3DTEXTUREFILTERTYPE)MagFilt[magFilt];
if (gstate_c.Supports(GPU_SUPPORTS_ANISOTROPY) && g_Config.iAnisotropyLevel > 0 && minf == D3DTEXF_LINEAR) {
minf = D3DTEXF_ANISOTROPIC;
}
dxstate.texMinFilter.set(minf);
dxstate.texMipFilter.set(mipf);
dxstate.texMagFilter.set(magf);
dxstate.texAddressU.set(sClamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP);
dxstate.texAddressV.set(tClamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP);
}
void TextureCacheDX9::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight) {
int minFilt;
int magFilt;
bool sClamp;
bool tClamp;
float lodBias;
GETexLevelMode mode;
GetSamplingParams(minFilt, magFilt, sClamp, tClamp, lodBias, 0, 0, mode);
dxstate.texMinFilter.set(MinFilt[minFilt]);
dxstate.texMipFilter.set(MipFilt[minFilt]);
dxstate.texMagFilter.set(MagFilt[magFilt]);
dxstate.texMipLodBias.set(0.0f);
dxstate.texMaxMipLevel.set(0.0f);
// Often the framebuffer will not match the texture size. We'll wrap/clamp in the shader in that case.
// This happens whether we have OES_texture_npot or not.
int w = gstate.getTextureWidth(0);
int h = gstate.getTextureHeight(0);
if (w != bufferWidth || h != bufferHeight) {
return;
}
dxstate.texAddressU.set(sClamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP);
dxstate.texAddressV.set(tClamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP);
dxstate.texAddressU.set(key.sClamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP);
dxstate.texAddressV.set(key.tClamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP);
}
void TextureCacheDX9::StartFrame() {
@@ -236,7 +159,6 @@ void TextureCacheDX9::StartFrame() {
DWORD anisotropyLevel = aniso > maxAnisotropyLevel ? maxAnisotropyLevel : aniso;
device_->SetSamplerState(0, D3DSAMP_MAXANISOTROPY, anisotropyLevel);
}
}
void TextureCacheDX9::UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBase, bool clutIndexIsSimple) {
@@ -281,7 +203,9 @@ void TextureCacheDX9::BindTexture(TexCacheEntry *entry) {
device_->SetTexture(0, texture);
lastBoundTexture = texture;
}
UpdateSamplingParams(*entry, false);
int maxLevel = (entry->status & TexCacheEntry::STATUS_BAD_MIPS) ? 0 : entry->maxLevel;
SamplerCacheKey samplerKey = GetSamplingParams(maxLevel, entry->addr);
ApplySamplingParams(samplerKey);
}
void TextureCacheDX9::Unbind() {
@@ -467,7 +391,9 @@ void TextureCacheDX9::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer, G
}
framebufferManagerDX9_->RebindFramebuffer("RebindFramebuffer - ApplyTextureFromFramebuffer");
SetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight);
SamplerCacheKey samplerKey = GetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight);
ApplySamplingParams(samplerKey);
}
void TextureCacheDX9::BuildTexture(TexCacheEntry *const entry) {
+2 -3
View File
@@ -52,8 +52,6 @@ public:
void ForgetLastTexture() override;
void InvalidateLastTexture(TexCacheEntry *entry = nullptr) override;
void SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight);
bool GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) override;
protected:
@@ -62,7 +60,8 @@ protected:
void ReleaseTexture(TexCacheEntry *entry, bool delete_them) override;
private:
void UpdateSamplingParams(TexCacheEntry &entry, bool force);
void ApplySamplingParams(const SamplerCacheKey &key);
void LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &replaced, int level, int maxLevel, int scaleFactor, u32 dstFmt);
D3DFORMAT GetDestFormat(GETextureFormat format, GEPaletteFormat clutFormat) const;
TexCacheEntry::TexStatus CheckAlpha(const u32 *pixelData, u32 dstFmt, int stride, int w, int h);
+3 -3
View File
@@ -17,17 +17,17 @@
#pragma once
#include <list>
#include <deque>
#include <string>
#include <vector>
#include "GPU/GPUCommon.h"
#include "GPU/GLES/FramebufferManagerGLES.h"
#include "GPU/GLES/DrawEngineGLES.h"
#include "GPU/GLES/TextureCacheGLES.h"
#include "GPU/GLES/DepalettizeShaderGLES.h"
#include "GPU/GLES/FragmentTestCacheGLES.h"
class ShaderManagerGLES;
class TextureCacheGLES;
class LinkedShader;
class GPU_GLES : public GPUCommon {
+22 -69
View File
@@ -115,76 +115,19 @@ static const GLuint MagFiltGL[2] = {
GL_LINEAR
};
// This should not have to be done per texture! OpenGL is silly yo
void TextureCacheGLES::UpdateSamplingParams(TexCacheEntry &entry, bool force) {
int minFilt;
int magFilt;
bool sClamp;
bool tClamp;
float lodBias;
u8 maxLevel = (entry.status & TexCacheEntry::STATUS_BAD_MIPS) ? 0 : entry.maxLevel;
GETexLevelMode mode;
GetSamplingParams(minFilt, magFilt, sClamp, tClamp, lodBias, maxLevel, entry.addr, mode);
void TextureCacheGLES::ApplySamplingParams(const SamplerCacheKey &key) {
if (gstate_c.Supports(GPU_SUPPORTS_TEXTURE_LOD_CONTROL)) {
float minLod = 0.0f;
float maxLod = 0.0f;
if (maxLevel != 0) {
// TODO: What about a swap of autoMip mode?
if (true) {
if (mode == GE_TEXLEVEL_MODE_AUTO) {
minLod = 0.0f;
maxLod = (float)maxLevel;
} else if (mode == GE_TEXLEVEL_MODE_CONST) {
minLod = std::max(0.0f, std::min((float)maxLevel, lodBias));
maxLod = std::max(0.0f, std::min((float)maxLevel, lodBias));
} else { // mode == GE_TEXLEVEL_MODE_SLOPE) {
// It's incorrect to use the slope as a bias. Instead it should be passed
// into the shader directly as an explicit lod level, with the bias on top. For now, we just kill the
// lodBias in this mode, working around #9772.
#ifndef USING_GLES2
lodBias = 0.0f;
#endif
minLod = 0.0f;
maxLod = (float)maxLevel;
}
}
} else {
minLod = 0.0f;
maxLod = 0.0f;
}
float minLod = (float)key.minLevel / 256.0f;
float maxLod = (float)key.maxLevel / 256.0f;
float lodBias = (float)key.lodBias / 256.0f;
render_->SetTextureLod(0, minLod, maxLod, lodBias);
}
float aniso = 0.0f;
render_->SetTextureSampler(0, sClamp ? GL_CLAMP_TO_EDGE : GL_REPEAT, tClamp ? GL_CLAMP_TO_EDGE : GL_REPEAT, MagFiltGL[magFilt], MinFiltGL[minFilt], aniso);
}
void TextureCacheGLES::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, bool forcePoint) {
int minFilt;
int magFilt;
bool sClamp;
bool tClamp;
float lodBias;
GETexLevelMode mode;
GetSamplingParams(minFilt, magFilt, sClamp, tClamp, lodBias, 0, 0, mode);
minFilt &= 1; // framebuffers can't mipmap.
if (forcePoint) {
minFilt &= ~1;
magFilt &= ~1;
}
// Often the framebuffer will not match the texture size. We'll wrap/clamp in the shader in that case.
// This happens whether we have OES_texture_npot or not.
int w = gstate.getTextureWidth(0);
int h = gstate.getTextureHeight(0);
if (w != bufferWidth || h != bufferHeight) {
sClamp = true;
tClamp = true;
}
float aniso = 0.0f;
render_->SetTextureSampler(TEX_SLOT_PSP_TEXTURE, sClamp ? GL_CLAMP_TO_EDGE : GL_REPEAT, tClamp ? GL_CLAMP_TO_EDGE : GL_REPEAT, MagFiltGL[magFilt], MinFiltGL[minFilt], aniso);
int magKey = ((int)key.mipEnable << 2) | ((int)key.mipFilt << 1) | ((int)key.magFilt);
render_->SetTextureSampler(0,
key.sClamp ? GL_CLAMP_TO_EDGE : GL_REPEAT, key.tClamp ? GL_CLAMP_TO_EDGE : GL_REPEAT,
MagFiltGL[magKey], key.minFilt ? GL_LINEAR : GL_NEAREST, aniso);
}
static void ConvertColors(void *dstBuf, const void *srcBuf, Draw::DataFormat dstFmt, int numPixels) {
@@ -287,7 +230,9 @@ void TextureCacheGLES::BindTexture(TexCacheEntry *entry) {
render_->BindTexture(0, entry->textureName);
lastBoundTexture = entry->textureName;
}
UpdateSamplingParams(*entry, false);
int maxLevel = (entry->status & TexCacheEntry::STATUS_BAD_MIPS) ? 0 : entry->maxLevel;
SamplerCacheKey samplerKey = GetSamplingParams(maxLevel, entry->addr);
ApplySamplingParams(samplerKey);
gstate_c.SetUseShaderDepal(false);
}
@@ -415,7 +360,11 @@ void TextureCacheGLES::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer,
render_->BindTexture(TEX_SLOT_CLUT, clutTexture);
render_->SetTextureSampler(TEX_SLOT_CLUT, GL_REPEAT, GL_CLAMP_TO_EDGE, GL_NEAREST, GL_NEAREST, 0.0f);
framebufferManagerGL_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_MAY_COPY_WITH_UV | BINDFBCOLOR_APPLY_TEX_OFFSET);
SetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight, true);
SamplerCacheKey samplerKey = GetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight);
samplerKey.magFilt = false;
samplerKey.minFilt = false;
samplerKey.mipEnable = false;
ApplySamplingParams(samplerKey);
InvalidateLastTexture();
// Since we started/ended render passes, might need these.
@@ -465,7 +414,9 @@ void TextureCacheGLES::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer,
}
framebufferManagerGL_->RebindFramebuffer("ApplyTextureFramebuffer");
SetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight, false);
SamplerCacheKey samplerKey = GetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight);
ApplySamplingParams(samplerKey);
// Since we started/ended render passes, might need these.
gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE);
@@ -648,7 +599,9 @@ void TextureCacheGLES::BuildTexture(TexCacheEntry *const entry) {
// This will rebind it, but that's okay.
// Need to actually bind it now - it might only have gotten bound in the init phase.
render_->BindTexture(TEX_SLOT_PSP_TEXTURE, entry->textureName);
UpdateSamplingParams(*entry, true);
SamplerCacheKey samplerKey = GetSamplingParams(entry->maxLevel, entry->addr);
ApplySamplingParams(samplerKey);
}
Draw::DataFormat TextureCacheGLES::GetDestFormat(GETextureFormat format, GEPaletteFormat clutFormat) const {
+1 -2
View File
@@ -63,7 +63,6 @@ public:
}
}
void SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, bool forcePoint);
bool GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) override;
void DeviceLost();
@@ -75,7 +74,7 @@ protected:
void ReleaseTexture(TexCacheEntry *entry, bool delete_them) override;
private:
void UpdateSamplingParams(TexCacheEntry &entry, bool force);
void ApplySamplingParams(const SamplerCacheKey &key);
void LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &replaced, int level, int scaleFactor, Draw::DataFormat dstFmt);
Draw::DataFormat GetDestFormat(GETextureFormat format, GEPaletteFormat clutFormat) const;
+1
View File
@@ -25,6 +25,7 @@
#include "Common/Vulkan/VulkanImage.h"
#include "GPU/Vulkan/GPU_Vulkan.h"
#include "GPU/Vulkan/VulkanUtil.h"
#include "GPU/Vulkan/TextureCacheVulkan.h"
#undef DrawText
+3 -3
View File
@@ -17,18 +17,18 @@
#pragma once
#include <list>
#include <deque>
#include <string>
#include <vector>
#include "GPU/GPUCommon.h"
#include "GPU/Vulkan/DrawEngineVulkan.h"
#include "GPU/Vulkan/PipelineManagerVulkan.h"
#include "GPU/Vulkan/TextureCacheVulkan.h"
#include "GPU/Vulkan/DepalettizeShaderVulkan.h"
class FramebufferManagerVulkan;
class ShaderManagerVulkan;
class LinkedShader;
class TextureCacheVulkan;
class GPU_Vulkan : public GPUCommon {
public:
-1
View File
@@ -28,7 +28,6 @@
#include "Core/Reporting.h"
#include "GPU/Vulkan/GPU_Vulkan.h"
#include "GPU/Vulkan/PipelineManagerVulkan.h"
#include "GPU/Vulkan/TextureCacheVulkan.h"
#include "GPU/Vulkan/FramebufferManagerVulkan.h"
#include "GPU/Vulkan/ShaderManagerVulkan.h"
#include "GPU/Vulkan/DrawEngineVulkan.h"
+3 -30
View File
@@ -439,31 +439,6 @@ static const VkFilter MagFiltVK[2] = {
VK_FILTER_LINEAR
};
void TextureCacheVulkan::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, SamplerCacheKey &key) {
int minFilt;
int magFilt;
bool sClamp;
bool tClamp;
float lodBias;
GETexLevelMode mode;
GetSamplingParams(minFilt, magFilt, sClamp, tClamp, lodBias, 0, 0, mode);
key.minFilt = minFilt & 1;
key.mipFilt = 0;
key.magFilt = magFilt & 1;
key.sClamp = sClamp;
key.tClamp = tClamp;
// Often the framebuffer will not match the texture size. We'll wrap/clamp in the shader in that case.
// This happens whether we have OES_texture_npot or not.
int w = gstate.getTextureWidth(0);
int h = gstate.getTextureHeight(0);
if (w != bufferWidth || h != bufferHeight) {
key.sClamp = true;
key.tClamp = true;
}
}
void TextureCacheVulkan::StartFrame() {
InvalidateLastTexture();
depalShaderCache_->Decimate();
@@ -541,10 +516,9 @@ void TextureCacheVulkan::BindTexture(TexCacheEntry *entry) {
entry->vkTex->Touch();
imageView_ = entry->vkTex->GetImageView();
SamplerCacheKey key{};
int maxLevel = (entry->status & TexCacheEntry::STATUS_BAD_MIPS) ? 0 : entry->maxLevel;
UpdateSamplingParams(maxLevel, entry->addr, key);
curSampler_ = samplerCache_.GetOrCreateSampler(key);
SamplerCacheKey samplerKey = GetSamplingParams(maxLevel, entry->addr);
curSampler_ = samplerCache_.GetOrCreateSampler(samplerKey);
drawEngine_->SetDepalTexture(VK_NULL_HANDLE);
gstate_c.SetUseShaderDepal(false);
}
@@ -556,8 +530,7 @@ void TextureCacheVulkan::Unbind() {
}
void TextureCacheVulkan::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer, GETextureFormat texFormat, FramebufferNotificationChannel channel) {
SamplerCacheKey samplerKey{};
SetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight, samplerKey);
SamplerCacheKey samplerKey = GetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight);
DepalShaderVulkan *depalShader = nullptr;
uint32_t clutMode = gstate.clutformat & 0xFFFFFF;
-1
View File
@@ -100,7 +100,6 @@ public:
imageView = imageView_;
sampler = curSampler_;
}
void SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, SamplerCacheKey &key);
bool GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) override;