mirror of
https://github.com/tangerineturtle1/NX2navi.git
synced 2026-11-15 19:19:58 -04:00
Give Streamline constants and null tags on a frame without inputs while frame generation is on.
A review of the DLSS and frame generation paths against NVIDIA's guides (the DLSS programming guide 310.6.0, the DLSS-FG guide 310.7.0, Streamline 2.14.16's guides and headers). What follows them: the texture bias (log2(render width / output width) - 1 on top of the game's own, at each change of the mode), the jitter (Halton, 8 x (output / render)^2 phases and 16 at least, in render pixels within half a pixel, the scene drawn with it and the motion vectors made without it), the creation flags (HDR, vectors at the render size, auto-exposure, depth not inverted) and the constants Streamline gets (unjittered matrices, the jitter in pixels, the vectors' scale of one over the render size). What did not: vk_dlssg.c holds a change of generation's state for FG_SETTLE_FRAMES frames, so for up to 12 frames after the depth, the motion vectors or the camera went away (a menu, a fade, a load) generation stayed on and nx2sl_frame set no constants and tagged nothing. Streamline's guide asks for the constants at every frame and for null tags where depth or motion vectors are not valid; it logged "Unable to find 'common' constants for frame" and "Failed to find global tag 'kBufferTypeDepth'" and used the frame before's (in every play log with frame generation). Such a frame now gets the last frame's constants with reset set and the three tags as null. Not run in a game yet: nx2navi_dlssg.dll builds and exports its 15 functions. What the guides leave open: the sign of the jitter offsets against the shift of the picture, which NVIDIA says to find by trying, and the bias reaches only the tiled, trilinear samplers, not every texture of the scene. For both there is a test switch now, read once: NX2NAVI_DLAA_JITTER_TEST=<x>,<y> tells the upscaler the jitter times two factors, and NX2NAVI_DLSS_LOD_BIAS_TEST=<bias> puts a bias in the rule's place. Neither was measured: the runs that would do it start the game. The line about the presents a second (the commit before) came at 59 a second under a limit of 60: it comes under 56 now. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
This commit is contained in:
@@ -50,7 +50,7 @@ static const char *const known[] = {
|
||||
"BIND_SKIP", "BIND_STATS", "BIND_UP", "BIND_X", "BIND_Y",
|
||||
"BIND_ZL", "BIND_ZR", "BLOCK_VIEWS_3D", "CACHE_DIE", "CLOTH_REALTIME", "COLOR_BRIGHTNESS", "COMPUTE_KEEP", "COLOR_CONTRAST", "COLOR_GAMMA",
|
||||
"COLOR_PRESET", "COLOR_SATURATION", "CONTACT_DEBUG", "CONTACT_SHADOWS", "CORE_DIAG", "CRIT", "CRIT_OUT",
|
||||
"DMABUF", "DMABUF_MB", "DRAW_CRUMBS", "GPA_LATE", "DESC_TEMPLATE", "DEVICE_PROFILE", "DISCORD_APP_ID", "DISCORD_IMAGE", "DISCORD_RPC", "DLAA", "DLAA_CAM_KEEP", "DLAA_CUT", "DLSS_IDLE_FREE", "DLAA_EDGE_FILL", "DLAA_AT_UPSCALER", "FFX_DEBUG", "FFX_KEYS", "FSR3_SHARPEN", "DLAA_JITTER", "DLAA_MV", "DLAA_MASKDEBUG", "DLAA_MVDEBUG", "DLAA_OBJMV", "DLAA_SURVEY", "DLAA_TARGET_KEEP", "DLAA_TIMES", "DLSS", "DLSS_CHAR_MASK", "DLSS_PRESET", "DLSS_PREBLOOM", "DLSS_RANGE", "DLSS_REACTIVE", "DUMP", "DUMP_BUF", "DUMP_DIR",
|
||||
"DMABUF", "DMABUF_MB", "DRAW_CRUMBS", "GPA_LATE", "DESC_TEMPLATE", "DEVICE_PROFILE", "DISCORD_APP_ID", "DISCORD_IMAGE", "DISCORD_RPC", "DLAA", "DLAA_CAM_KEEP", "DLAA_CUT", "DLSS_IDLE_FREE", "DLAA_EDGE_FILL", "DLAA_AT_UPSCALER", "FFX_DEBUG", "FFX_KEYS", "FSR3_SHARPEN", "DLAA_JITTER", "DLAA_JITTER_TEST", "DLSS_LOD_BIAS_TEST", "DLAA_MV", "DLAA_MASKDEBUG", "DLAA_MVDEBUG", "DLAA_OBJMV", "DLAA_SURVEY", "DLAA_TARGET_KEEP", "DLAA_TIMES", "DLSS", "DLSS_CHAR_MASK", "DLSS_PRESET", "DLSS_PREBLOOM", "DLSS_RANGE", "DLSS_REACTIVE", "DUMP", "DUMP_BUF", "DUMP_DIR",
|
||||
"UPSCALER_IDLE_WAIT",
|
||||
"DUMP_LOG", "DUMP_RAW", "DUMP_SHADERS", "DUMP_FILE", "DS3", "LOG_CS_BINDS", "LOG_TEX_FLAGS", "LOG_MESH", "MESH", "POOL", "NATIVE_TENSOR", "LOG_RCOND", "LOG_RT_SIZES", "DUMP_WHITE", "DUMP_AFTER", "DUMP_MOVIE", "SUBMIT_FINISH", "ACQUIRE_WAIT", "CRASH_FILTER_GUARD", "CS_FALLBACK", "EXEFS", "FEEDBACK", "FIX_C0", "FIX_ZERO", "FLIGHT", "FLIGHT_AT", "FLIGHT_DIR", "FLIGHT_FRAMES", "GPU_TIMELINE",
|
||||
"FFX_PIPE_CACHE", "FLIGHT_SPIKE_MS", "FREEZE_QUIET_MS", "FREEZE_LOAD_HOLD_MS", "STUTTER_MAP", "PAR_JOBS", "PIPE_RELEASE", "FLIGHT_THUMBS", "FLIGHT_EVERY", "FLIGHT_FLASH", "FLIGHT_FLASH_DIFF", "FLIGHT_FLASH_CELLS", "FLUSH_SPAN", "FLUSH_UPLOAD", "FOG_CULL", "FOLIAGE_SHADOW_CULL", "FOLIAGE_SHADOW_VRS", "FOV", "FOV_PATCH", "FG_HUDLESS_SHOW", "FG_MULT", "FPS60", "FPS_LIMIT", "FRAMEGEN", "FRAMEGEN_MULTIPLIER", "FREEZE_IDLE", "FREEZE_ASYNC", "FREEZE_BUDGET_US", "FREE_CORES",
|
||||
|
||||
@@ -237,6 +237,26 @@ extern "C" NX2SL_API int nx2sl_frame(VkCommandBuffer cb, const Nx2SlImage *depth
|
||||
uint32_t max = g_max.load();
|
||||
int n = enable > 0 ? enable : 0;
|
||||
if (n > (int)(max ? max : 1)) n = (int)(max ? max : 1);
|
||||
static sl::Constants last; // the constants of the last frame that had its inputs
|
||||
static bool have_last;
|
||||
if (n && !(depth && mv && cam) && have_last) {
|
||||
// Generation is on for this present and the frame has no depth, motion vectors or camera: a menu, a fade or a
|
||||
// load, while vk_dlssg.c holds the change of state for a few frames. Streamline's guide asks for the common
|
||||
// constants at every frame and for null tags wherever depth or motion vectors are not valid
|
||||
// (ProgrammingGuideDLSS_G.md 5.2 and 7.0). This frame gave neither, and Streamline logged "Unable to find
|
||||
// 'common' constants for frame" and "Failed to find global tag 'kBufferTypeDepth'" and went on with what the
|
||||
// frame before had set. It gets the last frame's constants again, as a new start, and the three tags as null.
|
||||
sl::Constants c = last;
|
||||
c.reset = sl::Boolean::eTrue;
|
||||
p_constants(c, *t, vp);
|
||||
sl::ResourceTag none[3] = {sl::ResourceTag(nullptr, sl::kBufferTypeDepth, sl::ResourceLifecycle::eValidUntilPresent),
|
||||
sl::ResourceTag(nullptr, sl::kBufferTypeMotionVectors, sl::ResourceLifecycle::eValidUntilPresent),
|
||||
sl::ResourceTag(nullptr, sl::kBufferTypeHUDLessColor, sl::ResourceLifecycle::eValidUntilPresent)};
|
||||
if ((t = token(frame))) p_tag(*t, vp, none, 3, (sl::CommandBuffer *)cb);
|
||||
static int said;
|
||||
if (!said++) say("dlssg: a frame without depth and motion vectors while generation is on gets the last constants "
|
||||
"as a new start and null tags");
|
||||
}
|
||||
if (n && depth && mv && cam) {
|
||||
sl::Constants c{};
|
||||
matrix(c.cameraViewToClip, cam->view_to_clip);
|
||||
@@ -259,6 +279,7 @@ extern "C" NX2SL_API int nx2sl_frame(VkCommandBuffer cb, const Nx2SlImage *depth
|
||||
c.motionVectors3D = sl::Boolean::eFalse;
|
||||
c.reset = cam->reset ? sl::Boolean::eTrue : sl::Boolean::eFalse;
|
||||
p_constants(c, *t, vp);
|
||||
last = c, have_last = true;
|
||||
sl::Resource rd = resource(depth), rm = resource(mv), rh = hudless ? resource(hudless) : sl::Resource{};
|
||||
sl::Extent ed{0, 0, depth->width, depth->height}, em{0, 0, mv->width, mv->height};
|
||||
sl::Extent eh{0, 0, hudless ? hudless->width : 0, hudless ? hudless->height : 0};
|
||||
|
||||
@@ -2451,6 +2451,21 @@ static void evaluate(VkExec *ex, const VkExecTarget *dst) {
|
||||
VkImageView zv = vk_exec_target_view(z->img, z->format, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_DEPTH_BIT, z->level,
|
||||
z->base_layer, 1, 0);
|
||||
float jx = D.jit_used ? D.ux : 0.0f, jy = D.jit_used ? D.uy : 0.0f;
|
||||
// NX2NAVI_DLAA_JITTER_TEST=<x>,<y> (test, read once): the upscaler is told the jitter the scene was drawn with
|
||||
// times these two factors. NVIDIA's DLSS guide gives no sign for the offsets against the projection's shift and
|
||||
// says to find it by trying (8.4.1: its development library negates, halves or doubles an axis by a key): the
|
||||
// picture of a still scene is sharp and stands still only with the right ones. The scene, the motion vectors and
|
||||
// frame generation keep the real jitter.
|
||||
static float jt[2] = {1.0f, 1.0f};
|
||||
static int jt_read;
|
||||
if (!jt_read) {
|
||||
jt_read = 1;
|
||||
const char *s = cfg_get("NX2NAVI_DLAA_JITTER_TEST");
|
||||
if (s && *s && sscanf(s, "%f,%f", &jt[0], &jt[1]) == 2)
|
||||
rt_log("dlaa: the upscaler is told the jitter times %g, %g (NX2NAVI_DLAA_JITTER_TEST, a test)", jt[0], jt[1]);
|
||||
else jt[0] = jt[1] = 1.0f;
|
||||
}
|
||||
const float tjx = jx * jt[0], tjy = jy * jt[1];
|
||||
edge_fill(cb, t, z, D.jit_used); // before the motion vectors read the depth
|
||||
static int no_mv = -1;
|
||||
if (no_mv < 0) no_mv = !rt_knob("DLAA_MV", "1"); // NX2NAVI_DLAA_MV=0: zero motion (test)
|
||||
@@ -2482,7 +2497,7 @@ static void evaluate(VkExec *ex, const VkExecTarget *dst) {
|
||||
fm = {e->mv, VK_FORMAT_R16G16_SFLOAT, w, h, 1}, fo = {e->out, VK_FORMAT_R16G16B16A16_SFLOAT, ow, oh, 1};
|
||||
VkFfxCamera fcam;
|
||||
if (!vk_dlaa_ffx_camera(&fcam)) memset(&fcam, 0, sizeof fcam); // no camera this frame: FSR's fixed values
|
||||
if (!vk_ffx_upscale(cb, &fc, &fz, &fm, &fo, jx, jy, D.reset, dt > 0 && dt < 100 ? (float)dt : 16.67f, &fcam))
|
||||
if (!vk_ffx_upscale(cb, &fc, &fz, &fm, &fo, tjx, tjy, D.reset, dt > 0 && dt < 100 ? (float)dt : 16.67f, &fcam))
|
||||
return dl_fail("FSR 3.1", 0);
|
||||
static int told;
|
||||
if (!told++) rt_log("dlaa: FSR 3.1 at %ux%u -> %ux%u (scene format %d, depth format %d)", w, h, ow, oh,
|
||||
@@ -2557,8 +2572,8 @@ own_feature:
|
||||
p_setp(p, "Output", &ro);
|
||||
p_setp(p, "Depth", &rz);
|
||||
p_setp(p, "MotionVectors", &rm);
|
||||
p_setf(p, "Jitter.Offset.X", jx);
|
||||
p_setf(p, "Jitter.Offset.Y", jy);
|
||||
p_setf(p, "Jitter.Offset.X", tjx);
|
||||
p_setf(p, "Jitter.Offset.Y", tjy);
|
||||
p_setf(p, "Sharpness", 0.0f);
|
||||
p_seti(p, "Reset", D.reset);
|
||||
// One bias mask: the reactive one (NX2NAVI_DLSS_REACTIVE, a test) where it ran, else the characters' (mv_pass), else
|
||||
@@ -3221,8 +3236,20 @@ static void dlss_mode(void) {
|
||||
bias_on = -1;
|
||||
}
|
||||
int b = dl_active();
|
||||
if (b != bias_on)
|
||||
bias_on = b, vk_sampler_dlss_bias(b ? res_dlss_lod_bias() + (jitter_on() ? JITTER_LOD_BIAS : 0.0f) : 0.0f);
|
||||
if (b != bias_on) {
|
||||
// NX2NAVI_DLSS_LOD_BIAS_TEST=<bias> (test, read once): this bias in the place of the rule's while an upscaler
|
||||
// runs, 0 for none: what the rule's bias does to the picture is the difference between two runs.
|
||||
static float test;
|
||||
static int test_on = -1;
|
||||
if (test_on < 0) {
|
||||
const char *s = cfg_get("NX2NAVI_DLSS_LOD_BIAS_TEST");
|
||||
test_on = s && *s;
|
||||
if (test_on) test = (float)atof(s), rt_log("dlaa: texture LOD bias %g while an upscaler runs "
|
||||
"(NX2NAVI_DLSS_LOD_BIAS_TEST, a test)", test);
|
||||
}
|
||||
float rule = res_dlss_lod_bias() + (jitter_on() ? JITTER_LOD_BIAS : 0.0f);
|
||||
bias_on = b, vk_sampler_dlss_bias(b ? (test_on ? test : rule) : 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -187,6 +187,7 @@ static uint32_t submit_epoch = 1; // bumped per queue submit: draw bindings ch
|
||||
// was over its budget.
|
||||
#define RATE_N 8
|
||||
#define RATE_SAY 16
|
||||
#define RATE_SAY_UNDER 240u // the log's line: under 56 presents a second (a limit of 60 measures 59 now and then)
|
||||
static uint32_t tex_rate = TRL_RATE_60;
|
||||
#define PRESENTS(n) trl_presents((uint64_t)(n), tex_rate)
|
||||
|
||||
@@ -225,10 +226,11 @@ static void rate_tick(void) { // each submission, tex_lock held
|
||||
ring[at++ % RATE_N] = trl_rate_sample(f - f0, t - t0, low);
|
||||
t0 = t, f0 = f;
|
||||
uint32_t m = trl_rate(ring, RATE_N);
|
||||
// one line at each crossing of 60, RATE_SAY times a run: the log then shows which waits the drops went by
|
||||
if ((m < TRL_RATE_60) != (tex_rate < TRL_RATE_60) && said < RATE_SAY) {
|
||||
said++;
|
||||
if (m < TRL_RATE_60)
|
||||
// one line at each crossing of RATE_SAY_UNDER, RATE_SAY times a run: the log then shows which waits the drops went by
|
||||
static int slow;
|
||||
if ((m < RATE_SAY_UNDER) != slow && said < RATE_SAY) {
|
||||
said++, slow = m < RATE_SAY_UNDER;
|
||||
if (slow)
|
||||
rt_log("vk: the game presents %u frames a second, fewer than 60, for %d seconds: the textures' waits count "
|
||||
"their seconds in these (2 s are %llu presents, not 120; NX2NAVI_TEX_RATE_LOW=0: 120)",
|
||||
m * 60 >> 8, RATE_N, (unsigned long long)trl_presents(120, m));
|
||||
|
||||
Reference in New Issue
Block a user