/** ****************************************************************************** * Xenia : Xbox 360 Emulator Research Project * ****************************************************************************** * Copyright 2022 Ben Vanik. All rights reserved. * * Released under the BSD license - see LICENSE in the root for more details. * ****************************************************************************** */ #include "xesl.xesli" #include "amd_language.xesli" #if XE_GUEST_OUTPUT_DITHER #include "dither_8bpc.xesli" #endif // XE_GUEST_OUTPUT_DITHER xesl_pushConstants_begin(b0, space0) // 16 used by the vertex shader (GLSL push constant offsets are across // stages). xesl_block_offset_member(16, c0.x, xesl_int2, xe_cas_output_offset) // CasSetup const1.x. xesl_block_offset_member(24, c0.z, float, xe_cas_sharpness_post_setup) xesl_pushConstants_end // FIXME(Triang3l): This approach doesn't work for MSL - the texture must be // passed explicitly from the entry point's arguments to CasLoad. // Forward declaration because CasLoad needs xe_cas_source from the entry point // bindings. void CasFilter(xesl_function_param_out(float, pixel_r), xesl_function_param_out(float, pixel_g), xesl_function_param_out(float, pixel_b), xesl_uint2 pixel_position, xesl_uint4 const0, xesl_uint4 const1, bool no_scaling); xesl_entry_outputs_begin xesl_entry_output_target(xesl_float4, xe_cas_color, 0) xesl_entry_outputs_end_stageInputs_begin xesl_entry_stageInputs_end_bindings_begin_pixel xesl_pushConstants_binding(buffer(0)) xesl_entry_binding_next xesl_texture(xesl_texture2D, xe_cas_source, set=0, binding=0, t0, space0, texture(0)) xesl_entry_bindings_end_inputs_begin xesl_entry_input_fragCoord xesl_entry_inputs_end_code_begin xesl_uint2 pixel_coord = xesl_uint2(xesl_int2(xesl_FragCoord.xy) - xesl_pushConstant(xe_cas_output_offset)); // CasSetup with smaller push constants usage. xesl_uint4 cas_const_0 = xesl_floatBitsToUint(xesl_float4(1.0, 1.0, 0.0, 0.0)); xesl_uint4 cas_const_1 = xesl_uint4( xesl_floatBitsToUint(xesl_pushConstant(xe_cas_sharpness_post_setup)), xesl_packHalf2x16(xesl_float2( xesl_pushConstant(xe_cas_sharpness_post_setup), 0.0)), xesl_floatBitsToUint(8.0), 0u); xesl_float4 cas_color; CasFilter(cas_color.r, cas_color.g, cas_color.b, pixel_coord, cas_const_0, cas_const_1, true); // Linear conversion approximation as recommended in the CAS presentation. cas_color.rgb = sqrt(cas_color.rgb); #if XE_GUEST_OUTPUT_DITHER // Clamping because on Vulkan, the surface may specify any format, including // floating-point. cas_color.rgb = xesl_saturate(cas_color.rgb + XeDitherOffset8bpc(pixel_coord)); #endif // XE_GUEST_OUTPUT_DITHER // Force alpha to 1 to make sure the surface won't be translucent. cas_color.a = 1.0; xesl_Output(xe_cas_color) = cas_color; xesl_entry_code_end #define A_GPU 1 #include "../../../../third_party/FidelityFX-CAS/ffx-cas/ffx_a.h" xesl_float3 CasLoad(xesl_int2 p) { return xesl_texelFetch2D(xe_cas_source, p, 0).rgb; } void CasInput(xesl_function_param_inout(float, r), xesl_function_param_inout(float, g), xesl_function_param_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"