From c6add663f84b368a8d8331c8340977ce072e0bfc Mon Sep 17 00:00:00 2001 From: TellowKrinkle Date: Sat, 15 Oct 2022 02:06:14 -0500 Subject: [PATCH] GS:HW: Clean up ps_convert_rgba_8i --- bin/resources/shaders/dx11/convert.fx | 84 ++++--------------- bin/resources/shaders/opengl/convert.glsl | 75 ++++------------- bin/resources/shaders/vulkan/convert.glsl | 87 +++++--------------- pcsx2/GS/Renderers/Metal/GSMTLShaderCommon.h | 4 + pcsx2/GS/Renderers/Metal/convert.metal | 77 ++++------------- 5 files changed, 75 insertions(+), 252 deletions(-) diff --git a/bin/resources/shaders/dx11/convert.fx b/bin/resources/shaders/dx11/convert.fx index 09d58ed4ce..80274f98c1 100644 --- a/bin/resources/shaders/dx11/convert.fx +++ b/bin/resources/shaders/dx11/convert.fx @@ -279,82 +279,32 @@ PS_OUTPUT ps_convert_rgba_8i(PS_INPUT input) // 1: 8 R | 8 B // 2: 8 G | 8 A // 3: 8 G | 8 A - float c; + uint2 pos = uint2(input.p.xy); - uint2 sel = uint2(input.p.xy) % uint2(16u, 16u); - int2 tb = ((int2(input.p.xy) & ~int2(15, 3)) >> 1); + // Collapse separate R G B A areas into their base pixel + uint2 block = (pos & ~uint2(15u, 3u)) >> 1; + uint2 subblock = pos & uint2(7u, 1u); + uint2 coord = block | subblock; - int ty = tb.y | (int(input.p.y) & 1); - int txN = tb.x | (int(input.p.x) & 7); - int txH = tb.x | ((int(input.p.x) + 4) & 7); + // Apply offset to cols 1 and 2 + uint is_col23 = pos.y & 4u; + uint is_col13 = pos.y & 2u; + uint is_col12 = is_col23 ^ (is_col13 << 1); + coord.x ^= is_col12; // If cols 1 or 2, flip bit 3 of x if (floor(PS_SCALE_FACTOR) != PS_SCALE_FACTOR) - { - txN = (int)((float)txN * PS_SCALE_FACTOR); - txH = (int)((float)txH * PS_SCALE_FACTOR); - ty = (int)((float)ty * PS_SCALE_FACTOR); - } + coord = uint2(float2(coord) * PS_SCALE_FACTOR); else - { - txN *= PS_SCALE_FACTOR; - txH *= PS_SCALE_FACTOR; - ty *= PS_SCALE_FACTOR; - } + coord *= PS_SCALE_FACTOR; - // TODO investigate texture gather - float4 cN = Texture.Load(int3(txN, ty, 0)); - float4 cH = Texture.Load(int3(txH, ty, 0)); - - - if ((sel.y & 4u) == 0u) - { + float4 pixel = Texture.Load(int3(int2(coord), 0)); #ifdef ONLY_BLUE - c = cN.b; + output.c = (float4)(pixel.b); // Divide by something here? #else - // Column 0 and 2 - if ((sel.y & 3u) < 2u) - { - // First 2 lines of the col - if (sel.x < 8u) - c = cN.r; - else - c = cN.b; - } - else - { - if (sel.x < 8u) - c = cH.g; - else - c = cH.a; - } + float2 sel0 = (pos.y & 2u) == 0u ? pixel.rb : pixel.ga; + float sel1 = (pos.x & 8u) == 0u ? sel0.x : sel0.y; + output.c = (float4)(sel1); // Divide by something here? #endif - } - else - { -#ifdef ONLY_BLUE - c = cH.b; -#else - // Column 1 and 3 - if ((sel.y & 3u) < 2u) - { - // First 2 lines of the col - if (sel.x < 8u) - c = cH.r; - else - c = cH.b; - } - else - { - if (sel.x < 8u) - c = cN.g; - else - c = cN.a; - } -#endif - } - - output.c = (float4)(c); // Divide by something here? - return output; } diff --git a/bin/resources/shaders/opengl/convert.glsl b/bin/resources/shaders/opengl/convert.glsl index 35164856a8..0600b345b1 100644 --- a/bin/resources/shaders/opengl/convert.glsl +++ b/bin/resources/shaders/opengl/convert.glsl @@ -226,73 +226,32 @@ void ps_convert_rgba_8i() // 1: 8 R | 8 B // 2: 8 G | 8 A // 3: 8 G | 8 A - float c; + uvec2 pos = uvec2(gl_FragCoord.xy); - uvec2 sel = uvec2(gl_FragCoord.xy) % uvec2(16u, 16u); - ivec2 tb = ((ivec2(gl_FragCoord.xy) & ~ivec2(15, 3)) >> 1); + // Collapse separate R G B A areas into their base pixel + uvec2 block = (pos & ~uvec2(15u, 3u)) >> 1; + uvec2 subblock = pos & uvec2(7u, 1u); + uvec2 coord = block | subblock; - int ty = tb.y | (int(gl_FragCoord.y) & 1); - int txN = tb.x | (int(gl_FragCoord.x) & 7); - int txH = tb.x | ((int(gl_FragCoord.x) + 4) & 7); + // Apply offset to cols 1 and 2 + uint is_col23 = pos.y & 4u; + uint is_col13 = pos.y & 2u; + uint is_col12 = is_col23 ^ (is_col13 << 1); + coord.x ^= is_col12; // If cols 1 or 2, flip bit 3 of x if (floor(PS_SCALE_FACTOR) != PS_SCALE_FACTOR) - { - txN = int(float(txN) * PS_SCALE_FACTOR); - txH = int(float(txH) * PS_SCALE_FACTOR); - ty = int(float(ty) * PS_SCALE_FACTOR); - } + coord = uvec2(vec2(coord) * PS_SCALE_FACTOR); else - { - txN *= int(PS_SCALE_FACTOR); - txH *= int(PS_SCALE_FACTOR); - ty *= int(PS_SCALE_FACTOR); - } + coord *= PS_SCALE_FACTOR; - // TODO investigate texture gather - vec4 cN = texelFetch(TextureSampler, ivec2(txN, ty), 0); - vec4 cH = texelFetch(TextureSampler, ivec2(txH, ty), 0); - - - if ((sel.y & 4u) == 0u) { - // Column 0 and 2 + vec4 pixel = texelFetch(TextureSampler, ivec2(coord), 0); #ifdef ONLY_BLUE - c = cN.b; + SV_Target0 = vec4(pixel.b); #else - if ((sel.y & 3u) < 2u) { - // first 2 lines of the col - if (sel.x < 8u) - c = cN.r; - else - c = cN.b; - } else { - if (sel.x < 8u) - c = cH.g; - else - c = cH.a; - } + vec2 sel0 = (pos.y & 2u) == 0u ? pixel.rb : pixel.ga; + float sel1 = (pos.x & 8u) == 0u ? sel0.x : sel0.y; + SV_Target0 = vec4(sel1); #endif - } else { -#ifdef ONLY_BLUE - c = cH.b; -#else - // Column 1 and 3 - if ((sel.y & 3u) < 2u) { - // first 2 lines of the col - if (sel.x < 8u) - c = cH.r; - else - c = cH.b; - } else { - if (sel.x < 8u) - c = cN.g; - else - c = cN.a; - } -#endif - } - - - SV_Target0 = vec4(c); } #endif diff --git a/bin/resources/shaders/vulkan/convert.glsl b/bin/resources/shaders/vulkan/convert.glsl index 485d778b6e..f8c8e04a6f 100644 --- a/bin/resources/shaders/vulkan/convert.glsl +++ b/bin/resources/shaders/vulkan/convert.glsl @@ -260,81 +260,32 @@ void ps_convert_rgba_8i() // 1: 8 R | 8 B // 2: 8 G | 8 A // 3: 8 G | 8 A - float c; + uvec2 pos = uvec2(gl_FragCoord.xy); - uvec2 sel = uvec2(gl_FragCoord.xy) % uvec2(16u, 16u); - ivec2 tb = ((ivec2(gl_FragCoord.xy) & ~ivec2(15, 3)) >> 1); + // Collapse separate R G B A areas into their base pixel + uvec2 block = (pos & ~uvec2(15u, 3u)) >> 1; + uvec2 subblock = pos & uvec2(7u, 1u); + uvec2 coord = block | subblock; - int ty = tb.y | (int(gl_FragCoord.y) & 1); - int txN = tb.x | (int(gl_FragCoord.x) & 7); - int txH = tb.x | ((int(gl_FragCoord.x) + 4) & 7); + // Apply offset to cols 1 and 2 + uint is_col23 = pos.y & 4u; + uint is_col13 = pos.y & 2u; + uint is_col12 = is_col23 ^ (is_col13 << 1); + coord.x ^= is_col12; // If cols 1 or 2, flip bit 3 of x - if (floor(PS_SCALE_FACTOR) != PS_SCALE_FACTOR) - { - txN = int(float(txN) * PS_SCALE_FACTOR); - txH = int(float(txH) * PS_SCALE_FACTOR); - ty = int(float(ty) * PS_SCALE_FACTOR); - } - else - { - txN *= int(PS_SCALE_FACTOR); - txH *= int(PS_SCALE_FACTOR); - ty *= int(PS_SCALE_FACTOR); - } + if (floor(PS_SCALE_FACTOR) != PS_SCALE_FACTOR) + coord = uvec2(vec2(coord) * PS_SCALE_FACTOR); + else + coord *= PS_SCALE_FACTOR; - // TODO investigate texture gather - vec4 cN = texelFetch(samp0, ivec2(txN, ty), 0); - vec4 cH = texelFetch(samp0, ivec2(txH, ty), 0); - - - if ((sel.y & 4u) == 0u) - { + vec4 pixel = texelFetch(samp0, ivec2(coord), 0); #ifdef ONLY_BLUE - c = cN.b; + o_col0 = vec4(pixel.b); // Divide by something here? #else - // Column 0 and 2 - if ((sel.y & 3u) < 2u) - { - // First 2 lines of the col - if (sel.x < 8u) - c = cN.r; - else - c = cN.b; - } - else - { - if (sel.x < 8u) - c = cH.g; - else - c = cH.a; - } + vec2 sel0 = (pos.y & 2u) == 0u ? pixel.rb : pixel.ga; + float sel1 = (pos.x & 8u) == 0u ? sel0.x : sel0.y; + o_col0 = vec4(sel1); // Divide by something here? #endif - } - else - { -#ifdef ONLY_BLUE - c = cH.b; -#else - // Column 1 and 3 - if ((sel.y & 3u) < 2u) - { - // First 2 lines of the col - if (sel.x < 8u) - c = cH.r; - else - c = cH.b; - } - else - { - if (sel.x < 8u) - c = cN.g; - else - c = cN.a; - } -#endif - } - - o_col0 = vec4(c); // Divide by something here? } #endif diff --git a/pcsx2/GS/Renderers/Metal/GSMTLShaderCommon.h b/pcsx2/GS/Renderers/Metal/GSMTLShaderCommon.h index 8a7b4fd4a4..f4d89490dd 100644 --- a/pcsx2/GS/Renderers/Metal/GSMTLShaderCommon.h +++ b/pcsx2/GS/Renderers/Metal/GSMTLShaderCommon.h @@ -58,3 +58,7 @@ static inline float4 convert_depth16_rgba8(float value) uint val = uint(value * 0x1p32); return float4(uint4(val << 3, val >> 2, val >> 7, val >> 8) & uint4(0xf8, 0xf8, 0xf8, 0x80)); } + +#ifndef __HAVE_MUL24__ +template T mul24(T a, T b) { return a * b; } +#endif diff --git a/pcsx2/GS/Renderers/Metal/convert.metal b/pcsx2/GS/Renderers/Metal/convert.metal index 3f025d0dfe..a750f8f228 100644 --- a/pcsx2/GS/Renderers/Metal/convert.metal +++ b/pcsx2/GS/Renderers/Metal/convert.metal @@ -247,7 +247,7 @@ fragment DepthOut ps_convert_rgb5a1_float16_biln(ConvertShaderData data [[stage_ return res.sample_biln(data.t); } -fragment float4 ps_convert_rgba_8i(ConvertShaderData data [[stage_in]], ConvertPSRes res, +fragment float4 ps_convert_rgba_8i(ConvertShaderData data [[stage_in]], DirectReadTextureIn res, constant GSMTLConvertPSUniform& uniform [[buffer(GSMTLBufferIndexUniforms)]]) { // Convert a RGBA texture into a 8 bits packed texture @@ -259,69 +259,28 @@ fragment float4 ps_convert_rgba_8i(ConvertShaderData data [[stage_in]], ConvertP // 1: 8 R | 8 B // 2: 8 G | 8 A // 3: 8 G | 8 A - float c; + uint2 pos = uint2(data.p.xy); - uint2 sel = uint2(data.p.xy) % uint2(16, 16); - uint2 tb = (uint2(data.p.xy) & ~uint2(15, 3)) >> 1; + // Collapse separate R G B A areas into their base pixel + uint2 block = (pos & ~uint2(15, 3)) >> 1; + uint2 subblock = pos & uint2(7, 1); + uint2 coord = block | subblock; - uint ty = tb.y | (uint(data.p.y) & 1); - uint txN = tb.x | (uint(data.p.x) & 7); - uint txH = tb.x | ((uint(data.p.x) + 4) & 7); + // Apply offset to cols 1 and 2 + uint is_col23 = pos.y & 4; + uint is_col13 = pos.y & 2; + uint is_col12 = is_col23 ^ (is_col13 << 1); + coord.x ^= is_col12; // If cols 1 or 2, flip bit 3 of x - if (floor(SCALING_FACTOR.x) != SCALING_FACTOR.x) - { - txN = (int)((float)txN * SCALING_FACTOR.x); - txH = (int)((float)txH * SCALING_FACTOR.x); - ty = (int)((float)ty * SCALING_FACTOR.y); - } + if (any(floor(SCALING_FACTOR) != SCALING_FACTOR)) + coord = uint2(float2(coord) * SCALING_FACTOR); else - { - txN *= SCALING_FACTOR.x; - txH *= SCALING_FACTOR.x; - ty *= SCALING_FACTOR.y; - } + coord = mul24(coord, uint2(SCALING_FACTOR)); - // TODO investigate texture gather - float4 cN = res.texture.read(uint2(txN, ty)); - float4 cH = res.texture.read(uint2(txH, ty)); - - if ((sel.y & 4) == 0) - { - // Column 0 and 2 - if ((sel.y & 2) == 0) - { - if ((sel.x & 8) == 0) - c = cN.r; - else - c = cN.b; - } - else - { - if ((sel.x & 8) == 0) - c = cH.g; - else - c = cH.a; - } - } - else - { - // Column 1 and 3 - if ((sel.y & 2) == 0) - { - if ((sel.x & 8) == 0) - c = cH.r; - else - c = cH.b; - } - else - { - if ((sel.x & 8) == 0) - c = cN.g; - else - c = cN.a; - } - } - return float4(c); + float4 pixel = res.tex.read(coord); + float2 sel0 = (pos.y & 2) == 0 ? pixel.rb : pixel.ga; + float sel1 = (pos.x & 8) == 0 ? sel0.x : sel0.y; + return float4(sel1); } fragment float4 ps_yuv(ConvertShaderData data [[stage_in]], ConvertPSRes res,