glsl: Rewrite MS sampling implementation

This commit is contained in:
kd-11 2022-03-30 22:09:13 +03:00 committed by kd-11
parent a8441b28e8
commit 43b267ea51

View file

@ -918,7 +918,7 @@ namespace glsl
" const uint flags = TEX_FLAGS(index);\n"
" const vec2 normalized_coords = COORD_SCALE2(index, coords);\n"
" const ivec2 sample_count = ivec2(2, textureSamples(tex) / 2);\n"
" const ivec2 image_size = textureSize(tex) * sample_count;"
" const ivec2 image_size = textureSize(tex) * sample_count;\n"
" const ivec2 icoords = ivec2(normalized_coords * image_size);\n"
" const vec4 sample0 = texelFetch2DMS(tex, sample_count, icoords, index, ivec2(0));\n"
"\n"
@ -927,19 +927,61 @@ namespace glsl
" return sample0;\n"
" }\n"
"\n"
" // Bilinear scaling, with upto 2x2 downscaling with simple weights\n"
" const vec2 uv_step = 1.0 / vec2(image_size);\n"
" const vec2 up_factor = normalized_coords - (vec2(icoords) * uv_step);\n"
" // Hacky downscaling for performance reasons. Simple weighted area, upto 2x2 down.\n"
" const vec2 actual_step = vec2(dFdx(normalized_coords.x), dFdy(normalized_coords.y));\n"
" const vec2 down_factor = min(actual_step / uv_step, 1.5) - 1.0;\n"
" const vec2 factor = _select(up_factor, down_factor, greaterThan(actual_step, uv_step));\n"
" // Do linear filter\n"
"\n"
" if (uv_step.x == actual_step.x && uv_step.y == actual_step.y)\n"
" {\n"
" return sample0;\n"
" }\n"
"\n"
" // Fetch remaining samples\n"
" const vec4 sample1 = texelFetch2DMS(tex, sample_count, icoords, index, ivec2(1, 0));\n"
" const vec4 sample2 = texelFetch2DMS(tex, sample_count, icoords, index, ivec2(0, 1));\n"
" const vec4 sample3 = texelFetch2DMS(tex, sample_count, icoords, index, ivec2(1, 1));\n"
" const vec4 a = mix(sample0, sample1, factor.x);\n"
" const vec4 b = mix(sample2, sample3, factor.x);\n"
" return mix(a, b, factor.y);\n"
"\n"
" vec4 a, b;\n"
" float factor;\n"
"\n"
" if (actual_step.x > uv_step.x)\n"
" {\n"
" // Downscale in X\n"
" factor = min(actual_step.x / uv_step.x, 2.0);\n"
" a = fma(sample1, (factor - 1.).xxxx, sample0) / factor;\n"
" b = fma(sample3, (factor - 1.).xxxx, sample2) / factor;\n"
" }\n"
" else if (actual_step.x < uv_step.x)\n"
" {\n"
" // Upscale in X\n"
" factor = frac(normalized_coords.x * image_size.x);\n"
" a = mix(sample0, sample1, factor);\n"
" b = mix(sample2, sample3, factor);\n"
" }\n"
" else\n"
" {\n"
" // No scaling, 1:1\n"
" a = sample0;\n"
" b = sample2;\n"
" }\n"
"\n"
" if (actual_step.y > uv_step.y)\n"
" {\n"
" // Downscale in Y\n"
" factor = min(actual_step.y / uv_step.y, 2.0);\n"
" return fma(b, (factor - 1).xxxx, a) / factor;\n"
" }\n"
" else if (actual_step.y < uv_step.y)\n"
" {\n"
" // Upscale in Y\n"
" factor = frac(normalized_coords.y * image_size.y);\n"
" return mix(a, b, factor);\n"
" }\n"
" else\n"
" {\n"
" // 1:1 no scale\n"
" return a;\n"
" }\n"
"}\n\n";
};