// At least #version 420. #if XE_GUEST_OUTPUT_DITHER #include "dither_8bpc.xesli" #endif // XE_GUEST_OUTPUT_DITHER layout(push_constant) uniform XeCasResampleConstants { // 16 occupied by the vertex shader. layout(offset = 16) ivec2 xe_cas_output_offset; // CasSetup const0.xy. layout(offset = 24) vec2 xe_cas_input_output_size_ratio; // CasSetup const1.x. layout(offset = 32) float xe_cas_sharpness_post_setup; }; layout(set = 0, binding = 0) uniform sampler2D xe_texture; layout(location = 0) out vec4 xe_frag_color; #define A_GPU 1 #define A_GLSL 1 #include "../../../../third_party/FidelityFX-CAS/ffx-cas/ffx_a.h" vec3 CasLoad(ivec2 p) { return texelFetch(xe_texture, p, 0).rgb; } void CasInput(inout float r, inout float g, inout float b) { // Linear conversion approximation as recommended in the CAS presentation. r *= r; g *= g; b *= b; } #include "../../../../third_party/FidelityFX-CAS/ffx-cas/ffx_cas.h" void main() { uvec2 pixel_coord = uvec2(ivec2(gl_FragCoord.xy) - xe_cas_output_offset); // CasSetup with smaller push constant usage. uvec4 cas_const_0 = uvec4(floatBitsToUint(xe_cas_input_output_size_ratio), floatBitsToUint(0.5 * xe_cas_input_output_size_ratio - 0.5)); uvec4 cas_const_1 = uvec4(floatBitsToUint(xe_cas_sharpness_post_setup), packHalf2x16(vec2(xe_cas_sharpness_post_setup, 0.0)), floatBitsToUint(8.0 * xe_cas_input_output_size_ratio.x), 0u); CasFilter(xe_frag_color.r, xe_frag_color.g, xe_frag_color.b, pixel_coord, cas_const_0, cas_const_1, false); // Linear conversion approximation as recommended in the CAS presentation. xe_frag_color.rgb = sqrt(xe_frag_color.rgb); #if XE_GUEST_OUTPUT_DITHER // Clamping because on Vulkan, the surface may specify any format, including // floating-point. xe_frag_color.rgb = clamp(xe_frag_color.rgb + XeDitherOffset8bpc(pixel_coord), vec3(0.0, 0.0, 0.0), vec3(1.0, 1.0, 1.0)); #endif // XE_GUEST_OUTPUT_DITHER // Force alpha to 1 to make sure the surface won't be translucent. xe_frag_color.a = 1.0; }