Workarounds for D3D9's very limited mip level control.

This commit is contained in:
Henrik Rydgård 2020-09-13 23:10:43 +02:00
parent 9ea295093b
commit 46b3fb0821
4 changed files with 28 additions and 50 deletions

View File

@ -146,19 +146,18 @@ 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();
void TextureCacheCommon::UpdateSamplingParams(int maxLevel, u32 texAddr, SamplerCacheKey &key) {
int minFilt = gstate.texfilter & 0x7;
int magFilt = gstate.isMagnifyFilteringEnabled();
bool sClamp = gstate.isTexCoordClampedS();
bool tClamp = gstate.isTexCoordClampedT();
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);
}
@ -175,8 +174,8 @@ void TextureCacheCommon::GetSamplingParams(int &minFilt, int &magFilt, bool &sCl
lodBias = 0.0f;
}
if (!(magFilt & 1) && addr != 0 && g_Config.iTexFiltering != TEX_FILTER_FORCE_NEAREST) {
if (videos_.find(addr & 0x3FFFFFFF) != videos_.end()) {
if (!(magFilt & 1) && texAddr != 0 && g_Config.iTexFiltering != TEX_FILTER_FORCE_NEAREST) {
if (videos_.find(texAddr & 0x3FFFFFFF) != videos_.end()) {
// Enforce bilinear filtering on magnification.
magFilt |= 1;
}
@ -211,18 +210,7 @@ void TextureCacheCommon::GetSamplingParams(int &minFilt, int &magFilt, bool &sCl
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;
@ -235,8 +223,9 @@ void TextureCacheCommon::UpdateSamplingParams(int maxLevel, u32 texAddr, Sampler
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;

View File

@ -159,6 +159,7 @@ void TextureCacheD3D11::InvalidateLastTexture(TexCacheEntry *entry) {
void TextureCacheD3D11::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, SamplerCacheKey &key) {
UpdateSamplingParams(0, 0, key);
key.mipEnable = false;
key.minFilt &= 1;
key.mipFilt = 0;
key.magFilt &= 1;

View File

@ -119,37 +119,15 @@ 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,
};
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,
};
static const u8 MagFilt[2] = {
D3DTEXF_POINT,
D3DTEXF_LINEAR
};
void TextureCacheDX9::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight) {
SamplerCacheKey key;
UpdateSamplingParams(0, 0, key);
key.mipEnable = false;
key.minFilt &= 1;
key.mipFilt = 0;
key.magFilt &= 1;
// 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);
@ -165,8 +143,17 @@ 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);
dxstate.texMipLodBias.set((float)key.lodBias / 256.0f);
dxstate.texMaxMipLevel.set(key.maxLevel / 256);
// 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.
if (!key.mipEnable) {
dxstate.texMaxMipLevel.set(0);
dxstate.texMipLodBias.set(-100.0f);
} else {
dxstate.texMipLodBias.set((float)key.lodBias / 256.0f);
dxstate.texMaxMipLevel.set(key.minLevel / 256);
}
dxstate.texAddressU.set(key.sClamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP);
dxstate.texAddressV.set(key.tClamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP);

View File

@ -442,6 +442,7 @@ static const VkFilter MagFiltVK[2] = {
void TextureCacheVulkan::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, SamplerCacheKey &key) {
UpdateSamplingParams(0, 0, key);
key.mipEnable = false;
key.minFilt &= 1;
key.mipFilt = 0;
key.magFilt &= 1;