mirror of https://github.com/PCSX2/pcsx2.git
GS/HW: Allow use of trilinear with shader sampling
This commit is contained in:
parent
f47b2d02cb
commit
ec8d5d1b71
|
@ -162,6 +162,7 @@ cbuffer cb1
|
|||
uint4 FbMask;
|
||||
float4 HalfTexel;
|
||||
float4 MinMax;
|
||||
float4 LODParams;
|
||||
float4 STRange;
|
||||
int4 ChannelShuffle;
|
||||
float2 TC_OffsetHack;
|
||||
|
@ -207,10 +208,10 @@ float4 sample_c(float2 uv, float uv_w)
|
|||
return Texture.Sample(TextureSampler, uv);
|
||||
#elif PS_MANUAL_LOD == 1
|
||||
// FIXME add LOD: K - ( LOG2(Q) * (1 << L))
|
||||
float K = MinMax.x;
|
||||
float L = MinMax.y;
|
||||
float bias = MinMax.z;
|
||||
float max_lod = MinMax.w;
|
||||
float K = LODParams.x;
|
||||
float L = LODParams.y;
|
||||
float bias = LODParams.z;
|
||||
float max_lod = LODParams.w;
|
||||
|
||||
float gs_lod = K - log2(abs(uv_w)) * L;
|
||||
// FIXME max useful ?
|
||||
|
|
|
@ -44,6 +44,7 @@ layout(std140, binding = 0) uniform cb21
|
|||
vec4 HalfTexel;
|
||||
|
||||
vec4 MinMax;
|
||||
vec4 LODParams;
|
||||
vec4 STRange;
|
||||
|
||||
ivec4 ChannelShuffle;
|
||||
|
@ -159,10 +160,10 @@ vec4 sample_c(vec2 uv)
|
|||
return texture(TextureSampler, uv);
|
||||
#elif PS_MANUAL_LOD == 1
|
||||
// FIXME add LOD: K - ( LOG2(Q) * (1 << L))
|
||||
float K = MinMax.x;
|
||||
float L = MinMax.y;
|
||||
float bias = MinMax.z;
|
||||
float max_lod = MinMax.w;
|
||||
float K = LODParams.x;
|
||||
float L = LODParams.y;
|
||||
float bias = LODParams.z;
|
||||
float max_lod = LODParams.w;
|
||||
|
||||
float gs_lod = K - log2(abs(PSin.t_float.w)) * L;
|
||||
// FIXME max useful ?
|
||||
|
|
|
@ -316,6 +316,7 @@ layout(std140, set = 0, binding = 1) uniform cb1
|
|||
uvec4 FbMask;
|
||||
vec4 HalfTexel;
|
||||
vec4 MinMax;
|
||||
vec4 LODParams;
|
||||
vec4 STRange;
|
||||
ivec4 ChannelShuffle;
|
||||
vec2 TC_OffsetHack;
|
||||
|
@ -399,10 +400,10 @@ vec4 sample_c(vec2 uv)
|
|||
return texture(Texture, uv);
|
||||
#elif PS_MANUAL_LOD == 1
|
||||
// FIXME add LOD: K - ( LOG2(Q) * (1 << L))
|
||||
float K = MinMax.x;
|
||||
float L = MinMax.y;
|
||||
float bias = MinMax.z;
|
||||
float max_lod = MinMax.w;
|
||||
float K = LODParams.x;
|
||||
float L = LODParams.y;
|
||||
float bias = LODParams.z;
|
||||
float max_lod = LODParams.w;
|
||||
|
||||
float gs_lod = K - log2(abs(vsIn.t.w)) * L;
|
||||
// FIXME max useful ?
|
||||
|
|
|
@ -585,6 +585,7 @@ struct alignas(16) GSHWDrawConfig
|
|||
|
||||
GSVector4 HalfTexel;
|
||||
GSVector4 MinMax;
|
||||
GSVector4 LODParams;
|
||||
GSVector4 STRange;
|
||||
GSVector4i ChannelShuffle;
|
||||
GSVector2 TCOffsetHack;
|
||||
|
|
|
@ -4743,7 +4743,6 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, bool& DAT
|
|||
__ri static constexpr bool IsRedundantClamp(u8 clamp, u32 clamp_min, u32 clamp_max, u32 tsize)
|
||||
{
|
||||
// Don't shader sample when the clamp/repeat is configured to the texture size.
|
||||
// That way trilinear etc still works.
|
||||
const u32 textent = (1u << tsize) - 1u;
|
||||
if (clamp == CLAMP_REGION_CLAMP)
|
||||
return (clamp_min == 0 && clamp_max >= textent);
|
||||
|
@ -4809,6 +4808,7 @@ __ri void GSRendererHW::EmulateTextureSampler(const GSTextureCache::Target* rt,
|
|||
const bool need_mipmap = IsMipMapDraw();
|
||||
const bool shader_emulated_sampler = tex->m_palette || (tex->m_target && !m_conf.ps.shuffle && cpsm.fmt != 0) ||
|
||||
complex_wms_wmt || psm.depth || target_region;
|
||||
const bool can_trilinear = !tex->m_palette && !tex->m_target && !m_conf.ps.shuffle;
|
||||
const bool trilinear_manual = need_mipmap && GSConfig.HWMipmap;
|
||||
|
||||
bool bilinear = m_vt.IsLinear();
|
||||
|
@ -4821,16 +4821,19 @@ __ri void GSRendererHW::EmulateTextureSampler(const GSTextureCache::Target* rt,
|
|||
// Force bilinear otherwise we can end up with min/mag nearest and mip linear.
|
||||
// We don't need to check for HWMipmapLevel::Off here, because forced trilinear implies forced mipmaps.
|
||||
bilinear = true;
|
||||
if (can_trilinear)
|
||||
{
|
||||
trilinear = static_cast<u8>(GS_MIN_FILTER::Linear_Mipmap_Linear);
|
||||
trilinear_auto = !tex->m_target && (!need_mipmap || !GSConfig.HWMipmap);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TriFiltering::PS2:
|
||||
case TriFiltering::Automatic:
|
||||
{
|
||||
// Can only use PS2 trilinear when mipmapping is enabled.
|
||||
if (need_mipmap && GSConfig.HWMipmap)
|
||||
if (need_mipmap && GSConfig.HWMipmap && can_trilinear)
|
||||
{
|
||||
trilinear = m_context->TEX1.MMIN;
|
||||
trilinear_auto = !tex->m_target && !GSConfig.HWMipmap;
|
||||
|
@ -5037,17 +5040,19 @@ __ri void GSRendererHW::EmulateTextureSampler(const GSTextureCache::Target* rt,
|
|||
m_conf.cb_ps.MinMax.w = (wmt == CLAMP_REGION_CLAMP && !m_conf.ps.depth_fmt) ? region_clamp.w : region_repeat.w;
|
||||
}
|
||||
}
|
||||
else if (trilinear_manual)
|
||||
|
||||
if (trilinear_manual)
|
||||
{
|
||||
// Reuse uv_min_max for mipmap parameter to avoid an extension of the UBO
|
||||
m_conf.cb_ps.MinMax.x = static_cast<float>(m_context->TEX1.K) / 16.0f;
|
||||
m_conf.cb_ps.MinMax.y = static_cast<float>(1 << m_context->TEX1.L);
|
||||
m_conf.cb_ps.MinMax.z = static_cast<float>(m_lod.x); // Offset because first layer is m_lod, dunno if we can do better
|
||||
m_conf.cb_ps.MinMax.w = static_cast<float>(m_lod.y);
|
||||
m_conf.cb_ps.LODParams.x = static_cast<float>(m_context->TEX1.K) / 16.0f;
|
||||
m_conf.cb_ps.LODParams.y = static_cast<float>(1 << m_context->TEX1.L);
|
||||
m_conf.cb_ps.LODParams.z = static_cast<float>(m_lod.x); // Offset because first layer is m_lod, dunno if we can do better
|
||||
m_conf.cb_ps.LODParams.w = static_cast<float>(m_lod.y);
|
||||
m_conf.ps.manual_lod = 1;
|
||||
}
|
||||
else if (trilinear_auto)
|
||||
{
|
||||
tex->m_texture->GenerateMipmapsIfNeeded();
|
||||
m_conf.ps.automatic_lod = 1;
|
||||
}
|
||||
|
||||
// TC Offset Hack
|
||||
|
@ -5063,7 +5068,11 @@ __ri void GSRendererHW::EmulateTextureSampler(const GSTextureCache::Target* rt,
|
|||
{
|
||||
m_conf.sampler.biln = 0;
|
||||
m_conf.sampler.aniso = 0;
|
||||
m_conf.sampler.triln = 0;
|
||||
|
||||
// Remove linear from trilinear, since we're doing the bilinear in the shader, and we only want this for mip selection.
|
||||
m_conf.sampler.triln = (trilinear >= static_cast<u8>(GS_MIN_FILTER::Linear_Mipmap_Nearest)) ?
|
||||
(trilinear - static_cast<u8>(GS_MIN_FILTER::Nearest_Mipmap_Nearest)) :
|
||||
0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5073,15 +5082,9 @@ __ri void GSRendererHW::EmulateTextureSampler(const GSTextureCache::Target* rt,
|
|||
const bool anisotropic = m_vt.m_primclass == GS_TRIANGLE_CLASS && !trilinear_manual;
|
||||
m_conf.sampler.aniso = anisotropic;
|
||||
m_conf.sampler.triln = trilinear;
|
||||
if (trilinear_manual)
|
||||
{
|
||||
m_conf.ps.manual_lod = 1;
|
||||
}
|
||||
else if (trilinear_auto || anisotropic)
|
||||
{
|
||||
if (anisotropic && !trilinear_manual)
|
||||
m_conf.ps.automatic_lod = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// clamp to base level if we're not providing or generating mipmaps
|
||||
// manual trilinear causes the chain to be uploaded, auto causes it to be generated
|
||||
|
|
|
@ -111,6 +111,7 @@ struct GSMTLMainPSUniform
|
|||
vector_float4 uv_min_max;
|
||||
vector_uint4 uv_msk_fix;
|
||||
};
|
||||
vector_float4 lod_params;
|
||||
vector_float4 st_range;
|
||||
struct
|
||||
{
|
||||
|
|
|
@ -356,10 +356,10 @@ struct PSMain
|
|||
}
|
||||
else if (PS_MANUAL_LOD)
|
||||
{
|
||||
float K = cb.uv_min_max.x;
|
||||
float L = cb.uv_min_max.y;
|
||||
float bias = cb.uv_min_max.z;
|
||||
float max_lod = cb.uv_min_max.w;
|
||||
float K = cb.lod_params.x;
|
||||
float L = cb.lod_params.y;
|
||||
float bias = cb.lod_params.z;
|
||||
float max_lod = cb.lod_params.w;
|
||||
|
||||
float gs_lod = K - log2(abs(in.t.w)) * L;
|
||||
// FIXME max useful ?
|
||||
|
|
|
@ -3,4 +3,4 @@
|
|||
|
||||
/// Version number for GS and other shaders. Increment whenever any of the contents of the
|
||||
/// shaders change, to invalidate the cache.
|
||||
static constexpr u32 SHADER_CACHE_VERSION = 50;
|
||||
static constexpr u32 SHADER_CACHE_VERSION = 51;
|
||||
|
|
Loading…
Reference in New Issue