mirror of
https://github.com/sal063/AC6_recomp
synced 2026-08-22 07:04:31 -04:00
23e463737c
The cutscene DoF chain is authored for the 640×360 guest grid; at render scale > 1 its guest-granular blur kernels alias against host-granular content, visible as streaks and ghost outlines. Fix: snap the two CoC pre-blur passes to guest texel centers and densify the two 13-tap gather passes per axis. Hash-allowlisted, behind ac6_fix_dof (on), inert at 1x.
130 lines
8.5 KiB
C++
130 lines
8.5 KiB
C++
/**
|
|
******************************************************************************
|
|
* Xenia : Xbox 360 Emulator Research Project *
|
|
******************************************************************************
|
|
* Copyright 2020 Ben Vanik. All rights reserved. *
|
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
|
******************************************************************************
|
|
*
|
|
* @modified Tom Clay, 2026 - Adapted for ReXGlue runtime
|
|
*/
|
|
|
|
#include <rex/graphics/flags.h>
|
|
#include <rex/logging.h>
|
|
#include <rex/ui/renderdoc_api.h>
|
|
|
|
REXCVAR_DEFINE_BOOL(gpu_allow_invalid_fetch_constants, false, "GPU",
|
|
"Allow invalid fetch constants");
|
|
REXCVAR_DEFINE_BOOL(native_2x_msaa, true, "GPU", "Enable native 2x MSAA");
|
|
REXCVAR_DEFINE_BOOL(depth_float24_round, false, "GPU", "Round float24 depth values");
|
|
REXCVAR_DEFINE_BOOL(depth_float24_convert_in_pixel_shader, false, "GPU",
|
|
"Convert float24 depth in pixel shader");
|
|
REXCVAR_DEFINE_BOOL(depth_transfer_not_equal_test, true, "GPU",
|
|
"Use not-equal test for depth transfer");
|
|
REXCVAR_DEFINE_BOOL(gamma_render_target_as_unorm16, true, "GPU",
|
|
"Use R16G16B16A16_UNORM for gamma render targets (more accurate than sRGB)")
|
|
.lifecycle(rex::cvar::Lifecycle::kHotReload);
|
|
REXCVAR_DEFINE_STRING(dump_shaders, "", "GPU", "Path to dump shaders to");
|
|
REXCVAR_DEFINE_BOOL(use_fuzzy_alpha_epsilon, true, "GPU",
|
|
"Use approximate compare for alpha test values to prevent "
|
|
"flickering on NVIDIA graphics cards");
|
|
REXCVAR_DEFINE_BOOL(vfetch_index_rounding_bias, false, "GPU/Shader",
|
|
"Apply small epsilon bias to vertex fetch indices before "
|
|
"flooring to fix black triangles caused by RCP precision");
|
|
REXCVAR_DEFINE_BOOL(draw_resolution_scaled_texture_offsets, true, "GPU/Shader",
|
|
"Scale texture offsets with draw resolution");
|
|
REXCVAR_DEFINE_BOOL(param_gen_integer_guest_position, false, "GPU/Shader",
|
|
"At >1x draw resolution scale, floor the PsParamGen pixel "
|
|
"position to the integer guest-pixel index instead of keeping "
|
|
"the sub-guest-pixel fraction. Fixes the mosaic in games that "
|
|
"feed the position into their own integer pixel-address math "
|
|
"(e.g. AC6's deferred EDRAM restore/de-swizzle passes), whose "
|
|
"frac()-based bit extraction otherwise sees a doubled period and "
|
|
"scrambles the sample coordinate. Those passes then sample at "
|
|
"guest resolution. Off by default; harmless for shaders that pass "
|
|
"the position straight to tfetch only at 1x.");
|
|
REXCVAR_DEFINE_BOOL(param_gen_host_subpixel_restore, false, "GPU/Shader",
|
|
"Builds on param_gen_integer_guest_position (and implies it): for "
|
|
"resolution-scaled, position-derived 2D samples in pixel shaders "
|
|
"that use PsParamGen, re-adds the host sub-pixel offset to the "
|
|
"sample coordinate so the de-swizzle restore passes sample at full "
|
|
"host resolution instead of the guest-texel center. Turns the "
|
|
"mosaic fix from clean-but-soft into true resolution-scaled detail. "
|
|
"Off by default; may need per-shader scoping if it disturbs other "
|
|
"passes that read scaled render targets via interpolated coords.");
|
|
REXCVAR_DEFINE_STRING(ac6_neutralize_deswizzle_hashes, "", "GPU/Shader",
|
|
"AC6: comma/space-separated tokens \"<hash>[:<slot>[+<slot>...]]\" "
|
|
"naming guest pixel-shader ucode hashes (hex) whose param_gen 2D "
|
|
"texture samples manually de-swizzle the raw EDRAM sub-tile order of "
|
|
"their source. The emulator's texture cache detiles everything to "
|
|
"linear, so that de-swizzle is always a wrong texel permutation here "
|
|
"(the mosaic/streak class). For a matching fetch the sample "
|
|
"coordinate is replaced unconditionally with the identity host-texel "
|
|
"UV (SV_Position.xy / (guest_size * scale)) -- a 1:1 copy. A bare "
|
|
"hash overrides ALL of that shader's fetches; \":4\" limits it to "
|
|
"Xenos tfetch slot 4 (needed when only some fetches de-swizzle, e.g. "
|
|
"the AC6 cloud compositor: scene fetch de-swizzles, mask/cloud "
|
|
"fetches use plain UVs and must be left alone). Runtime, no rebuild.");
|
|
REXCVAR_DEFINE_STRING(ac6_snap_guest_texel_hashes, "", "GPU/Shader",
|
|
"AC6: same \"<hash>[:<slot>[+<slot>...]]\" token list as "
|
|
"ac6_neutralize_deswizzle_hashes, naming guest pixel-shader ucode "
|
|
"hashes whose texture taps encode fractional guest-texel bilinear "
|
|
"positions (e.g. the cutscene depth-of-field gather pair). Sampling "
|
|
"a resolution-scaled texture with such a kernel reinterprets every "
|
|
"blend ratio against the finer host grid and alternates the kernel "
|
|
"phase per output pixel, aliasing into striping at >1x. For matching "
|
|
"fetches the normalized coordinate is snapped to the guest texel "
|
|
"center (where host bilinear of a scaled texture returns exactly the "
|
|
"guest texel's box average), restoring the guest sampling grid at any "
|
|
"draw resolution scale. Applied only at >1x and only to "
|
|
"resolution-scaled textures. Runtime, no rebuild.");
|
|
REXCVAR_DEFINE_STRING(ac6_densify_x_fetch_hashes, "", "GPU/Shader",
|
|
"AC6: \"<hash>[:<slot>[+<slot>...]]\" list for HORIZONTAL-axis "
|
|
"separable filter passes (e.g. the cutscene DoF H gather "
|
|
"6328f9c40913c82c). Each allowlisted fetch becomes the average of "
|
|
"2*draw_resolution_scale_x samples spread along X across one "
|
|
"guest-texel half-gap on each side of the original tap - the union "
|
|
"of all taps' cells covers the kernel span continuously, so ghost "
|
|
"copies of arbitrarily thin features merge at any resolution scale. "
|
|
"Convolving the authored kernel with the 2-texel cell box widens the "
|
|
"blur by ~2% (visually shape-faithful). Per-axis scale aware; no-op "
|
|
"when draw_resolution_scale_x is 1. Read at shader translation.");
|
|
REXCVAR_DEFINE_STRING(ac6_densify_y_fetch_hashes, "", "GPU/Shader",
|
|
"AC6: as ac6_densify_x_fetch_hashes, for VERTICAL-axis separable "
|
|
"filter passes (e.g. the cutscene DoF V gather 5bd20f9d0d911687): "
|
|
"2*draw_resolution_scale_y samples along Y per fetch. No-op when "
|
|
"draw_resolution_scale_y is 1.");
|
|
REXCVAR_DEFINE_BOOL(ac6_flare_drop_quad2, true, "GPU/Shader",
|
|
"AC6: cull the sun lens-flare's spurious second billboard "
|
|
"(vertices 4-7) to remove the faint rectangle in the sky");
|
|
REXCVAR_DEFINE_INT32(ac6_flare_drop_index_min, 4, "GPU/Shader",
|
|
"AC6: first vertex index of the flare draw to cull (the "
|
|
"spurious billboard is vertices 4-7 of 8)");
|
|
REXCVAR_DEFINE_BOOL(gpu_debug_markers, false, "GPU",
|
|
"Insert debug markers into GPU command streams for tools "
|
|
"like PIX and RenderDoc. Automatically enabled when "
|
|
"RenderDoc is detected.");
|
|
REXCVAR_DEFINE_BOOL(ac6_fix_trails, true, "AC6",
|
|
"Fix invisible missile/jet trails: drop stale cached vertex-buffer "
|
|
"residency so the GPU copy of AC6's fixed-address trail history ring "
|
|
"refreshes when the CPU writes it. On by default.");
|
|
|
|
bool IsGpuDebugMarkersEnabled() {
|
|
static bool cached = false;
|
|
static bool result = false;
|
|
if (!cached) {
|
|
cached = true;
|
|
if (REXCVAR_GET(gpu_debug_markers)) {
|
|
result = true;
|
|
REXLOG_INFO("GPU debug markers enabled via CVar");
|
|
} else {
|
|
auto renderdoc_api = rex::ui::RenderDocAPI::CreateIfConnected();
|
|
if (renderdoc_api) {
|
|
result = true;
|
|
REXLOG_INFO("GPU debug markers auto-enabled (RenderDoc detected)");
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|