mirror of
https://github.com/tangerineturtle1/NX2navi.git
synced 2026-11-15 19:19:58 -04:00
Sharpen FSR 3.1 more below a render scale of three quarters: its own sharpening towards the maximum, and a second, lighter RCAS pass over its picture.
FSR 3.1 was soft at Performance and Ultra Performance, most of all in motion. On a village save, while the camera turned at a steady rate (present screenshots every 0.4 s, the mean absolute Laplacian of the scene's luminance): FSR 3.1 Native AA 6.7, FSR 4 Performance 5.9 and Ultra Performance 5.4, FSR 3.1 Performance 4.0 and Ultra Performance 3.3. The library's own input checks found nothing wrong, and its tuning constants (velocity factor, accumulation per frame, shading change scale, behind the test switch NX2NAVI_FFX_KEYS) gave nothing or took detail away. Its own sharpening at 100 instead of the default 80 gave 5.0 and 4.1. Now the share of extra sharpening grows from none at three quarters of the output's width to all of it at half (vk_dlaa_fsr3_boost). FSR 3.1's own sharpness goes that share of the way to its maximum, and its picture gets a second RCAS pass (shaders/dlaa_sharpen.comp, AMD's FSR 1 header with the linear light taken through c / (1 + max c) and back), before the HUD is drawn. Both follow the sharpness slider; 0 turns them off, and NX2NAVI_FSR3_SHARPEN=0 leaves the second pass out. At RCAS's full strength the pass took Performance to 8.2, past Native AA, with grain on every surface, so it runs 1.5 stops weaker: Performance 5.7, Ultra Performance 4.7, Quality 5.2. 63.4 fps against 65.1 without the pass. The HDR picture is clean. FSR 4 is untouched. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
This commit is contained in:
@@ -37,7 +37,7 @@ Code copied or adapted from another project is listed here with its source, the
|
||||
| MacNativeGames host movie decoder (`movie::Decoder` for VP9 over libvpx: entry list, buffer and event semantics, NV12 output format, PTS pacing) | https://github.com/ly05010419/MacNativeGames @ `b75be8cfa704df3701e86130c8ced268e79d6b11` (`runtime/movie_host.c`, `movie_host.h`), Copyright (c) 2026 MacNativeGames contributors | MIT | `runtime/ov_movie.c`, `runtime/movie.h` |
|
||||
| libvpx 1.17.0 (MSYS2 `mingw-w64-ucrt-x86_64-libvpx`), static link (`libvpx.a`), no DLL shipped; the release notices must carry its BSD licence text and the WebM Project's `PATENTS` grant | https://chromium.googlesource.com/webm/libvpx, Copyright (c) 2010, The WebM Project authors | BSD-3-Clause | `runtime/ov_movie.c` (VP9 decoding of the `Event/Movie` WebM files) |
|
||||
| MacNativeGames NX2navi resolution patches: output, swapchain and scene size sites and instruction words for 1.2.1 and 1.4.3, the data-page layout, the HeapDef heap names and sizes | https://github.com/ly05010419/MacNativeGames @ `aaf6ba1f494fabaa209d049e528d6f923dfe822a` (`runtime/game_patches.c`, `game_patches_v143.c`, `game_version.h`, `scripts/make_output_res_overlay.py`), Copyright (c) 2026 MacNativeGames contributors | MIT | `recomp/patches-v121.txt`, `recomp/patches-v143.txt`, `runtime/resolution.c` |
|
||||
| AMD FidelityFX Super Resolution 1.0 (`ffx_a.h`, `ffx_fsr1.h`, unmodified; licence text in `runtime/shaders/ffx/LICENSE.txt`) | https://github.com/GPUOpen-Effects/FidelityFX-FSR @ `a21ffb8f6c13233ba336352bdff293894c706575`, Copyright (c) 2021 Advanced Micro Devices, Inc. | MIT | `runtime/shaders/ffx/`, `runtime/shaders/fsr_easu.comp`, `runtime/shaders/fsr_rcas.comp` (compiled into `runtime/fsr_easu_spv.h`, `runtime/fsr_rcas_spv.h`) |
|
||||
| AMD FidelityFX Super Resolution 1.0 (`ffx_a.h`, `ffx_fsr1.h`, unmodified; licence text in `runtime/shaders/ffx/LICENSE.txt`) | https://github.com/GPUOpen-Effects/FidelityFX-FSR @ `a21ffb8f6c13233ba336352bdff293894c706575`, Copyright (c) 2021 Advanced Micro Devices, Inc. | MIT | `runtime/shaders/ffx/`, `runtime/shaders/fsr_easu.comp`, `runtime/shaders/fsr_rcas.comp`, `runtime/shaders/dlaa_sharpen.comp` (compiled into `runtime/fsr_easu_spv.h`, `runtime/fsr_rcas_spv.h`, `runtime/dlaa_sharpen_spv.h`) |
|
||||
| RenoDX shader library: the swap chain pass's gamma correction, gamut compression, peak clamp and PQ encode, and the gamma correction of the tone mapper's peak, ported from HLSL to GLSL | https://github.com/clshortfuse/renodx @ `bc0ead39917634e95c534f7e8cfb59ab82880747` (`src/shaders/draw.hlsl`, `tonemap.hlsl`, `colorcorrect.hlsl`, `color/pq.hlsl`, `color/srgb.hlsl`, `color/gamma.hlsl`), Copyright (c) 2025 Carlos Lopez Jr. | MIT | `runtime/shaders/hdr_tonemap.frag` and `runtime/shaders/hdr_encode.comp` (compiled into `runtime/hdr_tonemap_spv.h`, `runtime/hdr_encode_spv.h`) |
|
||||
| RenoDX scene mapper for this game and its PsychoV35 tone mapper: the finite cone response in LMS with its mean, deficit and midpoint chroma, the exact fit to the target gamut, the mid grey anchor and tone slope of the game's curve, and the hue clip emulation, ported from HLSL and Slang to GLSL (the path of its default settings; without eye adaptation) | https://github.com/clshortfuse/renodx @ `59bd6f606a5d105bc6de52627332703c840443be` (`src/shaders/tonemap/psychov/test35.hlsl`, `src/games/zelda-oot-oz/scene_tonemap.slangi`, `shared.h`, `addon.cpp`), Copyright (C) 2026 Carlos Lopez | MIT | `runtime/shaders/hdr_tonemap.frag` (compiled into `runtime/hdr_tonemap_spv.h`) |
|
||||
| AMD Display Library (ADL) declarations: `AdapterInfo`, `ADLSingleSensorData`, `ADLPMLogDataOutput`, the `ADL_PMLOG_*` sensor numbers and the `ADL2_*` function signatures | https://github.com/GPUOpen-LibrariesAndSDKs/display-library @ `84c881cb2136f04287eb3af12de00a9e2867aa9e` (`include/adl_structures.h`, `include/adl_defines.h`, `include/adl_sdk.h`), Copyright (c) 2016 - 2022 Advanced Micro Devices, Inc. | MIT | `runtime/perfmon.c` |
|
||||
|
||||
@@ -22,6 +22,12 @@
|
||||
|
||||
## Changed
|
||||
|
||||
- **FSR 3.1 is sharper at Balanced, Performance and Ultra Performance.** It was soft there, most of all while the
|
||||
camera moved: turning the camera at a steady rate, FSR 3.1 Performance kept 60 % of Native AA's fine detail and Ultra
|
||||
Performance 50 %, where FSR 4 keeps 89 and 81 %. Below a render scale of three quarters, FSR 3.1's own sharpening now
|
||||
goes towards its maximum and its picture gets a second, lighter sharpening pass before the HUD is drawn; both follow
|
||||
the Sharpness slider, and 0 turns them off. Performance now keeps 85 % and Ultra Performance 71 %, for about 0.2 ms
|
||||
a frame. FSR 4 and Native AA are unchanged.
|
||||
- **Debug menu: the free camera has no limits.** It flies where it looks and goes through walls, objects and the
|
||||
ground; it used to keep its height and climb whenever anything in the lower part of the view came within three
|
||||
metres, a character or a rock it was flown towards included. *Ground avoidance* is now a switch in the free camera's
|
||||
|
||||
@@ -44,7 +44,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",
|
||||
"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", "DLAA_JITTER", "DLAA_MV", "DLAA_MASKDEBUG", "DLAA_MVDEBUG", "DLAA_OBJMV", "DLAA_SURVEY", "DLAA_TARGET_KEEP", "DLAA_TIMES", "DLSS", "DLSS_CHAR_MASK", "DLSS_PRESET", "DLSS_REACTIVE", "DUMP", "DUMP_BUF", "DUMP_DIR",
|
||||
"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_REACTIVE", "DUMP", "DUMP_BUF", "DUMP_DIR",
|
||||
"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", "FLIGHT_THUMBS", "FLIGHT_EVERY", "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",
|
||||
"FULLSCREEN", "FXAA", "GAME_ASPECT", "GAME_RES", "GPA", "GPA_EMPTY", "GPA_TWIN", "GPA_TWIN_MAX_KB", "MIRROR_CAPTURE_KB", "WB_SKIP_MB", "GPL", "GPL_DRAW_BUILD", "GPL_FEEDBACK", "PIPE_AHEAD", "PIPE_FAST_WORKERS", "PIPE_FRAME_WAIT_MS", "PIPE_LINK_DRAW_MS", "PIPE_SKIP_STEADY", "PROG_LEAD", "GPU", "GPU_INDEX", "GPU_PASSES", "GPU_NAME", "HDR",
|
||||
|
||||
51
runtime/shaders/dlaa_sharpen.comp
Normal file
51
runtime/shaders/dlaa_sharpen.comp
Normal file
@@ -0,0 +1,51 @@
|
||||
// A second pass of AMD's robust contrast-adaptive sharpening (RCAS) over FSR 3.1's picture in its scaling modes
|
||||
// (runtime/vk_dlaa.c fsr3_sharpen). ffx/ffx_a.h and ffx/ffx_fsr1.h are AMD's headers, unmodified (MIT,
|
||||
// ffx/LICENSE.txt). The picture is linear scene light without an upper bound, and RCAS limits its sharpening by each
|
||||
// channel's distance from 0 and from 1: every texel is taken through c / (1 + max(c)) on the way in, which keeps hue
|
||||
// and maps any light into 0..1, and through the inverse on the way out.
|
||||
#version 450
|
||||
#extension GL_GOOGLE_include_directive : require
|
||||
|
||||
layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
|
||||
|
||||
layout(set = 0, binding = 0) uniform sampler2D src;
|
||||
layout(set = 0, binding = 1, rgba16f) uniform writeonly image2D dst;
|
||||
|
||||
layout(push_constant) uniform Params {
|
||||
vec4 size; // width, height, sharpness in stops (0 = most), unused
|
||||
} pc;
|
||||
|
||||
#define A_GPU 1
|
||||
#define A_GLSL 1
|
||||
#include "ffx/ffx_a.h"
|
||||
#define FSR_RCAS_F 1
|
||||
AF4 FsrRcasLoadF(ASU2 p) {
|
||||
vec4 c = texelFetch(src, p, 0);
|
||||
c.rgb = max(c.rgb, vec3(0.0));
|
||||
c.rgb /= 1.0 + max(c.r, max(c.g, c.b));
|
||||
return c;
|
||||
}
|
||||
void FsrRcasInputF(inout AF1 r, inout AF1 g, inout AF1 b) {}
|
||||
#include "ffx/ffx_fsr1.h"
|
||||
|
||||
void put(AU2 p, AU4 con) {
|
||||
if (p.x >= uint(pc.size.x) || p.y >= uint(pc.size.y)) return;
|
||||
AF3 c;
|
||||
FsrRcasF(c.r, c.g, c.b, p, con);
|
||||
c = clamp(c, vec3(0.0), vec3(1.0));
|
||||
c /= max(1.0 - max(c.r, max(c.g, c.b)), 1.0 / 16384.0); // light up to 16,383 comes back as it went in
|
||||
imageStore(dst, ivec2(p), vec4(c, 1.0));
|
||||
}
|
||||
|
||||
void main() {
|
||||
AU4 con;
|
||||
FsrRcasCon(con, pc.size.z);
|
||||
AU2 p = ARmp8x8(gl_LocalInvocationID.x) + AU2(gl_WorkGroupID.x << 4u, gl_WorkGroupID.y << 4u);
|
||||
put(p, con);
|
||||
p.x += 8u;
|
||||
put(p, con);
|
||||
p.y += 8u;
|
||||
put(p, con);
|
||||
p.x -= 8u;
|
||||
put(p, con);
|
||||
}
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "vk_ffx.h"
|
||||
#include "vk_rec.h"
|
||||
#include "dlaa_mv_spv.h"
|
||||
#include "dlaa_sharpen_spv.h"
|
||||
|
||||
typedef int NgxResult; // NVSDK_NGX_Result: 1 success, 0xBAD00000 | n failures
|
||||
#define NGX_OK(r) (((unsigned)(r) & 0xFFF00000u) != 0xBAD00000u)
|
||||
@@ -472,6 +473,9 @@ static struct {
|
||||
VkImage out, mv;
|
||||
VmaAllocation out_mem, mv_mem;
|
||||
VkImageView out_view, mv_view;
|
||||
VkImage sharp; // FSR 3.1's second sharpening pass writes here (fsr3_sharpen), at the output size
|
||||
VmaAllocation sharp_mem;
|
||||
VkImageView sharp_view;
|
||||
VkImage mask, chars[2]; // the bias mask DLSS reads, the character class mask of this and last frame (R8)
|
||||
VmaAllocation mask_mem, chars_mem[2];
|
||||
VkImageView mask_view, chars_view[2];
|
||||
@@ -702,6 +706,8 @@ static void destroy_size(struct Size *e) {
|
||||
if (e->mv_view) vkDestroyImageView(c->device, e->mv_view, NULL);
|
||||
if (e->out) vmaDestroyImage(c->vma, e->out, e->out_mem);
|
||||
if (e->mv) vmaDestroyImage(c->vma, e->mv, e->mv_mem);
|
||||
if (e->sharp_view) vkDestroyImageView(c->device, e->sharp_view, NULL);
|
||||
if (e->sharp) vmaDestroyImage(c->vma, e->sharp, e->sharp_mem);
|
||||
if (e->mask_view) vkDestroyImageView(c->device, e->mask_view, NULL);
|
||||
if (e->mask) vmaDestroyImage(c->vma, e->mask, e->mask_mem);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
@@ -1910,6 +1916,116 @@ static void edge_fill(VkCommandBuffer cb, const VkExecTarget *t, const VkExecTar
|
||||
full_barrier(cb);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------- FSR 3.1's second sharpening pass
|
||||
// FSR 3.1 in its scaling modes is soft where FSR 4 is not, most of all while the camera moves. Measured on a village
|
||||
// save while the camera turned at a steady rate (present screenshots every 0.4 s, the mean absolute Laplacian of the
|
||||
// scene's luminance as the fine detail): FSR 3.1 Native AA 6.7, FSR 4 Performance 5.9 and Ultra Performance 5.4, FSR 3.1
|
||||
// Performance 4.0 and Ultra Performance 3.3 with its own sharpening at the slider's default of 80, 5.0 and 4.1 with it
|
||||
// at 100. FSR 3.1's tuning constants (velocity factor, accumulation per frame, shading change scale) gave nothing or
|
||||
// took detail away. So below a render scale of three quarters FSR 3.1's own sharpening goes towards its maximum
|
||||
// (vk_ffx.cpp vk_ffx_upscale) and its picture gets a second pass of RCAS here (shaders/dlaa_sharpen.comp), before the
|
||||
// HUD is drawn over it: both grow as the scale falls, full from Performance down, and both follow the sharpness
|
||||
// slider, 0 turning them off. NX2NAVI_FSR3_SHARPEN=0 (test): no second pass.
|
||||
#define SHARPEN_STOPS 1.5f
|
||||
static struct {
|
||||
int ok; // -1 not tried
|
||||
VkDescriptorSetLayout dsl;
|
||||
VkPipelineLayout layout;
|
||||
VkPipeline pipe;
|
||||
} SH = {.ok = -1};
|
||||
|
||||
static int sharpen_init(void) {
|
||||
if (SH.ok >= 0) return SH.ok;
|
||||
SH.ok = 0;
|
||||
const VkCtx *c = vk_ctx();
|
||||
if (!mv_init() || !D.mv_samp) return 0; // its sampler serves the texel fetches
|
||||
VkDescriptorSetLayoutBinding b[2] = {
|
||||
{0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, NULL},
|
||||
{1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT, NULL}};
|
||||
VkDescriptorSetLayoutCreateInfo dci = {.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
||||
.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,
|
||||
.bindingCount = 2, .pBindings = b};
|
||||
VkPushConstantRange pr = {VK_SHADER_STAGE_COMPUTE_BIT, 0, 4 * sizeof(float)};
|
||||
VkShaderModuleCreateInfo mi = {.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, .codeSize = sizeof dlaa_sharpen_spv,
|
||||
.pCode = dlaa_sharpen_spv};
|
||||
VkShaderModule m = VK_NULL_HANDLE;
|
||||
if (vkCreateDescriptorSetLayout(c->device, &dci, NULL, &SH.dsl) != VK_SUCCESS) return 0;
|
||||
VkPipelineLayoutCreateInfo li = {.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, .setLayoutCount = 1,
|
||||
.pSetLayouts = &SH.dsl, .pushConstantRangeCount = 1, .pPushConstantRanges = &pr};
|
||||
if (vkCreatePipelineLayout(c->device, &li, NULL, &SH.layout) != VK_SUCCESS ||
|
||||
vkCreateShaderModule(c->device, &mi, NULL, &m) != VK_SUCCESS)
|
||||
return 0;
|
||||
VkComputePipelineCreateInfo ci = {.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
|
||||
.stage = {.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
.stage = VK_SHADER_STAGE_COMPUTE_BIT, .module = m, .pName = "main"},
|
||||
.layout = SH.layout};
|
||||
VkResult r = vkCreateComputePipelines(c->device, VK_NULL_HANDLE, 1, &ci, NULL, &SH.pipe);
|
||||
vkDestroyShaderModule(c->device, m, NULL);
|
||||
if (r != VK_SUCCESS) {
|
||||
rt_log("dlaa: FSR 3.1's second sharpening pass could not be set up");
|
||||
return 0;
|
||||
}
|
||||
return SH.ok = 1;
|
||||
}
|
||||
|
||||
// How much of the extra sharpening a render scale takes: none from three quarters of the output's width up, all of it
|
||||
// from half (Performance) down. vk_ffx.cpp raises FSR 3.1's own sharpness by the same share.
|
||||
float vk_dlaa_fsr3_boost(uint32_t w, uint32_t ow) {
|
||||
double share = ow ? (double)w / ow : 1.0, k = (0.75 - share) / 0.25;
|
||||
return (float)(k < 0 ? 0 : k > 1 ? 1 : k);
|
||||
}
|
||||
|
||||
// FSR 3.1's picture e->out (w x h rendered, ow x oh out) sharpened once more, in place: RCAS into e->sharp and back.
|
||||
static void fsr3_sharpen(VkCommandBuffer cb, struct Size *e, uint32_t w, uint32_t ow, uint32_t oh) {
|
||||
static int on = -1;
|
||||
if (on < 0) on = rt_knob("FSR3_SHARPEN", "1");
|
||||
int slider = cfg_int("NX2NAVI_SHARPNESS");
|
||||
float k = vk_dlaa_fsr3_boost(w, ow);
|
||||
if (!on || slider <= 0 || k <= 0 || !sharpen_init()) return;
|
||||
if (!e->sharp) {
|
||||
VkImageUsageFlags u = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||
if (!image2d(ow, oh, VK_FORMAT_R16G16B16A16_SFLOAT, u, &e->sharp, &e->sharp_mem, &e->sharp_view)) {
|
||||
const VkCtx *c = vk_ctx();
|
||||
if (e->sharp_view) vkDestroyImageView(c->device, e->sharp_view, NULL);
|
||||
if (e->sharp) vmaDestroyImage(c->vma, e->sharp, e->sharp_mem);
|
||||
e->sharp = VK_NULL_HANDLE, e->sharp_view = VK_NULL_HANDLE;
|
||||
return;
|
||||
}
|
||||
VkImageMemoryBarrier2 ib = {.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
|
||||
.dstStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
|
||||
.dstAccessMask = VK_ACCESS_2_MEMORY_READ_BIT | VK_ACCESS_2_MEMORY_WRITE_BIT,
|
||||
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED, .newLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .image = e->sharp,
|
||||
.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}};
|
||||
VkDependencyInfo di = {.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO, .imageMemoryBarrierCount = 1,
|
||||
.pImageMemoryBarriers = &ib};
|
||||
vkCmdPipelineBarrier2(cb, &di);
|
||||
rt_log("dlaa: FSR 3.1's picture gets a second sharpening pass at this render scale (%u of %u wide)", w, ow);
|
||||
}
|
||||
// RCAS takes its sharpness in stops below the most (0). At full strength (0.4 stops at the slider's 80, as vk_fsr.c
|
||||
// maps it for the present) the pass took Performance's fine detail to 8.2, past Native AA's 6.7: grain on every
|
||||
// surface. It runs SHARPEN_STOPS weaker, and weaker still above Performance's scale.
|
||||
const float stops = SHARPEN_STOPS + (100.0f - (float)(slider > 100 ? 100 : slider)) / 50.0f + 2.0f * (1.0f - k);
|
||||
const float pc[4] = {(float)ow, (float)oh, stops, 0};
|
||||
VkDescriptorImageInfo si = {D.mv_samp, e->out_view, VK_IMAGE_LAYOUT_GENERAL},
|
||||
di = {VK_NULL_HANDLE, e->sharp_view, VK_IMAGE_LAYOUT_GENERAL};
|
||||
VkWriteDescriptorSet wr[2] = {
|
||||
{.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, .dstBinding = 0, .descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, .pImageInfo = &si},
|
||||
{.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, .dstBinding = 1, .descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, .pImageInfo = &di}};
|
||||
vkCmdBindPipeline(cb, VK_PIPELINE_BIND_POINT_COMPUTE, SH.pipe);
|
||||
rec_push(vk_pipeline_push_fn(), cb, VK_PIPELINE_BIND_POINT_COMPUTE, SH.layout, 0, 2, wr);
|
||||
vkCmdPushConstants(cb, SH.layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof pc, pc);
|
||||
vkCmdDispatch(cb, (ow + 15) / 16, (oh + 15) / 16, 1);
|
||||
full_barrier(cb);
|
||||
VkImageCopy cp = {.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}, .dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1},
|
||||
.extent = {ow, oh, 1}};
|
||||
vkCmdCopyImage(cb, e->sharp, VK_IMAGE_LAYOUT_GENERAL, e->out, VK_IMAGE_LAYOUT_GENERAL, 1, &cp);
|
||||
full_barrier(cb);
|
||||
}
|
||||
|
||||
// Set when the scene the upscaler runs on has another size than the last one; vk_dlaa_resized_take reads it.
|
||||
static volatile int32_t size_changed;
|
||||
|
||||
@@ -2058,6 +2174,7 @@ evaluated:
|
||||
if (D.evals % 600 == 0) query_vram();
|
||||
stale_sizes(e);
|
||||
full_barrier(cb);
|
||||
if (fsr && !vk_ffx_fsr4() && w < ow) fsr3_sharpen(cb, e, w, ow, oh); // FSR 3.1 made the picture
|
||||
vk_mvcheck_output(cb, e->out, ow, oh); // NX2NAVI_MV_CHECK (test)
|
||||
// the result into the scene target (DLAA: the bloom, the post passes and the HUD read it and draw over it) or into
|
||||
// the scaling pass's target (the HUD draws over it)
|
||||
|
||||
@@ -160,6 +160,27 @@ FfxApiResource image(const VkFfxImage *i, uint32_t state, uint32_t usage) {
|
||||
return ffxApiGetResourceVK((void *)i->image, ffxApiGetImageResourceDescriptionVK(i->image, ci, usage), state);
|
||||
}
|
||||
|
||||
// NX2NAVI_FFX_KEYS=<key>:<value>[,...] (test): FSR 3.1's tuning constants for each new context (ffx_upscale.h
|
||||
// FfxApiConfigureUpscaleKey: 0 velocity factor, 1 reactiveness scale, 2 shading change scale, 3 accumulation added per
|
||||
// frame, 4 minimum disocclusion accumulation). The library reads the value through the pointer.
|
||||
void configure_keys(ffxContext *ctx) {
|
||||
const char *e = cfg_get("NX2NAVI_FFX_KEYS");
|
||||
static float value[8];
|
||||
for (int n = 0; e && *e && n < 8; n++) {
|
||||
unsigned key = 0;
|
||||
float v = 0;
|
||||
if (sscanf(e, "%u:%f", &key, &v) != 2) break;
|
||||
value[n] = v;
|
||||
ffxConfigureDescUpscaleKeyValue d = {};
|
||||
d.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE;
|
||||
d.key = key, d.ptr = &value[n];
|
||||
ffxReturnCode_t r = A.configure(ctx, &d.header);
|
||||
rt_log("ffx: FSR 3.1 key %u = %g (%s)", key, (double)v, r == FFX_API_RETURN_OK ? "set" : "refused");
|
||||
e = strchr(e, ',');
|
||||
if (e) e++;
|
||||
}
|
||||
}
|
||||
|
||||
Up *context_for(uint32_t w, uint32_t h, uint32_t ow, uint32_t oh) {
|
||||
up_tick++;
|
||||
uint64_t now = plat_now_ns();
|
||||
@@ -218,6 +239,7 @@ Up *context_for(uint32_t w, uint32_t h, uint32_t ow, uint32_t oh) {
|
||||
return nullptr;
|
||||
}
|
||||
slot->mw = mw, slot->mh = mh, slot->ow = ow, slot->oh = oh, slot->drs = drs, slot->used = up_tick, slot->used_ns = now;
|
||||
configure_keys(&slot->ctx);
|
||||
ffxQueryGetProviderVersion v = {};
|
||||
v.header.type = FFX_API_QUERY_DESC_TYPE_GET_PROVIDER_VERSION;
|
||||
A.query(&slot->ctx, &v.header);
|
||||
@@ -321,10 +343,13 @@ extern "C" int vk_ffx_upscale(VkCommandBuffer cb, const VkFfxImage *color, const
|
||||
d.motionVectorScale = {1.0f, 1.0f};
|
||||
d.renderSize = {color->width, color->height};
|
||||
d.upscaleSize = {out->width, out->height};
|
||||
// The sharpness slider (0-100) drives FSR's own RCAS here, as it does for FSR 1
|
||||
// The sharpness slider (0-100) drives FSR's own RCAS here, as it does for FSR 1. Below a render scale of three
|
||||
// quarters it goes towards the maximum, all the way from Performance down, where FSR 3.1 is soft (vk_dlaa.c
|
||||
// "FSR 3.1's second sharpening pass", which has the measurements); 0 still turns it off.
|
||||
int sharp = cfg_int("NX2NAVI_SHARPNESS");
|
||||
d.enableSharpening = sharp > 0;
|
||||
d.sharpness = sharp > 100 ? 1.0f : sharp / 100.0f;
|
||||
if (sharp > 0) d.sharpness += (1.0f - d.sharpness) * vk_dlaa_fsr3_boost(color->width, out->width);
|
||||
d.frameTimeDelta = dt_ms;
|
||||
d.preExposure = 1.0f;
|
||||
d.reset = reset != 0;
|
||||
|
||||
@@ -14,6 +14,8 @@ typedef struct {
|
||||
// plane) and the metres in one unit of view space. A field of 0 is not known, and FSR then gets 1 radian, 0.1, 1e8 and
|
||||
// 1.
|
||||
typedef struct { float fov_y, znear, zfar, meters; } VkFfxCamera;
|
||||
// vk_dlaa.c: the share (0..1) of the extra sharpening FSR 3.1 gets at a render width w of an output width ow
|
||||
float vk_dlaa_fsr3_boost(uint32_t w, uint32_t ow);
|
||||
|
||||
int vk_ffx_load(void); // 1 when the library is there with its entry points (loaded once)
|
||||
// Whether FSR 3.1 upscaling can run in this build, for the settings menu: after vk_ffx_load ran, what it found; before,
|
||||
|
||||
Reference in New Issue
Block a user