From f3df3a772728e7cc1d1a8ad4cda9b6154e8d1c3c Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Tue, 27 Dec 2022 13:45:13 -0800 Subject: PixelShaderGen: Clamp texture layer when using manual texture sampling with stereoscopic 3D Otherwise, texelFetch() will use an out-of-bounds layer for game textures (that have 1 layer; EFB copies have 2 layers in stereoscopic 3D mode), which is undefined behavior (often resulting in a black image). The fast texture sampling path uses texture(), which always clamps (see https://www.khronos.org/opengl/wiki/Array_Texture#Access_in_shaders), so it was unaffected by this difference. --- Source/Core/VideoCommon/PixelShaderGen.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Source/Core/VideoCommon/PixelShaderGen.cpp') diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp index 3a612382e6..7db650e431 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/PixelShaderGen.cpp @@ -615,6 +615,7 @@ uint WrapCoord(int coord, uint wrap, int size) {{ int3 size = textureSize(tex, 0); int size_s = size.x; int size_t = size.y; + int num_layers = size.z; )"); if (g_ActiveConfig.backend_info.bSupportsTextureQueryLevels) { @@ -633,6 +634,8 @@ uint WrapCoord(int coord, uint wrap, int size) {{ // Rescale uv to account for the new texture size uv.x = (uv.x * size_s) / native_size_s; uv.y = (uv.y * size_t) / native_size_t; + // Clamp layer as well (texture() automatically clamps, but texelFetch() doesn't) + layer = clamp(layer, 0, num_layers - 1); )"); } else -- cgit v1.2.3