GS/HW: Adjust point sampler behavior.

VK/GL/Metal: Get rid of it completely as it doesn't seem needed anymore.
DX: Only enable it with combination with GPU Palette Conversion enabled as that's when the issue occurs.

Test: See if Metal breaks with no point sampler.

2
This commit is contained in:
lightningterror 2024-07-08 21:29:22 +02:00
parent 294bb4d4f2
commit 75defbeded
9 changed files with 11 additions and 44 deletions

View File

@ -132,15 +132,6 @@ vec4 sample_c(vec2 uv)
return texelFetch(TextureSampler, ivec2(uv), 0); return texelFetch(TextureSampler, ivec2(uv), 0);
#else #else
#if PS_POINT_SAMPLER
// Weird issue with ATI/AMD cards,
// it looks like they add 127/128 of a texel to sampling coordinates
// occasionally causing point sampling to erroneously round up.
// I'm manually adjusting coordinates to the centre of texels here,
// though the centre is just paranoia, the top left corner works fine.
// As of 2018 this issue is still present.
uv = (trunc(uv * WH.zw) + vec2(0.5, 0.5)) / WH.zw;
#endif
#if !PS_ADJS && !PS_ADJT #if !PS_ADJS && !PS_ADJT
uv *= STScale; uv *= STScale;
#else #else

View File

@ -268,7 +268,6 @@ void main()
#define PS_FBMASK 0 #define PS_FBMASK 0
#define PS_LTF 1 #define PS_LTF 1
#define PS_TCOFFSETHACK 0 #define PS_TCOFFSETHACK 0
#define PS_POINT_SAMPLER 0
#define PS_SHUFFLE 0 #define PS_SHUFFLE 0
#define PS_SHUFFLE_SAME 0 #define PS_SHUFFLE_SAME 0
#define PS_PROCESS_BA 0 #define PS_PROCESS_BA 0
@ -372,15 +371,7 @@ vec4 sample_c(vec2 uv)
#elif PS_REGION_RECT #elif PS_REGION_RECT
return texelFetch(Texture, ivec2(uv), 0); return texelFetch(Texture, ivec2(uv), 0);
#else #else
#if PS_POINT_SAMPLER
// Weird issue with ATI/AMD cards,
// it looks like they add 127/128 of a texel to sampling coordinates
// occasionally causing point sampling to erroneously round up.
// I'm manually adjusting coordinates to the centre of texels here,
// though the centre is just paranoia, the top left corner works fine.
// As of 2018 this issue is still present.
uv = (trunc(uv * WH.zw) + vec2(0.5, 0.5)) / WH.zw;
#endif
#if !PS_ADJS && !PS_ADJT #if !PS_ADJS && !PS_ADJT
uv *= STScale; uv *= STScale;
#else #else

View File

@ -5010,7 +5010,7 @@ __ri void GSRendererHW::EmulateTextureSampler(const GSTextureCache::Target* rt,
m_conf.ps.tcc = m_cached_ctx.TEX0.TCC; m_conf.ps.tcc = m_cached_ctx.TEX0.TCC;
m_conf.ps.ltf = bilinear && shader_emulated_sampler; m_conf.ps.ltf = bilinear && shader_emulated_sampler;
m_conf.ps.point_sampler = g_gs_device->Features().broken_point_sampler && !target_region && (!bilinear || shader_emulated_sampler); m_conf.ps.point_sampler = g_gs_device->Features().broken_point_sampler && GSConfig.GPUPaletteConversion && !target_region && (!bilinear || shader_emulated_sampler);
const int tw = static_cast<int>(1 << m_cached_ctx.TEX0.TW); const int tw = static_cast<int>(1 << m_cached_ctx.TEX0.TW);
const int th = static_cast<int>(1 << m_cached_ctx.TEX0.TH); const int th = static_cast<int>(1 << m_cached_ctx.TEX0.TH);

View File

@ -904,7 +904,7 @@ bool GSDeviceMTL::Create(GSVSyncMode vsync_mode, bool allow_present_throttle)
MTLPixelFormat layer_px_fmt = [m_layer pixelFormat]; MTLPixelFormat layer_px_fmt = [m_layer pixelFormat];
m_features.broken_point_sampler = [[m_dev.dev name] containsString:@"AMD"]; m_features.broken_point_sampler = false;
m_features.vs_expand = !GSConfig.DisableVertexShaderExpand; m_features.vs_expand = !GSConfig.DisableVertexShaderExpand;
m_features.primitive_id = m_dev.features.primid; m_features.primitive_id = m_dev.features.primid;
m_features.texture_barrier = true; m_features.texture_barrier = true;
@ -1861,7 +1861,6 @@ void GSDeviceMTL::MRESetHWPipelineState(GSHWDrawConfig::VSSelector vssel, GSHWDr
setFnConstantB(m_fn_constants, pssel.tex_is_fb, GSMTLConstantIndex_PS_TEX_IS_FB); setFnConstantB(m_fn_constants, pssel.tex_is_fb, GSMTLConstantIndex_PS_TEX_IS_FB);
setFnConstantB(m_fn_constants, pssel.automatic_lod, GSMTLConstantIndex_PS_AUTOMATIC_LOD); setFnConstantB(m_fn_constants, pssel.automatic_lod, GSMTLConstantIndex_PS_AUTOMATIC_LOD);
setFnConstantB(m_fn_constants, pssel.manual_lod, GSMTLConstantIndex_PS_MANUAL_LOD); setFnConstantB(m_fn_constants, pssel.manual_lod, GSMTLConstantIndex_PS_MANUAL_LOD);
setFnConstantB(m_fn_constants, pssel.point_sampler, GSMTLConstantIndex_PS_POINT_SAMPLER);
setFnConstantB(m_fn_constants, pssel.region_rect, GSMTLConstantIndex_PS_REGION_RECT); setFnConstantB(m_fn_constants, pssel.region_rect, GSMTLConstantIndex_PS_REGION_RECT);
setFnConstantI(m_fn_constants, pssel.scanmsk, GSMTLConstantIndex_PS_SCANMSK); setFnConstantI(m_fn_constants, pssel.scanmsk, GSMTLConstantIndex_PS_SCANMSK);
auto newps = LoadShader(@"ps_main"); auto newps = LoadShader(@"ps_main");

View File

@ -212,7 +212,6 @@ enum GSMTLFnConstants
GSMTLConstantIndex_PS_TEX_IS_FB, GSMTLConstantIndex_PS_TEX_IS_FB,
GSMTLConstantIndex_PS_AUTOMATIC_LOD, GSMTLConstantIndex_PS_AUTOMATIC_LOD,
GSMTLConstantIndex_PS_MANUAL_LOD, GSMTLConstantIndex_PS_MANUAL_LOD,
GSMTLConstantIndex_PS_POINT_SAMPLER,
GSMTLConstantIndex_PS_REGION_RECT, GSMTLConstantIndex_PS_REGION_RECT,
GSMTLConstantIndex_PS_SCANMSK, GSMTLConstantIndex_PS_SCANMSK,
}; };

View File

@ -67,7 +67,6 @@ constant bool PS_TALES_OF_ABYSS_HLE [[function_constant(GSMTLConstantIndex_PS_TA
constant bool PS_TEX_IS_FB [[function_constant(GSMTLConstantIndex_PS_TEX_IS_FB)]]; constant bool PS_TEX_IS_FB [[function_constant(GSMTLConstantIndex_PS_TEX_IS_FB)]];
constant bool PS_AUTOMATIC_LOD [[function_constant(GSMTLConstantIndex_PS_AUTOMATIC_LOD)]]; constant bool PS_AUTOMATIC_LOD [[function_constant(GSMTLConstantIndex_PS_AUTOMATIC_LOD)]];
constant bool PS_MANUAL_LOD [[function_constant(GSMTLConstantIndex_PS_MANUAL_LOD)]]; constant bool PS_MANUAL_LOD [[function_constant(GSMTLConstantIndex_PS_MANUAL_LOD)]];
constant bool PS_POINT_SAMPLER [[function_constant(GSMTLConstantIndex_PS_POINT_SAMPLER)]];
constant bool PS_REGION_RECT [[function_constant(GSMTLConstantIndex_PS_REGION_RECT)]]; constant bool PS_REGION_RECT [[function_constant(GSMTLConstantIndex_PS_REGION_RECT)]];
constant uint PS_SCANMSK [[function_constant(GSMTLConstantIndex_PS_SCANMSK)]]; constant uint PS_SCANMSK [[function_constant(GSMTLConstantIndex_PS_SCANMSK)]];
@ -324,16 +323,6 @@ struct PSMain
if (PS_REGION_RECT) if (PS_REGION_RECT)
return read_tex(uint2(uv)); return read_tex(uint2(uv));
if (PS_POINT_SAMPLER)
{
// Weird issue with ATI/AMD cards,
// it looks like they add 127/128 of a texel to sampling coordinates
// occasionally causing point sampling to erroneously round up.
// I'm manually adjusting coordinates to the centre of texels here,
// though the centre is just paranoia, the top left corner works fine.
// As of 2018 this issue is still present.
uv = (trunc(uv * cb.wh.zw) + 0.5) / cb.wh.zw;
}
if (!PS_ADJS && !PS_ADJT) if (!PS_ADJS && !PS_ADJT)
{ {
uv *= cb.st_scale; uv *= cb.st_scale;

View File

@ -606,7 +606,7 @@ bool GSDeviceOGL::CreateTextureFX()
bool GSDeviceOGL::CheckFeatures(bool& buggy_pbo) bool GSDeviceOGL::CheckFeatures(bool& buggy_pbo)
{ {
bool vendor_id_amd = false; //bool vendor_id_amd = false;
bool vendor_id_nvidia = false; bool vendor_id_nvidia = false;
//bool vendor_id_intel = false; //bool vendor_id_intel = false;
@ -615,7 +615,7 @@ bool GSDeviceOGL::CheckFeatures(bool& buggy_pbo)
std::strstr(vendor, "ATI")) std::strstr(vendor, "ATI"))
{ {
Console.WriteLn(Color_StrongRed, "OGL: AMD GPU detected."); Console.WriteLn(Color_StrongRed, "OGL: AMD GPU detected.");
vendor_id_amd = true; //vendor_id_amd = true;
} }
else if (std::strstr(vendor, "NVIDIA Corporation")) else if (std::strstr(vendor, "NVIDIA Corporation"))
{ {
@ -712,7 +712,7 @@ bool GSDeviceOGL::CheckFeatures(bool& buggy_pbo)
Console.Warning("Not using PBOs for texture downloads, this may reduce performance."); Console.Warning("Not using PBOs for texture downloads, this may reduce performance.");
// optional features based on context // optional features based on context
m_features.broken_point_sampler = vendor_id_amd; m_features.broken_point_sampler = false;
m_features.primitive_id = true; m_features.primitive_id = true;
m_features.framebuffer_fetch = GLAD_GL_EXT_shader_framebuffer_fetch; m_features.framebuffer_fetch = GLAD_GL_EXT_shader_framebuffer_fetch;
@ -1377,7 +1377,6 @@ std::string GSDeviceOGL::GetPSSource(const PSSelector& sel)
+ fmt::format("#define PS_COLCLIP {}\n", sel.colclip) + fmt::format("#define PS_COLCLIP {}\n", sel.colclip)
+ fmt::format("#define PS_DATE {}\n", sel.date) + fmt::format("#define PS_DATE {}\n", sel.date)
+ fmt::format("#define PS_TCOFFSETHACK {}\n", sel.tcoffsethack) + fmt::format("#define PS_TCOFFSETHACK {}\n", sel.tcoffsethack)
+ fmt::format("#define PS_POINT_SAMPLER {}\n", sel.point_sampler)
+ fmt::format("#define PS_REGION_RECT {}\n", sel.region_rect) + fmt::format("#define PS_REGION_RECT {}\n", sel.region_rect)
+ fmt::format("#define PS_BLEND_A {}\n", sel.blend_a) + fmt::format("#define PS_BLEND_A {}\n", sel.blend_a)
+ fmt::format("#define PS_BLEND_B {}\n", sel.blend_b) + fmt::format("#define PS_BLEND_B {}\n", sel.blend_b)

View File

@ -2568,14 +2568,14 @@ bool GSDeviceVK::CreateDeviceAndSwapChain()
bool GSDeviceVK::CheckFeatures() bool GSDeviceVK::CheckFeatures()
{ {
const VkPhysicalDeviceLimits& limits = m_device_properties.limits; const VkPhysicalDeviceLimits& limits = m_device_properties.limits;
const u32 vendorID = m_device_properties.vendorID; //const u32 vendorID = m_device_properties.vendorID;
const bool isAMD = (vendorID == 0x1002 || vendorID == 0x1022); //const bool isAMD = (vendorID == 0x1002 || vendorID == 0x1022);
// const bool isNVIDIA = (vendorID == 0x10DE); //const bool isNVIDIA = (vendorID == 0x10DE);
m_features.framebuffer_fetch = m_features.framebuffer_fetch =
m_optional_extensions.vk_ext_rasterization_order_attachment_access && !GSConfig.DisableFramebufferFetch; m_optional_extensions.vk_ext_rasterization_order_attachment_access && !GSConfig.DisableFramebufferFetch;
m_features.texture_barrier = GSConfig.OverrideTextureBarriers != 0; m_features.texture_barrier = GSConfig.OverrideTextureBarriers != 0;
m_features.broken_point_sampler = isAMD; m_features.broken_point_sampler = false;
// geometryShader is needed because gl_PrimitiveID is part of the Geometry SPIR-V Execution Model. // geometryShader is needed because gl_PrimitiveID is part of the Geometry SPIR-V Execution Model.
m_features.primitive_id = m_device_features.geometryShader; m_features.primitive_id = m_device_features.geometryShader;
@ -4722,7 +4722,6 @@ VkShaderModule GSDeviceVK::GetTFXFragmentShader(const GSHWDrawConfig::PSSelector
AddMacro(ss, "PS_COLCLIP", sel.colclip); AddMacro(ss, "PS_COLCLIP", sel.colclip);
AddMacro(ss, "PS_DATE", sel.date); AddMacro(ss, "PS_DATE", sel.date);
AddMacro(ss, "PS_TCOFFSETHACK", sel.tcoffsethack); AddMacro(ss, "PS_TCOFFSETHACK", sel.tcoffsethack);
AddMacro(ss, "PS_POINT_SAMPLER", sel.point_sampler);
AddMacro(ss, "PS_REGION_RECT", sel.region_rect); AddMacro(ss, "PS_REGION_RECT", sel.region_rect);
AddMacro(ss, "PS_BLEND_A", sel.blend_a); AddMacro(ss, "PS_BLEND_A", sel.blend_a);
AddMacro(ss, "PS_BLEND_B", sel.blend_b); AddMacro(ss, "PS_BLEND_B", sel.blend_b);

View File

@ -3,4 +3,4 @@
/// Version number for GS and other shaders. Increment whenever any of the contents of the /// Version number for GS and other shaders. Increment whenever any of the contents of the
/// shaders change, to invalidate the cache. /// shaders change, to invalidate the cache.
static constexpr u32 SHADER_CACHE_VERSION = 52; static constexpr u32 SHADER_CACHE_VERSION = 53;