mirror of
https://github.com/Mrsuss60/bloodborne_pc_windows_port.git
synced 2026-11-07 05:56:20 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b3350bb4f5 | ||
|
|
019939a5e5 | ||
|
|
17bfa1e4b7 | ||
|
|
1cc0678c21 | ||
|
|
432d2ddbf1 | ||
|
|
ce83b806b9 | ||
|
|
8d76278ccc | ||
|
|
3e60038643 | ||
|
|
8ea9aa3744 | ||
|
|
34e567b9e4 | ||
|
|
94388d5921 | ||
|
|
d9b1bc6e07 | ||
|
|
8841db5b24 | ||
|
|
ed73550c85 | ||
|
|
2054129fae | ||
|
|
d0f2a891b5 | ||
|
|
574f133635 | ||
|
|
d7b2db1122 | ||
|
|
85d9bc98da | ||
|
|
7889ca068a | ||
|
|
0176a88b3f | ||
|
|
2cc3764f59 | ||
|
|
ac726e6313 | ||
|
|
d81d63be3c | ||
|
|
b62051dba1 | ||
|
|
6b2cc0e07c | ||
|
|
c3f55890c2 | ||
|
|
da42893471 | ||
|
|
624ac74921 | ||
|
|
dcdb834f99 | ||
|
|
83a168eee2 | ||
|
|
f8f450b19f | ||
|
|
a7cbfae63e | ||
|
|
7b4bb9576c | ||
|
|
6efb5ac1e8 | ||
|
|
f8597057ed | ||
|
|
92c1461054 | ||
|
|
466e8e7dd4 | ||
|
|
2083ff8be9 | ||
|
|
bb91ba0537 | ||
|
|
45e4500328 | ||
|
|
4ad13c6ee5 | ||
|
|
cd4ca77e06 | ||
|
|
c0611c89e7 | ||
|
|
7c0e5f0d20 | ||
|
|
26198d6a44 | ||
|
|
5831879a2e | ||
|
|
b84dcb359c | ||
|
|
466e30ebc4 | ||
|
|
e0a64d48c6 | ||
|
|
116e1c2951 | ||
|
|
8d9ee1a2aa | ||
|
|
87011f0943 | ||
|
|
d81863f1bd | ||
|
|
04dd406111 | ||
|
|
4035ab4e13 | ||
|
|
0f60f96d5d | ||
|
|
7a9231bfe6 | ||
|
|
fde3de8497 |
No files matched your search
+42
-1
@@ -306,4 +306,45 @@ This document details the optimizations, fixes, and refactoring applied to ensur
|
||||
- **Change**:
|
||||
1. Automated executable symbol stripping (`strip -s`) in both `build.bat` and GitHub Actions CI workflow, reducing `bbport.exe` and `bb-probe.exe` binary footprint from ~260 MB to ~12.4 MB (~95% reduction).
|
||||
2. Filtered out protected Windows system DLLs from being bundled during release staging.
|
||||
3. Added comprehensive license notice staging for all MSYS2 packages, bundled third-party libraries, and the Python launcher runtime.
|
||||
3. Added comprehensive license notice staging for all MSYS2 packages, bundled third-party libraries, and the Python launcher runtime.
|
||||
|
||||
---
|
||||
|
||||
## 19. Crash Root-Cause Fixes: Allocation Failures, Assert Diagnostics, Non-BMI1 Lengths, TLS (Issues #148, #149, #151, #155)
|
||||
|
||||
- **Files**: `src/probe.c`, `src/runtime_kernel.c`, `src/runtime_memory.c`, `src/runtime.h`.
|
||||
- **Root cause summary**:
|
||||
1. The startup crashes (#148/#155/#151) were guest code dereferencing the NULL result of a failed allocation. The allocator's panic (`0x20b55b0`, id `0x104`/`0x148`) was silent because the printer's mode global is 2, and the failure reason was never recorded anywhere.
|
||||
2. The non-BMI1 LZCNT trap used a raw byte scan: it patched 135 `F3/0F BD` patterns that are data inside other instructions, missed 8 LZCNT instructions with redundant prefixes (`F3 F3`, `66 F3`, `49 F3 49`, ...), and advanced a fixed 4/5 bytes, so the 18 LZCNT instructions with a memory operand resumed in the middle of the next instruction.
|
||||
3. `enter_on_stack` kept its second argument in caller shadow space (`RSP+0x18`), which the two intervening calls are allowed to clobber, and executed `wrfsbase` even when the TCB lookup returned NULL.
|
||||
4. The VEH FS guard returned `EXCEPTION_CONTINUE_EXECUTION` whenever a TCB existed, even when rebasing could not fix the fault, which could retry forever.
|
||||
5. "Code 23" was `exit(23)` in `raise_exception` with no dump; "code 139" was the generic VEH exit. Neither identified the actual failure.
|
||||
- **Changes**:
|
||||
1. **Allocation failures are recorded and reported** (`runtime_memory.c`): every pool/section, direct allocate, direct map, flexible map, reserve, low map and batch-map failure now records operation, size, parameters, result and host error; the first 16 are printed, totals and the last failure appear in `runtime_report()` and in every crash dump.
|
||||
2. **Panic/assert printer hook** (`probe.c`): a 17-byte absolute entry patch at `0x20b55b0` jumps to a stub that preserves all argument/XMM registers, logs `rdi`/`esi`/`rdx` (first string, assert id, second string), then replays the original prologue and resumes at `0x20b55c2`. The absolute jump is used because thunks are host `VirtualAlloc` memory that can be outside `rel32` range.
|
||||
3. **`raise_exception` policy** (`runtime_kernel.c`): logs the code, argument and raising guest offset (real image range), writes an assert dump, and **continues by default** (retail behaviour). `BB_GAME_ASSERT_STOP=1` restores stopping, now with a dump and exit code 142 instead of 23. The previous hard-coded Yebis address windows are gone.
|
||||
4. **Assert dumps** (`runtime_crash_dump_assert`): the first 50 assertions produce full `out/assert_<timestamp>_<n>.log` files; later ones append a compact one-line record to `out/assert_repeat.log`, so a per-frame assert cannot create thousands of files or repeat an expensive dump.
|
||||
5. **Exact LZCNT patching** (`patch_non_bmi1`): a Zydis linear sweep over executable segments patches every decoded `LZCNT` (406 in the linked image, including `66 F3`, `F3 F3`, `49 F3 49`, `47 F3 48` forms) with its true length. The 135 raw `F3/0F BD` byte patterns that lie *inside other instructions* are data and are reported, not patched. `emulate_lzcnt_site` parses any prefix combination, handles 16/32/64-bit operand size correctly (16-bit writes preserve the upper register bits) and clears OF/SF/AF/PF as the instruction does.
|
||||
6. **`enter_on_stack`**: arg1 now lives in callee-saved `%rbx` (with matching push/pop and adjusted epilogue), and `wrfsbase` is skipped when the TCB is NULL.
|
||||
7. **VEH FS guard**: rebases FS only when the current base differs from the guest TCB, so a second fault cannot loop; if the CPU lacks FSGSBASE and the fault is not the 9-byte `mov rax, fs:[0]` form, it logs one `[FS GUARD]` diagnostic and fails instead of retrying. Startup now prints a clear "this CPU is not fully supported" warning.
|
||||
8. **Crash-dump quality** (`write_crash_dump`): the fault address is classified (`NULL+0x..`, guest code/module, guest stack/heap, host module), the first 16 bytes at RIP are decoded with Zydis, the old raw 16-qword "stack walk" is replaced by a real `RtlCaptureStackBackTrace` host unwind plus a bounds-validated guest RBP chain and a filtered guest-code stack scan, and the dump includes guest memory accounting, host physical/commit memory and the last captured assertion.
|
||||
9. **Distinct exit codes**: guest NULL dereference (fault address `< 0x10000` in guest code) exits 140; the deliberate panic abort trap at `0x20b56d2` (`mov dword ptr [0], 0xdeadba`) is classified and exits 141; `BB_GAME_ASSERT_STOP=1` exits 142; illegal instructions exit 132. Generic guest faults keep 139. The watchdog reaper now terminates with the classified code, so a dump that blocks can no longer turn a classified crash back into 139.
|
||||
- **Deliberately not changed**:
|
||||
- **TZCNT (`F3 0F BC`) is not trapped.** On non-BMI1 CPUs it decodes and executes as `BSF` with identical results and flags for nonzero input, so adding a trap would add risk without fixing a defect.
|
||||
- **Full `fs:`-relative decoding is not emulated on non-FSGSBASE CPUs.** Emulating every addressing form of every `fs:` instruction is a large, risky change; the port instead fails with a precise diagnostic. CPUs without FSGSBASE remain unsupported beyond the initial-TLS form.
|
||||
|
||||
---
|
||||
|
||||
## 20. NVIDIA DLSS Super Resolution (optional bridge, MSVC-built DLL)
|
||||
|
||||
- **Files**: `gpu/dlss_bridge/` (new), `gpu/shadps4/video_core/renderer_vulkan/vk_dlss.h/.cpp` (new), `vk_temporal_upscaler.h/.cpp`, `vk_instance.cpp`, `vk_platform.cpp`, `vk_scheduler.h`, `gpu/shim/bbport_settings.h/.cpp`, `gpu/shim/bbport_overlay.cpp`, `gpu/CMakeLists.txt`, `tests/test_upscaler_support.cpp`, `bblauncherAPP/`, `launcher/bbport_launcher.py`, `build.bat`, `bbport.ini`, `licenses/NVIDIA-DLSS-LICENSE.txt` (new).
|
||||
- **Change**:
|
||||
1. Ported upstream's DLSS Super Resolution path behind an isolated `bbport_dlss.dll` bridge (`gpu/dlss_bridge`, MIT, adapted from `IFreemz/shadPS4-Bloodborne-DLSS-FSR`). The port itself contains no NVIDIA headers: `vk_dlss.cpp` resolves the DLL with `LoadLibraryA("bbport_dlss.dll")` and calls a plain C ABI, so a missing bridge costs nothing.
|
||||
2. NVIDIA's Windows NGX SDK ships MSVC-only libraries (`nvsdk_ngx_s.lib` uses the MSVC CRT and C++ EH metadata; verified that MinGW's `ld` cannot link it). The bridge is therefore the single MSVC-built target; `build.bat` finds Visual Studio with `vswhere`, calls `vcvars64.bat`, builds it with CMake/Ninja and copies `bbport_dlss.dll` into `out/`. Everything else stays MinGW-w64. `BB_DLSS_BRIDGE=0` skips the step, and a missing VS/SDK only prints a notice.
|
||||
3. Only the redistributable SDK files are vendored (`include/nvsdk_ngx*.h`, `lib/Windows_x86_64/x64/nvsdk_ngx_s.lib`); NVIDIA's runtime `nvngx_dlss.dll` is **not** committed. It is loaded from next to `bb-probe.exe` or from `<user>/dlss/`, and its license is shipped as `licenses/NVIDIA-DLSS-LICENSE.txt`.
|
||||
4. DLSS gets the same temporal inputs as FSR 3.1: HDR scene colour, hardware depth, current-to-previous motion vectors with the same sign convention, camera jitter, reset flag, frame time and sharpness. `preset=0` (Native AA) maps to DLAA; other presets map to the matching DLSS quality mode from the render/output ratio.
|
||||
5. Lifecycle: NGX instance/device extensions are appended before creation and retried without them if the device refuses (DLSS then disables itself). The feature is created by `TemporalUpscaler::PrepareDlss` before the pass is recorded, and released on resize, preset change and frame-source recreation only after `scheduler.Finish()` has submitted and waited for all recorded work: a feature can still be referenced by commands recorded into the open command buffer but not submitted yet (a flip may be several frames away), and `scheduler.WaitSubmittedWork()` only covered submitted work, so freeing it earlier corrupted the driver (0xC0000005 in `vkCmdEndRendering` on RTX cards). All NGX-wrapped `VkImageView`s are released with the upscaler's resources, and `~Instance` calls `NVSDK_NGX_VULKAN_Shutdown` before the device dies.
|
||||
6. Graceful fallback: no bridge, no `nvngx_dlss.dll`, `BB_DLSS=0`, a non-NVIDIA GPU, a GTX-class GPU or any NGX failure leaves `dlss_supported=false`, prints the reason once and switches the saved `upscaler=dlss` choice to FSR 3.1 before the first frame. A feature that fails later also falls back at the next frame. No asserts or validation errors are raised.
|
||||
7. Exposed as `upscaler=dlss` in `bbport.ini`, in the in-game overlay (with the reason when disabled) and in both launchers (Windows PyQt and Linux GTK).
|
||||
8. `dlss_preset=0|10|11` selects NVIDIA's render-preset hint (0 driver default, 10 = J, 11 = K) and appears as a row under Preset when DLSS is selected; the hint is part of the feature description, so changing it releases and recreates the feature before the next pass is recorded. The port logs the loaded `nvngx_dlss.dll` version, and the NVIDIA DLSS indicator registry key is documented.
|
||||
- **Verified on a GTX 1650 (no Tensor cores, so the success path cannot run here)**: the bridge builds with MSVC 14.51 and exports only `BbDlssGetApi`; NGX reports `VK_KHR_get_physical_device_properties2` as its instance extension and rejects the GTX 1650 with `0xbad00001`, which the port turns into the FSR 3.1 fallback without a crash; the new unit test covers saved-choice fallback, success state and `dlss_problem`; `bbport.exe` links and the existing upscaler tests pass.
|
||||
@@ -7,6 +7,7 @@
|
||||
[](https://github.com/Mrsuss60/bloodborne_pc_windows_port/commits)
|
||||
|
||||
* Discord Server: https://discord.gg/JdZsJ2ArZ2
|
||||
* Download Latest Release: [v0.8.0](https://github.com/Mrsuss60/bloodborne_pc_windows_port/releases/tag/v0.8.0)
|
||||
#
|
||||
`bloodborne_pc_windows_port` is a 64-bit Windows port of the PlayStation 4 executable of *Bloodborne* (CUSA03173, version 1.09).
|
||||
|
||||
|
||||
+1333
-170
File diff suppressed because it is too large.
Load diff
+1135
-21
File diff suppressed because it is too large.
Load diff
+2096
-261
File diff suppressed because it is too large.
Load diff
@@ -30,6 +30,12 @@ if exist "icon.ico" (
|
||||
echo [INFO] icon.ico not found - building with default icon
|
||||
)
|
||||
|
||||
set "DATA_ARGS="
|
||||
if exist "resources" (
|
||||
echo [OK] resources folder found - will embed into executable
|
||||
set "DATA_ARGS=--add-data "resources;resources""
|
||||
)
|
||||
|
||||
if not exist "..\scripts\bb_guard.py" echo [WARN] ..\scripts\bb_guard.py not found - the exe will build without it
|
||||
if not exist "..\scripts\game_check.py" echo [WARN] ..\scripts\game_check.py not found - the exe will build without it
|
||||
echo.
|
||||
@@ -92,6 +98,7 @@ echo.
|
||||
%PY% -m PyInstaller --noconfirm --onefile --windowed ^
|
||||
--name "BloodborneLauncher" ^
|
||||
%ICON_ARGS% ^
|
||||
%DATA_ARGS% ^
|
||||
--distpath ".." ^
|
||||
--paths "." ^
|
||||
--paths "..\scripts" ^
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 353 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 520 KiB |
@@ -196,6 +196,12 @@ goto stage_dlls_done
|
||||
if not errorlevel 1 echo staged > "out\.dlls_staged"
|
||||
:stage_dlls_done
|
||||
|
||||
rem Optional: the DLSS bridge (bbport_dlss.dll). NVIDIA's Windows NGX SDK is MSVC-only, so this
|
||||
rem one DLL is built with MSVC while everything else stays MinGW-w64. Without Visual Studio or
|
||||
rem the vendored SDK the step is skipped and DLSS falls back to FSR 3.1 at run time.
|
||||
rem BB_DLSS_BRIDGE=0 skips it explicitly.
|
||||
call :build_dlss_bridge
|
||||
|
||||
echo Build complete: out\bbport.exe
|
||||
|
||||
if not "%~1"=="--test" goto build_done
|
||||
@@ -251,3 +257,58 @@ if errorlevel 1 exit /b 1
|
||||
|
||||
echo ALL TESTS PASSED!
|
||||
:build_done
|
||||
exit /b 0
|
||||
|
||||
rem ---------------------------------------------------------------------------------------------
|
||||
rem The DLSS bridge: gpu/dlss_bridge -> out/bbport_dlss.dll (MSVC, optionally Ninja).
|
||||
rem ---------------------------------------------------------------------------------------------
|
||||
:build_dlss_bridge
|
||||
if /i "%BB_DLSS_BRIDGE%"=="0" exit /b 0
|
||||
if not exist "gpu\dlss_bridge\bbport_dlss_bridge.cpp" exit /b 0
|
||||
if not exist "gpu\dlss_bridge\third_party\nvngx-sdk\lib\Windows_x86_64\x64\nvsdk_ngx_s.lib" (
|
||||
echo [INFO] No vendored NGX SDK: skipping the DLSS bridge; DLSS uses FSR 3.1.
|
||||
exit /b 0
|
||||
)
|
||||
set "VSWHERE=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe"
|
||||
if not exist "%VSWHERE%" (
|
||||
echo [INFO] Visual Studio not found: skipping the DLSS bridge; DLSS uses FSR 3.1.
|
||||
exit /b 0
|
||||
)
|
||||
set "VSINSTALL="
|
||||
for /f "usebackq delims=" %%i in (`"%VSWHERE%" -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath`) do set "VSINSTALL=%%i"
|
||||
if not defined VSINSTALL (
|
||||
echo [INFO] MSVC tools not found: skipping the DLSS bridge; DLSS uses FSR 3.1.
|
||||
exit /b 0
|
||||
)
|
||||
|
||||
echo Building the DLSS bridge (bbport_dlss.dll, MSVC)...
|
||||
call "%VSINSTALL%\VC\Auxiliary\Build\vcvars64.bat" >nul
|
||||
if errorlevel 1 (
|
||||
echo [WARN] vcvars64.bat failed: DLSS will use FSR 3.1.
|
||||
exit /b 0
|
||||
)
|
||||
set "DLSS_CMAKE_MAKE="
|
||||
where ninja.exe >nul 2>nul
|
||||
if errorlevel 1 if defined W64DEVKIT_DIR if exist "%W64DEVKIT_DIR%\bin\ninja.exe" (
|
||||
set "DLSS_CMAKE_MAKE=-DCMAKE_MAKE_PROGRAM=%W64DEVKIT_DIR%/bin/ninja.exe"
|
||||
)
|
||||
cmake -S gpu\dlss_bridge -B out\dlss-bridge -G Ninja -DCMAKE_BUILD_TYPE=Release ^
|
||||
-DCMAKE_CXX_COMPILER=cl %DLSS_CMAKE_MAKE% ^
|
||||
-DDLSS_SDK_ROOT="%CD%\gpu\dlss_bridge\third_party\nvngx-sdk" ^
|
||||
-DVULKAN_INCLUDE="%VULKAN_SDK%\include"
|
||||
if errorlevel 1 (
|
||||
echo [WARN] DLSS bridge configuration failed: DLSS will use FSR 3.1.
|
||||
exit /b 0
|
||||
)
|
||||
cmake --build out\dlss-bridge
|
||||
if errorlevel 1 (
|
||||
echo [WARN] DLSS bridge build failed: DLSS will use FSR 3.1.
|
||||
exit /b 0
|
||||
)
|
||||
copy /Y "out\dlss-bridge\bbport_dlss.dll" "out\bbport_dlss.dll" >nul
|
||||
if errorlevel 1 (
|
||||
echo [WARN] Could not copy bbport_dlss.dll next to bbport.exe.
|
||||
exit /b 0
|
||||
)
|
||||
echo DLSS bridge: out\bbport_dlss.dll
|
||||
exit /b 0
|
||||
@@ -1,5 +1,53 @@
|
||||
# Temporal upscaling and frame generation — frame analysis and plan
|
||||
|
||||
## NVIDIA DLSS Super Resolution (optional MSVC bridge, 2026-10-22)
|
||||
|
||||
`upscaler=dlss` / `BB_UPSCALER=dlss` runs DLSS Super Resolution through
|
||||
`bbport_dlss.dll`, a small MIT-licensed bridge in `gpu/dlss_bridge` adapted from
|
||||
`IFreemz/shadPS4-Bloodborne-DLSS-FSR`. The port itself contains no NVIDIA code: the
|
||||
bridge is loaded at run time with `LoadLibraryA`, and the port keeps FSR 3.1 when it
|
||||
(or NVIDIA's `nvngx_dlss.dll`) is absent. `BB_DLSS=0` disables DLSS explicitly.
|
||||
|
||||
DLSS receives the same temporal inputs as FSR 3.1: HDR scene colour, hardware depth,
|
||||
current-to-previous motion vectors (render pixels, same sign as the FSR path), Halton
|
||||
camera jitter, frame time, reset flag and sharpness. `preset=0` (Native AA) creates a
|
||||
DLAA feature; the other presets pick the DLSS quality mode from the render/output
|
||||
ratio. There is no reactive mask and no exposure input, exactly like the upstream
|
||||
port. The feature is released and recreated when the render/output size or the
|
||||
quality/preset/HDR set changes, after the scheduler has waited for the submitted work;
|
||||
`NVSDK_NGX_VULKAN_Shutdown` runs from `~Instance` before the `VkDevice` is destroyed.
|
||||
|
||||
`dlss_preset=0|10|11` (overlay: a row under Preset when DLSS is selected) sets NVIDIA's
|
||||
render-preset hint: 0 leaves the driver's choice, 10 is preset J (less ghosting, more
|
||||
flicker) and 11 is preset K (the transformer model, the default on recent drivers). The
|
||||
hint is part of the feature description, so changing it releases and recreates the
|
||||
feature with the same wait as a resize. At start the port logs the directory and the
|
||||
version of the `nvngx_dlss.dll` it loaded.
|
||||
|
||||
NVIDIA's DLSS indicator (the active mode and runtime version drawn in a screen corner) is
|
||||
a driver setting, not an SDK call: set the DWORD
|
||||
`HKCU\Software\NVIDIA Corporation\Global\NGXCore\ShowDlssIndicator` to `1` (`0` turns it
|
||||
off), for example with
|
||||
`reg add "HKCU\Software\NVIDIA Corporation\Global\NGXCore" /v ShowDlssIndicator /t REG_DWORD /d 1 /f`.
|
||||
|
||||
NVIDIA's Windows NGX SDK is MSVC-only (`nvsdk_ngx_s.lib` uses the MSVC CRT and C++ EH
|
||||
metadata; MinGW's `ld` cannot link it). `build.bat` therefore builds this single DLL
|
||||
with Visual Studio (found with `vswhere`, Ninja + `cl`) and copies it to `out/`; the
|
||||
rest of the port remains MinGW-w64. `BB_DLSS_BRIDGE=0` skips the step. Only the SDK's
|
||||
public headers and import library are vendored (`.downloads/DLSS` is not required);
|
||||
`licenses/NVIDIA-DLSS-LICENSE.txt` is shipped. NVIDIA's ~59 MB runtime
|
||||
`nvngx_dlss.dll` is **not** committed here, although the RTX SDKs license does allow
|
||||
shipping it with the application; place it next to `bb-probe.exe` or in
|
||||
`<user>/dlss/` (a release may bundle it together with the NVIDIA license).
|
||||
|
||||
On a GTX 1650 (no Tensor cores, so DLSS itself cannot run) the bridge loads, NGX asks
|
||||
for `VK_KHR_get_physical_device_properties2` and rejects the GPU with `0xbad00001`;
|
||||
the port logs the reason, sets `dlss_supported=false` and switches a saved
|
||||
`upscaler=dlss` choice to FSR 3.1 before the first frame, with no asserts or
|
||||
validation errors. `upscaler-support-test` covers that fallback plus the
|
||||
supported/`dlss_problem` states. The DLSS success path could not be exercised on this
|
||||
machine.
|
||||
|
||||
## Native TAA and missing FSR 4 assets (2026-10-01)
|
||||
|
||||
`upscaler=taa` / `BB_UPSCALER=taa` is a separate native-resolution temporal AA
|
||||
|
||||
+16
-9
@@ -107,14 +107,11 @@ endif()
|
||||
if (WIN32)
|
||||
if (NOT TARGET miniz::miniz)
|
||||
add_library(miniz::miniz INTERFACE IMPORTED)
|
||||
find_path(MINIZ_INC NAMES miniz.h PATHS "$ENV{MINGW_PREFIX}/include" "C:/msys64/mingw64/include")
|
||||
if (MINIZ_INC)
|
||||
target_include_directories(miniz::miniz INTERFACE "${MINIZ_INC}")
|
||||
endif()
|
||||
find_library(MINIZ_LIB NAMES miniz libminiz.a PATHS "$ENV{MINGW_PREFIX}/lib" "C:/msys64/mingw64/lib")
|
||||
if (MINIZ_LIB)
|
||||
target_link_libraries(miniz::miniz INTERFACE "${MINIZ_LIB}")
|
||||
endif()
|
||||
# Vendored miniz (public domain): compiled into bbgpu below, so the port needs no
|
||||
# miniz runtime DLL next to bbport.exe.
|
||||
target_include_directories(miniz::miniz INTERFACE
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/third_party/miniz")
|
||||
target_compile_definitions(miniz::miniz INTERFACE MINIZ_STATIC_DEFINE)
|
||||
endif()
|
||||
else()
|
||||
find_package(miniz REQUIRED)
|
||||
@@ -187,6 +184,8 @@ pkg_check_modules(FFMPEG REQUIRED IMPORTED_TARGET libavformat libavcodec libavut
|
||||
file(GLOB SHIM_SOURCES CONFIGURE_DEPENDS shim/*.cpp shim/*/*.cpp)
|
||||
if (WIN32)
|
||||
add_library(bbgpu STATIC ${VIDEO_CORE} ${RECOMPILER} ${COMMON} ${SHIM_SOURCES}
|
||||
third_party/miniz/miniz.c third_party/miniz/miniz_tdef.c
|
||||
third_party/miniz/miniz_tinfl.c third_party/miniz/miniz_zip.c
|
||||
shadps4/core/libraries/gnmdriver/gnmdriver.cpp
|
||||
shadps4/core/libraries/videoout/driver.cpp shadps4/core/libraries/videoout/video_out.cpp
|
||||
shadps4/core/libraries/kernel/equeue.cpp ${AVPLAYER}
|
||||
@@ -209,9 +208,10 @@ target_compile_definitions(bbgpu PRIVATE IMGUI_IMPL_VULKAN_NO_PROTOTYPES
|
||||
BB_FONT_PATH="${CMAKE_CURRENT_SOURCE_DIR}/third_party/fonts/DejaVuSans.ttf")
|
||||
set_source_files_properties(shim/bbport_overlay.cpp PROPERTIES
|
||||
OBJECT_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/third_party/fonts/DejaVuSans.ttf)
|
||||
target_include_directories(bbgpu PRIVATE shim shadps4 ${SHADER_INCLUDE} third_party/gcn/include third_party/half/include)
|
||||
target_include_directories(bbgpu PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} shim shadps4 ${SHADER_INCLUDE} third_party/gcn/include third_party/half/include)
|
||||
target_compile_definitions(bbgpu PRIVATE BOOST_ASIO_STANDALONE NDEBUG)
|
||||
if (WIN32)
|
||||
target_sources(bbgpu PRIVATE platform/win32/nvidia_profile.cpp)
|
||||
target_compile_definitions(bbgpu PRIVATE VK_USE_PLATFORM_WIN32_KHR)
|
||||
# In GCC 15/16 on MinGW-w64, -O2 causes an ICE in choose_baseaddr or runs out of memory on gnmdriver.cpp.
|
||||
# Compile gnmdriver.cpp with -O1 to avoid this compiler bug.
|
||||
@@ -276,6 +276,13 @@ add_dependencies(camera-motion-test host_shaders)
|
||||
add_executable(upscaler-support-test EXCLUDE_FROM_ALL ../tests/test_upscaler_support.cpp
|
||||
shim/bbport_settings.cpp)
|
||||
target_include_directories(upscaler-support-test PRIVATE shim)
|
||||
# bbport_settings.cpp includes and calls SDL3 for the key names.
|
||||
target_link_libraries(upscaler-support-test PRIVATE PkgConfig::SDL3)
|
||||
if (WIN32 AND TARGET SDL3::SDL3)
|
||||
add_custom_command(TARGET upscaler-support-test POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:SDL3::SDL3>
|
||||
$<TARGET_FILE_DIR:upscaler-support-test>)
|
||||
endif()
|
||||
target_compile_options(upscaler-support-test PRIVATE -UNDEBUG)
|
||||
|
||||
add_executable(fsr4-bench EXCLUDE_FROM_ALL tools/fsr4_bench.cpp
|
||||
|
||||
+141
-108
@@ -1,108 +1,141 @@
|
||||
/* C interface of the GPU library (gpu/): shadPS4's Liverpool/Vulkan video core,
|
||||
* GnmDriver, VideoOut and kernel event queues, adapted to the native loader. */
|
||||
#ifndef BBGPU_H
|
||||
#define BBGPU_H
|
||||
#include <stdint.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
typedef struct {
|
||||
const char *title; /* window title */
|
||||
const char *serial; /* CUSA id, names the pipeline cache */
|
||||
const char *user_dir; /* pipeline cache/logs directory */
|
||||
uint32_t sdk_version; /* from the eboot's procparam */
|
||||
uint32_t psf_attributes; /* param.sfo ATTRIBUTE */
|
||||
int32_t width, height; /* initial window size */
|
||||
} BbGpuConfig;
|
||||
/* Registers kernel event queues (needed with or without graphics). */
|
||||
void bbgpu_register_kernel(void);
|
||||
/* Creates window, Vulkan device, presenter and GPU command processor. */
|
||||
int bbgpu_init(const BbGpuConfig *config);
|
||||
/* Function for an imported NID ("NID#lib#mod"), or 0 when the GPU library does not provide it. */
|
||||
uintptr_t bbgpu_resolve(const char *scoped_nid);
|
||||
/* Called first by the loader's SIGSEGV handler: 1 when a GPU page-tracking fault was handled. */
|
||||
int bbgpu_handle_fault(void *ucontext, void *address);
|
||||
/* BB_WRITE_LOG=1: prints the logged GPU-side writes to guest memory near the fault. */
|
||||
void bbgpu_dump_guest_writes(void *ucontext);
|
||||
/* Keyboard text entry through the game window (IME dialog). begin returns 0 when
|
||||
* no window exists; poll returns 0 typing, 1 confirmed, 2 cancelled (UTF-8 text). */
|
||||
int bbgpu_text_input_begin(const char *initial_utf8, const char *prompt_utf8);
|
||||
int bbgpu_text_input_poll(char *out_utf8, uint64_t size);
|
||||
int bbgpu_text_input_is_active(void);
|
||||
/* 1 while the in-game settings menu is open: the game's pad input is held neutral. */
|
||||
int bbgpu_overlay_captures_input(void);
|
||||
/* Number of symbols registered by the vendored libraries (diagnostics). */
|
||||
unsigned bbgpu_symbol_count(void);
|
||||
/* Flips and submissions query for heartbeat / diagnostics. */
|
||||
uint64_t bbgpu_get_flip_count(void);
|
||||
uint64_t bbgpu_get_submit_count(void);
|
||||
/* Dumps host GPU / presenter thread states and counters to a log file. */
|
||||
void bbgpu_dump_host_threads_hang(void *file_handle);
|
||||
/* Computes average FPS and p95/p99 frame times in milliseconds over recent flips. */
|
||||
void bbgpu_get_frametime_percentiles(double *avg_fps, double *p95_ms, double *p99_ms);
|
||||
/* Dumps GPU breadcrumbs state to log/crash files. */
|
||||
void bbgpu_dump_breadcrumbs(void *file_handle);
|
||||
/* Retrieves GPU device name, driver version, and Vulkan API version. */
|
||||
void bbgpu_get_device_info(char *vendor_buf, size_t vendor_sz,
|
||||
char *model_buf, size_t model_sz,
|
||||
char *driver_buf, size_t driver_sz,
|
||||
char *api_buf, size_t api_sz);
|
||||
/* Consumes accumulated mouse motion delta (pixels) since last call. */
|
||||
void bbgpu_consume_mouse_delta(float *dx, float *dy);
|
||||
/* Returns 1 if mouse look is actively capturing the cursor in relative mode. */
|
||||
int bbgpu_mouse_captured(void);
|
||||
/* Explicitly requests or releases mouse capture. */
|
||||
void bbgpu_set_mouse_capture(int capture);
|
||||
/* Returns 1 if M&K is enabled, and retrieves sensitivity and invert flags. */
|
||||
int bbgpu_get_mk_config(float *sens_x, float *sens_y, int *invert_x, int *invert_y, float *deadzone, float *smoothing);
|
||||
/* Returns 1 if native direct mouse camera rotation is enabled. */
|
||||
int bbgpu_get_mk_native_mouse(void);
|
||||
/* Hooks the game's menu list update for the mouse pointer; before the image is protected. */
|
||||
int bbgpu_menu_pointer_install(unsigned char *image, uint64_t size);
|
||||
/* Notes the pad's own state and returns the buttons the menu pointer presses this sample. */
|
||||
uint32_t bbgpu_menu_pointer_buttons(uint32_t buttons, uint8_t lx, uint8_t ly);
|
||||
|
||||
enum BbCustomKey {
|
||||
BB_KEY_NONE = 0,
|
||||
BB_KEY_MOUSE_LEFT = 601,
|
||||
BB_KEY_MOUSE_RIGHT = 602,
|
||||
BB_KEY_MOUSE_MIDDLE = 603,
|
||||
BB_KEY_MOUSE_X1 = 604,
|
||||
BB_KEY_MOUSE_X2 = 605,
|
||||
BB_KEY_CHORD_SHIFT_LMB = 606,
|
||||
BB_KEY_CHORD_SHIFT_RMB = 607,
|
||||
};
|
||||
|
||||
enum BbAction {
|
||||
BB_ACTION_ATTACK = 0, /* R1 (Light Attack) */
|
||||
BB_ACTION_HEAVY_ATTACK, /* R2 (Heavy / Charged Attack) */
|
||||
BB_ACTION_FIREARM, /* L2 (Gun / Secondary) */
|
||||
BB_ACTION_TRANSFORM, /* L1 (Trick Weapon Transform) */
|
||||
BB_ACTION_LOCK_ON, /* R3 (Lock Target) */
|
||||
BB_ACTION_MOVE_FORWARD, /* Left Stick Up */
|
||||
BB_ACTION_MOVE_BACKWARD, /* Left Stick Down */
|
||||
BB_ACTION_MOVE_LEFT, /* Left Stick Left */
|
||||
BB_ACTION_MOVE_RIGHT, /* Left Stick Right */
|
||||
BB_ACTION_DODGE, /* Circle (Roll / Sprint / Jump while sprinting) */
|
||||
BB_ACTION_INTERACT, /* Cross (Interact / Pick Up / Talk) */
|
||||
BB_ACTION_USE_ITEM, /* Square (Use Quick Item) */
|
||||
BB_ACTION_HEAL, /* Triangle (Heal / Blood Vial) */
|
||||
BB_ACTION_DPAD_UP, /* D-Pad Up (Blood Bullets) */
|
||||
BB_ACTION_DPAD_DOWN, /* D-Pad Down (Switch Item) */
|
||||
BB_ACTION_DPAD_LEFT, /* D-Pad Left (Switch Left Weapon) */
|
||||
BB_ACTION_DPAD_RIGHT, /* D-Pad Right (Switch Right Weapon) */
|
||||
BB_ACTION_GESTURES, /* Touchpad Left (Gestures Menu) */
|
||||
BB_ACTION_PERSONAL_EFFECTS, /* Touchpad Right (Personal Effects) */
|
||||
BB_ACTION_MENU, /* Options (System Menu) */
|
||||
BB_ACTION_WALK, /* Hold: partial left stick deflection */
|
||||
BB_ACTION_COUNT
|
||||
};
|
||||
|
||||
/* Action keybinding queries */
|
||||
int bbgpu_get_action_binding(int action);
|
||||
void bbgpu_get_all_action_bindings(int *out_bindings, int count);
|
||||
void bbgpu_set_action_binding(int action, int code);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
/* C interface of the GPU library (gpu/): shadPS4's Liverpool/Vulkan video core,
|
||||
* GnmDriver, VideoOut and kernel event queues, adapted to the native loader. */
|
||||
#ifndef BBGPU_H
|
||||
#define BBGPU_H
|
||||
#include <stdint.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
typedef struct {
|
||||
const char *title; /* window title */
|
||||
const char *serial; /* CUSA id, names the pipeline cache */
|
||||
const char *user_dir; /* pipeline cache/logs directory */
|
||||
uint32_t sdk_version; /* from the eboot's procparam */
|
||||
uint32_t psf_attributes; /* param.sfo ATTRIBUTE */
|
||||
int32_t width, height; /* initial window size */
|
||||
} BbGpuConfig;
|
||||
/* Registers kernel event queues (needed with or without graphics). */
|
||||
void bbgpu_register_kernel(void);
|
||||
/* Creates window, Vulkan device, presenter and GPU command processor. */
|
||||
int bbgpu_init(const BbGpuConfig *config);
|
||||
/* Function for an imported NID ("NID#lib#mod"), or 0 when the GPU library does not provide it. */
|
||||
uintptr_t bbgpu_resolve(const char *scoped_nid);
|
||||
/* Called first by the loader's SIGSEGV handler: 1 when a GPU page-tracking fault was handled. */
|
||||
int bbgpu_handle_fault(void *ucontext, void *address);
|
||||
/* Set while a fault from the PS4 red-zone vertex generators is being handled: their pages must
|
||||
* stay writable, because the Windows exception frame destroys the red-zone locals. */
|
||||
void bbgpu_set_redzone_fault(int active);
|
||||
/* BB_WRITE_LOG=1: prints the logged GPU-side writes to guest memory near the fault. */
|
||||
void bbgpu_dump_guest_writes(void *ucontext);
|
||||
/* Keyboard text entry through the game window (IME dialog). begin returns 0 when
|
||||
* no window exists; poll returns 0 typing, 1 confirmed, 2 cancelled (UTF-8 text). */
|
||||
int bbgpu_text_input_begin(const char *initial_utf8, const char *prompt_utf8);
|
||||
int bbgpu_text_input_poll(char *out_utf8, uint64_t size);
|
||||
int bbgpu_text_input_is_active(void);
|
||||
/* 1 while the in-game settings menu is open: the game's pad input is held neutral. */
|
||||
int bbgpu_overlay_captures_input(void);
|
||||
/* Number of symbols registered by the vendored libraries (diagnostics). */
|
||||
unsigned bbgpu_symbol_count(void);
|
||||
/* Flips and submissions query for heartbeat / diagnostics. */
|
||||
uint64_t bbgpu_get_flip_count(void);
|
||||
uint64_t bbgpu_get_submit_count(void);
|
||||
/* Dumps host GPU / presenter thread states and counters to a log file. */
|
||||
void bbgpu_dump_host_threads_hang(void *file_handle);
|
||||
/* Computes average FPS and p95/p99 frame times in milliseconds over recent flips. */
|
||||
void bbgpu_get_frametime_percentiles(double *avg_fps, double *p95_ms, double *p99_ms);
|
||||
/* Dumps GPU breadcrumbs state to log/crash files. */
|
||||
void bbgpu_dump_breadcrumbs(void *file_handle);
|
||||
/* Retrieves GPU device name, driver version, and Vulkan API version. */
|
||||
void bbgpu_get_device_info(char *vendor_buf, size_t vendor_sz,
|
||||
char *model_buf, size_t model_sz,
|
||||
char *driver_buf, size_t driver_sz,
|
||||
char *api_buf, size_t api_sz);
|
||||
/* Consumes accumulated mouse motion delta (pixels) since last call. */
|
||||
void bbgpu_consume_mouse_delta(float *dx, float *dy);
|
||||
/* Returns 1 if mouse look is actively capturing the cursor in relative mode. */
|
||||
int bbgpu_mouse_captured(void);
|
||||
/* Returns 1 if the mouse produced input (motion, button or wheel) within the last 250 ms. */
|
||||
int bbgpu_mouse_active_recent(void);
|
||||
/* Explicitly requests or releases mouse capture. */
|
||||
void bbgpu_set_mouse_capture(int capture);
|
||||
/* Returns 1 if M&K is enabled, and retrieves sensitivity and invert flags. */
|
||||
int bbgpu_get_mk_config(float *sens_x, float *sens_y, int *invert_x, int *invert_y, float *deadzone, float *smoothing);
|
||||
/* Returns 1 if native direct mouse camera rotation is enabled. */
|
||||
int bbgpu_get_mk_native_mouse(void);
|
||||
/* Live engine clock (probe.c hook): mode 1 when live FPS patching is requested, the target
|
||||
* rate (0 = uncapped) and the physics max-dt frequency. Relaxed atomic reads only. */
|
||||
void bbgpu_get_live_clock(int *mode, int *target_fps, int *max_dt_hz);
|
||||
/* The probe reports whether the eboot signature matched and the hook is installed. */
|
||||
void bbgpu_set_live_clock_supported(int supported);
|
||||
/* Per-frame sample for the overlay diagnostic line (dt in seconds, target fps, 0 = uncapped). */
|
||||
void bbgpu_note_live_clock(float dt, int target_fps);
|
||||
/* Hooks the game's menu list update for the mouse pointer; before the image is protected. */
|
||||
int bbgpu_menu_pointer_install(unsigned char *image, uint64_t size);
|
||||
/* Notes the pad's own state and returns the buttons the menu pointer presses this sample. */
|
||||
uint32_t bbgpu_menu_pointer_buttons(uint32_t buttons, uint8_t lx, uint8_t ly);
|
||||
/* The mouse buttons the menu pointer takes while it has the mouse: 1 left (choose), 2 right (back). */
|
||||
int bbgpu_menu_pointer_mouse_buttons(void);
|
||||
|
||||
enum BbCustomKey {
|
||||
BB_KEY_NONE = 0,
|
||||
BB_KEY_MOUSE_LEFT = 601,
|
||||
BB_KEY_MOUSE_RIGHT = 602,
|
||||
BB_KEY_MOUSE_MIDDLE = 603,
|
||||
BB_KEY_MOUSE_X1 = 604,
|
||||
BB_KEY_MOUSE_X2 = 605,
|
||||
BB_KEY_CHORD_SHIFT_LMB = 606,
|
||||
BB_KEY_CHORD_SHIFT_RMB = 607,
|
||||
};
|
||||
|
||||
enum BbAction {
|
||||
BB_ACTION_ATTACK = 0, /* R1 (Light Attack) */
|
||||
BB_ACTION_HEAVY_ATTACK, /* R2 (Heavy / Charged Attack) */
|
||||
BB_ACTION_FIREARM, /* L2 (Gun / Secondary) */
|
||||
BB_ACTION_TRANSFORM, /* L1 (Trick Weapon Transform) */
|
||||
BB_ACTION_LOCK_ON, /* R3 (Lock Target) */
|
||||
BB_ACTION_MOVE_FORWARD, /* Left Stick Up */
|
||||
BB_ACTION_MOVE_BACKWARD, /* Left Stick Down */
|
||||
BB_ACTION_MOVE_LEFT, /* Left Stick Left */
|
||||
BB_ACTION_MOVE_RIGHT, /* Left Stick Right */
|
||||
BB_ACTION_DODGE, /* Circle (Roll / Sprint / Jump while sprinting) */
|
||||
BB_ACTION_INTERACT, /* Cross (Interact / Pick Up / Talk) */
|
||||
BB_ACTION_USE_ITEM, /* Square (Use Quick Item) */
|
||||
BB_ACTION_HEAL, /* Triangle (Heal / Blood Vial) */
|
||||
BB_ACTION_DPAD_UP, /* D-Pad Up (Blood Bullets) */
|
||||
BB_ACTION_DPAD_DOWN, /* D-Pad Down (Switch Item) */
|
||||
BB_ACTION_DPAD_LEFT, /* D-Pad Left (Switch Left Weapon) */
|
||||
BB_ACTION_DPAD_RIGHT, /* D-Pad Right (Switch Right Weapon) */
|
||||
BB_ACTION_GESTURES, /* Touchpad Left (Gestures Menu) */
|
||||
BB_ACTION_PERSONAL_EFFECTS, /* Touchpad Right (Personal Effects) */
|
||||
BB_ACTION_MENU, /* Options (System Menu) */
|
||||
BB_ACTION_WALK, /* Hold: partial left stick deflection */
|
||||
/* End of the gameplay actions. runtime_pad.c only maps these to the virtual pad. */
|
||||
BB_ACTION_GAMEPLAY_COUNT,
|
||||
/* UI hotkeys: configurable from the launcher and the in-game keybind list. */
|
||||
BB_ACTION_OVERLAY_TOGGLE = BB_ACTION_GAMEPLAY_COUNT, /* Settings / debug overlay */
|
||||
BB_ACTION_HUD_TOGGLE, /* Performance HUD */
|
||||
BB_ACTION_CHEAT_TOGGLE, /* In-game cheat menu */
|
||||
BB_ACTION_MOUSE_CAPTURE_TOGGLE, /* Capture / release the mouse */
|
||||
BB_ACTION_COUNT
|
||||
};
|
||||
|
||||
/* Action keybinding queries */
|
||||
int bbgpu_get_action_binding(int action);
|
||||
void bbgpu_get_all_action_bindings(int *out_bindings, int count);
|
||||
void bbgpu_set_action_binding(int action, int code);
|
||||
|
||||
/* Save data safeguards */
|
||||
int bbgpu_get_save_auto_backup(void);
|
||||
|
||||
/* Shader recipes & cache rebuilds (Phase 2) */
|
||||
int bbgpu_rebuild_shader_caches(void);
|
||||
int bbgpu_rebuild_shader_cache(const char *dir);
|
||||
int bbgpu_export_shader_recipes(const char *cache_dir, const char *game_dir, const char *out_path);
|
||||
int bbgpu_import_shader_recipes(const char *cache_dir, const char *pack, const char *game_dir,
|
||||
unsigned long long motion_params, unsigned long long motion_positions);
|
||||
int bbgpu_merge_shader_metas(const char *cache_dir, const char *pack, const char *game_dir,
|
||||
const char *meta_dir, const char *out_pack, const char *work_dir, int jobs);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,59 @@
|
||||
# SPDX-FileCopyrightText: Copyright 2026 IFreemz (shadps4_dlss bridge), bbport contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
# bbport_dlss (bbport_dlss.dll) links the NVIDIA DLSS SDK and is built separately from the port.
|
||||
# Everything else in bbport is MinGW-w64; this one DLL must be MSVC because NVIDIA's Windows NGX
|
||||
# SDK ships MSVC-only libraries (nvsdk_ngx_s.lib uses the MSVC CRT and C++ EH metadata).
|
||||
#
|
||||
# The SDK's public part is vendored in third_party/nvngx-sdk (github.com/NVIDIA/DLSS):
|
||||
# include/nvsdk_ngx*.h and lib/Windows_x86_64/x64/nvsdk_ngx_s.lib
|
||||
# Point DLSS_SDK_ROOT at another copy (e.g. .downloads/DLSS) to build against it instead.
|
||||
#
|
||||
# Build (from a "x64 Native Tools Command Prompt for VS", or after vcvars64.bat):
|
||||
# cmake -S gpu/dlss_bridge -B out/dlss-bridge -G Ninja -DCMAKE_BUILD_TYPE=Release ^
|
||||
# -DCMAKE_CXX_COMPILER=cl
|
||||
# cmake --build out/dlss-bridge
|
||||
# build.bat does this automatically and copies the DLL next to bb-probe.exe.
|
||||
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
project(bbport_dlss LANGUAGES CXX)
|
||||
|
||||
set(DEFAULT_DLSS_SDK_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/third_party/nvngx-sdk")
|
||||
set(DLSS_SDK_ROOT "${DEFAULT_DLSS_SDK_ROOT}" CACHE PATH
|
||||
"NVIDIA DLSS SDK root (contains include/ and lib/)")
|
||||
set(VULKAN_INCLUDE "" CACHE PATH "Vulkan-Headers include directory")
|
||||
|
||||
if (NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
message(FATAL_ERROR "The DLSS bridge is x86-64 only")
|
||||
endif()
|
||||
if (NOT EXISTS "${DLSS_SDK_ROOT}/include/nvsdk_ngx_vk.h")
|
||||
message(FATAL_ERROR "Set DLSS_SDK_ROOT to the NVIDIA DLSS SDK (github.com/NVIDIA/DLSS)")
|
||||
endif()
|
||||
if (WIN32 AND NOT MSVC)
|
||||
message(FATAL_ERROR
|
||||
"NVIDIA's Windows NGX SDK ships MSVC-only libraries. Build gpu/dlss_bridge with MSVC "
|
||||
"(cl.exe); the rest of bbport stays MinGW-w64. DLSS falls back to FSR 3.1 without it.")
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
# nvsdk_ngx_s.lib is the static-CRT (/MT) variant: no Visual C++ runtime install needed.
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded")
|
||||
|
||||
add_library(bbport_dlss SHARED bbport_dlss_bridge.cpp bbport_dlss_bridge.h)
|
||||
target_include_directories(bbport_dlss PRIVATE "${DLSS_SDK_ROOT}/include" ${VULKAN_INCLUDE})
|
||||
|
||||
if (WIN32)
|
||||
# advapi32 (NGX reads its driver-store path from the registry) and user32 are not in MSVC's
|
||||
# default library set for a /LD build.
|
||||
target_link_libraries(bbport_dlss PRIVATE
|
||||
"${DLSS_SDK_ROOT}/lib/Windows_x86_64/x64/nvsdk_ngx_s.lib"
|
||||
advapi32 user32)
|
||||
target_compile_definitions(bbport_dlss PRIVATE NOMINMAX WIN32_LEAN_AND_MEAN)
|
||||
else()
|
||||
# Only BbDlssGetApi is exported; NGX finds libnvidia-ngx-dlss.so.<version> next to bb-probe.
|
||||
set_target_properties(bbport_dlss PROPERTIES CXX_VISIBILITY_PRESET hidden)
|
||||
target_link_libraries(bbport_dlss PRIVATE "${DLSS_SDK_ROOT}/lib/Linux_x86_64/libnvsdk_ngx.a"
|
||||
${CMAKE_DL_LIBS})
|
||||
target_link_options(bbport_dlss PRIVATE -Wl,--no-undefined -Wl,--exclude-libs,ALL)
|
||||
endif()
|
||||
@@ -0,0 +1,27 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 IFreemz
|
||||
Copyright (c) 2026 bbport contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
This license covers the files in this directory only. The bridge is adapted from
|
||||
the shadps4_dlss bridge of https://github.com/IFreemz/shadPS4-Bloodborne-DLSS-FSR.
|
||||
Building it requires the NVIDIA DLSS SDK (https://github.com/NVIDIA/DLSS), which is
|
||||
licensed separately by NVIDIA Corporation and is not included in this repository.
|
||||
@@ -0,0 +1,89 @@
|
||||
# bbport DLSS bridge
|
||||
|
||||
`bbport_dlss.dll` — the only part of bbport that links NVIDIA's DLSS SDK. The port itself
|
||||
(`bbport.exe`, `src/`, `gpu/`) never includes NGX headers or libraries: `vk_dlss.cpp` loads this
|
||||
DLL at run time with `LoadLibraryA("bbport_dlss.dll")` and calls the plain C ABI in
|
||||
`bbport_dlss_bridge.h`. Without the DLL, without an RTX GPU or with `BB_DLSS=0` the port keeps
|
||||
FSR 3.1 and changes nothing else.
|
||||
|
||||
The code is adapted from `IFreemz/shadPS4-Bloodborne-DLSS-FSR` (MIT, `LICENSE.txt`).
|
||||
|
||||
## Why MSVC and not MinGW
|
||||
|
||||
NVIDIA's Windows SDK ships `nvsdk_ngx_s.lib` (and the debug variants) built with MSVC. It
|
||||
references the MSVC C++ runtime and exception-handling metadata, so MinGW-w64's `ld` cannot link
|
||||
it (undefined `__std_*`, `__security_cookie`, SEH records). Verified with gcc 15 / binutils 2.44:
|
||||
the failure is intrinsic, not a missing flag. The bridge is therefore the one target built with
|
||||
MSVC (`cl.exe`); everything else stays MinGW-w64.
|
||||
|
||||
`build.bat` performs the MSVC build automatically when Visual Studio (Build Tools or IDE) and the
|
||||
vendored SDK are present, and warns + keeps FSR 3.1 otherwise.
|
||||
|
||||
## SDK files kept in the tree
|
||||
|
||||
Only the public, redistributable part of <https://github.com/NVIDIA/DLSS> is vendored, in
|
||||
`third_party/nvngx-sdk/`:
|
||||
|
||||
```
|
||||
include/nvsdk_ngx.h
|
||||
include/nvsdk_ngx_defs.h
|
||||
include/nvsdk_ngx_helpers.h
|
||||
include/nvsdk_ngx_helpers_dlssd.h
|
||||
include/nvsdk_ngx_helpers_vk.h
|
||||
include/nvsdk_ngx_params.h
|
||||
include/nvsdk_ngx_vk.h
|
||||
lib/Windows_x86_64/x64/nvsdk_ngx_s.lib
|
||||
```
|
||||
|
||||
To use a full SDK checkout instead, pass `-DDLSS_SDK_ROOT=<path>` to CMake
|
||||
(the `.downloads/DLSS` sparse checkout used during development works).
|
||||
|
||||
**`nvngx_dlss.dll` is not part of this repository** (NVIDIA's runtime, ~59 MB). The NVIDIA RTX
|
||||
SDKs license allows shipping it as part of a DLSS-enabled application together with the license
|
||||
text, but `build.bat` never copies it into `out/`: place it there or in `<user>/dlss/` yourself
|
||||
(or add it to your own release archive, keeping `licenses/NVIDIA-DLSS-LICENSE.txt`).
|
||||
|
||||
## Build
|
||||
|
||||
From a normal shell (the script finds VS with `vswhere` and calls `vcvars64.bat`):
|
||||
|
||||
```
|
||||
build.bat
|
||||
```
|
||||
|
||||
or manually, from an *x64 Native Tools Command Prompt* (or after `vcvars64.bat`):
|
||||
|
||||
```
|
||||
cmake -S gpu/dlss_bridge -B out/dlss-bridge -G Ninja -DCMAKE_BUILD_TYPE=Release ^
|
||||
-DCMAKE_CXX_COMPILER=cl ^
|
||||
-DDLSS_SDK_ROOT=gpu/dlss_bridge/third_party/nvngx-sdk ^
|
||||
-DVULKAN_INCLUDE=<Vulkan-Headers>/include
|
||||
cmake --build out/dlss-bridge
|
||||
```
|
||||
|
||||
The result is `out/dlss-bridge/bbport_dlss.dll`; `build.bat` copies it to `out/bbport_dlss.dll`
|
||||
next to `bb-probe.exe`. Set `BB_DLSS_BRIDGE=0` to skip the step.
|
||||
|
||||
## Runtime files
|
||||
|
||||
DLSS needs three pieces, all optional:
|
||||
|
||||
| File | Where | Notes |
|
||||
| --- | --- | --- |
|
||||
| `bbport_dlss.dll` | next to `bb-probe.exe` (built by `build.bat`) | this bridge |
|
||||
| `nvngx_dlss.dll` | next to `bb-probe.exe`, or in `<user>/dlss/` | NVIDIA's Super Resolution library, from a driver install (`C:\ProgramData\NVIDIA Corporation\NGX\models\...` and the DriverStore) or the SDK download |
|
||||
| NVIDIA driver | — | RTX 20 series or newer for DLSS |
|
||||
|
||||
`<user>` is the port's user directory (`BB_GPU_USER_DIR`, i.e. the folder that holds saves and
|
||||
shader caches); NGX also writes its logs there, in `dlss/`.
|
||||
|
||||
The loader order is: `BB_DLSS=0` → off; no `bbport_dlss.dll` → off; no `nvngx_dlss.dll` → off;
|
||||
non-NVIDIA GPU → off; NVIDIA GPU/driver without DLSS support (GTX) → off. In every case the
|
||||
upscaler silently stays on FSR 3.1 and the overlay shows why DLSS is unavailable.
|
||||
|
||||
## License
|
||||
|
||||
- Bridge source: MIT (`LICENSE.txt`).
|
||||
- NVIDIA RTX SDKs license: `licenses/NVIDIA-DLSS-LICENSE.txt` (shipped with the port).
|
||||
- `nvngx_dlss.dll` is NVIDIA's; do not add it to the repository or to release archives that are
|
||||
not covered by the NVIDIA RTX SDKs license.
|
||||
@@ -0,0 +1,265 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 IFreemz (shadps4_dlss bridge), bbport contributors
|
||||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// libbbport_dlss.so / bbport_dlss.dll: the only part of the project that uses the NVIDIA DLSS
|
||||
// (NGX) SDK; the port loads it at run time. Linux: build.sh with DLSS_SDK_ROOT; Windows: MSVC
|
||||
// (the SDK's Windows libraries are MSVC only), see CMakeLists.txt.
|
||||
// Adapted from IFreemz/shadPS4-Bloodborne-DLSS-FSR (dlss_bridge).
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
|
||||
#include "bbport_dlss_bridge.h" // Vulkan first: the NGX headers expect its types
|
||||
|
||||
#include <nvsdk_ngx_helpers.h>
|
||||
#include <nvsdk_ngx_vk.h>
|
||||
#include <nvsdk_ngx_helpers_vk.h>
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr char ProjectId[] = "42359704-c9f3-4806-9fb5-d469000fdb8a";
|
||||
#ifdef _WIN32
|
||||
constexpr char EngineVersion[] = "bbport-windows";
|
||||
#else
|
||||
constexpr char EngineVersion[] = "bbport-linux";
|
||||
#endif
|
||||
|
||||
struct State {
|
||||
BbDlssLogFn log{};
|
||||
std::wstring dll_directory;
|
||||
std::wstring data_directory;
|
||||
const wchar_t* dll_path{};
|
||||
NVSDK_NGX_FeatureCommonInfo common{};
|
||||
NVSDK_NGX_FeatureDiscoveryInfo discovery{};
|
||||
NVSDK_NGX_Parameter* capabilities{};
|
||||
NVSDK_NGX_Parameter* parameters{};
|
||||
NVSDK_NGX_Handle* feature{};
|
||||
BbDlssFeature feature_desc{};
|
||||
VkDevice device{};
|
||||
bool configured{};
|
||||
bool initialized{};
|
||||
} state;
|
||||
|
||||
template <typename... Args>
|
||||
void Log(int warning, const char* format, Args... args) {
|
||||
if (!state.log)
|
||||
return;
|
||||
if constexpr (sizeof...(Args) == 0) {
|
||||
state.log(warning, format); // a plain message (no format string without arguments)
|
||||
} else {
|
||||
std::array<char, 1024> text{};
|
||||
std::snprintf(text.data(), text.size(), format, args...);
|
||||
state.log(warning, text.data());
|
||||
}
|
||||
}
|
||||
|
||||
bool Check(const char* operation, NVSDK_NGX_Result result) {
|
||||
if (NVSDK_NGX_FAILED(result)) {
|
||||
Log(1, "%s failed: 0x%08x", operation, static_cast<unsigned>(result));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void NVSDK_CONV NgxLog(const char* message, NVSDK_NGX_Logging_Level, NVSDK_NGX_Feature) {
|
||||
Log(0, "NGX: %s", message ? message : "");
|
||||
}
|
||||
|
||||
int32_t Configure(const wchar_t* dll_directory, const wchar_t* data_directory, BbDlssLogFn log) {
|
||||
state.log = log;
|
||||
state.dll_directory = dll_directory ? dll_directory : L".";
|
||||
state.data_directory = data_directory ? data_directory : L".";
|
||||
state.dll_path = state.dll_directory.c_str();
|
||||
state.common.PathListInfo = {&state.dll_path, 1};
|
||||
state.common.LoggingInfo = {NgxLog, NVSDK_NGX_LOGGING_LEVEL_OFF, false};
|
||||
state.discovery.SDKVersion = NVSDK_NGX_Version_API;
|
||||
state.discovery.FeatureID = NVSDK_NGX_Feature_SuperSampling;
|
||||
state.discovery.Identifier.IdentifierType = NVSDK_NGX_Application_Identifier_Type_Project_Id;
|
||||
state.discovery.Identifier.v.ProjectDesc = {ProjectId, NVSDK_NGX_ENGINE_TYPE_CUSTOM,
|
||||
EngineVersion};
|
||||
state.discovery.ApplicationDataPath = state.data_directory.c_str();
|
||||
state.discovery.FeatureInfo = &state.common;
|
||||
state.configured = true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t InstanceExtensions(uint32_t* count, const VkExtensionProperties** extensions) {
|
||||
VkExtensionProperties* required{};
|
||||
if (!state.configured ||
|
||||
!Check("Instance extension query",
|
||||
NVSDK_NGX_VULKAN_GetFeatureInstanceExtensionRequirements(&state.discovery, count,
|
||||
&required)))
|
||||
return 0;
|
||||
*extensions = required;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t DeviceExtensions(VkInstance instance, VkPhysicalDevice physical, uint32_t* count,
|
||||
const VkExtensionProperties** extensions) {
|
||||
if (!state.configured)
|
||||
return 0;
|
||||
NVSDK_NGX_FeatureRequirement support{};
|
||||
if (!Check("Feature requirement query",
|
||||
NVSDK_NGX_VULKAN_GetFeatureRequirements(instance, physical, &state.discovery,
|
||||
&support)))
|
||||
return 0;
|
||||
if (support.FeatureSupported != NVSDK_NGX_FeatureSupportResult_Supported) {
|
||||
Log(1, "DLSS is not supported on this GPU or driver (code 0x%x)",
|
||||
static_cast<unsigned>(support.FeatureSupported));
|
||||
return 0;
|
||||
}
|
||||
VkExtensionProperties* required{};
|
||||
if (!Check("Device extension query",
|
||||
NVSDK_NGX_VULKAN_GetFeatureDeviceExtensionRequirements(
|
||||
instance, physical, &state.discovery, count, &required)))
|
||||
return 0;
|
||||
*extensions = required;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t Initialize(VkInstance instance, VkPhysicalDevice physical, VkDevice device,
|
||||
PFN_vkGetInstanceProcAddr get_instance_proc,
|
||||
PFN_vkGetDeviceProcAddr get_device_proc) {
|
||||
if (!state.configured || state.initialized)
|
||||
return 0;
|
||||
if (!Check("NGX initialization",
|
||||
NVSDK_NGX_VULKAN_Init_with_ProjectID(
|
||||
ProjectId, NVSDK_NGX_ENGINE_TYPE_CUSTOM, EngineVersion,
|
||||
state.data_directory.c_str(), instance, physical, device, get_instance_proc,
|
||||
get_device_proc, &state.common)))
|
||||
return 0;
|
||||
state.initialized = true;
|
||||
state.device = device;
|
||||
if (!Check("Capability query", NVSDK_NGX_VULKAN_GetCapabilityParameters(&state.capabilities)))
|
||||
return 0;
|
||||
int available{}, needs_driver{};
|
||||
NVSDK_NGX_Parameter_GetI(state.capabilities, NVSDK_NGX_Parameter_SuperSampling_Available,
|
||||
&available);
|
||||
NVSDK_NGX_Parameter_GetI(state.capabilities,
|
||||
NVSDK_NGX_Parameter_SuperSampling_NeedsUpdatedDriver, &needs_driver);
|
||||
if (needs_driver) {
|
||||
Log(1, "DLSS needs a newer NVIDIA driver");
|
||||
return 0;
|
||||
}
|
||||
if (!available) {
|
||||
Log(1, "DLSS Super Resolution is not available on this system");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ReleaseFeature() {
|
||||
if (state.feature) {
|
||||
NVSDK_NGX_VULKAN_ReleaseFeature(state.feature);
|
||||
state.feature = nullptr;
|
||||
}
|
||||
if (state.parameters) {
|
||||
NVSDK_NGX_VULKAN_DestroyParameters(state.parameters);
|
||||
state.parameters = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t CreateFeature(VkCommandBuffer command, const BbDlssFeature* desc) {
|
||||
if (!state.initialized || !state.capabilities || !desc)
|
||||
return 0;
|
||||
ReleaseFeature();
|
||||
if (!Check("Parameter allocation", NVSDK_NGX_VULKAN_AllocateParameters(&state.parameters)))
|
||||
return 0;
|
||||
for (const char* key : {NVSDK_NGX_Parameter_DLSS_Hint_Render_Preset_DLAA,
|
||||
NVSDK_NGX_Parameter_DLSS_Hint_Render_Preset_Quality,
|
||||
NVSDK_NGX_Parameter_DLSS_Hint_Render_Preset_Balanced,
|
||||
NVSDK_NGX_Parameter_DLSS_Hint_Render_Preset_Performance,
|
||||
NVSDK_NGX_Parameter_DLSS_Hint_Render_Preset_UltraPerformance,
|
||||
NVSDK_NGX_Parameter_DLSS_Hint_Render_Preset_UltraQuality})
|
||||
NVSDK_NGX_Parameter_SetUI(state.parameters, key, desc->preset);
|
||||
static constexpr std::array qualities{
|
||||
NVSDK_NGX_PerfQuality_Value_DLAA, NVSDK_NGX_PerfQuality_Value_MaxQuality,
|
||||
NVSDK_NGX_PerfQuality_Value_Balanced, NVSDK_NGX_PerfQuality_Value_MaxPerf,
|
||||
NVSDK_NGX_PerfQuality_Value_UltraPerformance};
|
||||
NVSDK_NGX_DLSS_Create_Params settings{};
|
||||
settings.Feature.InWidth = desc->input_width;
|
||||
settings.Feature.InHeight = desc->input_height;
|
||||
settings.Feature.InTargetWidth = desc->output_width;
|
||||
settings.Feature.InTargetHeight = desc->output_height;
|
||||
settings.Feature.InPerfQualityValue = qualities[std::clamp(desc->quality, 0, 4)];
|
||||
settings.InFeatureCreateFlags =
|
||||
NVSDK_NGX_DLSS_Feature_Flags_MVLowRes |
|
||||
(desc->depth_inverted ? NVSDK_NGX_DLSS_Feature_Flags_DepthInverted : 0) |
|
||||
(desc->hdr ? NVSDK_NGX_DLSS_Feature_Flags_IsHDR | NVSDK_NGX_DLSS_Feature_Flags_AutoExposure
|
||||
: 0);
|
||||
const auto result = NGX_VULKAN_CREATE_DLSS_EXT1(state.device, command, 1, 1, &state.feature,
|
||||
state.parameters, &settings);
|
||||
if (!Check("DLSS feature creation", result) || !state.feature) {
|
||||
state.feature = nullptr;
|
||||
return 0;
|
||||
}
|
||||
state.feature_desc = *desc;
|
||||
Log(0, "DLSS %ux%u -> %ux%u, quality %d, preset %u%s", desc->input_width, desc->input_height,
|
||||
desc->output_width, desc->output_height, desc->quality, desc->preset,
|
||||
desc->hdr ? ", HDR input" : "");
|
||||
return 1;
|
||||
}
|
||||
|
||||
NVSDK_NGX_Resource_VK Wrap(const BbDlssImage& image, bool writable) {
|
||||
return NVSDK_NGX_Create_ImageView_Resource_VK(image.view, image.image, image.range,
|
||||
image.format, image.width, image.height,
|
||||
writable);
|
||||
}
|
||||
|
||||
int32_t Evaluate(VkCommandBuffer command, const BbDlssEvaluate* evaluate) {
|
||||
if (!state.feature || !state.parameters || !evaluate)
|
||||
return 0;
|
||||
auto color = Wrap(evaluate->color, false);
|
||||
auto depth = Wrap(evaluate->depth, false);
|
||||
auto motion = Wrap(evaluate->motion, false);
|
||||
auto output = Wrap(evaluate->output, true);
|
||||
NVSDK_NGX_VK_DLSS_Eval_Params parameters{};
|
||||
parameters.Feature.pInColor = &color;
|
||||
parameters.Feature.pInOutput = &output;
|
||||
parameters.Feature.InSharpness = evaluate->sharpness;
|
||||
parameters.pInDepth = &depth;
|
||||
parameters.pInMotionVectors = &motion;
|
||||
parameters.InRenderSubrectDimensions = {state.feature_desc.input_width,
|
||||
state.feature_desc.input_height};
|
||||
parameters.InJitterOffsetX = evaluate->jitter_x;
|
||||
parameters.InJitterOffsetY = evaluate->jitter_y;
|
||||
parameters.InReset = evaluate->reset;
|
||||
parameters.InMVScaleX = parameters.InMVScaleY = 1.0f;
|
||||
parameters.InPreExposure = parameters.InExposureScale = 1.0f;
|
||||
parameters.InFrameTimeDeltaInMsec = evaluate->frame_ms;
|
||||
return Check("DLSS evaluation", NGX_VULKAN_EVALUATE_DLSS_EXT(command, state.feature,
|
||||
state.parameters, ¶meters))
|
||||
? 1
|
||||
: 0;
|
||||
}
|
||||
|
||||
void Shutdown() {
|
||||
ReleaseFeature();
|
||||
if (state.capabilities) {
|
||||
NVSDK_NGX_VULKAN_DestroyParameters(state.capabilities);
|
||||
state.capabilities = nullptr;
|
||||
}
|
||||
if (state.initialized) {
|
||||
NVSDK_NGX_VULKAN_Shutdown1(state.device);
|
||||
state.initialized = false;
|
||||
state.device = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
const BbDlssApi api{BBPORT_DLSS_BRIDGE_ABI, Configure, InstanceExtensions, DeviceExtensions,
|
||||
Initialize, CreateFeature, Evaluate, ReleaseFeature,
|
||||
Shutdown};
|
||||
|
||||
} // namespace
|
||||
|
||||
#ifdef _WIN32
|
||||
#define BBPORT_DLSS_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define BBPORT_DLSS_EXPORT __attribute__((visibility("default")))
|
||||
#endif
|
||||
|
||||
extern "C" BBPORT_DLSS_EXPORT const BbDlssApi* BbDlssGetApi() {
|
||||
return &api;
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 IFreemz (shadps4_dlss bridge), bbport contributors
|
||||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// C interface between bbport and the DLSS bridge (libbbport_dlss.so / bbport_dlss.dll). The port
|
||||
// contains no NVIDIA code: it loads the bridge at run time when it is present (next to bb-probe,
|
||||
// with NVIDIA's libnvidia-ngx-dlss.so.<version> / nvngx_dlss.dll) and keeps
|
||||
// its other upscalers when it is absent. Adapted from IFreemz/shadPS4-Bloodborne-DLSS-FSR.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define BBPORT_DLSS_BRIDGE_ABI 1
|
||||
|
||||
typedef void (*BbDlssLogFn)(int warning, const char* message);
|
||||
|
||||
typedef struct BbDlssImage {
|
||||
VkImage image;
|
||||
VkImageView view;
|
||||
VkImageSubresourceRange range;
|
||||
VkFormat format;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
} BbDlssImage;
|
||||
|
||||
typedef struct BbDlssFeature {
|
||||
uint32_t input_width;
|
||||
uint32_t input_height;
|
||||
uint32_t output_width;
|
||||
uint32_t output_height;
|
||||
int32_t quality; // 0 DLAA, 1 Quality, 2 Balanced, 3 Performance, 4 Ultra Performance
|
||||
int32_t depth_inverted;
|
||||
uint32_t preset; // NVSDK_NGX_DLSS_Hint_Render_Preset value, 0 = driver default
|
||||
int32_t hdr; // 1: linear HDR colour with automatic exposure, 0: tonemapped colour
|
||||
} BbDlssFeature;
|
||||
|
||||
typedef struct BbDlssEvaluate {
|
||||
BbDlssImage color; // sampled
|
||||
BbDlssImage depth; // sampled, hardware depth
|
||||
BbDlssImage motion; // sampled, render-resolution pixels, current to previous
|
||||
BbDlssImage output; // storage, general layout
|
||||
float jitter_x;
|
||||
float jitter_y;
|
||||
int32_t reset;
|
||||
float frame_ms;
|
||||
float sharpness; // 0..1; 0 leaves the output unsharpened
|
||||
} BbDlssEvaluate;
|
||||
|
||||
typedef struct BbDlssApi {
|
||||
uint32_t abi;
|
||||
// wchar_t paths (NGX's type): the directory with NVIDIA's DLSS library, and a writable data
|
||||
// directory.
|
||||
int32_t (*Configure)(const wchar_t* dll_directory, const wchar_t* data_directory,
|
||||
BbDlssLogFn log);
|
||||
// Vulkan extensions NGX needs. The arrays stay valid until Shutdown.
|
||||
int32_t (*InstanceExtensions)(uint32_t* count, const VkExtensionProperties** extensions);
|
||||
int32_t (*DeviceExtensions)(VkInstance instance, VkPhysicalDevice physical, uint32_t* count,
|
||||
const VkExtensionProperties** extensions);
|
||||
int32_t (*Initialize)(VkInstance instance, VkPhysicalDevice physical, VkDevice device,
|
||||
PFN_vkGetInstanceProcAddr get_instance_proc,
|
||||
PFN_vkGetDeviceProcAddr get_device_proc);
|
||||
int32_t (*CreateFeature)(VkCommandBuffer command, const BbDlssFeature* feature);
|
||||
int32_t (*Evaluate)(VkCommandBuffer command, const BbDlssEvaluate* evaluate);
|
||||
// The caller must have waited for the GPU work that used the feature.
|
||||
void (*ReleaseFeature)(void);
|
||||
void (*Shutdown)(void);
|
||||
} BbDlssApi;
|
||||
|
||||
typedef const BbDlssApi* (*BbDlssGetApiFn)(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,712 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2018-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: LicenseRef-NvidiaProprietary
|
||||
*
|
||||
* NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
|
||||
* property and proprietary rights in and to this material, related
|
||||
* documentation and any modifications thereto. Any use, reproduction,
|
||||
* disclosure or distribution of this material and related documentation
|
||||
* without an express license agreement from NVIDIA CORPORATION or
|
||||
* its affiliates is strictly prohibited.
|
||||
*/
|
||||
|
||||
/*
|
||||
* HOW TO USE:
|
||||
*
|
||||
* IMPORTANT: FOR DLSS/DLISP PLEASE SEE THE PROGRAMMING GUIDE
|
||||
*
|
||||
* IMPORTANT: Methods in this library are NOT thread safe. It is up to the
|
||||
* client to ensure that thread safety is enforced as needed.
|
||||
*
|
||||
* 1) Call NVSDK_CONV NVSDK_NGX_D3D11/D3D12/CUDA_Init and pass your app Id
|
||||
* and other parameters. This will initialize SDK or return an error code
|
||||
* if SDK cannot run on target machine. Depending on error user might
|
||||
* need to update drivers. Please note that application Id is provided
|
||||
* by NVIDIA so if you do not have one please contact us.
|
||||
*
|
||||
* 2) Call NVSDK_NGX_D3D11/D3D12/CUDA_GetCapabilityParameters to obtain pointer to
|
||||
* interface used to pass parameters to SDK. Interface instance is
|
||||
* allocated and released by SDK so there is no need to do any memory
|
||||
* management on client side.
|
||||
*
|
||||
* 3) Set key parameters for the feature you want to use. For example,
|
||||
* width and height are required for all features and they can be
|
||||
* set like this:
|
||||
* Params->Set(NVSDK_NGX_Parameter_Width,MY_WIDTH);
|
||||
* Params->Set(NVSDK_NGX_Parameter_Height,MY_HEIGHT);
|
||||
*
|
||||
* Please refer to samples since different features need different
|
||||
* parameters and hints.
|
||||
*
|
||||
* 4) Call NVSDK_NGX_D3D11/D3D12/CUDA_GetScratchBufferSize to obtain size of
|
||||
* the scratch buffer needed by specific feature. This D3D or CUDA buffer
|
||||
* should be allocated by client and passed as:
|
||||
* Params->Set(NVSDK_NGX_Parameter_Scratch,MY_SCRATCH_POINTER)
|
||||
* Params->Set(NVSDK_NGX_Parameter_Scratch_SizeInBytes,MY_SCRATCH_SIZE_IN_BYTES)
|
||||
* NOTE: Returned size can be 0 if feature does not use any scratch buffer.
|
||||
* It is OK to use bigger buffer or reuse buffers across features as long
|
||||
* as minimum size requirement is met.
|
||||
*
|
||||
* 5) Call NVSDK_NGX_D3D11/D3D12/CUDA_CreateFeature to create feature you need.
|
||||
* On success SDK will return a handle which must be used in any successive
|
||||
* calls to SDK which require feature handle. SDK will use all parameters
|
||||
* and hints provided by client to generate feature. If feature with the same
|
||||
* parameters already exists and error code will be returned.
|
||||
*
|
||||
* 6) Call NVSDK_NGX_D3D11/D3D12/CUDA_EvaluateFeature to invoke execution of
|
||||
* specific feature. Before feature can be evaluated input parameters must
|
||||
* be specified (like for example color/albedo buffer, motion vectors etc)
|
||||
*
|
||||
* 6) Call NVSDK_NGX_D3D11/D3D12/CUDA_ReleaseFeature when feature is no longer
|
||||
* needed. After this call feature handle becomes invalid and cannot be used.
|
||||
*
|
||||
* 7) Call NVSDK_NGX_D3D11/D3D12/CUDA_Shutdown when SDK is no longer needed to
|
||||
* release all resources.
|
||||
|
||||
* Contact: [email protected]
|
||||
*/
|
||||
|
||||
|
||||
#ifndef NVSDK_NGX_H
|
||||
#define NVSDK_NGX_H
|
||||
|
||||
#include <stddef.h> // For size_t
|
||||
|
||||
#include "nvsdk_ngx_defs.h"
|
||||
#include "nvsdk_ngx_params.h"
|
||||
#ifndef __cplusplus
|
||||
#include <stdbool.h>
|
||||
#include <wchar.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef struct IDXGIAdapter IDXGIAdapter;
|
||||
typedef struct ID3D11Device ID3D11Device;
|
||||
typedef struct ID3D11Resource ID3D11Resource;
|
||||
typedef struct ID3D11DeviceContext ID3D11DeviceContext;
|
||||
|
||||
typedef struct ID3D12Device ID3D12Device;
|
||||
typedef struct ID3D12GraphicsCommandList ID3D12GraphicsCommandList;
|
||||
|
||||
typedef unsigned long long CUtexObject;
|
||||
|
||||
// NOTE: Functions under the same name and different function signatures exist
|
||||
// between the NGX SDK, NGX Core (driver), and NGX Snippets. To discern the
|
||||
// different signatures here we check if NGX_SNIPPET_BUILD is defined. When that
|
||||
// is the case we know that the function signature in-use should be that of
|
||||
// between NGX Core and the Snippet. Otherwise the signature should be between
|
||||
// NGX SDK and NGX Core.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NVSDK_NGX_Init
|
||||
// -----------------------------------------------------------------------------
|
||||
// Initializes a new SDK instance.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Initializes a new SDK instance. Most NGX SDK functions require the NGX
|
||||
// SDK to be initialized for the corresponding graphics API and device to
|
||||
// function properly.
|
||||
//
|
||||
// NVSDK_NGX_Init requires an application ID provided by NVIDIA. If an
|
||||
// application ID is not available, use NVSDK_NGX_Init_with_ProjectID to
|
||||
// supply your own identifier.
|
||||
//
|
||||
// Be sure to call NVSDK_NGX_Shutdown to shut down the SDK when it is no
|
||||
// longer needed.
|
||||
//
|
||||
// PARAMETERS:
|
||||
// InApplicationId:
|
||||
// Unique ID provided by NVIDIA.
|
||||
//
|
||||
// InApplicationDataPath:
|
||||
// Directory to store logs and other temporary files. Write access is
|
||||
// required. Typically, this would be next to the application executable,
|
||||
// or in a location like Documents or ProgramData.
|
||||
//
|
||||
// InDevice (D3D11/12 only):
|
||||
// DirectX device to use.
|
||||
//
|
||||
// InFeatureInfo:
|
||||
// Contains information common to all features, including a list of paths
|
||||
// where feature DLLs can be located, other than the default path (application directory).
|
||||
//
|
||||
// InSDKVersion:
|
||||
// Version of the SDK currently in use. Typically, this should be left as
|
||||
// the default value, NVSDK_NGX_Version_API.
|
||||
//
|
||||
// RETURNS:
|
||||
// NVSDK_NGX_Result indicating success or failure. Common values include:
|
||||
// - NVSDK_NGX_Result_Success if the function executed successfully
|
||||
// - NVSDK_NGX_Result_FAIL_FeatureNotSupported if the NGX SDK is not
|
||||
// supported on the current system
|
||||
// Check the NGX logs for additional information about any failures.
|
||||
//
|
||||
#if defined(NGX_SNIPPET_BUILD)
|
||||
#ifdef __cplusplus
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_Init(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, ID3D11Device *InDevice, NVSDK_NGX_Version InSDKVersion = NVSDK_NGX_Version_API);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_Init_Ext(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, ID3D11Device *InDevice, NVSDK_NGX_Version InSDKVersion = NVSDK_NGX_Version_API, const NVSDK_NGX_Parameter* InParameters = nullptr);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D12_Init(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, ID3D12Device *InDevice, NVSDK_NGX_Version InSDKVersion = NVSDK_NGX_Version_API);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D12_Init_Ext(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, ID3D12Device *InDevice, NVSDK_NGX_Version InSDKVersion = NVSDK_NGX_Version_API, const NVSDK_NGX_Parameter* InParameters = nullptr);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_Init(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, NVSDK_NGX_Version InSDKVersion = NVSDK_NGX_Version_API);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_Init_Ext(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, NVSDK_NGX_Version InSDKVersion = NVSDK_NGX_Version_API, const NVSDK_NGX_Parameter* InParameters = nullptr);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_Init_Ext1(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, NVSDK_NGX_CUDADevice *InDevice, NVSDK_NGX_Version InSDKVersion = NVSDK_NGX_Version_API, const NVSDK_NGX_Parameter* InParameters = nullptr);
|
||||
#else
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_Init(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, ID3D11Device *InDevice, NVSDK_NGX_Version InSDKVersion);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_Init_Ext(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, ID3D11Device *InDevice, NVSDK_NGX_Version InSDKVersion, const NVSDK_NGX_Parameter* InParameters);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D12_Init(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, ID3D12Device *InDevice, NVSDK_NGX_Version InSDKVersion);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D12_Init_Ext(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, ID3D12Device *InDevice, NVSDK_NGX_Version InSDKVersion, const NVSDK_NGX_Parameter* InParameters);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_Init(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, NVSDK_NGX_Version InSDKVersion);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_Init_Ext(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, NVSDK_NGX_Version InSDKVersion, const NVSDK_NGX_Parameter* InParameters);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_Init_Ext1(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, NVSDK_NGX_CUDADevice *InDevice, NVSDK_NGX_Version InSDKVersion, const NVSDK_NGX_Parameter* InParameters);
|
||||
#endif
|
||||
#else
|
||||
#ifdef __cplusplus
|
||||
NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_Init(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, ID3D11Device *InDevice, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo = nullptr, NVSDK_NGX_Version InSDKVersion = NVSDK_NGX_Version_API);
|
||||
NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D12_Init(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, ID3D12Device *InDevice, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo = nullptr, NVSDK_NGX_Version InSDKVersion = NVSDK_NGX_Version_API);
|
||||
NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_Init(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo = nullptr, NVSDK_NGX_Version InSDKVersion = NVSDK_NGX_Version_API);
|
||||
NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_Init1(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, NVSDK_NGX_CUDADevice *InDevice, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo = nullptr, NVSDK_NGX_Version InSDKVersion = NVSDK_NGX_Version_API);
|
||||
#else
|
||||
NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_Init(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, ID3D11Device *InDevice, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo, NVSDK_NGX_Version InSDKVersion);
|
||||
NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D12_Init(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, ID3D12Device *InDevice, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo, NVSDK_NGX_Version InSDKVersion);
|
||||
NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_Init(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo, NVSDK_NGX_Version InSDKVersion);
|
||||
NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_Init1(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, NVSDK_NGX_CUDADevice *InDevice, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo, NVSDK_NGX_Version InSDKVersion);
|
||||
#endif
|
||||
#endif // defined(NGX_SNIPPET_BUILD)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NVSDK_NGX_Init_with_ProjectID
|
||||
// -----------------------------------------------------------------------------
|
||||
// Initializes a new SDK instance using a project ID.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Initializes a new SDK instance. Most NGX SDK functions require the NGX
|
||||
// SDK to be initialized for the corresponding graphics API and device to
|
||||
// function properly.
|
||||
//
|
||||
// Applications must provide a unique identifier to initialize the NGX SDK.
|
||||
// If an identifier was provided by NVIDIA, use NVSDK_NGX_Init instead.
|
||||
//
|
||||
// For projects using third-party engines such as Unreal Engine or
|
||||
// Omniverse, the integration for those engines should handle providing the
|
||||
// correct Project ID to NGX. Ensure that the project ID is set in the
|
||||
// engine's editor.
|
||||
//
|
||||
// For other engines, use NVSDK_NGX_EngineType CUSTOM. The driver will
|
||||
// validate that the Project ID is GUID-like, for example,
|
||||
// "a0f57b54-1daf-4934-90ae-c4035c19df04". Ensure your project ID matches
|
||||
// this format.
|
||||
//
|
||||
// Be sure to call NVSDK_NGX_Shutdown to shut down the SDK when it is no
|
||||
// longer needed.
|
||||
//
|
||||
// PARAMETERS:
|
||||
// InProjectId:
|
||||
// Unique ID provided by the rendering engine used. Must be a GUID-like
|
||||
// string.
|
||||
//
|
||||
// InEngineType:
|
||||
// Rendering engine used by the application/plugin. Use NVSDK_NGX_EngineType
|
||||
// CUSTOM if the specific engine type is not explicitly supported.
|
||||
//
|
||||
// InEngineVersion:
|
||||
// Version number of the rendering engine used by the application/plugin.
|
||||
//
|
||||
// InApplicationDataPath:
|
||||
// Directory to store logs and other temporary files (write access required).
|
||||
//
|
||||
// InDevice (D3D11/12 only):
|
||||
// DirectX device to use.
|
||||
//
|
||||
// InFeatureInfo:
|
||||
// Contains information common to all features, including a list of paths
|
||||
// where feature DLLs can be located in addition to the default path
|
||||
// (the application directory).
|
||||
//
|
||||
// InSDKVersion:
|
||||
// Version of the SDK currently in use. Typically, this should be left as
|
||||
// the default value, NVSDK_NGX_Version_API.
|
||||
//
|
||||
// RETURNS:
|
||||
// NVSDK_NGX_Result indicating success or failure. Common values include:
|
||||
// - NVSDK_NGX_Result_Success if the function executed successfully
|
||||
// - NVSDK_NGX_Result_InvalidParameter if the provided project ID is in
|
||||
// an invalid format
|
||||
// - NVSDK_NGX_Result_FAIL_FeatureNotSupported if the NGX SDK is not
|
||||
// supported on the current system
|
||||
// Check the NGX logs for additional information about any failures.
|
||||
//
|
||||
#if defined(NGX_SNIPPET_BUILD)
|
||||
// No NGX Core <---> Snippet interfaces
|
||||
#else
|
||||
#ifdef __cplusplus
|
||||
NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_Init_with_ProjectID(const char *InProjectId, NVSDK_NGX_EngineType InEngineType, const char *InEngineVersion, const wchar_t *InApplicationDataPath, ID3D11Device *InDevice, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo = nullptr, NVSDK_NGX_Version InSDKVersion = NVSDK_NGX_Version_API);
|
||||
NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D12_Init_with_ProjectID(const char *InProjectId, NVSDK_NGX_EngineType InEngineType, const char *InEngineVersion, const wchar_t *InApplicationDataPath, ID3D12Device *InDevice, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo = nullptr, NVSDK_NGX_Version InSDKVersion = NVSDK_NGX_Version_API);
|
||||
NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_Init_with_ProjectID(const char *InProjectId, NVSDK_NGX_EngineType InEngineType, const char *InEngineVersion, const wchar_t *InApplicationDataPath, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo = nullptr, NVSDK_NGX_Version InSDKVersion = NVSDK_NGX_Version_API);
|
||||
#else
|
||||
NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_Init_with_ProjectID(const char *InProjectId, NVSDK_NGX_EngineType InEngineType, const char *InEngineVersion, const wchar_t *InApplicationDataPath, ID3D11Device *InDevice, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo, NVSDK_NGX_Version InSDKVersion);
|
||||
NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D12_Init_with_ProjectID(const char *InProjectId, NVSDK_NGX_EngineType InEngineType, const char *InEngineVersion, const wchar_t *InApplicationDataPath, ID3D12Device *InDevice, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo, NVSDK_NGX_Version InSDKVersion);
|
||||
NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_Init_with_ProjectID(const char *InProjectId, NVSDK_NGX_EngineType InEngineType, const char *InEngineVersion, const wchar_t *InApplicationDataPath, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo, NVSDK_NGX_Version InSDKVersion);
|
||||
#endif
|
||||
#endif // defined(NGX_SNIPPET_BUILD)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NVSDK_NGX_Shutdown
|
||||
// -----------------------------------------------------------------------------
|
||||
// Shuts down the current SDK instance and releases all resources.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Shuts down the current SDK instance and releases all resources. If a
|
||||
// device is provided, NVSDK_NGX_Shutdown1 shuts down the instance
|
||||
// corresponding to the specified device. If nullptr is provided, all
|
||||
// instances are shut down.
|
||||
//
|
||||
// Deprecation Notice: The use of Shutdown() is deprecated. Please use
|
||||
// Shutdown1(nullptr) instead.
|
||||
//
|
||||
// PARAMETERS:
|
||||
// InDevice:
|
||||
// Device to shut down. If nullptr, the SDK is shut down for all devices.
|
||||
//
|
||||
// RETURNS:
|
||||
// NVSDK_NGX_Result indicating success or failure.
|
||||
//
|
||||
#ifdef NGX_ENABLE_DEPRECATED_SHUTDOWN
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_Shutdown(void);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D12_Shutdown(void);
|
||||
#endif
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_Shutdown1(ID3D11Device *InDevice);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D12_Shutdown1(ID3D12Device *InDevice);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_Shutdown(void);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_Shutdown1(NVSDK_NGX_CUDADevice *InDevice);
|
||||
|
||||
#ifdef NGX_ENABLE_DEPRECATED_GET_PARAMETERS
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NVSDK_NGX_GetParameters
|
||||
// -----------------------------------------------------------------------------
|
||||
// Retrieves a parameter map used to set parameters needed by the SDK.
|
||||
//
|
||||
// DEPRECATED: Use NVSDK_NGX_AllocateParameters or
|
||||
// NVSDK_NGX_GetCapabilityParameters instead.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Retrieves the common NVSDK_NGX_Parameter map for providing parameters to
|
||||
// the SDK. The NVSDK_NGX_Parameter interface allows simple parameter setup
|
||||
// using named fields. For example, set the width by calling
|
||||
// Parameters->Set(NVSDK_NGX_Parameter_Width, 100) or provide a resource
|
||||
// pointer by calling Parameters->Set(NVSDK_NGX_Parameter_Color, resource).
|
||||
// For more details, see the sample code.
|
||||
//
|
||||
// Parameter maps returned by NVSDK_NGX_GetParameters are pre-populated
|
||||
// with NGX capabilities and available features. Unlike
|
||||
// NVSDK_NGX_AllocateParameters, parameter maps returned by
|
||||
// NVSDK_NGX_GetParameters have their lifetimes managed by NGX and must not
|
||||
// be destroyed by the application using NVSDK_NGX_DestroyParameters.
|
||||
//
|
||||
// This function may only be called after a successful call to
|
||||
// NVSDK_NGX_Init.
|
||||
//
|
||||
// Note: Allocated memory will be freed by NGX, so do not use the
|
||||
// free/delete operator.
|
||||
//
|
||||
// Deprecation Notice: NVSDK_NGX_GetParameters is deprecated. Applications
|
||||
// should use NVSDK_NGX_AllocateParameters and
|
||||
// NVSDK_NGX_GetCapabilityParameters when possible. However, if there is a
|
||||
// possibility that the user may be using an older driver version (driver
|
||||
// version 445 or older), NVSDK_NGX_GetParameters may still be used as a
|
||||
// fallback if NVSDK_NGX_AllocateParameters or
|
||||
// NVSDK_NGX_GetCapabilityParameters return
|
||||
// NVSDK_NGX_Result_FAIL_OutOfDate.
|
||||
//
|
||||
// PARAMETERS:
|
||||
// OutParameters:
|
||||
// Output pointer that will be populated with an NVSDK_NGX_Parameter
|
||||
// interface.
|
||||
//
|
||||
// RETURNS:
|
||||
// NVSDK_NGX_Result indicating success or failure.
|
||||
//
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_GetParameters(NVSDK_NGX_Parameter **OutParameters);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D12_GetParameters(NVSDK_NGX_Parameter **OutParameters);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_GetParameters(NVSDK_NGX_Parameter **OutParameters);
|
||||
#endif // NGX_ENABLE_DEPRECATED_GET_PARAMETERS
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NVSDK_NGX_AllocateParameters
|
||||
// -----------------------------------------------------------------------------
|
||||
// Allocates a parameter map used to set parameters needed by the SDK.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Allocates a new NVSDK_NGX_Parameter map for providing parameters to the
|
||||
// SDK. The lifetime of this parameter map must be managed by the
|
||||
// application. The NVSDK_NGX_Parameter interface allows simple parameter
|
||||
// setup using named fields. For example, set the width by calling
|
||||
// Parameters->Set(NVSDK_NGX_Parameter_Width, 100) or provide a resource
|
||||
// pointer by calling Parameters->Set(NVSDK_NGX_Parameter_Color, resource).
|
||||
// For more details, see the sample code.
|
||||
//
|
||||
// Use NVSDK_NGX_DestroyParameters to free a parameter map created by
|
||||
// NVSDK_NGX_AllocateParameters. Parameter maps created by
|
||||
// NVSDK_NGX_AllocateParameters must NOT be freed using the free/delete
|
||||
// operator.
|
||||
//
|
||||
// Parameter maps created by NVSDK_NGX_AllocateParameters do not come
|
||||
// pre-populated with NGX capabilities and available features. To create a
|
||||
// new parameter map pre-populated with such information, use
|
||||
// NVSDK_NGX_GetCapabilityParameters instead.
|
||||
//
|
||||
// This function may return NVSDK_NGX_Result_FAIL_OutOfDate if using an
|
||||
// older driver that does not support this API call. In such a case,
|
||||
// NVSDK_NGX_GetParameters may be used as a fallback.
|
||||
//
|
||||
// This function may only be called after a successful call to
|
||||
// NVSDK_NGX_Init.
|
||||
//
|
||||
// PARAMETERS:
|
||||
// OutParameters:
|
||||
// Output pointer that will be populated with the newly-allocated
|
||||
// NVSDK_NGX_Parameter interface.
|
||||
//
|
||||
// RETURNS:
|
||||
// NVSDK_NGX_Result indicating success or failure. Common values include:
|
||||
// - NVSDK_NGX_Result_Success if the function executed successfully
|
||||
// - NVSDK_NGX_Result_FAIL_OutOfDate if this function is not supported by
|
||||
// the current display driver
|
||||
// Check the NGX logs for additional information about any failures.
|
||||
//
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_AllocateParameters(NVSDK_NGX_Parameter** OutParameters);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D12_AllocateParameters(NVSDK_NGX_Parameter** OutParameters);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_AllocateParameters(NVSDK_NGX_Parameter** OutParameters);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NVSDK_NGX_GetCapabilityParameters
|
||||
// -----------------------------------------------------------------------------
|
||||
// Allocates a parameter map populated with NGX and feature capabilities.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Allocates a new NVSDK_NGX_Parameter map pre-populated with NGX
|
||||
// capabilities and information about available features. The output
|
||||
// parameter map can also be used in the same ways as a parameter map
|
||||
// allocated with NVSDK_NGX_AllocateParameters. However, it is not
|
||||
// recommended to use NVSDK_NGX_GetCapabilityParameters unless querying NGX
|
||||
// capabilities due to the overhead associated with pre-populating the
|
||||
// parameter map.
|
||||
//
|
||||
// Use NVSDK_NGX_DestroyParameters to free a parameter map created by
|
||||
// NVSDK_NGX_GetCapabilityParameters. Parameter maps created by
|
||||
// NVSDK_NGX_GetCapabilityParameters must NOT be freed using the
|
||||
// free/delete operator.
|
||||
//
|
||||
// This function may return NVSDK_NGX_Result_FAIL_OutOfDate if using an
|
||||
// older driver that does not support this API call. In such a case,
|
||||
// NVSDK_NGX_GetParameters may be used as a fallback.
|
||||
//
|
||||
// This function may only be called after a successful call to
|
||||
// NVSDK_NGX_Init.
|
||||
//
|
||||
// PARAMETERS:
|
||||
// OutParameters:
|
||||
// Output pointer that will be populated with the newly-allocated
|
||||
// NVSDK_NGX_Parameter interface.
|
||||
//
|
||||
// RETURNS:
|
||||
// NVSDK_NGX_Result indicating success or failure. Common values include:
|
||||
// - NVSDK_NGX_Result_Success if the function executed successfully
|
||||
// - NVSDK_NGX_Result_FAIL_OutOfDate if this function is not supported by
|
||||
// the current display driver
|
||||
// Check the NGX logs for additional information about any failures.
|
||||
//
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_GetCapabilityParameters(NVSDK_NGX_Parameter** OutParameters);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D12_GetCapabilityParameters(NVSDK_NGX_Parameter** OutParameters);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_GetCapabilityParameters(NVSDK_NGX_Parameter** OutParameters);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NVSDK_NGX_DestroyParameters
|
||||
// -----------------------------------------------------------------------------
|
||||
// Destroys the specified parameter map.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Destroys the input parameter map. Once NVSDK_NGX_DestroyParameters is
|
||||
// called on a parameter map, it must not be used again.
|
||||
//
|
||||
// NVSDK_NGX_DestroyParameters must not be called on any parameter map
|
||||
// returned by NVSDK_NGX_GetParameters; NGX will manage the lifetime of
|
||||
// those parameter maps.
|
||||
//
|
||||
// This function may only be called after a successful call to
|
||||
// NVSDK_NGX_Init.
|
||||
//
|
||||
// PARAMETERS:
|
||||
// InParameters:
|
||||
// The parameter map to be destroyed.
|
||||
//
|
||||
// RETURNS:
|
||||
// NVSDK_NGX_Result indicating success or failure.
|
||||
//
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_DestroyParameters(NVSDK_NGX_Parameter* InParameters);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D12_DestroyParameters(NVSDK_NGX_Parameter* InParameters);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_DestroyParameters(NVSDK_NGX_Parameter* InParameters);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NVSDK_NGX_GetScratchBufferSize
|
||||
// -----------------------------------------------------------------------------
|
||||
// Retrieves the size of the scratch buffer needed for the specified feature.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// The SDK requires a buffer of a certain size provided by the client to
|
||||
// initialize some NGX features. Once the feature is no longer needed, the
|
||||
// buffer can be released. It is safe to reuse the same scratch buffer for
|
||||
// different features as long as the minimum size requirement is met for
|
||||
// all features. Some features might not need a scratch buffer, so a return
|
||||
// size of 0 is completely valid.
|
||||
//
|
||||
// Note: Most current NGX features do not use scratch buffers. Please check
|
||||
// the documentation for the particular feature in use to determine whether
|
||||
// a scratch buffer needs to be created.
|
||||
//
|
||||
// PARAMETERS:
|
||||
// InFeatureId:
|
||||
// Identifier of the feature to query.
|
||||
//
|
||||
// InParameters:
|
||||
// Parameters used by the feature to determine scratch buffer size.
|
||||
//
|
||||
// OutSizeInBytes:
|
||||
// Number of bytes needed for the scratch buffer for the specified feature.
|
||||
//
|
||||
// RETURNS:
|
||||
// NVSDK_NGX_Result indicating success or failure.
|
||||
//
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_GetScratchBufferSize(NVSDK_NGX_Feature InFeatureId, const NVSDK_NGX_Parameter *InParameters, size_t *OutSizeInBytes);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D12_GetScratchBufferSize(NVSDK_NGX_Feature InFeatureId, const NVSDK_NGX_Parameter *InParameters, size_t *OutSizeInBytes);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_GetScratchBufferSize(NVSDK_NGX_Feature InFeatureId, const NVSDK_NGX_Parameter *InParameters, size_t *OutSizeInBytes);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NVSDK_NGX_CreateFeature
|
||||
// -----------------------------------------------------------------------------
|
||||
// Creates and initializes an instance of the specified NGX feature.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Each feature needs to be created before it can be used. The parameters
|
||||
// required to create the feature vary. Refer to the feature's
|
||||
// documentation and/or sample code to find out which input parameters are
|
||||
// needed to create a specific feature.
|
||||
//
|
||||
// NVSDK_NGX_CreateFeature creates an NVSDK_NGX_Handle to the feature, which
|
||||
// is needed to reference the feature in later calls to
|
||||
// NVSDK_NGX_EvaluateFeature. Multiple instances of the same feature may be
|
||||
// created, and evaluating one instance of a feature should not change the
|
||||
// state of other instances.
|
||||
//
|
||||
// When a feature instance is no longer needed, it should be freed using
|
||||
// NVSDK_NGX_ReleaseFeature.
|
||||
//
|
||||
// PARAMETERS:
|
||||
// InCmdList (D3D12 only):
|
||||
// Command list to use to execute GPU commands. Must:
|
||||
// - Be open and recording
|
||||
// - Have a node mask that includes the device provided in
|
||||
// NVSDK_NGX_D3D12_Init
|
||||
// - Be executed on a non-copy command queue
|
||||
//
|
||||
// InDevCtx (D3D11 only):
|
||||
// Device context to use to execute GPU commands. Must be an immediate
|
||||
// context. Passing a deferred context is not supported and will cause the
|
||||
// API to return an error.
|
||||
//
|
||||
// InFeatureID:
|
||||
// Identifier of the feature to initialize.
|
||||
//
|
||||
// InParameters:
|
||||
// Parameters used to create the feature.
|
||||
//
|
||||
// OutHandle:
|
||||
// Handle which uniquely identifies the feature.
|
||||
//
|
||||
// RETURNS:
|
||||
// NVSDK_NGX_Result indicating success or failure. Common values include:
|
||||
// - NVSDK_NGX_Result_Success if the function executed successfully
|
||||
// - NVSDK_NGX_Result_FAIL_UnableToInitializeFeature if the feature
|
||||
// cannot be created, for example, because the feature is not supported
|
||||
// on the current hardware, or because the DLL could not be found
|
||||
// - NVSDK_NGX_Result_FAIL_InvalidParameter if any of the input
|
||||
// parameters are invalid
|
||||
// - NVSDK_NGX_Result_FAIL_FeatureAlreadyExists if a feature instance
|
||||
// with the same parameters has already been created, and the feature
|
||||
// doesn't allow multiple instances to be created with the same
|
||||
// parameters.
|
||||
// Check the NGX logs for additional information about any failures.
|
||||
//
|
||||
#if defined(NGX_SNIPPET_BUILD)
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_CreateFeature(ID3D11DeviceContext *InDevCtx, NVSDK_NGX_Feature InFeatureID, const NVSDK_NGX_Parameter *InParameters, NVSDK_NGX_Handle **OutHandle);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D12_CreateFeature(ID3D12GraphicsCommandList *InCmdList, NVSDK_NGX_Feature InFeatureID, const NVSDK_NGX_Parameter *InParameters, NVSDK_NGX_Handle **OutHandle);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_CreateFeature(NVSDK_NGX_Feature InFeatureID, const NVSDK_NGX_Parameter *InParameters, NVSDK_NGX_Handle **OutHandle);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_CreateFeature1(NVSDK_NGX_CUDADevice *InDevice, NVSDK_NGX_Feature InFeatureID, const NVSDK_NGX_Parameter *InParameters, NVSDK_NGX_Handle **OutHandle);
|
||||
#else
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_CreateFeature(ID3D11DeviceContext *InDevCtx, NVSDK_NGX_Feature InFeatureID, NVSDK_NGX_Parameter *InParameters, NVSDK_NGX_Handle **OutHandle);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D12_CreateFeature(ID3D12GraphicsCommandList *InCmdList, NVSDK_NGX_Feature InFeatureID, NVSDK_NGX_Parameter *InParameters, NVSDK_NGX_Handle **OutHandle);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_CreateFeature(NVSDK_NGX_Feature InFeatureID, const NVSDK_NGX_Parameter *InParameters, NVSDK_NGX_Handle **OutHandle);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_CreateFeature1(NVSDK_NGX_CUDADevice *InDevice, NVSDK_NGX_Feature InFeatureID, const NVSDK_NGX_Parameter *InParameters, NVSDK_NGX_Handle **OutHandle);
|
||||
|
||||
#endif // defined(NGX_SNIPPET_BUILD)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NVSDK_NGX_ReleaseFeature
|
||||
// -----------------------------------------------------------------------------
|
||||
// Releases the specified NGX feature.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Releases the feature associated with the given handle and frees its
|
||||
// memory. Handles are not reference counted, so after this call, it is
|
||||
// invalid to use the provided handle.
|
||||
//
|
||||
// PARAMETERS:
|
||||
// InHandle:
|
||||
// Handle to the feature to be released.
|
||||
//
|
||||
// RETURNS:
|
||||
// NVSDK_NGX_Result indicating success or failure.
|
||||
//
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_ReleaseFeature(NVSDK_NGX_Handle *InHandle);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D12_ReleaseFeature(NVSDK_NGX_Handle *InHandle);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_ReleaseFeature(NVSDK_NGX_Handle *InHandle);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NVSDK_NGX_GetFeatureRequirements
|
||||
// -----------------------------------------------------------------------------
|
||||
// Identifies system requirements to support a given NGX feature.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Utility function used to identify system requirements to support a given
|
||||
// NGX feature on a system, given its display device subsystem adapter
|
||||
// information that will be subsequently used for creating the graphics
|
||||
// device. The output parameter OutSupported will be populated with
|
||||
// requirements and is valid if and only if the function returns
|
||||
// NVSDK_NGX_Result_Success. The result includes:
|
||||
// - FeatureSupported: Bitfield of reasons why the feature is
|
||||
// unsupported, as specified in NVSDK_NGX_Feature_Support_Result. 0 if
|
||||
// the feature is supported
|
||||
// - MinHWArchitecture: The hardware architecture version corresponding
|
||||
// to an NV_GPU_ARCHITECTURE_ID value defined in the NvAPI GPU
|
||||
// Framework
|
||||
// - MinOSVersion: The minimum OS version required for the provided
|
||||
// feature
|
||||
//
|
||||
// NVSDK_NGX_Init does NOT need to be called before calling this function.
|
||||
// Applications may wish to use this function to determine whether a
|
||||
// desired feature is supported before initializing the complete SDK.
|
||||
//
|
||||
// PARAMETERS:
|
||||
// Adapter (D3D11/12 only):
|
||||
// Physical adapter which will be used to create the graphics device.
|
||||
//
|
||||
// FeatureDiscoveryInfo:
|
||||
// Struct containing information about the feature to query and how it is
|
||||
// expected to be initialized, including the feature ID and information
|
||||
// that would be provided to NVSDK_NGX_Init.
|
||||
//
|
||||
// OutSupported:
|
||||
// Populated with the requirements for the specified feature.
|
||||
//
|
||||
// RETURNS:
|
||||
// NVSDK_NGX_Result indicating success or failure.
|
||||
//
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_GetFeatureRequirements(IDXGIAdapter *Adapter,
|
||||
const NVSDK_NGX_FeatureDiscoveryInfo *FeatureDiscoveryInfo,
|
||||
NVSDK_NGX_FeatureRequirement *OutSupported);
|
||||
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D12_GetFeatureRequirements(IDXGIAdapter *Adapter,
|
||||
const NVSDK_NGX_FeatureDiscoveryInfo *FeatureDiscoveryInfo,
|
||||
NVSDK_NGX_FeatureRequirement *OutSupported);
|
||||
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_GetFeatureRequirements(int CudaDevice,
|
||||
const NVSDK_NGX_FeatureDiscoveryInfo *FeatureDiscoveryInfo,
|
||||
NVSDK_NGX_FeatureRequirement *OutSupported);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NVSDK_NGX_EvaluateFeature
|
||||
// -----------------------------------------------------------------------------
|
||||
// Evaluates the specified NGX feature using the provided parameters.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Evaluates the given feature using the provided parameters. The
|
||||
// parameters required to evaluate a feature vary. Refer to the feature's
|
||||
// documentation and sample code to determine which input parameters are
|
||||
// needed.
|
||||
//
|
||||
// To evaluate a feature, an NVSDK_NGX_Handle to an instance of that
|
||||
// feature, created with NVSDK_NGX_CreateFeature, must be provided.
|
||||
//
|
||||
// For most features, it is beneficial to pass as many input buffers and
|
||||
// parameters as possible (e.g., provide all render targets like color,
|
||||
// albedo, normals, depth, etc.). This will ensure maximum future
|
||||
// compatibility with new updates.
|
||||
//
|
||||
// PARAMETERS:
|
||||
// InCmdList (D3D12 only):
|
||||
// Command list to use to execute GPU commands. Must be:
|
||||
// - Open and recording
|
||||
// - With a node mask including the device provided in NVSDK_NGX_D3D12_Init
|
||||
// - Executed on a non-copy command queue
|
||||
//
|
||||
// InDevCtx (D3D11 only):
|
||||
// Device context to use to execute GPU commands. Must be an immediate
|
||||
// context. Passing a deferred context is not supported and will cause the
|
||||
// API to return an error.
|
||||
//
|
||||
// InFeatureHandle:
|
||||
// Handle representing the feature to be evaluated.
|
||||
//
|
||||
// InParameters:
|
||||
// List of parameters required to evaluate the feature.
|
||||
//
|
||||
// InCallback:
|
||||
// Optional callback for features that might take longer to execute. If
|
||||
// specified, the SDK will call it with progress values in the range 0.0f -
|
||||
// 1.0f. Not all features support progress callbacks. Refer to the
|
||||
// documentation for the specific feature to determine whether or not
|
||||
// progress callbacks are supported.
|
||||
//
|
||||
// RETURNS:
|
||||
// NVSDK_NGX_Result indicating success or failure. Common values include:
|
||||
// - NVSDK_NGX_Result_Success if the function executed successfully.
|
||||
// - NVSDK_NGX_Result_FAIL_InvalidParameter if any of the input
|
||||
// parameters are missing or invalid.
|
||||
// - NVSDK_NGX_Result_FAIL_FeatureNotFound if a feature with the provided
|
||||
// handle could not be found.
|
||||
// Check the NGX logs for additional information about any failures.
|
||||
//
|
||||
#ifdef __cplusplus
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_EvaluateFeature(ID3D11DeviceContext *InDevCtx, const NVSDK_NGX_Handle *InFeatureHandle, const NVSDK_NGX_Parameter *InParameters, PFN_NVSDK_NGX_ProgressCallback InCallback = NULL);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCommandList *InCmdList, const NVSDK_NGX_Handle *InFeatureHandle, const NVSDK_NGX_Parameter *InParameters, PFN_NVSDK_NGX_ProgressCallback InCallback = NULL);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_EvaluateFeature(const NVSDK_NGX_Handle *InFeatureHandle, const NVSDK_NGX_Parameter *InParameters, PFN_NVSDK_NGX_ProgressCallback InCallback = NULL);
|
||||
#endif
|
||||
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_EvaluateFeature_C(ID3D11DeviceContext *InDevCtx, const NVSDK_NGX_Handle *InFeatureHandle, const NVSDK_NGX_Parameter *InParameters, PFN_NVSDK_NGX_ProgressCallback_C InCallback);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D12_EvaluateFeature_C(ID3D12GraphicsCommandList *InCmdList, const NVSDK_NGX_Handle *InFeatureHandle, const NVSDK_NGX_Parameter *InParameters, PFN_NVSDK_NGX_ProgressCallback_C InCallback);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_EvaluateFeature_C(const NVSDK_NGX_Handle *InFeatureHandle, const NVSDK_NGX_Parameter *InParameters, PFN_NVSDK_NGX_ProgressCallback_C InCallback);
|
||||
|
||||
#if defined(NGX_SNIPPET_BUILD)
|
||||
// No NGX Core <---> Snippet interfaces
|
||||
#else
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_UpdateFeature(const NVSDK_NGX_Application_Identifier *ApplicationId, const NVSDK_NGX_Feature FeatureID);
|
||||
#endif // defined(NGX_SNIPPET_BUILD)
|
||||
|
||||
// NGX return-code conversion-to-string utility only as a helper for debugging/logging - not for official use.
|
||||
const wchar_t* NVSDK_CONV GetNGXResultAsString(NVSDK_NGX_Result InNGXResult);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#if defined(NVSDK_NGX_HEADER_ONLY)
|
||||
#include "nvsdk_ngx_loader.h"
|
||||
#if !defined(NVSDK_NGX_NO_CUDA)
|
||||
# include "nvsdk_ngx_standalone_cuda.h"
|
||||
#endif
|
||||
#endif /* NVSDK_NGX_HEADER_ONLY */
|
||||
|
||||
#endif // #define NVSDK_NGX_H
|
||||
@@ -0,0 +1,859 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2018-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: LicenseRef-NvidiaProprietary
|
||||
*
|
||||
* NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
|
||||
* property and proprietary rights in and to this material, related
|
||||
* documentation and any modifications thereto. Any use, reproduction,
|
||||
* disclosure or distribution of this material and related documentation
|
||||
* without an express license agreement from NVIDIA CORPORATION or
|
||||
* its affiliates is strictly prohibited.
|
||||
*/
|
||||
|
||||
#ifndef NVSDK_NGX_DEFS_H
|
||||
#define NVSDK_NGX_DEFS_H
|
||||
#pragma once
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stddef.h> // For size_t
|
||||
#include <stdbool.h>
|
||||
#include <wchar.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if defined(NGX_CORE_BUILD) && defined(_WIN32)
|
||||
#define NVSDK_NGX_API extern "C" __declspec(dllexport)
|
||||
#else
|
||||
#define NVSDK_NGX_API extern "C"
|
||||
#endif
|
||||
#else
|
||||
#if defined(NGX_CORE_BUILD) && defined(_WIN32)
|
||||
#define NVSDK_NGX_API __declspec(dllexport)
|
||||
#else
|
||||
#define NVSDK_NGX_API
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define NVSDK_CONV
|
||||
#else
|
||||
#define NVSDK_CONV __cdecl
|
||||
#endif
|
||||
|
||||
#define NVSDK_NGX_ARRAY_LEN(a) (sizeof(a) / sizeof((a)[0]))
|
||||
|
||||
// Version Notes:
|
||||
// Version 0x0000014:
|
||||
// * Added a logging callback that the app may pass in on init
|
||||
// * Added ability for the app to override the logging level
|
||||
// Version 0x0000015:
|
||||
// * Support multiple GPUs (bug 3270533)
|
||||
#define NVSDK_NGX_VERSION_API_MACRO 0x0000015 // NGX_VERSION_DOT 1.5.0
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus >= 201402L
|
||||
#define SR_DEPRECATED_SHARPENING [[deprecated("Sharpness is not supported")]]
|
||||
#else
|
||||
#define SR_DEPRECATED_SHARPENING
|
||||
#endif
|
||||
#else
|
||||
#define SR_DEPRECATED_SHARPENING
|
||||
#endif
|
||||
|
||||
typedef unsigned long long AppId;
|
||||
|
||||
typedef enum NVSDK_NGX_DLSS_Hint_Render_Preset
|
||||
{
|
||||
NVSDK_NGX_DLSS_Hint_Render_Preset_Default = 0, // default behavior, may or may not change after OTA
|
||||
// NVSDK_NGX_DLSS_Hint_Render_Preset_A removed, use preset J or K
|
||||
// NVSDK_NGX_DLSS_Hint_Render_Preset_B removed, use preset J or K
|
||||
// NVSDK_NGX_DLSS_Hint_Render_Preset_C removed, use preset J or K
|
||||
// NVSDK_NGX_DLSS_Hint_Render_Preset_D removed, use preset J or K
|
||||
NVSDK_NGX_DLSS_Hint_Render_Preset_E = 5, // Deprecated
|
||||
NVSDK_NGX_DLSS_Hint_Render_Preset_F = 6, // Deprecated
|
||||
NVSDK_NGX_DLSS_Hint_Render_Preset_G = 7, // Do not use, reverts to default behavior
|
||||
NVSDK_NGX_DLSS_Hint_Render_Preset_H_Reserved = 8, // Do not use, reverts to default behavior
|
||||
NVSDK_NGX_DLSS_Hint_Render_Preset_I_Reserved = 9, // Do not use, reverts to default behavior
|
||||
NVSDK_NGX_DLSS_Hint_Render_Preset_J = 10, // Similar to preset K. Preset J might exhibit slightly less ghosting at the cost of extra flickering. Preset K is generally recommended over preset J
|
||||
NVSDK_NGX_DLSS_Hint_Render_Preset_K = 11, // Default preset for DLAA/Balanced/Quality modes that is transformer based. Best image quality preset at a higher performance cost
|
||||
NVSDK_NGX_DLSS_Hint_Render_Preset_L = 12, // Default for Ultra Perf mode
|
||||
NVSDK_NGX_DLSS_Hint_Render_Preset_M = 13, // Default for Perf mode
|
||||
NVSDK_NGX_DLSS_Hint_Render_Preset_N = 14, // Do not use, reverts to default behavior
|
||||
NVSDK_NGX_DLSS_Hint_Render_Preset_O = 15, // Do not use, reverts to default behavior
|
||||
} NVSDK_NGX_DLSS_Hint_Render_Preset;
|
||||
|
||||
typedef struct NVSDK_NGX_Handle NVSDK_NGX_Handle;
|
||||
typedef struct NVSDK_NGX_Parameter NVSDK_NGX_Parameter;
|
||||
typedef struct NVSDK_NGX_FeatureCommonInfo_Internal NVSDK_NGX_FeatureCommonInfo_Internal;
|
||||
|
||||
typedef enum NVSDK_NGX_Version { NVSDK_NGX_Version_API = NVSDK_NGX_VERSION_API_MACRO } NVSDK_NGX_Version;
|
||||
|
||||
typedef enum NVSDK_NGX_Result
|
||||
{
|
||||
// The operation completed successfully.
|
||||
NVSDK_NGX_Result_Success = 0x1,
|
||||
|
||||
// Generic failure. Check the NGX logs for detailed information.
|
||||
NVSDK_NGX_Result_Fail = 0xBAD00000,
|
||||
|
||||
// The NGX SDK or a specific feature is not supported by the current system,
|
||||
// hardware, and/or graphics API.
|
||||
NVSDK_NGX_Result_FAIL_FeatureNotSupported = NVSDK_NGX_Result_Fail | 1,
|
||||
|
||||
// An error occurred within the underlying platform, which includes the
|
||||
// graphics API in use, the operating system, or other system libraries and
|
||||
// dependencies that are not part of the NGX SDK, such as NvAPI. Consult the
|
||||
// NGX logs and the graphics API's validation layers for detailed
|
||||
// information.
|
||||
NVSDK_NGX_Result_FAIL_PlatformError = NVSDK_NGX_Result_Fail | 2,
|
||||
|
||||
// The NGX feature could not be created because a feature with identical
|
||||
// parameters already exists, and the feature does not support multiple
|
||||
// identical instances.
|
||||
NVSDK_NGX_Result_FAIL_FeatureAlreadyExists = NVSDK_NGX_Result_Fail | 3,
|
||||
|
||||
// A feature associated with the provided handle could not be found.
|
||||
NVSDK_NGX_Result_FAIL_FeatureNotFound = NVSDK_NGX_Result_Fail | 4,
|
||||
|
||||
// One or more provided parameters had an incorrect value or type, or a
|
||||
// required parameter was not provided.
|
||||
NVSDK_NGX_Result_FAIL_InvalidParameter = NVSDK_NGX_Result_Fail | 5,
|
||||
|
||||
// The feature requires a scratch buffer, but none was provided or the
|
||||
// provided buffer is too small. Use NVSDK_NGX_GetScratchBufferSize to
|
||||
// determine the necessary size.
|
||||
NVSDK_NGX_Result_FAIL_ScratchBufferTooSmall = NVSDK_NGX_Result_Fail | 6,
|
||||
|
||||
// A function that requires the NGX SDK to be initialized was called before
|
||||
// the SDK was properly initialized.
|
||||
NVSDK_NGX_Result_FAIL_NotInitialized = NVSDK_NGX_Result_Fail | 7,
|
||||
|
||||
// One or more input buffers supplied to the feature had an unsupported
|
||||
// format.
|
||||
NVSDK_NGX_Result_FAIL_UnsupportedInputFormat = NVSDK_NGX_Result_Fail | 8,
|
||||
|
||||
// The feature requires read/write access to output buffers, but one or more
|
||||
// provided buffers did not have the correct access flags (UAV in
|
||||
// D3D11/D3D12).
|
||||
NVSDK_NGX_Result_FAIL_RWFlagMissing = NVSDK_NGX_Result_Fail | 9,
|
||||
|
||||
// A required input parameter was not provided.
|
||||
NVSDK_NGX_Result_FAIL_MissingInput = NVSDK_NGX_Result_Fail | 10,
|
||||
|
||||
// The requested feature could not be initialized, likely because the
|
||||
// library for that feature could not be found.
|
||||
NVSDK_NGX_Result_FAIL_UnableToInitializeFeature = NVSDK_NGX_Result_Fail | 11,
|
||||
|
||||
// A function was used which requires a newer version of the NVIDIA Display
|
||||
// Driver or feature library than is currently installed.
|
||||
NVSDK_NGX_Result_FAIL_OutOfDate = NVSDK_NGX_Result_Fail | 12,
|
||||
|
||||
// An operation could not be completed because the system lacked sufficient
|
||||
// GPU memory.
|
||||
NVSDK_NGX_Result_FAIL_OutOfGPUMemory = NVSDK_NGX_Result_Fail | 13,
|
||||
|
||||
// One or more buffers provided to the feature had an unsupported format.
|
||||
NVSDK_NGX_Result_FAIL_UnsupportedFormat = NVSDK_NGX_Result_Fail | 14,
|
||||
|
||||
// The SDK does not have the necessary write permissions for the path
|
||||
// specified in InApplicationDataPath.
|
||||
NVSDK_NGX_Result_FAIL_UnableToWriteToAppDataPath = NVSDK_NGX_Result_Fail | 15,
|
||||
|
||||
// A parameter supplied to the feature is either unsupported by the current
|
||||
// version or has an unsupported value.
|
||||
NVSDK_NGX_Result_FAIL_UnsupportedParameter = NVSDK_NGX_Result_Fail | 16,
|
||||
|
||||
// NVIDIA has restricted the use of this feature in the current application.
|
||||
// Contact NVIDIA for further information.
|
||||
NVSDK_NGX_Result_FAIL_Denied = NVSDK_NGX_Result_Fail | 17,
|
||||
|
||||
// The requested feature or functionality has not been implemented in the
|
||||
// current version of the NGX SDK, display driver, or feature library.
|
||||
NVSDK_NGX_Result_FAIL_NotImplemented = NVSDK_NGX_Result_Fail | 18,
|
||||
} NVSDK_NGX_Result;
|
||||
|
||||
// Skip setting the debug overlay value if it is UNSET.
|
||||
#define NVSDK_NGX_DLSS_DEBUG_OVERLAY_VALUE_UNSET -1
|
||||
|
||||
#define NVSDK_NGX_SUCCEED(value) (((value) & 0xFFF00000) != NVSDK_NGX_Result_Fail)
|
||||
#define NVSDK_NGX_FAILED(value) (((value) & 0xFFF00000) == NVSDK_NGX_Result_Fail)
|
||||
|
||||
typedef enum NVSDK_NGX_Feature
|
||||
{
|
||||
NVSDK_NGX_Feature_Reserved0 = 0,
|
||||
|
||||
NVSDK_NGX_Feature_SuperSampling = 1,
|
||||
|
||||
NVSDK_NGX_Feature_InPainting = 2,
|
||||
|
||||
NVSDK_NGX_Feature_ImageSuperResolution = 3,
|
||||
|
||||
NVSDK_NGX_Feature_SlowMotion = 4,
|
||||
|
||||
NVSDK_NGX_Feature_VideoSuperResolution = 5,
|
||||
|
||||
NVSDK_NGX_Feature_Reserved1 = 6,
|
||||
|
||||
NVSDK_NGX_Feature_Reserved2 = 7,
|
||||
|
||||
NVSDK_NGX_Feature_Reserved3 = 8,
|
||||
|
||||
NVSDK_NGX_Feature_ImageSignalProcessing = 9,
|
||||
|
||||
NVSDK_NGX_Feature_DeepResolve = 10,
|
||||
|
||||
NVSDK_NGX_Feature_FrameGeneration = 11,
|
||||
|
||||
NVSDK_NGX_Feature_DeepDVC = 12,
|
||||
|
||||
NVSDK_NGX_Feature_RayReconstruction = 13,
|
||||
|
||||
NVSDK_NGX_Feature_Reserved14 = 14,
|
||||
|
||||
NVSDK_NGX_Feature_Reserved15 = 15,
|
||||
|
||||
NVSDK_NGX_Feature_Reserved16 = 16,
|
||||
|
||||
NVSDK_NGX_Feature_Reserved17 = 17,
|
||||
|
||||
NVSDK_NGX_Feature_Reserved18 = 18,
|
||||
|
||||
// New features go here
|
||||
NVSDK_NGX_Feature_Count,
|
||||
|
||||
// These members are not strictly NGX features, but are
|
||||
// components of the NGX system, and it may sometimes
|
||||
// be useful to identify them using the same enum
|
||||
NVSDK_NGX_Feature_Reserved_SDK = 32764,
|
||||
|
||||
NVSDK_NGX_Feature_Reserved_Core = 32765,
|
||||
|
||||
NVSDK_NGX_Feature_Reserved_Unknown = 32766
|
||||
} NVSDK_NGX_Feature;
|
||||
|
||||
//TODO create grayscale format (R32F?)
|
||||
typedef enum NVSDK_NGX_Buffer_Format
|
||||
{
|
||||
NVSDK_NGX_Buffer_Format_Unknown,
|
||||
NVSDK_NGX_Buffer_Format_RGB8UI,
|
||||
NVSDK_NGX_Buffer_Format_RGB16F,
|
||||
NVSDK_NGX_Buffer_Format_RGB32F,
|
||||
NVSDK_NGX_Buffer_Format_RGBA8UI,
|
||||
NVSDK_NGX_Buffer_Format_RGBA16F,
|
||||
NVSDK_NGX_Buffer_Format_RGBA32F,
|
||||
} NVSDK_NGX_Buffer_Format;
|
||||
|
||||
typedef enum NVSDK_NGX_PerfQuality_Value
|
||||
{
|
||||
NVSDK_NGX_PerfQuality_Value_MaxPerf,
|
||||
NVSDK_NGX_PerfQuality_Value_Balanced,
|
||||
NVSDK_NGX_PerfQuality_Value_MaxQuality,
|
||||
// Extended PerfQuality modes
|
||||
NVSDK_NGX_PerfQuality_Value_UltraPerformance,
|
||||
NVSDK_NGX_PerfQuality_Value_UltraQuality,
|
||||
NVSDK_NGX_PerfQuality_Value_DLAA,
|
||||
} NVSDK_NGX_PerfQuality_Value;
|
||||
|
||||
typedef enum NVSDK_NGX_RTX_Value
|
||||
{
|
||||
NVSDK_NGX_RTX_Value_Off,
|
||||
NVSDK_NGX_RTX_Value_On,
|
||||
} NVSDK_NGX_RTX_Value;
|
||||
|
||||
// For each unique instance, a pointer to NVSDK_NGX_CUDADevice is passed in to
|
||||
// NVSDK_NGX_CUDA_Init1, NVSDK_NGX_CUDA_CreateFeature1 and NVSDK_NGX_CUDA_Shutdown1.
|
||||
// This is needed in the case of running multiple threads in a single process.
|
||||
// Depending on the app usage of CUDA, one or both of cudaContext and cudaStream can be set.
|
||||
typedef struct NVSDK_NGX_CUDADevice
|
||||
{
|
||||
void* cudaContext; // CUcontext returned from cuCtxCreate
|
||||
void* cudaStream; // CUstream returned from cuStreamCreate
|
||||
} NVSDK_NGX_CUDADevice;
|
||||
|
||||
typedef enum NVSDK_NGX_DLSS_Mode
|
||||
{
|
||||
NVSDK_NGX_DLSS_Mode_Off, // use existing in-engine AA + upscale solution
|
||||
NVSDK_NGX_DLSS_Mode_DLSS_DLISP,
|
||||
NVSDK_NGX_DLSS_Mode_DLISP_Only, // use existing in-engine AA solution
|
||||
NVSDK_NGX_DLSS_Mode_DLSS, // DLSS will apply AA and upsample at the same time
|
||||
} NVSDK_NGX_DLSS_Mode;
|
||||
|
||||
typedef enum NVSDK_NGX_DLSS_Feature_Flags
|
||||
{
|
||||
NVSDK_NGX_DLSS_Feature_Flags_IsInvalid = 1 << 31,
|
||||
|
||||
NVSDK_NGX_DLSS_Feature_Flags_None = 0,
|
||||
NVSDK_NGX_DLSS_Feature_Flags_IsHDR = 1 << 0,
|
||||
NVSDK_NGX_DLSS_Feature_Flags_MVLowRes = 1 << 1,
|
||||
NVSDK_NGX_DLSS_Feature_Flags_MVJittered = 1 << 2,
|
||||
NVSDK_NGX_DLSS_Feature_Flags_DepthInverted = 1 << 3,
|
||||
NVSDK_NGX_DLSS_Feature_Flags_Reserved_0 = 1 << 4,
|
||||
NVSDK_NGX_DLSS_Feature_Flags_DoSharpening SR_DEPRECATED_SHARPENING = 1 << 5, // Sharpness is not supported
|
||||
NVSDK_NGX_DLSS_Feature_Flags_AutoExposure = 1 << 6,
|
||||
NVSDK_NGX_DLSS_Feature_Flags_AlphaUpscaling = 1 << 7,
|
||||
NVSDK_NGX_DLSS_Feature_Flags_Reserved_8 = 1 << 8,
|
||||
} NVSDK_NGX_DLSS_Feature_Flags;
|
||||
|
||||
typedef enum NVSDK_NGX_ToneMapperType
|
||||
{
|
||||
NVSDK_NGX_TONEMAPPER_STRING = 0,
|
||||
NVSDK_NGX_TONEMAPPER_REINHARD,
|
||||
NVSDK_NGX_TONEMAPPER_ONEOVERLUMA,
|
||||
NVSDK_NGX_TONEMAPPER_ACES,
|
||||
NVSDK_NGX_TONEMAPPERTYPE_NUM
|
||||
} NVSDK_NGX_ToneMapperType;
|
||||
|
||||
typedef enum NVSDK_NGX_GBufferType
|
||||
{
|
||||
NVSDK_NGX_GBUFFER_ALBEDO = 0,
|
||||
NVSDK_NGX_GBUFFER_ROUGHNESS,
|
||||
NVSDK_NGX_GBUFFER_METALLIC,
|
||||
NVSDK_NGX_GBUFFER_SPECULAR,
|
||||
NVSDK_NGX_GBUFFER_SUBSURFACE,
|
||||
NVSDK_NGX_GBUFFER_NORMALS,
|
||||
NVSDK_NGX_GBUFFER_SHADINGMODELID, /* unique identifier for drawn object or how the object is drawn */
|
||||
NVSDK_NGX_GBUFFER_MATERIALID, /* unique identifier for material */
|
||||
NVSDK_NGX_GBUFFER_SPECULAR_ALBEDO,
|
||||
NVSDK_NGX_GBUFFER_INDIRECT_ALBEDO,
|
||||
NVSDK_NGX_GBUFFER_SPECULAR_MVEC,
|
||||
NVSDK_NGX_GBUFFER_DISOCCL_MASK, /* deprecated: use NVSDK_NGX_GBUFFER_RESPONSIVITY_MASK*/
|
||||
NVSDK_NGX_GBUFFER_EMISSIVE,
|
||||
NVSDK_NGX_GBUFFER_RESPONSIVITY_MASK,
|
||||
NVSDK_NGX_GBUFFERTYPE_NUM = 17
|
||||
} NVSDK_NGX_GBufferType;
|
||||
|
||||
typedef struct NVSDK_NGX_Coordinates
|
||||
{
|
||||
unsigned int X;
|
||||
unsigned int Y;
|
||||
} NVSDK_NGX_Coordinates;
|
||||
|
||||
typedef struct NVSDK_NGX_Dimensions
|
||||
{
|
||||
unsigned int Width;
|
||||
unsigned int Height;
|
||||
} NVSDK_NGX_Dimensions;
|
||||
|
||||
typedef struct NVSDK_NGX_PrecisionInfo
|
||||
{
|
||||
// 1 if and only if the associated resource buffer is considered low-precision
|
||||
unsigned int IsLowPrecision;
|
||||
|
||||
// Bias and Scale values, such that `hi = lo * Scale + Bias`
|
||||
float Bias;
|
||||
float Scale;
|
||||
} NVSDK_NGX_PrecisionInfo;
|
||||
|
||||
typedef struct NVSDK_NGX_PathListInfo
|
||||
{
|
||||
// Pointer to a const string
|
||||
wchar_t const* const* Path;
|
||||
// Path-list length
|
||||
unsigned int Length;
|
||||
} NVSDK_NGX_PathListInfo;
|
||||
|
||||
typedef enum NVSDK_NGX_Logging_Level
|
||||
{
|
||||
NVSDK_NGX_LOGGING_LEVEL_OFF = 0,
|
||||
NVSDK_NGX_LOGGING_LEVEL_ON,
|
||||
NVSDK_NGX_LOGGING_LEVEL_VERBOSE,
|
||||
NVSDK_NGX_LOGGING_LEVEL_NUM
|
||||
} NVSDK_NGX_Logging_Level;
|
||||
|
||||
// A logging callback provided by the app to allow piping log lines back to the app.
|
||||
// Please take careful note of the signature and calling convention.
|
||||
// The callback must be able to be called from any thread.
|
||||
// It must also be fully thread-safe and any number of threads may call into it concurrently.
|
||||
// It must fully process message by the time it returns, and there is no guarantee that
|
||||
// message will still be valid or allocated after it returns.
|
||||
// message will be a null-terminated string and may contain multibyte characters.
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
typedef void NVSDK_CONV(*NVSDK_NGX_AppLogCallback)(const char* message, NVSDK_NGX_Logging_Level loggingLevel, NVSDK_NGX_Feature sourceComponent);
|
||||
#else
|
||||
typedef void(NVSDK_CONV* NVSDK_NGX_AppLogCallback)(const char* message, NVSDK_NGX_Logging_Level loggingLevel, NVSDK_NGX_Feature sourceComponent);
|
||||
#endif
|
||||
|
||||
typedef struct NVSDK_NGX_LoggingInfo
|
||||
{
|
||||
// Fields below were introduced in SDK version 0x0000014
|
||||
|
||||
// App-provided logging callback
|
||||
NVSDK_NGX_AppLogCallback LoggingCallback;
|
||||
|
||||
// The minimum logging level to use. If this is higher
|
||||
// than the logging level otherwise configured, this will override
|
||||
// that logging level. Otherwise, that logging level will be used.
|
||||
NVSDK_NGX_Logging_Level MinimumLoggingLevel;
|
||||
|
||||
// Whether or not to disable writing log lines to sinks other than the app log callback. This
|
||||
// may be useful if the app provides a logging callback. LoggingCallback must be non-null and point
|
||||
// to a valid logging callback if this is set to true.
|
||||
bool DisableOtherLoggingSinks;
|
||||
|
||||
} NVSDK_NGX_LoggingInfo;
|
||||
|
||||
typedef struct NVSDK_NGX_FeatureCommonInfo
|
||||
{
|
||||
// List of all paths in descending order of search sequence to locate a feature dll in, other than the default path - application folder.
|
||||
NVSDK_NGX_PathListInfo PathListInfo;
|
||||
// Used internally by NGX
|
||||
NVSDK_NGX_FeatureCommonInfo_Internal* InternalData; // Introduced in SDK version 0x0000013
|
||||
|
||||
// Fields below were introduced in SDK version 0x0000014
|
||||
NVSDK_NGX_LoggingInfo LoggingInfo;
|
||||
} NVSDK_NGX_FeatureCommonInfo;
|
||||
|
||||
typedef enum NVSDK_NGX_Opt_Level
|
||||
{
|
||||
NVSDK_NGX_OPT_LEVEL_UNDEFINED = 0,
|
||||
NVSDK_NGX_OPT_LEVEL_DEBUG = 20,
|
||||
NVSDK_NGX_OPT_LEVEL_DEVELOP = 30,
|
||||
NVSDK_NGX_OPT_LEVEL_RELEASE = 40
|
||||
} NVSDK_NGX_Opt_Level;
|
||||
|
||||
typedef enum NVSDK_NGX_EngineType
|
||||
{
|
||||
NVSDK_NGX_ENGINE_TYPE_CUSTOM = 0,
|
||||
NVSDK_NGX_ENGINE_TYPE_UNREAL,
|
||||
NVSDK_NGX_ENGINE_TYPE_UNITY,
|
||||
NVSDK_NGX_ENGINE_TYPE_OMNIVERSE,
|
||||
NVSDK_NGX_ENGINE_COUNT
|
||||
} NVSDK_NGX_EngineType;
|
||||
|
||||
typedef enum NVSDK_NGX_GraphicsAPI
|
||||
{
|
||||
NVSDK_NGX_GRAPHICS_API_CUDA = 0,
|
||||
NVSDK_NGX_GRAPHICS_API_D3D11 = 1,
|
||||
NVSDK_NGX_GRAPHICS_API_D3D12 = 2,
|
||||
NVSDK_NGX_GRAPHICS_API_VULKAN = 3,
|
||||
NVSDK_NGX_GRAPHICS_API_COUNT
|
||||
} NVSDK_NGX_GraphicsAPI;
|
||||
|
||||
typedef enum NVSDK_NGX_Feature_Support_Result
|
||||
{
|
||||
NVSDK_NGX_FeatureSupportResult_Supported = 0,
|
||||
NVSDK_NGX_FeatureSupportResult_CheckNotPresent = 1,
|
||||
NVSDK_NGX_FeatureSupportResult_DriverVersionUnsupported = 2,
|
||||
NVSDK_NGX_FeatureSupportResult_AdapterUnsupported = 4,
|
||||
NVSDK_NGX_FeatureSupportResult_OSVersionBelowMinimumSupported = 8,
|
||||
NVSDK_NGX_FeatureSupportResult_NotImplemented = 16
|
||||
} NVSDK_NGX_Feature_Support_Result;
|
||||
|
||||
typedef enum NVSDK_NGX_Application_Identifier_Type
|
||||
{
|
||||
NVSDK_NGX_Application_Identifier_Type_Application_Id = 0,
|
||||
NVSDK_NGX_Application_Identifier_Type_Project_Id = 1,
|
||||
} NVSDK_NGX_Application_Identifier_Type;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// NVSDK_NGX_ProjectIdDescription
|
||||
// -------------------------------------
|
||||
// Contains information to identify an application built using a common rendering engine (list of supported rendering engines is defined in NVSDK_NGX_EngineType).
|
||||
// Should only be used by plugins for the supported rendering engines, unless using NVSDK_NGX_ENGINE_TYPE_CUSTOM as the engine type.
|
||||
//
|
||||
// ProjectId
|
||||
// Unique Id provided by the rendering engine used
|
||||
//
|
||||
// EngineType
|
||||
// Rendering engine used by the application / plugin.
|
||||
// Use NVSDK_NGX_ENGINE_TYPE_CUSTOM if the specific engine type is not supported explicitly
|
||||
//
|
||||
// EngineVersion
|
||||
// Version number of the rendering engine used by the application / plugin.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Contains information to identify an application built using a common rendering engine (list of supported rendering engines is defined in NVSDK_NGX_EngineType).
|
||||
// Should only be used by plugins for the supported rendering engines, unless using NVSDK_NGX_ENGINE_TYPE_CUSTOM as the engine type.
|
||||
//
|
||||
typedef struct NVSDK_NGX_ProjectIdDescription
|
||||
{
|
||||
const char* ProjectId;
|
||||
NVSDK_NGX_EngineType EngineType;
|
||||
const char* EngineVersion;
|
||||
} NVSDK_NGX_ProjectIdDescription;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// NVSDK_NGX_Application_Identifier
|
||||
// -------------------------------------
|
||||
// Identifier for each application. Required for over the air updates (both optional and mandatory)
|
||||
// as well as for app-specific customizations for features like DLSS-SR
|
||||
//
|
||||
// IdentifierType:
|
||||
// Whether using a NVSDK_NGX_ProjectIdDescription or an Unique Application Identifier
|
||||
//
|
||||
// ProjectDesc:
|
||||
// If using NVSDK_NGX_ProjectIdDescription, this contains the project ID and engine info required to identify this app
|
||||
//
|
||||
// ApplicationIdentifier:
|
||||
// If not using NVSDK_NGX_ProjectIdDescription, this contains an ID provided by NVIDIA for this app
|
||||
// If your NVIDIA contact did not provide you an ID for this purpose, use ProjectDesc with NVSDK_NGX_ENGINE_TYPE_CUSTOM as the engine type
|
||||
//
|
||||
typedef struct NVSDK_NGX_Application_Identifier
|
||||
{
|
||||
NVSDK_NGX_Application_Identifier_Type IdentifierType;
|
||||
union v {
|
||||
NVSDK_NGX_ProjectIdDescription ProjectDesc;
|
||||
unsigned long long ApplicationId;
|
||||
} v;
|
||||
} NVSDK_NGX_Application_Identifier;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// NVSDK_NGX_FeatureDiscoveryInfo
|
||||
// -------------------------------------
|
||||
// Contains information common to all features, used by NGX in determining requested Feature availability
|
||||
//
|
||||
// InSDKVersion:
|
||||
// API Struct version number
|
||||
//
|
||||
// FeatureID
|
||||
// Valid NVSDK_NGX_Feature enum corresponding to DLSS v3 Feature which is being queried for availability
|
||||
//
|
||||
// ApplicationId
|
||||
// Unique Id provided by NVIDIA corresponding to a particular Application or alternatively custom Id set by Engine
|
||||
//
|
||||
// InApplicationDataPath:
|
||||
// Folder to store logs and other temporary files (write access required),
|
||||
// Normally this would be a location in Documents or ProgramData.
|
||||
//
|
||||
// FeatureInfo:
|
||||
// Contains information common to all features, presently only a list of all paths
|
||||
// feature dlls can be located in, other than the default path - application directory.
|
||||
//
|
||||
typedef struct NVSDK_NGX_FeatureDiscoveryInfo
|
||||
{
|
||||
NVSDK_NGX_Version SDKVersion;
|
||||
NVSDK_NGX_Feature FeatureID;
|
||||
NVSDK_NGX_Application_Identifier Identifier;
|
||||
const wchar_t* ApplicationDataPath;
|
||||
const NVSDK_NGX_FeatureCommonInfo* FeatureInfo;
|
||||
} NVSDK_NGX_FeatureDiscoveryInfo;
|
||||
|
||||
typedef struct NVSDK_NGX_FeatureRequirement
|
||||
{
|
||||
// Bitfield of bit shifted values specified in NVSDK_NGX_Feature_Support_Result. 0 if Feature is Supported.
|
||||
NVSDK_NGX_Feature_Support_Result FeatureSupported;
|
||||
|
||||
// Returned HW Architecture value corresponding to NV_GPU_ARCHITECTURE_ID values defined in NvAPI GPU Framework.
|
||||
unsigned int MinHWArchitecture;
|
||||
|
||||
// Value corresponding to minimum OS version required for NGX Feature Support
|
||||
char MinOSVersion[255];
|
||||
} NVSDK_NGX_FeatureRequirement;
|
||||
|
||||
// Callback function types
|
||||
typedef NVSDK_NGX_Result(NVSDK_CONV *PFN_NVSDK_NGX_DLSS_GetStatsCallback)(NVSDK_NGX_Parameter *InParams);
|
||||
typedef NVSDK_NGX_Result(NVSDK_CONV *PFN_NVSDK_NGX_DLSS_GetOptimalSettingsCallback)(NVSDK_NGX_Parameter *InParams);
|
||||
|
||||
typedef struct IUnknown IUnknown;
|
||||
typedef struct D3D11_TEXTURE2D_DESC D3D11_TEXTURE2D_DESC;
|
||||
typedef struct D3D11_BUFFER_DESC D3D11_BUFFER_DESC;
|
||||
typedef struct ID3D11Buffer ID3D11Buffer;
|
||||
typedef struct ID3D11Texture2D ID3D11Texture2D;
|
||||
typedef struct ID3D12Resource ID3D12Resource;
|
||||
typedef struct D3D12_RESOURCE_DESC D3D12_RESOURCE_DESC;
|
||||
typedef struct CD3DX12_HEAP_PROPERTIES CD3DX12_HEAP_PROPERTIES;
|
||||
|
||||
typedef void (NVSDK_CONV *PFN_NVSDK_NGX_D3D12_ResourceAllocCallback)(D3D12_RESOURCE_DESC *InDesc, int InState, CD3DX12_HEAP_PROPERTIES *InHeap, ID3D12Resource **OutResource);
|
||||
typedef void (NVSDK_CONV *PFN_NVSDK_NGX_D3D11_BufferAllocCallback)(D3D11_BUFFER_DESC *InDesc, ID3D11Buffer **OutResource);
|
||||
typedef void (NVSDK_CONV *PFN_NVSDK_NGX_D3D11_Tex2DAllocCallback)(D3D11_TEXTURE2D_DESC *InDesc, ID3D11Texture2D **OutResource);
|
||||
typedef void (NVSDK_CONV *PFN_NVSDK_NGX_ResourceReleaseCallback)(IUnknown *InResource);
|
||||
|
||||
#ifdef __cplusplus
|
||||
typedef void (NVSDK_CONV *PFN_NVSDK_NGX_ProgressCallback)(float InCurrentProgress, bool &OutShouldCancel);
|
||||
#endif
|
||||
typedef void (NVSDK_CONV *PFN_NVSDK_NGX_ProgressCallback_C)(float InCurrentProgress, bool *OutShouldCancel);
|
||||
|
||||
// Read-only parameters provided by NGX
|
||||
#define NVSDK_NGX_EParameter_Reserved00 "#\x00"
|
||||
#define NVSDK_NGX_EParameter_SuperSampling_Available "#\x01"
|
||||
#define NVSDK_NGX_EParameter_InPainting_Available "#\x02"
|
||||
#define NVSDK_NGX_EParameter_ImageSuperResolution_Available "#\x03"
|
||||
#define NVSDK_NGX_EParameter_SlowMotion_Available "#\x04"
|
||||
#define NVSDK_NGX_EParameter_VideoSuperResolution_Available "#\x05"
|
||||
#define NVSDK_NGX_EParameter_Reserved06 "#\x06"
|
||||
#define NVSDK_NGX_EParameter_Reserved07 "#\x07"
|
||||
#define NVSDK_NGX_EParameter_Reserved08 "#\x08"
|
||||
#define NVSDK_NGX_EParameter_ImageSignalProcessing_Available "#\x09"
|
||||
#define NVSDK_NGX_EParameter_ImageSuperResolution_ScaleFactor_2_1 "#\x0a"
|
||||
#define NVSDK_NGX_EParameter_ImageSuperResolution_ScaleFactor_3_1 "#\x0b"
|
||||
#define NVSDK_NGX_EParameter_ImageSuperResolution_ScaleFactor_3_2 "#\x0c"
|
||||
#define NVSDK_NGX_EParameter_ImageSuperResolution_ScaleFactor_4_3 "#\x0d"
|
||||
#define NVSDK_NGX_EParameter_NumFrames "#\x0e"
|
||||
#define NVSDK_NGX_EParameter_Scale "#\x0f"
|
||||
#define NVSDK_NGX_EParameter_Width "#\x10"
|
||||
#define NVSDK_NGX_EParameter_Height "#\x11"
|
||||
#define NVSDK_NGX_EParameter_OutWidth "#\x12"
|
||||
#define NVSDK_NGX_EParameter_OutHeight "#\x13"
|
||||
#define NVSDK_NGX_EParameter_Sharpness "#\x14"
|
||||
#define NVSDK_NGX_EParameter_Scratch "#\x15"
|
||||
#define NVSDK_NGX_EParameter_Scratch_SizeInBytes "#\x16"
|
||||
#define NVSDK_NGX_EParameter_EvaluationNode "#\x17" // valid since API 0x13 (replaced a deprecated param)
|
||||
#define NVSDK_NGX_EParameter_Input1 "#\x18"
|
||||
#define NVSDK_NGX_EParameter_Input1_Format "#\x19"
|
||||
#define NVSDK_NGX_EParameter_Input1_SizeInBytes "#\x1a"
|
||||
#define NVSDK_NGX_EParameter_Input2 "#\x1b"
|
||||
#define NVSDK_NGX_EParameter_Input2_Format "#\x1c"
|
||||
#define NVSDK_NGX_EParameter_Input2_SizeInBytes "#\x1d"
|
||||
#define NVSDK_NGX_EParameter_Color "#\x1e"
|
||||
#define NVSDK_NGX_EParameter_Color_Format "#\x1f"
|
||||
#define NVSDK_NGX_EParameter_Color_SizeInBytes "#\x20"
|
||||
#define NVSDK_NGX_EParameter_Albedo "#\x21"
|
||||
#define NVSDK_NGX_EParameter_Output "#\x22"
|
||||
#define NVSDK_NGX_EParameter_Output_Format "#\x23"
|
||||
#define NVSDK_NGX_EParameter_Output_SizeInBytes "#\x24"
|
||||
#define NVSDK_NGX_EParameter_Reset "#\x25"
|
||||
#define NVSDK_NGX_EParameter_BlendFactor "#\x26"
|
||||
#define NVSDK_NGX_EParameter_MotionVectors "#\x27"
|
||||
#define NVSDK_NGX_EParameter_Rect_X "#\x28"
|
||||
#define NVSDK_NGX_EParameter_Rect_Y "#\x29"
|
||||
#define NVSDK_NGX_EParameter_Rect_W "#\x2a"
|
||||
#define NVSDK_NGX_EParameter_Rect_H "#\x2b"
|
||||
#define NVSDK_NGX_EParameter_MV_Scale_X "#\x2c"
|
||||
#define NVSDK_NGX_EParameter_MV_Scale_Y "#\x2d"
|
||||
#define NVSDK_NGX_EParameter_Model "#\x2e"
|
||||
#define NVSDK_NGX_EParameter_Format "#\x2f"
|
||||
#define NVSDK_NGX_EParameter_SizeInBytes "#\x30"
|
||||
#define NVSDK_NGX_EParameter_ResourceAllocCallback "#\x31"
|
||||
#define NVSDK_NGX_EParameter_BufferAllocCallback "#\x32"
|
||||
#define NVSDK_NGX_EParameter_Tex2DAllocCallback "#\x33"
|
||||
#define NVSDK_NGX_EParameter_ResourceReleaseCallback "#\x34"
|
||||
#define NVSDK_NGX_EParameter_CreationNodeMask "#\x35"
|
||||
#define NVSDK_NGX_EParameter_VisibilityNodeMask "#\x36"
|
||||
#define NVSDK_NGX_EParameter_PreviousOutput "#\x37"
|
||||
#define NVSDK_NGX_EParameter_MV_Offset_X "#\x38"
|
||||
#define NVSDK_NGX_EParameter_MV_Offset_Y "#\x39"
|
||||
#define NVSDK_NGX_EParameter_Hint_UseFireflySwatter "#\x3a"
|
||||
#define NVSDK_NGX_EParameter_Resource_Width "#\x3b"
|
||||
#define NVSDK_NGX_EParameter_Resource_Height "#\x3c"
|
||||
#define NVSDK_NGX_EParameter_Depth "#\x3d"
|
||||
#define NVSDK_NGX_EParameter_DLSSOptimalSettingsCallback "#\x3e"
|
||||
#define NVSDK_NGX_EParameter_PerfQualityValue "#\x3f"
|
||||
#define NVSDK_NGX_EParameter_RTXValue "#\x40"
|
||||
#define NVSDK_NGX_EParameter_DLSSMode "#\x41"
|
||||
#define NVSDK_NGX_EParameter_DeepResolve_Available "#\x42"
|
||||
#define NVSDK_NGX_EParameter_Deprecated_43 "#\x43"
|
||||
#define NVSDK_NGX_EParameter_OptLevel "#\x44"
|
||||
#define NVSDK_NGX_EParameter_IsDevSnippetBranch "#\x45"
|
||||
#define NVSDK_NGX_EParameter_DeepDVC_Available "#\x46"
|
||||
#define NVSDK_NGX_EParameter_Graphics_API "#\x47"
|
||||
#define NVSDK_NGX_EParameter_Reserved_48 "#\x48"
|
||||
#define NVSDK_NGX_EParameter_Reserved_49 "#\x49"
|
||||
|
||||
#define NVSDK_NGX_Parameter_OptLevel "Snippet.OptLevel"
|
||||
#define NVSDK_NGX_Parameter_IsDevSnippetBranch "Snippet.IsDevBranch"
|
||||
#define NVSDK_NGX_Parameter_SuperSampling_ScaleFactor "SuperSampling.ScaleFactor"
|
||||
#define NVSDK_NGX_Parameter_ImageSignalProcessing_ScaleFactor "ImageSignalProcessing.ScaleFactor"
|
||||
#define NVSDK_NGX_Parameter_SuperSampling_Available "SuperSampling.Available"
|
||||
#define NVSDK_NGX_Parameter_InPainting_Available "InPainting.Available"
|
||||
#define NVSDK_NGX_Parameter_ImageSuperResolution_Available "ImageSuperResolution.Available"
|
||||
#define NVSDK_NGX_Parameter_SlowMotion_Available "SlowMotion.Available"
|
||||
#define NVSDK_NGX_Parameter_VideoSuperResolution_Available "VideoSuperResolution.Available"
|
||||
#define NVSDK_NGX_Parameter_ImageSignalProcessing_Available "ImageSignalProcessing.Available"
|
||||
#define NVSDK_NGX_Parameter_DeepResolve_Available "DeepResolve.Available"
|
||||
#define NVSDK_NGX_Parameter_SuperSampling_NeedsUpdatedDriver "SuperSampling.NeedsUpdatedDriver"
|
||||
#define NVSDK_NGX_Parameter_InPainting_NeedsUpdatedDriver "InPainting.NeedsUpdatedDriver"
|
||||
#define NVSDK_NGX_Parameter_ImageSuperResolution_NeedsUpdatedDriver "ImageSuperResolution.NeedsUpdatedDriver"
|
||||
#define NVSDK_NGX_Parameter_SlowMotion_NeedsUpdatedDriver "SlowMotion.NeedsUpdatedDriver"
|
||||
#define NVSDK_NGX_Parameter_VideoSuperResolution_NeedsUpdatedDriver "VideoSuperResolution.NeedsUpdatedDriver"
|
||||
#define NVSDK_NGX_Parameter_ImageSignalProcessing_NeedsUpdatedDriver "ImageSignalProcessing.NeedsUpdatedDriver"
|
||||
#define NVSDK_NGX_Parameter_DeepResolve_NeedsUpdatedDriver "DeepResolve.NeedsUpdatedDriver"
|
||||
#define NVSDK_NGX_Parameter_FrameInterpolation_NeedsUpdatedDriver "FrameInterpolation.NeedsUpdatedDriver"
|
||||
#define NVSDK_NGX_Parameter_SuperSampling_MinDriverVersionMajor "SuperSampling.MinDriverVersionMajor"
|
||||
#define NVSDK_NGX_Parameter_InPainting_MinDriverVersionMajor "InPainting.MinDriverVersionMajor"
|
||||
#define NVSDK_NGX_Parameter_ImageSuperResolution_MinDriverVersionMajor "ImageSuperResolution.MinDriverVersionMajor"
|
||||
#define NVSDK_NGX_Parameter_SlowMotion_MinDriverVersionMajor "SlowMotion.MinDriverVersionMajor"
|
||||
#define NVSDK_NGX_Parameter_VideoSuperResolution_MinDriverVersionMajor "VideoSuperResolution.MinDriverVersionMajor"
|
||||
#define NVSDK_NGX_Parameter_ImageSignalProcessing_MinDriverVersionMajor "ImageSignalProcessing.MinDriverVersionMajor"
|
||||
#define NVSDK_NGX_Parameter_DeepResolve_MinDriverVersionMajor "DeepResolve.MinDriverVersionMajor"
|
||||
#define NVSDK_NGX_Parameter_FrameInterpolation_MinDriverVersionMajor "FrameInterpolation.MinDriverVersionMajor"
|
||||
#define NVSDK_NGX_Parameter_SuperSampling_MinDriverVersionMinor "SuperSampling.MinDriverVersionMinor"
|
||||
#define NVSDK_NGX_Parameter_InPainting_MinDriverVersionMinor "InPainting.MinDriverVersionMinor"
|
||||
#define NVSDK_NGX_Parameter_ImageSuperResolution_MinDriverVersionMinor "ImageSuperResolution.MinDriverVersionMinor"
|
||||
#define NVSDK_NGX_Parameter_SlowMotion_MinDriverVersionMinor "SlowMotion.MinDriverVersionMinor"
|
||||
#define NVSDK_NGX_Parameter_VideoSuperResolution_MinDriverVersionMinor "VideoSuperResolution.MinDriverVersionMinor"
|
||||
#define NVSDK_NGX_Parameter_ImageSignalProcessing_MinDriverVersionMinor "ImageSignalProcessing.MinDriverVersionMinor"
|
||||
#define NVSDK_NGX_Parameter_DeepResolve_MinDriverVersionMinor "DeepResolve.MinDriverVersionMinor"
|
||||
#define NVSDK_NGX_Parameter_SuperSampling_FeatureInitResult "SuperSampling.FeatureInitResult"
|
||||
#define NVSDK_NGX_Parameter_InPainting_FeatureInitResult "InPainting.FeatureInitResult"
|
||||
#define NVSDK_NGX_Parameter_ImageSuperResolution_FeatureInitResult "ImageSuperResolution.FeatureInitResult"
|
||||
#define NVSDK_NGX_Parameter_SlowMotion_FeatureInitResult "SlowMotion.FeatureInitResult"
|
||||
#define NVSDK_NGX_Parameter_VideoSuperResolution_FeatureInitResult "VideoSuperResolution.FeatureInitResult"
|
||||
#define NVSDK_NGX_Parameter_ImageSignalProcessing_FeatureInitResult "ImageSignalProcessing.FeatureInitResult"
|
||||
#define NVSDK_NGX_Parameter_DeepResolve_FeatureInitResult "DeepResolve.FeatureInitResult"
|
||||
#define NVSDK_NGX_Parameter_FrameInterpolation_FeatureInitResult "FrameInterpolation.FeatureInitResult"
|
||||
#define NVSDK_NGX_Parameter_ImageSuperResolution_ScaleFactor_2_1 "ImageSuperResolution.ScaleFactor.2.1"
|
||||
#define NVSDK_NGX_Parameter_ImageSuperResolution_ScaleFactor_3_1 "ImageSuperResolution.ScaleFactor.3.1"
|
||||
#define NVSDK_NGX_Parameter_ImageSuperResolution_ScaleFactor_3_2 "ImageSuperResolution.ScaleFactor.3.2"
|
||||
#define NVSDK_NGX_Parameter_ImageSuperResolution_ScaleFactor_4_3 "ImageSuperResolution.ScaleFactor.4.3"
|
||||
#define NVSDK_NGX_Parameter_NumFrames "NumFrames"
|
||||
#define NVSDK_NGX_Parameter_Scale "Scale"
|
||||
#define NVSDK_NGX_Parameter_Width "Width"
|
||||
#define NVSDK_NGX_Parameter_Height "Height"
|
||||
#define NVSDK_NGX_Parameter_OutWidth "OutWidth"
|
||||
#define NVSDK_NGX_Parameter_OutHeight "OutHeight"
|
||||
#define NVSDK_NGX_Parameter_Sharpness "Sharpness"
|
||||
#define NVSDK_NGX_Parameter_Scratch "Scratch"
|
||||
#define NVSDK_NGX_Parameter_Scratch_SizeInBytes "Scratch.SizeInBytes"
|
||||
#define NVSDK_NGX_Parameter_Input1 "Input1"
|
||||
#define NVSDK_NGX_Parameter_Input1_Format "Input1.Format"
|
||||
#define NVSDK_NGX_Parameter_Input1_SizeInBytes "Input1.SizeInBytes"
|
||||
#define NVSDK_NGX_Parameter_Input2 "Input2"
|
||||
#define NVSDK_NGX_Parameter_Input2_Format "Input2.Format"
|
||||
#define NVSDK_NGX_Parameter_Input2_SizeInBytes "Input2.SizeInBytes"
|
||||
#define NVSDK_NGX_Parameter_Color "Color"
|
||||
#define NVSDK_NGX_Parameter_Color_Format "Color.Format"
|
||||
#define NVSDK_NGX_Parameter_Color_SizeInBytes "Color.SizeInBytes"
|
||||
#define NVSDK_NGX_Parameter_FI_Color1 "Color1"
|
||||
#define NVSDK_NGX_Parameter_FI_Color2 "Color2"
|
||||
#define NVSDK_NGX_Parameter_Albedo "Albedo"
|
||||
#define NVSDK_NGX_Parameter_Output "Output"
|
||||
#define NVSDK_NGX_Parameter_Output_Format "Output.Format"
|
||||
#define NVSDK_NGX_Parameter_Output_SizeInBytes "Output.SizeInBytes"
|
||||
#define NVSDK_NGX_Parameter_FI_Output1 "Output1"
|
||||
#define NVSDK_NGX_Parameter_FI_Output2 "Output2"
|
||||
#define NVSDK_NGX_Parameter_FI_Output3 "Output3"
|
||||
#define NVSDK_NGX_Parameter_Reset "Reset"
|
||||
#define NVSDK_NGX_Parameter_BlendFactor "BlendFactor"
|
||||
#define NVSDK_NGX_Parameter_MotionVectors "MotionVectors"
|
||||
#define NVSDK_NGX_Parameter_FI_MotionVectors1 "MotionVectors1"
|
||||
#define NVSDK_NGX_Parameter_FI_MotionVectors2 "MotionVectors2"
|
||||
#define NVSDK_NGX_Parameter_Rect_X "Rect.X"
|
||||
#define NVSDK_NGX_Parameter_Rect_Y "Rect.Y"
|
||||
#define NVSDK_NGX_Parameter_Rect_W "Rect.W"
|
||||
#define NVSDK_NGX_Parameter_Rect_H "Rect.H"
|
||||
#define NVSDK_NGX_Parameter_OutRect_X "OutRect.X"
|
||||
#define NVSDK_NGX_Parameter_OutRect_Y "OutRect.Y"
|
||||
#define NVSDK_NGX_Parameter_OutRect_W "OutRect.W"
|
||||
#define NVSDK_NGX_Parameter_OutRect_H "OutRect.H"
|
||||
#define NVSDK_NGX_Parameter_MV_Scale_X "MV.Scale.X"
|
||||
#define NVSDK_NGX_Parameter_MV_Scale_Y "MV.Scale.Y"
|
||||
#define NVSDK_NGX_Parameter_Model "Model"
|
||||
#define NVSDK_NGX_Parameter_Format "Format"
|
||||
#define NVSDK_NGX_Parameter_SizeInBytes "SizeInBytes"
|
||||
#define NVSDK_NGX_Parameter_ResourceAllocCallback "ResourceAllocCallback"
|
||||
#define NVSDK_NGX_Parameter_BufferAllocCallback "BufferAllocCallback"
|
||||
#define NVSDK_NGX_Parameter_Tex2DAllocCallback "Tex2DAllocCallback"
|
||||
#define NVSDK_NGX_Parameter_ResourceReleaseCallback "ResourceReleaseCallback"
|
||||
#define NVSDK_NGX_Parameter_CreationNodeMask "CreationNodeMask"
|
||||
#define NVSDK_NGX_Parameter_VisibilityNodeMask "VisibilityNodeMask"
|
||||
#define NVSDK_NGX_Parameter_MV_Offset_X "MV.Offset.X"
|
||||
#define NVSDK_NGX_Parameter_MV_Offset_Y "MV.Offset.Y"
|
||||
#define NVSDK_NGX_Parameter_Hint_UseFireflySwatter "Hint.UseFireflySwatter"
|
||||
#define NVSDK_NGX_Parameter_Resource_Width "ResourceWidth"
|
||||
#define NVSDK_NGX_Parameter_Resource_Height "ResourceHeight"
|
||||
#define NVSDK_NGX_Parameter_Resource_OutWidth "ResourceOutWidth"
|
||||
#define NVSDK_NGX_Parameter_Resource_OutHeight "ResourceOutHeight"
|
||||
#define NVSDK_NGX_Parameter_Depth "Depth"
|
||||
#define NVSDK_NGX_Parameter_FI_Depth1 "Depth1"
|
||||
#define NVSDK_NGX_Parameter_FI_Depth2 "Depth2"
|
||||
#define NVSDK_NGX_Parameter_DLSSOptimalSettingsCallback "DLSSOptimalSettingsCallback"
|
||||
#define NVSDK_NGX_Parameter_DLSSGetStatsCallback "DLSSGetStatsCallback"
|
||||
#define NVSDK_NGX_Parameter_PerfQualityValue "PerfQualityValue"
|
||||
#define NVSDK_NGX_Parameter_RTXValue "RTXValue"
|
||||
#define NVSDK_NGX_Parameter_DLSSMode "DLSSMode"
|
||||
#define NVSDK_NGX_Parameter_FI_Mode "FIMode"
|
||||
#define NVSDK_NGX_Parameter_FI_OF_Preset "FIOFPreset"
|
||||
#define NVSDK_NGX_Parameter_FI_OF_GridSize "FIOFGridSize"
|
||||
#define NVSDK_NGX_Parameter_Jitter_Offset_X "Jitter.Offset.X"
|
||||
#define NVSDK_NGX_Parameter_Jitter_Offset_Y "Jitter.Offset.Y"
|
||||
#define NVSDK_NGX_Parameter_Denoise "Denoise"
|
||||
#define NVSDK_NGX_Parameter_TransparencyMask "TransparencyMask"
|
||||
#define NVSDK_NGX_Parameter_ExposureTexture "ExposureTexture" // a 1x1 texture containing the final exposure scale
|
||||
#define NVSDK_NGX_Parameter_DLSS_Feature_Create_Flags "DLSS.Feature.Create.Flags"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Checkerboard_Jitter_Hack "DLSS.Checkerboard.Jitter.Hack"
|
||||
#define NVSDK_NGX_Parameter_GBuffer_Normals "GBuffer.Normals"
|
||||
#define NVSDK_NGX_Parameter_GBuffer_Albedo "GBuffer.Albedo"
|
||||
#define NVSDK_NGX_Parameter_GBuffer_Roughness "GBuffer.Roughness"
|
||||
#define NVSDK_NGX_Parameter_GBuffer_DiffuseAlbedo "GBuffer.DiffuseAlbedo"
|
||||
#define NVSDK_NGX_Parameter_GBuffer_SpecularAlbedo "GBuffer.SpecularAlbedo"
|
||||
#define NVSDK_NGX_Parameter_GBuffer_IndirectAlbedo "GBuffer.IndirectAlbedo"
|
||||
#define NVSDK_NGX_Parameter_GBuffer_SpecularMvec "GBuffer.SpecularMvec"
|
||||
#define NVSDK_NGX_Parameter_GBuffer_DisocclusionMask "GBuffer.DisocclusionMask"
|
||||
#define NVSDK_NGX_Parameter_GBuffer_Metallic "GBuffer.Metallic"
|
||||
#define NVSDK_NGX_Parameter_GBuffer_Specular "GBuffer.Specular"
|
||||
#define NVSDK_NGX_Parameter_GBuffer_Subsurface "GBuffer.Subsurface"
|
||||
#define NVSDK_NGX_Parameter_GBuffer_ShadingModelId "GBuffer.ShadingModelId"
|
||||
#define NVSDK_NGX_Parameter_GBuffer_MaterialId "GBuffer.MaterialId"
|
||||
#define NVSDK_NGX_Parameter_GBuffer_Atrrib_8 "GBuffer.Attrib.8"
|
||||
#define NVSDK_NGX_Parameter_GBuffer_Atrrib_9 "GBuffer.Attrib.9"
|
||||
#define NVSDK_NGX_Parameter_GBuffer_Atrrib_10 "GBuffer.Attrib.10"
|
||||
#define NVSDK_NGX_Parameter_GBuffer_Atrrib_11 "GBuffer.Attrib.11"
|
||||
#define NVSDK_NGX_Parameter_GBuffer_Atrrib_12 "GBuffer.Attrib.12"
|
||||
#define NVSDK_NGX_Parameter_GBuffer_Atrrib_13 "GBuffer.Attrib.13"
|
||||
#define NVSDK_NGX_Parameter_GBuffer_Atrrib_14 "GBuffer.Attrib.14"
|
||||
#define NVSDK_NGX_Parameter_GBuffer_Atrrib_15 "GBuffer.Attrib.15"
|
||||
#define NVSDK_NGX_Parameter_TonemapperType "TonemapperType"
|
||||
#define NVSDK_NGX_Parameter_FreeMemOnReleaseFeature "FreeMemOnReleaseFeature"
|
||||
#define NVSDK_NGX_Parameter_MotionVectors3D "MotionVectors3D"
|
||||
#define NVSDK_NGX_Parameter_IsParticleMask "IsParticleMask"
|
||||
#define NVSDK_NGX_Parameter_AnimatedTextureMask "AnimatedTextureMask"
|
||||
#define NVSDK_NGX_Parameter_DepthHighRes "DepthHighRes"
|
||||
#define NVSDK_NGX_Parameter_Position_ViewSpace "Position.ViewSpace"
|
||||
#define NVSDK_NGX_Parameter_FrameTimeDeltaInMsec "FrameTimeDeltaInMsec"
|
||||
#define NVSDK_NGX_Parameter_RayTracingHitDistance "RayTracingHitDistance"
|
||||
#define NVSDK_NGX_Parameter_MotionVectorsReflection "MotionVectorsReflection"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Enable_Output_Subrects "DLSS.Enable.Output.Subrects"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Input_Color_Subrect_Base_X "DLSS.Input.Color.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Input_Color_Subrect_Base_Y "DLSS.Input.Color.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Input_Depth_Subrect_Base_X "DLSS.Input.Depth.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Input_Depth_Subrect_Base_Y "DLSS.Input.Depth.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Input_MV_SubrectBase_X "DLSS.Input.MV.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Input_MV_SubrectBase_Y "DLSS.Input.MV.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Input_Translucency_SubrectBase_X "DLSS.Input.Translucency.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Input_Translucency_SubrectBase_Y "DLSS.Input.Translucency.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Output_Subrect_Base_X "DLSS.Output.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Output_Subrect_Base_Y "DLSS.Output.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Render_Subrect_Dimensions_Width "DLSS.Render.Subrect.Dimensions.Width"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Render_Subrect_Dimensions_Height "DLSS.Render.Subrect.Dimensions.Height"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Pre_Exposure "DLSS.Pre.Exposure"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Exposure_Scale "DLSS.Exposure.Scale"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_Mask "DLSS.Input.Bias.Current.Color.Mask"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_SubrectBase_X "DLSS.Input.Bias.Current.Color.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_SubrectBase_Y "DLSS.Input.Bias.Current.Color.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Indicator_Invert_Y_Axis "DLSS.Indicator.Invert.Y.Axis"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Indicator_Invert_X_Axis "DLSS.Indicator.Invert.X.Axis"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Overlay_Debug_Layer "DLSS.Overlay.Debug.Layer"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Overlay_Full_Screen "DLSS.Overlay.Full.Screen"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Overlay_Show_Nans "DLSS.Overlay.Show.Nans"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Overlay_Jitter_Debug "DLSS.Overlay.Jitter.Debug"
|
||||
#define NVSDK_NGX_Parameter_DLSS_INV_VIEW_PROJECTION_MATRIX "InvViewProjectionMatrix"
|
||||
#define NVSDK_NGX_Parameter_DLSS_CLIP_TO_PREV_CLIP_MATRIX "ClipToPrevClipMatrix"
|
||||
|
||||
#define NVSDK_NGX_Parameter_DLSS_TransparencyLayer "DLSS.TransparencyLayer"
|
||||
#define NVSDK_NGX_Parameter_DLSS_TransparencyLayer_Subrect_Base_X "DLSS.TransparencyLayer.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSS_TransparencyLayer_Subrect_Base_Y "DLSS.TransparencyLayer.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSS_TransparencyLayerOpacity "DLSS.TransparencyLayerOpacity"
|
||||
#define NVSDK_NGX_Parameter_DLSS_TransparencyLayerOpacity_Subrect_Base_X "DLSS.TransparencyLayerOpacity.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSS_TransparencyLayerOpacity_Subrect_Base_Y "DLSS.TransparencyLayerOpacity.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSS_TransparencyLayerMvecs "DLSS.TransparencyLayerMvecs"
|
||||
#define NVSDK_NGX_Parameter_DLSS_TransparencyLayerMvecs_Subrect_Base_X "DLSS.TransparencyLayerMvecs.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSS_TransparencyLayerMvecs_Subrect_Base_Y "DLSS.TransparencyLayerMvecs.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSS_DisocclusionMask "DLSS.DisocclusionMask"
|
||||
#define NVSDK_NGX_Parameter_DLSS_DisocclusionMask_Subrect_Base_X "DLSS.DisocclusionMask.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSS_DisocclusionMask_Subrect_Base_Y "DLSS.DisocclusionMask.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSS_ResponsivityMask "DLSS.ResponsivityMask"
|
||||
#define NVSDK_NGX_Parameter_DLSS_ResponsivityMask_Subrect_Base_X "DLSS.ResponsivityMask.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSS_ResponsivityMask_Subrect_Base_Y "DLSS.ResponsivityMask.Subrect.Base.Y"
|
||||
|
||||
#define NVSDK_NGX_Parameter_DLSS_Get_Dynamic_Max_Render_Width "DLSS.Get.Dynamic.Max.Render.Width"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Get_Dynamic_Max_Render_Height "DLSS.Get.Dynamic.Max.Render.Height"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Get_Dynamic_Min_Render_Width "DLSS.Get.Dynamic.Min.Render.Width"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Get_Dynamic_Min_Render_Height "DLSS.Get.Dynamic.Min.Render.Height"
|
||||
|
||||
#define NVSDK_NGX_Parameter_DLSS_Hint_Render_Preset_DLAA "DLSS.Hint.Render.Preset.DLAA"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Hint_Render_Preset_Quality "DLSS.Hint.Render.Preset.Quality"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Hint_Render_Preset_Balanced "DLSS.Hint.Render.Preset.Balanced"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Hint_Render_Preset_Performance "DLSS.Hint.Render.Preset.Performance"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Hint_Render_Preset_UltraPerformance "DLSS.Hint.Render.Preset.UltraPerformance"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Hint_Render_Preset_UltraQuality "DLSS.Hint.Render.Preset.UltraQuality"
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: LicenseRef-NvidiaProprietary
|
||||
*
|
||||
* NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
|
||||
* property and proprietary rights in and to this material, related
|
||||
* documentation and any modifications thereto. Any use, reproduction,
|
||||
* disclosure or distribution of this material and related documentation
|
||||
* without an express license agreement from NVIDIA CORPORATION or
|
||||
* its affiliates is strictly prohibited.
|
||||
*/
|
||||
|
||||
#ifndef NVSDK_NGX_DEFS_DLSSD_H
|
||||
#define NVSDK_NGX_DEFS_DLSSD_H
|
||||
#pragma once
|
||||
|
||||
typedef enum NVSDK_NGX_DLSS_Denoise_Mode
|
||||
{
|
||||
NVSDK_NGX_DLSS_Denoise_Mode_Off = 0,
|
||||
NVSDK_NGX_DLSS_Denoise_Mode_DLUnified = 1, // DL based unified upscaler
|
||||
} NVSDK_NGX_DLSS_Denoise_Mode;
|
||||
|
||||
typedef enum NVSDK_NGX_DLSS_Roughness_Mode
|
||||
{
|
||||
NVSDK_NGX_DLSS_Roughness_Mode_Unpacked = 0, // Read roughness separately
|
||||
NVSDK_NGX_DLSS_Roughness_Mode_Packed = 1, // Read roughness from normals.w
|
||||
} NVSDK_NGX_DLSS_Roughness_Mode;
|
||||
|
||||
typedef enum NVSDK_NGX_DLSS_Depth_Type
|
||||
{
|
||||
NVSDK_NGX_DLSS_Depth_Type_Linear = 0, // Linear Depth
|
||||
NVSDK_NGX_DLSS_Depth_Type_HW = 1, // HW Depth
|
||||
} NVSDK_NGX_DLSS_Depth_Type;
|
||||
|
||||
|
||||
typedef enum NVSDK_NGX_RayReconstruction_Hint_Render_Preset
|
||||
{
|
||||
NVSDK_NGX_RayReconstruction_Hint_Render_Preset_Default = 0, // default behavior, may or may not change after OTA
|
||||
// NVSDK_NGX_RayReconstruction_Hint_Render_Preset_A removed, use preset D or E
|
||||
// NVSDK_NGX_RayReconstruction_Hint_Render_Preset_B removed, use preset D or E
|
||||
// NVSDK_NGX_RayReconstruction_Hint_Render_Preset_C removed, use preset D or E
|
||||
NVSDK_NGX_RayReconstruction_Hint_Render_Preset_D = 4, // Transformer model
|
||||
NVSDK_NGX_RayReconstruction_Hint_Render_Preset_E = 5, // Latest transformer model (must use if DoF guide is needed)
|
||||
NVSDK_NGX_RayReconstruction_Hint_Render_Preset_F = 6, // Default model RR2
|
||||
NVSDK_NGX_RayReconstruction_Hint_Render_Preset_G = 7, // Do not use, reverts to default behavior
|
||||
NVSDK_NGX_RayReconstruction_Hint_Render_Preset_H = 8, // Do not use, reverts to default behavior
|
||||
NVSDK_NGX_RayReconstruction_Hint_Render_Preset_I = 9, // Do not use, reverts to default behavior
|
||||
NVSDK_NGX_RayReconstruction_Hint_Render_Preset_J = 10, // Do not use, reverts to default behavior
|
||||
NVSDK_NGX_RayReconstruction_Hint_Render_Preset_K = 11, // Do not use, reverts to default behavior
|
||||
NVSDK_NGX_RayReconstruction_Hint_Render_Preset_L = 12, // Do not use, reverts to default behavior
|
||||
NVSDK_NGX_RayReconstruction_Hint_Render_Preset_M = 13, // Do not use, reverts to default behavior
|
||||
NVSDK_NGX_RayReconstruction_Hint_Render_Preset_N = 14, // Do not use, reverts to default behavior
|
||||
NVSDK_NGX_RayReconstruction_Hint_Render_Preset_O = 15, // Do not use, reverts to default behavior
|
||||
} NVSDK_NGX_RayReconstruction_Hint_Render_Preset;
|
||||
|
||||
#define NVSDK_NGX_Parameter_DLSS_Denoise_Mode "DLSS.Denoise.Mode"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Roughness_Mode "DLSS.Roughness.Mode"
|
||||
#define NVSDK_NGX_Parameter_DiffuseAlbedo "DLSS.Input.DiffuseAlbedo"
|
||||
#define NVSDK_NGX_Parameter_SpecularAlbedo "DLSS.Input.SpecularAlbedo"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Input_DiffuseAlbedo_Subrect_Base_X "DLSS.Input.DiffuseAlbedo.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Input_DiffuseAlbedo_Subrect_Base_Y "DLSS.Input.DiffuseAlbedo.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Input_SpecularAlbedo_Subrect_Base_X "DLSS.Input.SpecularAlbedo.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Input_SpecularAlbedo_Subrect_Base_Y "DLSS.Input.SpecularAlbedo.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Input_Normals_Subrect_Base_X "DLSS.Input.Normals.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Input_Normals_Subrect_Base_Y "DLSS.Input.Normals.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Input_Roughness_Subrect_Base_X "DLSS.Input.Roughness.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSS_Input_Roughness_Subrect_Base_Y "DLSS.Input.Roughness.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_ViewToClipMatrix "ViewToClipMatrix"
|
||||
#define NVSDK_NGX_Parameter_GBuffer_Emissive "GBuffer.Emissive"
|
||||
#define NVSDK_NGX_Parameter_Use_Folded_Network "DLSS.Use.Folded.Network"
|
||||
#define NVSDK_NGX_Parameter_Diffuse_Ray_Direction "Diffuse.Ray.Direction"
|
||||
#define NVSDK_NGX_Parameter_DLSS_WORLD_TO_VIEW_MATRIX "WorldToViewMatrix"
|
||||
#define NVSDK_NGX_Parameter_DLSS_VIEW_TO_CLIP_MATRIX "ViewToClipMatrix"
|
||||
#define NVSDK_NGX_Parameter_Use_HW_Depth "DLSS.Use.HW.Depth"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ReflectedAlbedo "DLSSD.ReflectedAlbedo"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ColorBeforeParticles "DLSSD.ColorBeforeParticles"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ColorAfterParticles "DLSSD.ColorAfterParticles"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ColorBeforeTransparency "DLSSD.ColorBeforeTransparency"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ColorAfterTransparency "DLSSD.ColorAfterTransparency"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ColorBeforeFog "DLSSD.ColorBeforeFog"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ColorAfterFog "DLSSD.ColorAfterFog"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ScreenSpaceSubsurfaceScatteringGuide "DLSSD.ScreenSpaceSubsurfaceScatteringGuide"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ColorBeforeScreenSpaceSubsurfaceScattering "DLSSD.ColorBeforeScreenSpaceSubsurfaceScattering"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ColorAfterScreenSpaceSubsurfaceScattering "DLSSD.ColorAfterScreenSpaceSubsurfaceScattering"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ScreenSpaceRefractionGuide "DLSSD.ScreenSpaceRefractionGuide"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ColorBeforeScreenSpaceRefraction "DLSSD.ColorBeforeScreenSpaceRefraction"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ColorAfterScreenSpaceRefraction "DLSSD.ColorAfterScreenSpaceRefraction"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_DepthOfFieldGuide "DLSSD.DepthOfFieldGuide"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ColorBeforeDepthOfField "DLSSD.ColorBeforeDepthOfField"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ColorAfterDepthOfField "DLSSD.ColorAfterDepthOfField"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_DiffuseHitDistance "DLSSD.DiffuseHitDistance"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_SpecularHitDistance "DLSSD.SpecularHitDistance"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_DiffuseRayDirection "DLSSD.DiffuseRayDirection"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_SpecularRayDirection "DLSSD.SpecularRayDirection"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_DiffuseRayDirectionHitDistance "DLSSD.DiffuseRayDirectionHitDistance"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_SpecularRayDirectionHitDistance "DLSSD.SpecularRayDirectionHitDistance"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_Alpha "DLSSD.Alpha"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_OutputAlpha "DLSSD.OutputAlpha"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ResponsivityMask "DLSSD.ResponsivityMask"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_Alpha_Subrect_Base_X "DLSSD.Alpha.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_Alpha_Subrect_Base_Y "DLSSD.Alpha.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_OutputAlpha_Subrect_Base_X "DLSSD.OutputAlpha.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_OutputAlpha_Subrect_Base_Y "DLSSD.OutputAlpha.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ReflectedAlbedo_Subrect_Base_X "DLSSD.ReflectedAlbedo.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ReflectedAlbedo_Subrect_Base_Y "DLSSD.ReflectedAlbedo.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ColorBeforeParticles_Subrect_Base_X "DLSSD.ColorBeforeParticles.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ColorBeforeParticles_Subrect_Base_Y "DLSSD.ColorBeforeParticles.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ColorAfterParticles_Subrect_Base_X "DLSSD.ColorAfterParticles.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ColorAfterParticles_Subrect_Base_Y "DLSSD.ColorAfterParticles.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ColorBeforeTransparency_Subrect_Base_X "DLSSD.ColorBeforeTransparency.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ColorBeforeTransparency_Subrect_Base_Y "DLSSD.ColorBeforeTransparency.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ColorAfterTransparency_Subrect_Base_X "DLSSD.ColorAfterTransparency.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ColorAfterTransparency_Subrect_Base_Y "DLSSD.ColorAfterTransparency.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ColorBeforeFog_Subrect_Base_X "DLSSD.ColorBeforeFog.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ColorBeforeFog_Subrect_Base_Y "DLSSD.ColorBeforeFog.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ColorAfterFog_Subrect_Base_X "DLSSD.ColorAfterFog.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ColorAfterFog_Subrect_Base_Y "DLSSD.ColorAfterFog.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ScreenSpaceSubsurfaceScatteringGuide_Subrect_Base_X "DLSSD.ScreenSpaceSubsurfaceScatteringGuide.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ScreenSpaceSubsurfaceScatteringGuide_Subrect_Base_Y "DLSSD.ScreenSpaceSubsurfaceScatteringGuide.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ColorBeforeScreenSpaceSubsurfaceScattering_Subrect_Base_X "DLSSD.ColorBeforeScreenSpaceSubsurfaceScattering.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ColorBeforeScreenSpaceSubsurfaceScattering_Subrect_Base_Y "DLSSD.ColorBeforeScreenSpaceSubsurfaceScattering.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ColorAfterScreenSpaceSubsurfaceScattering_Subrect_Base_X "DLSSD.ColorAfterScreenSpaceSubsurfaceScattering.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ColorAfterScreenSpaceSubsurfaceScattering_Subrect_Base_Y "DLSSD.ColorAfterScreenSpaceSubsurfaceScattering.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ScreenSpaceRefractionGuide_Subrect_Base_X "DLSSD.ScreenSpaceRefractionGuide.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ScreenSpaceRefractionGuide_Subrect_Base_Y "DLSSD.ScreenSpaceRefractionGuide.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ColorBeforeScreenSpaceRefraction_Subrect_Base_X "DLSSD.ColorBeforeScreenSpaceRefraction.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ColorBeforeScreenSpaceRefraction_Subrect_Base_Y "DLSSD.ColorBeforeScreenSpaceRefraction.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ColorAfterScreenSpaceRefraction_Subrect_Base_X "DLSSD.ColorAfterScreenSpaceRefraction.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ColorAfterScreenSpaceRefraction_Subrect_Base_Y "DLSSD.ColorAfterScreenSpaceRefraction.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_DepthOfFieldGuide_Subrect_Base_X "DLSSD.DepthOfFieldGuide.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_DepthOfFieldGuide_Subrect_Base_Y "DLSSD.DepthOfFieldGuide.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ColorBeforeDepthOfField_Subrect_Base_X "DLSSD.ColorBeforeDepthOfField.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ColorBeforeDepthOfField_Subrect_Base_Y "DLSSD.ColorBeforeDepthOfField.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ColorAfterDepthOfField_Subrect_Base_X "DLSSD.ColorAfterDepthOfField.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ColorAfterDepthOfField_Subrect_Base_Y "DLSSD.ColorAfterDepthOfField.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_DiffuseHitDistance_Subrect_Base_X "DLSSD.DiffuseHitDistance.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_DiffuseHitDistance_Subrect_Base_Y "DLSSD.DiffuseHitDistance.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_SpecularHitDistance_Subrect_Base_X "DLSSD.SpecularHitDistance.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_SpecularHitDistance_Subrect_Base_Y "DLSSD.SpecularHitDistance.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_DiffuseRayDirection_Subrect_Base_X "DLSSD.DiffuseRayDirection.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_DiffuseRayDirection_Subrect_Base_Y "DLSSD.DiffuseRayDirection.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_SpecularRayDirection_Subrect_Base_X "DLSSD.SpecularRayDirection.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_SpecularRayDirection_Subrect_Base_Y "DLSSD.SpecularRayDirection.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_DiffuseRayDirectionHitDistance_Subrect_Base_X "DLSSD.DiffuseRayDirectionHitDistance.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_DiffuseRayDirectionHitDistance_Subrect_Base_Y "DLSSD.DiffuseRayDirectionHitDistance.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_SpecularRayDirectionHitDistance_Subrect_Base_X "DLSSD.SpecularRayDirectionHitDistance.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_SpecularRayDirectionHitDistance_Subrect_Base_Y "DLSSD.SpecularRayDirectionHitDistance.Subrect.Base.Y"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ResponsivityMask_Subrect_Base_X "DLSSD.ResponsivityMask.Subrect.Base.X"
|
||||
#define NVSDK_NGX_Parameter_DLSSD_ResponsivityMask_Subrect_Base_Y "DLSSD.ResponsivityMask.Subrect.Base.Y"
|
||||
|
||||
#define NVSDK_NGX_Parameter_SuperSamplingDenoising_Available "SuperSamplingDenoising.Available"
|
||||
#define NVSDK_NGX_Parameter_SuperSamplingDenoising_NeedsUpdatedDriver "SuperSamplingDenoising.NeedsUpdatedDriver"
|
||||
#define NVSDK_NGX_Parameter_SuperSamplingDenoising_MinDriverVersionMajor "SuperSamplingDenoising.MinDriverVersionMajor"
|
||||
#define NVSDK_NGX_Parameter_SuperSamplingDenoising_MinDriverVersionMinor "SuperSamplingDenoising.MinDriverVersionMinor"
|
||||
#define NVSDK_NGX_Parameter_SuperSamplingDenoising_FeatureInitResult "SuperSamplingDenoising.FeatureInitResult"
|
||||
#define NVSDK_NGX_Parameter_DLSSDOptimalSettingsCallback "DLSSDOptimalSettingsCallback"
|
||||
#define NVSDK_NGX_Parameter_DLSSDGetStatsCallback "DLSSDGetStatsCallback"
|
||||
|
||||
#define NVSDK_NGX_Parameter_RayReconstruction_Hint_Render_Preset_DLAA "RayReconstruction.Hint.Render.Preset.DLAA"
|
||||
#define NVSDK_NGX_Parameter_RayReconstruction_Hint_Render_Preset_Quality "RayReconstruction.Hint.Render.Preset.Quality"
|
||||
#define NVSDK_NGX_Parameter_RayReconstruction_Hint_Render_Preset_Balanced "RayReconstruction.Hint.Render.Preset.Balanced"
|
||||
#define NVSDK_NGX_Parameter_RayReconstruction_Hint_Render_Preset_Performance "RayReconstruction.Hint.Render.Preset.Performance"
|
||||
#define NVSDK_NGX_Parameter_RayReconstruction_Hint_Render_Preset_UltraPerformance "RayReconstruction.Hint.Render.Preset.UltraPerformance"
|
||||
#define NVSDK_NGX_Parameter_RayReconstruction_Hint_Render_Preset_UltraQuality "RayReconstruction.Hint.Render.Preset.UltraQuality"
|
||||
|
||||
#endif // NVSDK_NGX_DEFS_DLSSD_H
|
||||
@@ -0,0 +1,378 @@
|
||||
#pragma once
|
||||
/*
|
||||
* Copyright (c) 2021-2024 NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* NVIDIA Corporation and its licensors retain all intellectual property and proprietary
|
||||
* rights in and to this software, related documentation and any modifications thereto.
|
||||
* Any use, reproduction, disclosure or distribution of this software and related
|
||||
* documentation without an express license agreement from NVIDIA Corporation is strictly
|
||||
* prohibited.
|
||||
*
|
||||
* TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED *AS IS*
|
||||
* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS OR IMPLIED,
|
||||
* INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT
|
||||
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF
|
||||
* BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR
|
||||
* INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef NVSDK_NGX_DEFS_DLSSG_H
|
||||
#define NVSDK_NGX_DEFS_DLSSG_H
|
||||
|
||||
#include <stddef.h> // for size_t
|
||||
#include <stdint.h> // for uint64_t
|
||||
|
||||
#include "nvsdk_ngx_defs.h"
|
||||
#include "nvsdk_ngx_params.h"
|
||||
|
||||
typedef enum NVSDK_NGX_DLSSG_ResourceFlags
|
||||
{
|
||||
NVSDK_NGX_DLSSG_ResourceFlags_Backbuffer = 1 << 0,
|
||||
NVSDK_NGX_DLSSG_ResourceFlags_MVecs = 1 << 1,
|
||||
NVSDK_NGX_DLSSG_ResourceFlags_Depth = 1 << 2,
|
||||
NVSDK_NGX_DLSSG_ResourceFlags_HUDLess = 1 << 3,
|
||||
NVSDK_NGX_DLSSG_ResourceFlags_UI = 1 << 4,
|
||||
NVSDK_NGX_DLSSG_ResourceFlags_BidirectionalDistortionField = 1 << 5,
|
||||
NVSDK_NGX_DLSSG_ResourceFlags_Reserved6 = 1 << 6,
|
||||
NVSDK_NGX_DLSSG_ResourceFlags_UIAlpha = 1 << 7,
|
||||
|
||||
NVSDK_NGX_DLSSG_ResourceFlags_OutputInterpolated = 1 << 24,
|
||||
NVSDK_NGX_DLSSG_ResourceFlags_OutputReal = 1 << 25,
|
||||
NVSDK_NGX_DLSSG_ResourceFlags_OutputDisableInterpolation = 1 << 26,
|
||||
} NVSDK_NGX_DLSSG_ResourceFlags;
|
||||
|
||||
#define NVSDK_NGX_Parameter_FrameGeneration_Available "FrameGeneration.Available"
|
||||
#define NVSDK_NGX_Parameter_FrameGeneration_FeatureInitResult "FrameGeneration.FeatureInitResult"
|
||||
#define NVSDK_NGX_Parameter_FrameGeneration_MinDriverVersionMajor "FrameGeneration.MinDriverVersionMajor"
|
||||
#define NVSDK_NGX_Parameter_FrameGeneration_MinDriverVersionMinor "FrameGeneration.MinDriverVersionMinor"
|
||||
#define NVSDK_NGX_Parameter_FrameGeneration_NeedsUpdatedDriver "FrameGeneration.NeedsUpdatedDriver"
|
||||
|
||||
#define NVSDK_NGX_Parameter_FrameInterpolation_Available "FrameInterpolation.Available"
|
||||
#define NVSDK_NGX_Parameter_FrameInterpolation_FeatureInitResult "FrameInterpolation.FeatureInitResult"
|
||||
#define NVSDK_NGX_Parameter_FrameInterpolation_MinDriverVersionMajor "FrameInterpolation.MinDriverVersionMajor"
|
||||
#define NVSDK_NGX_Parameter_FrameInterpolation_MinDriverVersionMinor "FrameInterpolation.MinDriverVersionMinor"
|
||||
#define NVSDK_NGX_Parameter_FrameInterpolation_NeedsUpdatedDriver "FrameInterpolation.NeedsUpdatedDriver"
|
||||
|
||||
#define NVSDK_NGX_DLSSG_Parameter_BackbufferFormat "DLSSG.BackbufferFormat"
|
||||
|
||||
// Required Input Textures
|
||||
|
||||
#define NVSDK_NGX_DLSSG_Parameter_Backbuffer "DLSSG.Backbuffer"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_MVecs "DLSSG.MVecs"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_Depth "DLSSG.Depth"
|
||||
|
||||
// Optional Input Textures to improve Image Quality (strongly suggested)
|
||||
|
||||
// NVSDK_NGX_DLSSG_Parameter_BidirectionalDistortionField: Resource describing post-processing distortion effects,
|
||||
// such as lens distortion, that have been applied to the final color. If you use this type of effect, the final
|
||||
// color is no longer aligned with the input depth, motion vectors, and camera information.
|
||||
// The bidirectional distortion field serves as a mapping between the pixels in the distorted color texture
|
||||
// and the undistorted guide buffers.
|
||||
#define NVSDK_NGX_DLSSG_Parameter_BidirectionalDistortionField "DLSSG.BidirectionalDistortionField"
|
||||
// NVSDK_NGX_DLSSG_Parameter_HUDLess: Contains the scene color before any UI or HUD elements
|
||||
// are drawn. Its content for non-UI pixels should be identical to the backbuffer.
|
||||
#define NVSDK_NGX_DLSSG_Parameter_HUDLess "DLSSG.HUDLess"
|
||||
// NVSDK_NGX_DLSSG_Parameter_UI: A four-channel resource containing the color and opacity/alpha of the UI.
|
||||
// The color should be pre-multiplied by the alpha value, such that for each pixel:
|
||||
// backbuffer_color = ui_color + (1 - ui_alpha) * hudless_scene_color
|
||||
#define NVSDK_NGX_DLSSG_Parameter_UI "DLSSG.UI"
|
||||
// NVSDK_NGX_DLSSG_Parameter_UIAlpha: A single channel resource of only the alpha UI values, between 0.0f and 1.0f.
|
||||
#define NVSDK_NGX_DLSSG_Parameter_UIAlpha "DLSSG.UIAlpha"
|
||||
// Note: Only one of NVSDK_NGX_DLSSG_Parameter_UIAlpha or NVSDK_NGX_DLSSG_Parameter_UI need to be provided.
|
||||
// For User Interface Recomposition (UIR) frame generation, both HUDless and one of UI or UIAlpha must be provided.
|
||||
// Additionally set the NVSDK_NGX_DLSSG_Parameter_UserInterfaceRecompositionEnabled parameter to trigger
|
||||
// the create time decisions required for this UIR mode. See that parameter description for more information.
|
||||
|
||||
// Required Output Texture (same texture format as Backbuffer)
|
||||
#define NVSDK_NGX_DLSSG_Parameter_OutputInterpolated "DLSSG.OutputInterpolated"
|
||||
// Optional Output Texture (gives FG the opportunity to render text or debug info onto the real frame)
|
||||
#define NVSDK_NGX_DLSSG_Parameter_OutputReal "DLSSG.OutputReal"
|
||||
|
||||
// Legacy names for the output interpolated and real frames. Use the equivalent parameters
|
||||
// NVSDK_NGX_DLSSG_Parameter_OutputInterpolated and NVSDK_NGX_DLSSG_Parameter_OutputReal
|
||||
// instead.
|
||||
#define NVSDK_NGX_Parameter_OutputInterpolated "DLSSG.OutputInterpolated"
|
||||
#define NVSDK_NGX_Parameter_OutputReal "DLSSG.OutputReal"
|
||||
|
||||
// Create-time resource flag bitmasks (see NVSDK_NGX_DLSSG_ResourceFlags)
|
||||
// denoting resources that the application will always/never provide for the
|
||||
// lifetime of the feature instance. Setting these values may enable memory
|
||||
// optimizations to reduce VRAM. Resources not specified in either mask remain
|
||||
// optional, and may be provided on some frames, but not others. Resources
|
||||
// required by the algorithm (backbuffer, mvecs, depth, and output) are assumed
|
||||
// to be set in AlwaysProvidedFlags and unset in NeverProvidedFlags, regardless
|
||||
// of the actual values
|
||||
#define NVSDK_NGX_DLSSG_Parameter_ResourceAlwaysProvided_Flags "DLSSG.ResourceAlwaysProvidedFlags"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_ResourceNeverProvided_Flags "DLSSG.ResourceNeverProvidedFlags"
|
||||
|
||||
// DLFG-specific width/height parameters, to avoid name conflicts with other
|
||||
// features. If set in CreateFeature, these parameters will be used instead of
|
||||
// the generic NVSDK_NGX_Parameter{Width,Height}
|
||||
#define NVSDK_NGX_DLSSG_Parameter_Width "DLSSG.Width"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_Height "DLSSG.Height"
|
||||
|
||||
// Output resource which allows the snippet to hint to the host application that
|
||||
// the interpolated frame(s) should not be shown this frame. This resource must
|
||||
// be created by the application with a minimum size of 4 bytes, and will be filled
|
||||
// by the snippet: if interpolation should be disabled for this frame, boolean true
|
||||
// will be written to the first byte of the buffer.
|
||||
#define NVSDK_NGX_DLSSG_Parameter_OutputDisableInterpolation "DLSSG.OutputDisableInterpolation"
|
||||
|
||||
// IMPORTANT: All matrices should NOT contain temporal AA jitter offset
|
||||
// Specifies matrix transformation from the camera view to the clip space.
|
||||
// Float4x4 as void*
|
||||
#define NVSDK_NGX_DLSSG_Parameter_CameraViewToClip "DLSSG.CameraViewToClip"
|
||||
// Float4x4 as void*
|
||||
#define NVSDK_NGX_DLSSG_Parameter_ClipToCameraView "DLSSG.ClipToCameraView"
|
||||
// Float4x4 as void*
|
||||
#define NVSDK_NGX_DLSSG_Parameter_ClipToLensClip "DLSSG.ClipToLensClip"
|
||||
// Float4x4 as void*
|
||||
#define NVSDK_NGX_DLSSG_Parameter_ClipToPrevClip "DLSSG.ClipToPrevClip"
|
||||
// Float4x4 as void*
|
||||
#define NVSDK_NGX_DLSSG_Parameter_PrevClipToClip "DLSSG.PrevClipToClip"
|
||||
|
||||
// Specifies clip space jitter offset
|
||||
#define NVSDK_NGX_DLSSG_Parameter_JitterOffsetX "DLSSG.JitterOffsetX"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_JitterOffsetY "DLSSG.JitterOffsetY"
|
||||
|
||||
// Specifies scale factors used to normalize motion vectors (so the values are in [-1,1] range)
|
||||
#define NVSDK_NGX_DLSSG_Parameter_MvecScaleX "DLSSG.MvecScaleX"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_MvecScaleY "DLSSG.MvecScaleY"
|
||||
|
||||
// Specifies camera pinhole offset.
|
||||
#define NVSDK_NGX_DLSSG_Parameter_CameraPinholeOffsetX "DLSSG.CameraPinholeOffsetX"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_CameraPinholeOffsetY "DLSSG.CameraPinholeOffsetY"
|
||||
|
||||
// Specifies camera position in world space.
|
||||
#define NVSDK_NGX_DLSSG_Parameter_CameraPosX "DLSSG.CameraPosX"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_CameraPosY "DLSSG.CameraPosY"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_CameraPosZ "DLSSG.CameraPosZ"
|
||||
|
||||
// Specifies camera up vector in world space.
|
||||
#define NVSDK_NGX_DLSSG_Parameter_CameraUpX "DLSSG.CameraUpX"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_CameraUpY "DLSSG.CameraUpY"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_CameraUpZ "DLSSG.CameraUpZ"
|
||||
|
||||
// Specifies camera right vector in world space.
|
||||
#define NVSDK_NGX_DLSSG_Parameter_CameraRightX "DLSSG.CameraRightX"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_CameraRightY "DLSSG.CameraRightY"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_CameraRightZ "DLSSG.CameraRightZ"
|
||||
|
||||
// Specifies camera forward vector in world space.
|
||||
#define NVSDK_NGX_DLSSG_Parameter_CameraFwdX "DLSSG.CameraFwdX"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_CameraFwdY "DLSSG.CameraFwdY"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_CameraFwdZ "DLSSG.CameraFwdZ"
|
||||
|
||||
// Specifies camera near view plane distance.
|
||||
#define NVSDK_NGX_DLSSG_Parameter_CameraNear "DLSSG.CameraNear"
|
||||
|
||||
// Specifies camera far view plane distance.
|
||||
#define NVSDK_NGX_DLSSG_Parameter_CameraFar "DLSSG.CameraFar"
|
||||
|
||||
// Specifies camera field of view in radians.
|
||||
#define NVSDK_NGX_DLSSG_Parameter_CameraFOV "DLSSG.CameraFOV"
|
||||
|
||||
// Specifies camera aspect ratio defined as view space width divided by height.
|
||||
#define NVSDK_NGX_DLSSG_Parameter_CameraAspectRatio "DLSSG.CameraAspectRatio"
|
||||
|
||||
// Specifies if tagged color buffers are full HDR (rendering to an HDR monitor) or not
|
||||
#define NVSDK_NGX_DLSSG_Parameter_ColorBuffersHDR "DLSSG.ColorBuffersHDR"
|
||||
|
||||
// Specifies if depth values are inverted (value closer to the camera is higher) or not.
|
||||
#define NVSDK_NGX_DLSSG_Parameter_DepthInverted "DLSSG.DepthInverted"
|
||||
|
||||
// Specifies if camera motion is included in the MVec buffer.
|
||||
#define NVSDK_NGX_DLSSG_Parameter_CameraMotionIncluded "DLSSG.CameraMotionIncluded"
|
||||
|
||||
// Specifies if motion vectors include jitter data.
|
||||
|
||||
// Specifies if previous frame has no connection to the current one (motion vectors are invalid)
|
||||
#define NVSDK_NGX_DLSSG_Parameter_Reset "DLSSG.Reset"
|
||||
|
||||
// Specifies if Automode overrode the input Reset flag to true.
|
||||
#define NVSDK_NGX_DLSSG_Parameter_AutomodeOverrideReset "DLSSG.AutomodeOverrideReset"
|
||||
|
||||
// Specifies if application is not currently rendering game frames (paused in menu, playing video cut-scenes)
|
||||
#define NVSDK_NGX_DLSSG_Parameter_NotRenderingGameFrames "DLSSG.NotRenderingGameFrames"
|
||||
|
||||
// Specifies if orthographic projection is used or not.
|
||||
#define NVSDK_NGX_DLSSG_Parameter_OrthoProjection "DLSSG.OrthoProjection"
|
||||
|
||||
#define NVSDK_NGX_DLSSG_Parameter_EstimateVRAMCallback "DLSSG.EstimateVRAMCallback"
|
||||
|
||||
#define NVSDK_NGX_DLSSG_Parameter_InvertXAxis "DLSSG.InvertXAxis"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_InvertYAxis "DLSSG.InvertYAxis"
|
||||
|
||||
#define NVSDK_NGX_DLSSG_Parameter_UserDebugText "DLSSG.UserDebugText"
|
||||
|
||||
#define NVSDK_NGX_DLSSG_Parameter_MvecInvalidValue "DLSSG.MvecInvalidValue"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_MvecDilated "DLSSG.MvecDilated"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_MvecJittered "DLSSG.MvecJittered"
|
||||
|
||||
#define NVSDK_NGX_DLSSG_Parameter_MenuDetectionEnabled "DLSSG.MenuDetectionEnabled"
|
||||
|
||||
// If true, allow the snippet to create internal resources on a separate thread, to avoid hitches during feature creation (default false)
|
||||
#define NVSDK_NGX_DLSSG_Parameter_AsyncCreateEnabled "DLSSG.AsyncCreateEnabled"
|
||||
|
||||
// The DLSS Frame Generation algorithm processes all depth in a "linearized" depth space using the below formulation.
|
||||
//
|
||||
// if NVSDK_NGX_DLSSG_Parameter_DepthInverted is false: `lin_depth = 1 / (1 - depth)`
|
||||
// if NVSDK_NGX_DLSSG_Parameter_DepthInverted is true: `lin_depth = 1 / depth`
|
||||
//
|
||||
// This enables the algorithm to reliably threshold and characterize depth interactions.
|
||||
//
|
||||
// The Frame Generation algorithm is tuned such that most game integrations do not need to modify these values.
|
||||
// However, the below parameters provide mechanisms to control the shape of the internal depth processing space.
|
||||
// Typically useful when input raw depth units are compressed into a small dynamic range. The scale modifier
|
||||
// NVSDK_NGX_DLSSG_Parameter_LinearizedDepth_Scale is a good place to start that won't require more changes.
|
||||
//
|
||||
// Note: the input depth texture must be consistent with the input camera transformation matrices, e.g. clip2prevclip.
|
||||
|
||||
// Optional scalar on the linearized depth before algorithm processing.
|
||||
//
|
||||
// Defaults to 1.0f. A value of 0.1f can help with a compressed input depth range.
|
||||
#define NVSDK_NGX_DLSSG_Parameter_LinearizedDepth_Scale "DLSSG.LinearizedDepth_Scale"
|
||||
|
||||
// Optional heuristic that defines the z-distance to the depth plane that artificially partitions near from far objects.
|
||||
// DLSS Frame Generation uses this plane to restrict far plane object motion from scattering into near plane objects.
|
||||
//
|
||||
// Defaults to 600.0f. A value of 4000.0f can help with a compressed input depth range.
|
||||
#define NVSDK_NGX_DLSSG_Parameter_LinearizedDepth_NearFarPartition "DLSSG.LinearizedDepth_NearFarPartition"
|
||||
|
||||
// Optional heuristic that specifies the minimum linearized depth difference between two objects in screen-space.
|
||||
// DLSS Frame Generation uses this heuristic to understand contiguous depth surfaces.
|
||||
//
|
||||
// Defaults to 40.0f.
|
||||
#define NVSDK_NGX_DLSSG_Parameter_MinRelativeLinearDepthObjectSeparation "DLSSG.MinRelativeLinearDepthObjectSeparation"
|
||||
|
||||
// Texture Subrect Definitions
|
||||
|
||||
// Subrect definitions for the input backbuffer (NVSDK_NGX_DLSSG_Parameter_Backbuffer)
|
||||
#define NVSDK_NGX_DLSSG_Parameter_InputBackbufferSubrectBaseX "DLSSG.InputBackbufferSubrectBaseX"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_InputBackbufferSubrectBaseY "DLSSG.InputBackbufferSubrectBaseY"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_InputBackbufferSubrectWidth "DLSSG.InputBackbufferSubrectWidth"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_InputBackbufferSubrectHeight "DLSSG.InputBackbufferSubrectHeight"
|
||||
|
||||
#define NVSDK_NGX_DLSSG_Parameter_MVecsSubrectBaseX "DLSSG.MVecsSubrectBaseX"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_MVecsSubrectBaseY "DLSSG.MVecsSubrectBaseY"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_MVecsSubrectWidth "DLSSG.MVecsSubrectWidth"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_MVecsSubrectHeight "DLSSG.MVecsSubrectHeight"
|
||||
|
||||
#define NVSDK_NGX_DLSSG_Parameter_DepthSubrectBaseX "DLSSG.DepthSubrectBaseX"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_DepthSubrectBaseY "DLSSG.DepthSubrectBaseY"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_DepthSubrectWidth "DLSSG.DepthSubrectWidth"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_DepthSubrectHeight "DLSSG.DepthSubrectHeight"
|
||||
|
||||
#define NVSDK_NGX_DLSSG_Parameter_HUDLessSubrectBaseX "DLSSG.HUDLessSubrectBaseX"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_HUDLessSubrectBaseY "DLSSG.HUDLessSubrectBaseY"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_HUDLessSubrectWidth "DLSSG.HUDLessSubrectWidth"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_HUDLessSubrectHeight "DLSSG.HUDLessSubrectHeight"
|
||||
|
||||
#define NVSDK_NGX_DLSSG_Parameter_UISubrectBaseX "DLSSG.UISubrectBaseX"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_UISubrectBaseY "DLSSG.UISubrectBaseY"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_UISubrectWidth "DLSSG.UISubrectWidth"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_UISubrectHeight "DLSSG.UISubrectHeight"
|
||||
|
||||
#define NVSDK_NGX_DLSSG_Parameter_UIAlphaSubrectBaseX "DLSSG.UIAlphaSubrectBaseX"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_UIAlphaSubrectBaseY "DLSSG.UIAlphaSubrectBaseY"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_UIAlphaSubrectWidth "DLSSG.UIAlphaSubrectWidth"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_UIAlphaSubrectHeight "DLSSG.UIAlphaSubrectHeight"
|
||||
|
||||
#define NVSDK_NGX_DLSSG_Parameter_BidirectionalDistortionFieldSubrectBaseX "DLSSG.BidirectionalDistortionFieldSubrectBaseX"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_BidirectionalDistortionFieldSubrectBaseY "DLSSG.BidirectionalDistortionFieldSubrectBaseY"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_BidirectionalDistortionFieldSubrectWidth "DLSSG.BidirectionalDistortionFieldSubrectWidth"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_BidirectionalDistortionFieldSubrectHeight "DLSSG.BidirectionalDistortionFieldSubrectHeight"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_BidirectionalDistortionField_LowPrecision_IsLowPrecision "DLSSG.BidirectionalDistortionFieldLowPrecision.IsLowPrecision"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_BidirectionalDistortionField_LowPrecision_Bias "DLSSG.BidirectionalDistortionFieldLowPrecision.Bias"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_BidirectionalDistortionField_LowPrecision_Scale "DLSSG.BidirectionalDistortionFieldLowPrecision.Scale"
|
||||
|
||||
#define NVSDK_NGX_DLSSG_Parameter_OutputInterpolatedSubrectBaseX "DLSSG.OutputInterpolatedSubrectBaseX"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_OutputInterpolatedSubrectBaseY "DLSSG.OutputInterpolatedSubrectBaseY"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_OutputInterpolatedSubrectWidth "DLSSG.OutputInterpolatedSubrectWidth"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_OutputInterpolatedSubrectHeight "DLSSG.OutputInterpolatedSubrectHeight"
|
||||
|
||||
#define NVSDK_NGX_DLSSG_Parameter_OutputRealSubrectBaseX "DLSSG.OutputRealSubrectBaseX"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_OutputRealSubrectBaseY "DLSSG.OutputRealSubrectBaseY"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_OutputRealSubrectWidth "DLSSG.OutputRealSubrectWidth"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_OutputRealSubrectHeight "DLSSG.OutputRealSubrectHeight"
|
||||
|
||||
// DEPRECATED. Backbuffer subrect definitions. These apply to BOTH the input and
|
||||
// output backbuffer resources (Backbuffer, OutputInterpolated, OutputReal).
|
||||
//
|
||||
// Use InputBackbufferSubrect, OutputInterpolatedSubrect, and OutputRealSubrect
|
||||
// instead.
|
||||
#define NVSDK_NGX_DLSSG_Parameter_BackbufferSubrectBaseX "DLSSG.BackbufferSubrectBaseX"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_BackbufferSubrectBaseY "DLSSG.BackbufferSubrectBaseY"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_BackbufferSubrectWidth "DLSSG.BackbufferSubrectWidth"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_BackbufferSubrectHeight "DLSSG.BackbufferSubrectHeight"
|
||||
|
||||
// Specifies the internal resolution to be used (mainly for dynamic resolution)
|
||||
#define NVSDK_NGX_DLSSG_Parameter_InternalWidth "DLSSG.InternalWidth"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_InternalHeight "DLSSG.InternalHeight"
|
||||
|
||||
// If nonzero, we expect to use dynamic resolution (MVec and Depth res will change, possibly per frame)
|
||||
#define NVSDK_NGX_DLSSG_Parameter_DynamicResolution "DLSSG.DynamicResolution"
|
||||
|
||||
typedef enum NVSDK_NGX_DLSSG_EvalFlags
|
||||
{
|
||||
// The default behaviour for evaluate is to write the interpolated pixels inside of the
|
||||
// backbuffer extent and uninterpolated pixels - outside of the extent. If this flag is
|
||||
// set, then only the inside of the backbuffer extent is updated, the outside of the extent
|
||||
// stays untouched.
|
||||
NVSDK_NGX_DLSSG_EvalFlags_UpdateOnlyInsideExtents = (1 << 0)
|
||||
} NVSDK_NGX_DLSSG_EvalFlags;
|
||||
#define NVSDK_NGX_DLSSG_Parameter_EvalFlags "DLSSG.EvalFlags"
|
||||
|
||||
typedef enum NVSDK_NGX_DLSSG_FullscreenMode
|
||||
{
|
||||
NVSDK_NGX_DLSSG_FullscreenMode_Windowed = 0,
|
||||
NVSDK_NGX_DLSSG_FullscreenMode_Borderless = 1,
|
||||
NVSDK_NGX_DLSSG_FullscreenMode_Exclusive = 2
|
||||
} NVSDK_NGX_DLSSG_FullscreenMode;
|
||||
|
||||
#define NVSDK_NGX_DLSSG_Parameter_FullscreenMode "DLSSG.FullscreenMode"
|
||||
#define NVSDK_NGX_DLSSG_Parameter_TargetFrameRate "DLSSG.TargetFrameRate"
|
||||
|
||||
// Callback function types
|
||||
typedef NVSDK_NGX_Result(NVSDK_CONV* PFN_NVSDK_NGX_DLSSG_GetCurrentSettingsCallback)(const NVSDK_NGX_Handle* InHandle, NVSDK_NGX_Parameter* InParams);
|
||||
typedef NVSDK_NGX_Result(NVSDK_CONV* PFN_NVSDK_NGX_DLSSG_EstimateVRAMCallback)(uint32_t mvecDepthWidth, uint32_t mvecDepthHeight,
|
||||
uint32_t colorWidth, uint32_t colorHeight,
|
||||
uint32_t colorBufferFormat,
|
||||
uint32_t mvecBufferFormat, uint32_t depthBufferFormat,
|
||||
uint32_t hudLessBufferFormat, uint32_t uiBufferFormat, size_t* estimatedVRAMInBytes);
|
||||
|
||||
// DLSS 4
|
||||
|
||||
// Output Capability Parameters (access via GetDeviceCapabilityParameters)
|
||||
// The maximum number of generated frames supported by the feature (e.g. 3 for 4x)
|
||||
// If 1 or not set, multiframe is not supported
|
||||
#define NVSDK_NGX_DLSSG_Parameter_MultiFrameCountMax "DLSSG.MultiFrameCountMax"
|
||||
|
||||
// InParameters
|
||||
// uint32_t, Total of Number Frames expected to Interpolate for given Real-Frame Pair. For 4x, this is 3. For 2x, this is 1.
|
||||
#define NVSDK_NGX_DLSSG_Parameter_MultiFrameCount "DLSSG.MultiFrameCount"
|
||||
// uint32_t, Current inner frame index. For 4x, this is 1, 2, and 3. For 2x, this is 1.
|
||||
#define NVSDK_NGX_DLSSG_Parameter_MultiFrameIndex "DLSSG.MultiFrameIndex"
|
||||
|
||||
// Optional: uint64_t that increments by one for each fully rendered backbuffer frame such that
|
||||
// Current Backbuffer ID == (Previous Backbuffer ID + 1). The number should increment even
|
||||
// if FG is off, for example, when rendering a menu with FG temporarily disabled.
|
||||
#define NVSDK_NGX_DLSSG_Parameter_BackbufferFrameID "DLSSG.BackbufferFrameID"
|
||||
|
||||
// Create Time Parameter: Specifies if User Interface Recomposition is enabled.
|
||||
// When enabled, the algorithm will generate output frames using the HUDless and UI Color & Alpha textures if present.
|
||||
// Boolean value: 0 (disabled) or 1 (enabled).
|
||||
// The end user can override this with Nvidia App DLSS Override.
|
||||
#define NVSDK_NGX_DLSSG_Parameter_UserInterfaceRecompositionEnabled "DLSSG.UserInterfaceRecompositionEnabled"
|
||||
|
||||
// Create Time Parameter: Specifies if Lite Candidate Blending is enabled.
|
||||
// When enabled, the algorithm will use a lighter blending mode for generating
|
||||
// the final output.
|
||||
// Boolean value: 0 (disabled) or 1 (enabled).
|
||||
#define NVSDK_NGX_DLSSG_Parameter_LiteCandidateBlendingEnabled "DLSSG.LiteCandidateBlendingEnabled"
|
||||
|
||||
#endif // NVSDK_NGX_DEFS_DLSSG_H
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: LicenseRef-NvidiaProprietary
|
||||
*
|
||||
* NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
|
||||
* property and proprietary rights in and to this material, related
|
||||
* documentation and any modifications thereto. Any use, reproduction,
|
||||
* disclosure or distribution of this material and related documentation
|
||||
* without an express license agreement from NVIDIA CORPORATION or
|
||||
* its affiliates is strictly prohibited.
|
||||
*/
|
||||
|
||||
#ifndef NVSDK_NGX_DEFS_VK_H
|
||||
#define NVSDK_NGX_DEFS_VK_H
|
||||
#pragma once
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef enum NVSDK_NGX_Resource_VK_Type
|
||||
{
|
||||
NVSDK_NGX_RESOURCE_VK_TYPE_VK_IMAGEVIEW,
|
||||
NVSDK_NGX_RESOURCE_VK_TYPE_VK_BUFFER
|
||||
} NVSDK_NGX_Resource_VK_Type;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NVSDK_NGX_ImageViewInfo_VK [Vulkan only]
|
||||
// Contains ImageView-specific metadata.
|
||||
// ImageView:
|
||||
// The VkImageView resource.
|
||||
//
|
||||
// Image:
|
||||
// The VkImage associated to this VkImageView.
|
||||
//
|
||||
// SubresourceRange:
|
||||
// The VkImageSubresourceRange associated to this VkImageView.
|
||||
//
|
||||
// Format:
|
||||
// The format of the resource.
|
||||
//
|
||||
// Width:
|
||||
// The width of the resource.
|
||||
//
|
||||
// Height:
|
||||
// The height of the resource.
|
||||
//
|
||||
typedef struct NVSDK_NGX_ImageViewInfo_VK {
|
||||
VkImageView ImageView;
|
||||
VkImage Image;
|
||||
VkImageSubresourceRange SubresourceRange;
|
||||
VkFormat Format;
|
||||
unsigned int Width;
|
||||
unsigned int Height;
|
||||
} NVSDK_NGX_ImageViewInfo_VK;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NVSDK_NGX_BufferInfo_VK [Vulkan only]
|
||||
// Contains Buffer-specific metadata.
|
||||
// Buffer
|
||||
// The VkBuffer resource.
|
||||
//
|
||||
// SizeInBytes:
|
||||
// The size of the resource (in bytes).
|
||||
//
|
||||
typedef struct NVSDK_NGX_BufferInfo_VK {
|
||||
VkBuffer Buffer;
|
||||
unsigned int SizeInBytes;
|
||||
} NVSDK_NGX_BufferInfo_VK;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NVSDK_NGX_Resource_VK [Vulkan only]
|
||||
//
|
||||
// ImageViewInfo:
|
||||
// The VkImageView resource, and VkImageView-specific metadata. A NVSDK_NGX_Resource_VK can only have one of ImageViewInfo or BufferInfo.
|
||||
//
|
||||
// BufferInfo:
|
||||
// The VkBuffer Resource, and VkBuffer-specific metadata. A NVSDK_NGX_Resource_VK can only have one of ImageViewInfo or BufferInfo.
|
||||
//
|
||||
// Type:
|
||||
// Whether or this resource is a VkImageView or a VkBuffer.
|
||||
//
|
||||
// ReadWrite:
|
||||
// True if the resource is available for read and write access.
|
||||
// For VkBuffer resources: VkBufferUsageFlags includes VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT or VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
|
||||
// For VkImage resources: VkImageUsageFlags for associated VkImage includes VK_IMAGE_USAGE_STORAGE_BIT
|
||||
//
|
||||
typedef struct NVSDK_NGX_Resource_VK {
|
||||
union {
|
||||
NVSDK_NGX_ImageViewInfo_VK ImageViewInfo;
|
||||
NVSDK_NGX_BufferInfo_VK BufferInfo;
|
||||
} Resource;
|
||||
NVSDK_NGX_Resource_VK_Type Type;
|
||||
bool ReadWrite;
|
||||
} NVSDK_NGX_Resource_VK;
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // NVSDK_NGX_DEFS_VK_H
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: LicenseRef-NvidiaProprietary
|
||||
*
|
||||
* NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
|
||||
* property and proprietary rights in and to this material, related
|
||||
* documentation and any modifications thereto. Any use, reproduction,
|
||||
* disclosure or distribution of this material and related documentation
|
||||
* without an express license agreement from NVIDIA CORPORATION or
|
||||
* its affiliates is strictly prohibited.
|
||||
*/
|
||||
|
||||
#ifndef NVSDK_NGX_HELPERS_H
|
||||
#define NVSDK_NGX_HELPERS_H
|
||||
#pragma once
|
||||
|
||||
#include "nvsdk_ngx.h"
|
||||
#include "nvsdk_ngx_defs.h"
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_DLSS_GET_STATS_2(
|
||||
NVSDK_NGX_Parameter *pInParams,
|
||||
unsigned long long *pVRAMAllocatedBytes,
|
||||
unsigned int *pOptLevel, unsigned int *IsDevSnippetBranch)
|
||||
{
|
||||
void *Callback = NULL;
|
||||
NVSDK_NGX_Parameter_GetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSGetStatsCallback, &Callback);
|
||||
if (!Callback)
|
||||
{
|
||||
// Possible reasons for this:
|
||||
// - Installed DLSS is out of date and does not support the feature we need
|
||||
// - You used NVSDK_NGX_AllocateParameters() for creating InParams. Try using NVSDK_NGX_GetCapabilityParameters() instead
|
||||
return NVSDK_NGX_Result_FAIL_OutOfDate;
|
||||
}
|
||||
|
||||
NVSDK_NGX_Result Res = NVSDK_NGX_Result_Success;
|
||||
PFN_NVSDK_NGX_DLSS_GetStatsCallback PFNCallback = (PFN_NVSDK_NGX_DLSS_GetStatsCallback)Callback;
|
||||
Res = PFNCallback(pInParams);
|
||||
if (NVSDK_NGX_FAILED(Res))
|
||||
{
|
||||
return Res;
|
||||
}
|
||||
NVSDK_NGX_Parameter_GetULL(pInParams, NVSDK_NGX_Parameter_SizeInBytes, pVRAMAllocatedBytes);
|
||||
NVSDK_NGX_Parameter_GetUI(pInParams, NVSDK_NGX_EParameter_OptLevel, pOptLevel);
|
||||
NVSDK_NGX_Parameter_GetUI(pInParams, NVSDK_NGX_EParameter_IsDevSnippetBranch, IsDevSnippetBranch);
|
||||
return Res;
|
||||
}
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_DLSS_GET_STATS_1(
|
||||
NVSDK_NGX_Parameter *pInParams,
|
||||
unsigned long long *pVRAMAllocatedBytes,
|
||||
unsigned int *pOptLevel)
|
||||
{
|
||||
unsigned int dummy = 0;
|
||||
return NGX_DLSS_GET_STATS_2(pInParams, pVRAMAllocatedBytes, pOptLevel, &dummy);
|
||||
}
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_DLSS_GET_STATS(
|
||||
NVSDK_NGX_Parameter *pInParams,
|
||||
unsigned long long *pVRAMAllocatedBytes)
|
||||
{
|
||||
unsigned int dummy = 0;
|
||||
return NGX_DLSS_GET_STATS_2(pInParams, pVRAMAllocatedBytes, &dummy, &dummy);
|
||||
}
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_DLSS_GET_OPTIMAL_SETTINGS(
|
||||
NVSDK_NGX_Parameter *pInParams,
|
||||
unsigned int InUserSelectedWidth,
|
||||
unsigned int InUserSelectedHeight,
|
||||
NVSDK_NGX_PerfQuality_Value InPerfQualityValue,
|
||||
unsigned int *pOutRenderOptimalWidth,
|
||||
unsigned int *pOutRenderOptimalHeight,
|
||||
unsigned int *pOutRenderMaxWidth,
|
||||
unsigned int *pOutRenderMaxHeight,
|
||||
unsigned int *pOutRenderMinWidth,
|
||||
unsigned int *pOutRenderMinHeight,
|
||||
float *pOutSharpness)
|
||||
{
|
||||
void *Callback = NULL;
|
||||
NVSDK_NGX_Parameter_GetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSOptimalSettingsCallback, &Callback);
|
||||
if (!Callback)
|
||||
{
|
||||
// Possible reasons for this:
|
||||
// - Installed DLSS is out of date and does not support the feature we need
|
||||
// - You used NVSDK_NGX_AllocateParameters() for creating InParams. Try using NVSDK_NGX_GetCapabilityParameters() instead
|
||||
return NVSDK_NGX_Result_FAIL_OutOfDate;
|
||||
}
|
||||
|
||||
// These are selections made by user in UI
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Width, InUserSelectedWidth);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Height, InUserSelectedHeight);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_PerfQualityValue, InPerfQualityValue);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_RTXValue, false); // Some older DLSS dlls still expect this value to be set
|
||||
|
||||
NVSDK_NGX_Result Res = NVSDK_NGX_Result_Success;
|
||||
PFN_NVSDK_NGX_DLSS_GetOptimalSettingsCallback PFNCallback = (PFN_NVSDK_NGX_DLSS_GetOptimalSettingsCallback)Callback;
|
||||
Res = PFNCallback(pInParams);
|
||||
if (NVSDK_NGX_FAILED(Res))
|
||||
{
|
||||
return Res;
|
||||
}
|
||||
NVSDK_NGX_Parameter_GetUI(pInParams, NVSDK_NGX_Parameter_OutWidth, pOutRenderOptimalWidth);
|
||||
NVSDK_NGX_Parameter_GetUI(pInParams, NVSDK_NGX_Parameter_OutHeight, pOutRenderOptimalHeight);
|
||||
// If we have an older DLSS Dll those might need to be set to the optimal dimensions instead
|
||||
*pOutRenderMaxWidth = *pOutRenderOptimalWidth;
|
||||
*pOutRenderMaxHeight = *pOutRenderOptimalHeight;
|
||||
*pOutRenderMinWidth = *pOutRenderOptimalWidth;
|
||||
*pOutRenderMinHeight = *pOutRenderOptimalHeight;
|
||||
NVSDK_NGX_Parameter_GetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Get_Dynamic_Max_Render_Width, pOutRenderMaxWidth);
|
||||
NVSDK_NGX_Parameter_GetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Get_Dynamic_Max_Render_Height, pOutRenderMaxHeight);
|
||||
NVSDK_NGX_Parameter_GetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Get_Dynamic_Min_Render_Width, pOutRenderMinWidth);
|
||||
NVSDK_NGX_Parameter_GetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Get_Dynamic_Min_Render_Height, pOutRenderMinHeight);
|
||||
NVSDK_NGX_Parameter_GetF(pInParams, NVSDK_NGX_Parameter_Sharpness, pOutSharpness);
|
||||
return Res;
|
||||
}
|
||||
|
||||
#include "nvsdk_ngx_helpers_d3d.h"
|
||||
#include "nvsdk_ngx_helpers_cuda.h"
|
||||
|
||||
#endif // NVSDK_NGX_HELPERS_H
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: LicenseRef-NvidiaProprietary
|
||||
*
|
||||
* NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
|
||||
* property and proprietary rights in and to this material, related
|
||||
* documentation and any modifications thereto. Any use, reproduction,
|
||||
* disclosure or distribution of this material and related documentation
|
||||
* without an express license agreement from NVIDIA CORPORATION or
|
||||
* its affiliates is strictly prohibited.
|
||||
*/
|
||||
|
||||
#ifndef NVSDK_NGX_HELPERS_CUDA_H
|
||||
#define NVSDK_NGX_HELPERS_CUDA_H
|
||||
#pragma once
|
||||
|
||||
#include "nvsdk_ngx.h"
|
||||
#include "nvsdk_ngx_defs.h"
|
||||
|
||||
typedef struct NVSDK_NGX_CUDA_Feature_Eval_Params
|
||||
{
|
||||
CUtexObject* pInColor;
|
||||
CUtexObject* pInOutput;
|
||||
/*** OPTIONAL for DLSS ***/
|
||||
float InSharpness;
|
||||
} NVSDK_NGX_CUDA_Feature_Eval_Params;
|
||||
|
||||
typedef struct NVSDK_NGX_CUDA_DLISP_Eval_Params
|
||||
{
|
||||
NVSDK_NGX_CUDA_Feature_Eval_Params Feature;
|
||||
/*** OPTIONAL - leave to 0/0.0f if unused ***/
|
||||
unsigned int InRectX;
|
||||
unsigned int InRectY;
|
||||
unsigned int InRectW;
|
||||
unsigned int InRectH;
|
||||
float InDenoise;
|
||||
} NVSDK_NGX_CUDA_DLISP_Eval_Params;
|
||||
static inline NVSDK_NGX_Result NGX_CUDA_CREATE_DLISP_EXT(
|
||||
NVSDK_NGX_Handle** ppOutHandle,
|
||||
NVSDK_NGX_Parameter* pInParams,
|
||||
NVSDK_NGX_Feature_Create_Params* pDlispCreateParams)
|
||||
{
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Width, pDlispCreateParams->InWidth);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Height, pDlispCreateParams->InHeight);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutWidth, pDlispCreateParams->InTargetWidth);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutHeight, pDlispCreateParams->InTargetHeight);
|
||||
|
||||
return NVSDK_NGX_CUDA_CreateFeature(NVSDK_NGX_Feature_ImageSignalProcessing, pInParams, ppOutHandle);
|
||||
}
|
||||
static inline NVSDK_NGX_Result NGX_CUDA_EVALUATE_DLISP_EXT(
|
||||
NVSDK_NGX_Handle *pInHandle,
|
||||
NVSDK_NGX_Parameter *pInParams,
|
||||
NVSDK_NGX_CUDA_DLISP_Eval_Params *pDlispEvalParams)
|
||||
{
|
||||
if (pDlispEvalParams->Feature.InSharpness < 0.0f || pDlispEvalParams->Feature.InSharpness > 1.0f || pDlispEvalParams->InDenoise < 0.0f || pDlispEvalParams->InDenoise > 1.0f)
|
||||
{
|
||||
return NVSDK_NGX_Result_FAIL_InvalidParameter;
|
||||
}
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_Color, pDlispEvalParams->Feature.pInColor);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_Output, pDlispEvalParams->Feature.pInOutput);
|
||||
// Both sharpness and denoise in range [0.0f,1.0f]
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Sharpness, pDlispEvalParams->Feature.InSharpness);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Denoise, pDlispEvalParams->InDenoise);
|
||||
// If input is atlas - use RECT to upscale only the required area
|
||||
if (pDlispEvalParams->InRectW)
|
||||
{
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Rect_X, pDlispEvalParams->InRectX);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Rect_Y, pDlispEvalParams->InRectY);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Rect_W, pDlispEvalParams->InRectW);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Rect_H, pDlispEvalParams->InRectH);
|
||||
}
|
||||
|
||||
return NVSDK_NGX_CUDA_EvaluateFeature_C(pInHandle, pInParams, NULL);
|
||||
}
|
||||
#endif // NVSDK_NGX_HELPERS_CUDA_H
|
||||
@@ -0,0 +1,407 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: LicenseRef-NvidiaProprietary
|
||||
*
|
||||
* NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
|
||||
* property and proprietary rights in and to this material, related
|
||||
* documentation and any modifications thereto. Any use, reproduction,
|
||||
* disclosure or distribution of this material and related documentation
|
||||
* without an express license agreement from NVIDIA CORPORATION or
|
||||
* its affiliates is strictly prohibited.
|
||||
*/
|
||||
|
||||
#ifndef NVSDK_NGX_HELPERS_D3D_H
|
||||
#define NVSDK_NGX_HELPERS_D3D_H
|
||||
#pragma once
|
||||
|
||||
#include "nvsdk_ngx.h"
|
||||
#include "nvsdk_ngx_defs.h"
|
||||
|
||||
/*** D3D11 ***/
|
||||
typedef struct NVSDK_NGX_D3D11_Feature_Eval_Params
|
||||
{
|
||||
ID3D11Resource* pInColor;
|
||||
ID3D11Resource* pInOutput;
|
||||
/*** OPTIONAL for DLSS ***/
|
||||
float InSharpness;
|
||||
} NVSDK_NGX_D3D11_Feature_Eval_Params;
|
||||
|
||||
typedef struct NVSDK_NGX_D3D11_GBuffer
|
||||
{
|
||||
ID3D11Resource* pInAttrib[NVSDK_NGX_GBUFFERTYPE_NUM];
|
||||
} NVSDK_NGX_D3D11_GBuffer;
|
||||
|
||||
typedef struct NVSDK_NGX_D3D11_DLSS_Eval_Params
|
||||
{
|
||||
NVSDK_NGX_D3D11_Feature_Eval_Params Feature;
|
||||
ID3D11Resource* pInDepth;
|
||||
ID3D11Resource* pInMotionVectors;
|
||||
float InJitterOffsetX; /* Jitter offset must be in input/render pixel space */
|
||||
float InJitterOffsetY;
|
||||
NVSDK_NGX_Dimensions InRenderSubrectDimensions;
|
||||
/*** OPTIONAL - leave to 0/0.0f if unused ***/
|
||||
int InReset; /* Set to 1 when scene changes completely (new level etc) */
|
||||
float InMVScaleX; /* If MVs need custom scaling to convert to pixel space */
|
||||
float InMVScaleY;
|
||||
ID3D11Resource* pInTransparencyMask; /* Unused/Reserved for future use */
|
||||
ID3D11Resource* pInExposureTexture;
|
||||
ID3D11Resource* pInBiasCurrentColorMask;
|
||||
NVSDK_NGX_Coordinates InColorSubrectBase;
|
||||
NVSDK_NGX_Coordinates InDepthSubrectBase;
|
||||
NVSDK_NGX_Coordinates InMVSubrectBase;
|
||||
NVSDK_NGX_Coordinates InTranslucencySubrectBase;
|
||||
NVSDK_NGX_Coordinates InBiasCurrentColorSubrectBase;
|
||||
NVSDK_NGX_Coordinates InOutputSubrectBase;
|
||||
float InPreExposure;
|
||||
float InExposureScale;
|
||||
int InIndicatorInvertXAxis;
|
||||
int InIndicatorInvertYAxis;
|
||||
/*** OPTIONAL - only for research purposes ***/
|
||||
NVSDK_NGX_D3D11_GBuffer GBufferSurface;
|
||||
NVSDK_NGX_ToneMapperType InToneMapperType;
|
||||
ID3D11Resource* pInMotionVectors3D;
|
||||
ID3D11Resource* pInIsParticleMask; /* to identify which pixels contains particles, essentially that are not drawn as part of base pass */
|
||||
ID3D11Resource* pInAnimatedTextureMask; /* a binary mask covering pixels occupied by animated textures */
|
||||
ID3D11Resource* pInDepthHighRes;
|
||||
ID3D11Resource* pInPositionViewSpace;
|
||||
float InFrameTimeDeltaInMsec; /* helps in determining the amount to denoise or anti-alias based on the speed of the object from motion vector magnitudes and fps as determined by this delta */
|
||||
ID3D11Resource* pInRayTracingHitDistance; /* for each effect - approximation to the amount of noise in a ray-traced color */
|
||||
ID3D11Resource* pInMotionVectorsReflections; /* motion vectors of reflected objects like for mirrored surfaces */
|
||||
} NVSDK_NGX_D3D11_DLSS_Eval_Params;
|
||||
|
||||
typedef struct NVSDK_NGX_D3D11_DLISP_Eval_Params
|
||||
{
|
||||
NVSDK_NGX_D3D11_Feature_Eval_Params Feature;
|
||||
/*** OPTIONAL - leave to 0/0.0f if unused ***/
|
||||
unsigned int InRectX;
|
||||
unsigned int InRectY;
|
||||
unsigned int InRectW;
|
||||
unsigned int InRectH;
|
||||
float InDenoise;
|
||||
} NVSDK_NGX_D3D11_DLISP_Eval_Params;
|
||||
|
||||
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_D3D11_CREATE_DLSS_EXT(
|
||||
ID3D11DeviceContext *pInCtx,
|
||||
NVSDK_NGX_Handle **ppOutHandle,
|
||||
NVSDK_NGX_Parameter *pInParams,
|
||||
NVSDK_NGX_DLSS_Create_Params *pInDlssCreateParams)
|
||||
{
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Width, pInDlssCreateParams->Feature.InWidth);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Height, pInDlssCreateParams->Feature.InHeight);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutWidth, pInDlssCreateParams->Feature.InTargetWidth);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutHeight, pInDlssCreateParams->Feature.InTargetHeight);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_PerfQualityValue, pInDlssCreateParams->Feature.InPerfQualityValue);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Feature_Create_Flags, pInDlssCreateParams->InFeatureCreateFlags);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Enable_Output_Subrects, pInDlssCreateParams->InEnableOutputSubrects ? 1 : 0);
|
||||
|
||||
return NVSDK_NGX_D3D11_CreateFeature(pInCtx, NVSDK_NGX_Feature_SuperSampling, pInParams, ppOutHandle);
|
||||
}
|
||||
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_D3D11_EVALUATE_DLSS_EXT(
|
||||
ID3D11DeviceContext *pInCtx,
|
||||
NVSDK_NGX_Handle *pInHandle,
|
||||
NVSDK_NGX_Parameter *pInParams,
|
||||
NVSDK_NGX_D3D11_DLSS_Eval_Params *pInDlssEvalParams)
|
||||
{
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_Color, pInDlssEvalParams->Feature.pInColor);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_Output, pInDlssEvalParams->Feature.pInOutput);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_Depth, pInDlssEvalParams->pInDepth);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_MotionVectors, pInDlssEvalParams->pInMotionVectors);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Jitter_Offset_X, pInDlssEvalParams->InJitterOffsetX);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Jitter_Offset_Y, pInDlssEvalParams->InJitterOffsetY);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Sharpness, pInDlssEvalParams->Feature.InSharpness);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_Reset, pInDlssEvalParams->InReset);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_MV_Scale_X, pInDlssEvalParams->InMVScaleX == 0.0f ? 1.0f : pInDlssEvalParams->InMVScaleX);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_MV_Scale_Y, pInDlssEvalParams->InMVScaleY == 0.0f ? 1.0f : pInDlssEvalParams->InMVScaleY);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_TransparencyMask, pInDlssEvalParams->pInTransparencyMask);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_ExposureTexture, pInDlssEvalParams->pInExposureTexture);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_Mask, pInDlssEvalParams->pInBiasCurrentColorMask);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Albedo, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_ALBEDO]);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Roughness, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_ROUGHNESS]);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Metallic, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_METALLIC]);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Specular, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_SPECULAR]);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Subsurface, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_SUBSURFACE]);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Normals, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_NORMALS]);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_ShadingModelId, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_SHADINGMODELID]);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_MaterialId, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_MATERIALID]);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_8, pInDlssEvalParams->GBufferSurface.pInAttrib[8]);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_9, pInDlssEvalParams->GBufferSurface.pInAttrib[9]);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_10, pInDlssEvalParams->GBufferSurface.pInAttrib[10]);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_11, pInDlssEvalParams->GBufferSurface.pInAttrib[11]);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_12, pInDlssEvalParams->GBufferSurface.pInAttrib[12]);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_13, pInDlssEvalParams->GBufferSurface.pInAttrib[13]);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_14, pInDlssEvalParams->GBufferSurface.pInAttrib[14]);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_15, pInDlssEvalParams->GBufferSurface.pInAttrib[15]);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_TonemapperType, pInDlssEvalParams->InToneMapperType);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_MotionVectors3D, pInDlssEvalParams->pInMotionVectors3D);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_IsParticleMask, pInDlssEvalParams->pInIsParticleMask);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_AnimatedTextureMask, pInDlssEvalParams->pInAnimatedTextureMask);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_DepthHighRes, pInDlssEvalParams->pInDepthHighRes);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_Position_ViewSpace, pInDlssEvalParams->pInPositionViewSpace);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_FrameTimeDeltaInMsec, pInDlssEvalParams->InFrameTimeDeltaInMsec);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_RayTracingHitDistance, pInDlssEvalParams->pInRayTracingHitDistance);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_MotionVectorsReflection, pInDlssEvalParams->pInMotionVectorsReflections);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Color_Subrect_Base_X, pInDlssEvalParams->InColorSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Color_Subrect_Base_Y, pInDlssEvalParams->InColorSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Depth_Subrect_Base_X, pInDlssEvalParams->InDepthSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Depth_Subrect_Base_Y, pInDlssEvalParams->InDepthSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_MV_SubrectBase_X, pInDlssEvalParams->InMVSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_MV_SubrectBase_Y, pInDlssEvalParams->InMVSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Translucency_SubrectBase_X, pInDlssEvalParams->InTranslucencySubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Translucency_SubrectBase_Y, pInDlssEvalParams->InTranslucencySubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_SubrectBase_X, pInDlssEvalParams->InBiasCurrentColorSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_SubrectBase_Y, pInDlssEvalParams->InBiasCurrentColorSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Output_Subrect_Base_X, pInDlssEvalParams->InOutputSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Output_Subrect_Base_Y, pInDlssEvalParams->InOutputSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Render_Subrect_Dimensions_Width , pInDlssEvalParams->InRenderSubrectDimensions.Width);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Render_Subrect_Dimensions_Height, pInDlssEvalParams->InRenderSubrectDimensions.Height);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_DLSS_Pre_Exposure, pInDlssEvalParams->InPreExposure == 0.0f ? 1.0f : pInDlssEvalParams->InPreExposure);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_DLSS_Exposure_Scale, pInDlssEvalParams->InExposureScale == 0.0f ? 1.0f : pInDlssEvalParams->InExposureScale);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Indicator_Invert_X_Axis, pInDlssEvalParams->InIndicatorInvertXAxis);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Indicator_Invert_Y_Axis, pInDlssEvalParams->InIndicatorInvertYAxis);
|
||||
|
||||
return NVSDK_NGX_D3D11_EvaluateFeature_C(pInCtx, pInHandle, pInParams, NULL);
|
||||
}
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_D3D11_CREATE_DLISP_EXT(
|
||||
ID3D11DeviceContext *pInCtx,
|
||||
NVSDK_NGX_Handle **ppOutHandle,
|
||||
NVSDK_NGX_Parameter *pInParams,
|
||||
NVSDK_NGX_Feature_Create_Params *pDlispCreateParams)
|
||||
{
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Width, pDlispCreateParams->InWidth);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Height, pDlispCreateParams->InHeight);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutWidth, pDlispCreateParams->InTargetWidth);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutHeight, pDlispCreateParams->InTargetHeight);
|
||||
|
||||
return NVSDK_NGX_D3D11_CreateFeature(pInCtx, NVSDK_NGX_Feature_ImageSignalProcessing, pInParams, ppOutHandle);
|
||||
}
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_D3D11_EVALUATE_DLISP_EXT(
|
||||
ID3D11DeviceContext *pInCtx,
|
||||
NVSDK_NGX_Handle *pInHandle,
|
||||
NVSDK_NGX_Parameter *pInParams,
|
||||
NVSDK_NGX_D3D11_DLISP_Eval_Params *pDlispEvalParams)
|
||||
{
|
||||
if (pDlispEvalParams->Feature.InSharpness < 0.0f || pDlispEvalParams->Feature.InSharpness > 1.0f || pDlispEvalParams->InDenoise < 0.0f || pDlispEvalParams->InDenoise > 1.0f)
|
||||
{
|
||||
return NVSDK_NGX_Result_FAIL_InvalidParameter;
|
||||
}
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_Color, pDlispEvalParams->Feature.pInColor);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_Output, pDlispEvalParams->Feature.pInOutput);
|
||||
// Both sharpness and denoise in range [0.0f,1.0f]
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Sharpness, pDlispEvalParams->Feature.InSharpness);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Denoise, pDlispEvalParams->InDenoise);
|
||||
// If input is atlas - use RECT to upscale only the required area
|
||||
if (pDlispEvalParams->InRectW)
|
||||
{
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Rect_X, pDlispEvalParams->InRectX);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Rect_Y, pDlispEvalParams->InRectY);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Rect_W, pDlispEvalParams->InRectW);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Rect_H, pDlispEvalParams->InRectH);
|
||||
}
|
||||
|
||||
return NVSDK_NGX_D3D11_EvaluateFeature_C(pInCtx, pInHandle, pInParams, NULL);
|
||||
}
|
||||
|
||||
|
||||
/*** D3D12 ***/
|
||||
typedef struct NVSDK_NGX_D3D12_Feature_Eval_Params
|
||||
{
|
||||
ID3D12Resource* pInColor;
|
||||
ID3D12Resource* pInOutput;
|
||||
/*** OPTIONAL for DLSS ***/
|
||||
float InSharpness;
|
||||
} NVSDK_NGX_D3D12_Feature_Eval_Params;
|
||||
|
||||
typedef struct NVSDK_NGX_D3D12_GBuffer
|
||||
{
|
||||
ID3D12Resource* pInAttrib[NVSDK_NGX_GBUFFERTYPE_NUM];
|
||||
} NVSDK_NGX_D3D12_GBuffer;
|
||||
|
||||
typedef struct NVSDK_NGX_D3D12_DLSS_Eval_Params
|
||||
{
|
||||
NVSDK_NGX_D3D12_Feature_Eval_Params Feature;
|
||||
ID3D12Resource* pInDepth;
|
||||
ID3D12Resource* pInMotionVectors;
|
||||
float InJitterOffsetX; /* Jitter offset must be in input/render pixel space */
|
||||
float InJitterOffsetY;
|
||||
NVSDK_NGX_Dimensions InRenderSubrectDimensions;
|
||||
/*** OPTIONAL - leave to 0/0.0f if unused ***/
|
||||
int InReset; /* Set to 1 when scene changes completely (new level etc) */
|
||||
float InMVScaleX; /* If MVs need custom scaling to convert to pixel space */
|
||||
float InMVScaleY;
|
||||
ID3D12Resource* pInTransparencyMask; /* Unused/Reserved for future use */
|
||||
ID3D12Resource* pInExposureTexture;
|
||||
ID3D12Resource* pInBiasCurrentColorMask;
|
||||
NVSDK_NGX_Coordinates InColorSubrectBase;
|
||||
NVSDK_NGX_Coordinates InDepthSubrectBase;
|
||||
NVSDK_NGX_Coordinates InMVSubrectBase;
|
||||
NVSDK_NGX_Coordinates InTranslucencySubrectBase;
|
||||
NVSDK_NGX_Coordinates InBiasCurrentColorSubrectBase;
|
||||
NVSDK_NGX_Coordinates InOutputSubrectBase;
|
||||
float InPreExposure;
|
||||
float InExposureScale;
|
||||
int InIndicatorInvertXAxis;
|
||||
int InIndicatorInvertYAxis;
|
||||
/*** OPTIONAL - only for research purposes ***/
|
||||
NVSDK_NGX_D3D12_GBuffer GBufferSurface;
|
||||
NVSDK_NGX_ToneMapperType InToneMapperType;
|
||||
ID3D12Resource* pInMotionVectors3D;
|
||||
ID3D12Resource* pInIsParticleMask; /* to identify which pixels contains particles, essentially that are not drawn as part of base pass */
|
||||
ID3D12Resource* pInAnimatedTextureMask; /* a binary mask covering pixels occupied by animated textures */
|
||||
ID3D12Resource* pInDepthHighRes;
|
||||
ID3D12Resource* pInPositionViewSpace;
|
||||
float InFrameTimeDeltaInMsec; /* helps in determining the amount to denoise or anti-alias based on the speed of the object from motion vector magnitudes and fps as determined by this delta */
|
||||
ID3D12Resource* pInRayTracingHitDistance; /* for each effect - approximation to the amount of noise in a ray-traced color */
|
||||
ID3D12Resource* pInMotionVectorsReflections; /* motion vectors of reflected objects like for mirrored surfaces */
|
||||
} NVSDK_NGX_D3D12_DLSS_Eval_Params;
|
||||
|
||||
typedef struct NVSDK_NGX_D3D12_DLISP_Eval_Params
|
||||
{
|
||||
NVSDK_NGX_D3D12_Feature_Eval_Params Feature;
|
||||
/*** OPTIONAL ***/
|
||||
unsigned int InRectX;
|
||||
unsigned int InRectY;
|
||||
unsigned int InRectW;
|
||||
unsigned int InRectH;
|
||||
float InDenoise;
|
||||
} NVSDK_NGX_D3D12_DLISP_Eval_Params;
|
||||
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_D3D12_CREATE_DLSS_EXT(
|
||||
ID3D12GraphicsCommandList *pInCmdList,
|
||||
unsigned int InCreationNodeMask,
|
||||
unsigned int InVisibilityNodeMask,
|
||||
NVSDK_NGX_Handle **ppOutHandle,
|
||||
NVSDK_NGX_Parameter *pInParams,
|
||||
NVSDK_NGX_DLSS_Create_Params *pInDlssCreateParams)
|
||||
{
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_CreationNodeMask, InCreationNodeMask);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_VisibilityNodeMask, InVisibilityNodeMask);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Width, pInDlssCreateParams->Feature.InWidth);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Height, pInDlssCreateParams->Feature.InHeight);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutWidth, pInDlssCreateParams->Feature.InTargetWidth);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutHeight, pInDlssCreateParams->Feature.InTargetHeight);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_PerfQualityValue, pInDlssCreateParams->Feature.InPerfQualityValue);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Feature_Create_Flags, pInDlssCreateParams->InFeatureCreateFlags);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Enable_Output_Subrects, pInDlssCreateParams->InEnableOutputSubrects ? 1 : 0);
|
||||
|
||||
return NVSDK_NGX_D3D12_CreateFeature(pInCmdList, NVSDK_NGX_Feature_SuperSampling, pInParams, ppOutHandle);
|
||||
}
|
||||
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_D3D12_EVALUATE_DLSS_EXT(
|
||||
ID3D12GraphicsCommandList *pInCmdList,
|
||||
NVSDK_NGX_Handle *pInHandle,
|
||||
NVSDK_NGX_Parameter *pInParams,
|
||||
NVSDK_NGX_D3D12_DLSS_Eval_Params *pInDlssEvalParams)
|
||||
{
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_Color, pInDlssEvalParams->Feature.pInColor);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_Output, pInDlssEvalParams->Feature.pInOutput);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_Depth, pInDlssEvalParams->pInDepth);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_MotionVectors, pInDlssEvalParams->pInMotionVectors);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Jitter_Offset_X, pInDlssEvalParams->InJitterOffsetX);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Jitter_Offset_Y, pInDlssEvalParams->InJitterOffsetY);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Sharpness, pInDlssEvalParams->Feature.InSharpness);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_Reset, pInDlssEvalParams->InReset);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_MV_Scale_X, pInDlssEvalParams->InMVScaleX == 0.0f ? 1.0f : pInDlssEvalParams->InMVScaleX);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_MV_Scale_Y, pInDlssEvalParams->InMVScaleY == 0.0f ? 1.0f : pInDlssEvalParams->InMVScaleY);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_TransparencyMask, pInDlssEvalParams->pInTransparencyMask);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_ExposureTexture, pInDlssEvalParams->pInExposureTexture);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_Mask, pInDlssEvalParams->pInBiasCurrentColorMask);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Albedo, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_ALBEDO]);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Roughness, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_ROUGHNESS]);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Metallic, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_METALLIC]);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Specular, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_SPECULAR]);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Subsurface, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_SUBSURFACE]);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Normals, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_NORMALS]);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_ShadingModelId, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_SHADINGMODELID]);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_MaterialId, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_MATERIALID]);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_8, pInDlssEvalParams->GBufferSurface.pInAttrib[8]);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_9, pInDlssEvalParams->GBufferSurface.pInAttrib[9]);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_10, pInDlssEvalParams->GBufferSurface.pInAttrib[10]);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_11, pInDlssEvalParams->GBufferSurface.pInAttrib[11]);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_12, pInDlssEvalParams->GBufferSurface.pInAttrib[12]);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_13, pInDlssEvalParams->GBufferSurface.pInAttrib[13]);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_14, pInDlssEvalParams->GBufferSurface.pInAttrib[14]);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_15, pInDlssEvalParams->GBufferSurface.pInAttrib[15]);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_TonemapperType, pInDlssEvalParams->InToneMapperType);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_MotionVectors3D, pInDlssEvalParams->pInMotionVectors3D);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_IsParticleMask, pInDlssEvalParams->pInIsParticleMask);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_AnimatedTextureMask, pInDlssEvalParams->pInAnimatedTextureMask);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_DepthHighRes, pInDlssEvalParams->pInDepthHighRes);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_Position_ViewSpace, pInDlssEvalParams->pInPositionViewSpace);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_FrameTimeDeltaInMsec, pInDlssEvalParams->InFrameTimeDeltaInMsec);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_RayTracingHitDistance, pInDlssEvalParams->pInRayTracingHitDistance);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_MotionVectorsReflection, pInDlssEvalParams->pInMotionVectorsReflections);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Color_Subrect_Base_X, pInDlssEvalParams->InColorSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Color_Subrect_Base_Y, pInDlssEvalParams->InColorSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Depth_Subrect_Base_X, pInDlssEvalParams->InDepthSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Depth_Subrect_Base_Y, pInDlssEvalParams->InDepthSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_MV_SubrectBase_X, pInDlssEvalParams->InMVSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_MV_SubrectBase_Y, pInDlssEvalParams->InMVSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Translucency_SubrectBase_X, pInDlssEvalParams->InTranslucencySubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Translucency_SubrectBase_Y, pInDlssEvalParams->InTranslucencySubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_SubrectBase_X, pInDlssEvalParams->InBiasCurrentColorSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_SubrectBase_Y, pInDlssEvalParams->InBiasCurrentColorSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Output_Subrect_Base_X, pInDlssEvalParams->InOutputSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Output_Subrect_Base_Y, pInDlssEvalParams->InOutputSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Render_Subrect_Dimensions_Width , pInDlssEvalParams->InRenderSubrectDimensions.Width);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Render_Subrect_Dimensions_Height, pInDlssEvalParams->InRenderSubrectDimensions.Height);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_DLSS_Pre_Exposure, pInDlssEvalParams->InPreExposure == 0.0f ? 1.0f : pInDlssEvalParams->InPreExposure);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_DLSS_Exposure_Scale, pInDlssEvalParams->InExposureScale == 0.0f ? 1.0f : pInDlssEvalParams->InExposureScale);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Indicator_Invert_X_Axis, pInDlssEvalParams->InIndicatorInvertXAxis);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Indicator_Invert_Y_Axis, pInDlssEvalParams->InIndicatorInvertYAxis);
|
||||
|
||||
return NVSDK_NGX_D3D12_EvaluateFeature_C(pInCmdList, pInHandle, pInParams, NULL);
|
||||
}
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_D3D12_CREATE_DLISP_EXT(
|
||||
ID3D12GraphicsCommandList *InCmdList,
|
||||
unsigned int InCreationNodeMask,
|
||||
unsigned int InVisibilityNodeMask,
|
||||
NVSDK_NGX_Handle **ppOutHandle,
|
||||
NVSDK_NGX_Parameter *pInParams,
|
||||
NVSDK_NGX_Feature_Create_Params *pDlispCreateParams)
|
||||
{
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_CreationNodeMask, InCreationNodeMask);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_VisibilityNodeMask, InVisibilityNodeMask);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Width, pDlispCreateParams->InWidth);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Height, pDlispCreateParams->InHeight);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutWidth, pDlispCreateParams->InTargetWidth);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutHeight, pDlispCreateParams->InTargetHeight);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_PerfQualityValue, pDlispCreateParams->InPerfQualityValue);
|
||||
|
||||
return NVSDK_NGX_D3D12_CreateFeature(InCmdList, NVSDK_NGX_Feature_ImageSignalProcessing, pInParams, ppOutHandle);
|
||||
}
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_D3D12_EVALUATE_DLISP_EXT(
|
||||
ID3D12GraphicsCommandList *pInCmdList,
|
||||
NVSDK_NGX_Handle *pInHandle,
|
||||
NVSDK_NGX_Parameter *pInParams,
|
||||
NVSDK_NGX_D3D12_DLISP_Eval_Params *pDlispEvalParams)
|
||||
{
|
||||
if (pDlispEvalParams->Feature.InSharpness < 0.0f || pDlispEvalParams->Feature.InSharpness > 1.0f || pDlispEvalParams->InDenoise < 0.0f || pDlispEvalParams->InDenoise > 1.0f)
|
||||
{
|
||||
return NVSDK_NGX_Result_FAIL_InvalidParameter;
|
||||
}
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_Color, pDlispEvalParams->Feature.pInColor);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_Output, pDlispEvalParams->Feature.pInOutput);
|
||||
// Both sharpness and denoise in range [0.0f,1.0f]
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Sharpness, pDlispEvalParams->Feature.InSharpness);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Denoise, pDlispEvalParams->InDenoise);
|
||||
// If input is atlas - use RECT to upscale only the required area
|
||||
if (pDlispEvalParams->InRectW)
|
||||
{
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Rect_X, pDlispEvalParams->InRectX);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Rect_Y, pDlispEvalParams->InRectY);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Rect_W, pDlispEvalParams->InRectW);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Rect_H, pDlispEvalParams->InRectH);
|
||||
}
|
||||
return NVSDK_NGX_D3D12_EvaluateFeature_C(pInCmdList, pInHandle, pInParams, NULL);
|
||||
}
|
||||
#endif // NVSDK_NGX_HELPERS_D3D_H
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: LicenseRef-NvidiaProprietary
|
||||
*
|
||||
* NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
|
||||
* property and proprietary rights in and to this material, related
|
||||
* documentation and any modifications thereto. Any use, reproduction,
|
||||
* disclosure or distribution of this material and related documentation
|
||||
* without an express license agreement from NVIDIA CORPORATION or
|
||||
* its affiliates is strictly prohibited.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#pragma message("nvsdk_ngx_helpers_dlssd.h is deprecated; #include \"nvsdk_ngx_helpers_dlssd_d3d.h\" instead")
|
||||
|
||||
#include "nvsdk_ngx_helpers_dlssd_d3d.h"
|
||||
+364
@@ -0,0 +1,364 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: LicenseRef-NvidiaProprietary
|
||||
*
|
||||
* NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
|
||||
* property and proprietary rights in and to this material, related
|
||||
* documentation and any modifications thereto. Any use, reproduction,
|
||||
* disclosure or distribution of this material and related documentation
|
||||
* without an express license agreement from NVIDIA CORPORATION or
|
||||
* its affiliates is strictly prohibited.
|
||||
*/
|
||||
|
||||
#ifndef NVSDK_NGX_HELPERS_DLSSD_CUDA_H
|
||||
#define NVSDK_NGX_HELPERS_DLSSD_CUDA_H
|
||||
#pragma once
|
||||
|
||||
#include "nvsdk_ngx_helpers.h"
|
||||
#include "nvsdk_ngx_defs_dlssd.h"
|
||||
#include "nvsdk_ngx_params_dlssd.h"
|
||||
#if 1
|
||||
static inline NVSDK_NGX_Result NGX_DLSSD_GET_STATS_2(
|
||||
NVSDK_NGX_Parameter* pInParams,
|
||||
unsigned long long* pVRAMAllocatedBytes,
|
||||
unsigned int* pOptLevel, unsigned int* IsDevSnippetBranch)
|
||||
{
|
||||
void* Callback = NULL;
|
||||
NVSDK_NGX_Parameter_GetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSDGetStatsCallback, &Callback);
|
||||
if (!Callback)
|
||||
{
|
||||
// Possible reasons for this:
|
||||
// - Installed DLSS is out of date and does not support the feature we need
|
||||
// - You used NVSDK_NGX_AllocateParameters() for creating InParams. Try using NVSDK_NGX_GetCapabilityParameters() instead
|
||||
return NVSDK_NGX_Result_FAIL_OutOfDate;
|
||||
}
|
||||
|
||||
NVSDK_NGX_Result Res = NVSDK_NGX_Result_Success;
|
||||
PFN_NVSDK_NGX_DLSS_GetStatsCallback PFNCallback = (PFN_NVSDK_NGX_DLSS_GetStatsCallback)Callback;
|
||||
Res = PFNCallback(pInParams);
|
||||
if (NVSDK_NGX_FAILED(Res))
|
||||
{
|
||||
return Res;
|
||||
}
|
||||
NVSDK_NGX_Parameter_GetULL(pInParams, NVSDK_NGX_Parameter_SizeInBytes, pVRAMAllocatedBytes);
|
||||
NVSDK_NGX_Parameter_GetUI(pInParams, NVSDK_NGX_EParameter_OptLevel, pOptLevel);
|
||||
NVSDK_NGX_Parameter_GetUI(pInParams, NVSDK_NGX_EParameter_IsDevSnippetBranch, IsDevSnippetBranch);
|
||||
return Res;
|
||||
}
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_DLSSD_GET_STATS_1(
|
||||
NVSDK_NGX_Parameter* pInParams,
|
||||
unsigned long long* pVRAMAllocatedBytes,
|
||||
unsigned int* pOptLevel)
|
||||
{
|
||||
unsigned int dummy = 0;
|
||||
return NGX_DLSSD_GET_STATS_2(pInParams, pVRAMAllocatedBytes, pOptLevel, &dummy);
|
||||
}
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_DLSSD_GET_STATS(
|
||||
NVSDK_NGX_Parameter* pInParams,
|
||||
unsigned long long* pVRAMAllocatedBytes)
|
||||
{
|
||||
unsigned int dummy = 0;
|
||||
return NGX_DLSSD_GET_STATS_2(pInParams, pVRAMAllocatedBytes, &dummy, &dummy);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_DLSSD_GET_OPTIMAL_SETTINGS(
|
||||
NVSDK_NGX_Parameter* pInParams,
|
||||
unsigned int InUserSelectedWidth,
|
||||
unsigned int InUserSelectedHeight,
|
||||
NVSDK_NGX_PerfQuality_Value InPerfQualityValue,
|
||||
unsigned int* pOutRenderOptimalWidth,
|
||||
unsigned int* pOutRenderOptimalHeight,
|
||||
unsigned int* pOutRenderMaxWidth,
|
||||
unsigned int* pOutRenderMaxHeight,
|
||||
unsigned int* pOutRenderMinWidth,
|
||||
unsigned int* pOutRenderMinHeight,
|
||||
float* pOutSharpness)
|
||||
{
|
||||
void* Callback = NULL;
|
||||
NVSDK_NGX_Parameter_GetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSDOptimalSettingsCallback, &Callback);
|
||||
if (!Callback)
|
||||
{
|
||||
// Possible reasons for this:
|
||||
// - Installed DLSS is out of date and does not support the feature we need
|
||||
// - You used NVSDK_NGX_AllocateParameters() for creating InParams. Try using NVSDK_NGX_GetCapabilityParameters() instead
|
||||
return NVSDK_NGX_Result_FAIL_OutOfDate;
|
||||
}
|
||||
|
||||
// These are selections made by user in UI
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Width, InUserSelectedWidth);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Height, InUserSelectedHeight);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_PerfQualityValue, InPerfQualityValue);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_RTXValue, false); // Some older DLSS dlls still expect this value to be set
|
||||
|
||||
NVSDK_NGX_Result Res = NVSDK_NGX_Result_Success;
|
||||
PFN_NVSDK_NGX_DLSS_GetOptimalSettingsCallback PFNCallback = (PFN_NVSDK_NGX_DLSS_GetOptimalSettingsCallback)Callback;
|
||||
Res = PFNCallback(pInParams);
|
||||
if (NVSDK_NGX_FAILED(Res))
|
||||
{
|
||||
return Res;
|
||||
}
|
||||
NVSDK_NGX_Parameter_GetUI(pInParams, NVSDK_NGX_Parameter_OutWidth, pOutRenderOptimalWidth);
|
||||
NVSDK_NGX_Parameter_GetUI(pInParams, NVSDK_NGX_Parameter_OutHeight, pOutRenderOptimalHeight);
|
||||
// If we have an older DLSS Dll those might need to be set to the optimal dimensions instead
|
||||
*pOutRenderMaxWidth = *pOutRenderOptimalWidth;
|
||||
*pOutRenderMaxHeight = *pOutRenderOptimalHeight;
|
||||
*pOutRenderMinWidth = *pOutRenderOptimalWidth;
|
||||
*pOutRenderMinHeight = *pOutRenderOptimalHeight;
|
||||
NVSDK_NGX_Parameter_GetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Get_Dynamic_Max_Render_Width, pOutRenderMaxWidth);
|
||||
NVSDK_NGX_Parameter_GetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Get_Dynamic_Max_Render_Height, pOutRenderMaxHeight);
|
||||
NVSDK_NGX_Parameter_GetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Get_Dynamic_Min_Render_Width, pOutRenderMinWidth);
|
||||
NVSDK_NGX_Parameter_GetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Get_Dynamic_Min_Render_Height, pOutRenderMinHeight);
|
||||
NVSDK_NGX_Parameter_GetF(pInParams, NVSDK_NGX_Parameter_Sharpness, pOutSharpness);
|
||||
return Res;
|
||||
}
|
||||
|
||||
typedef struct NVSDK_NGX_CUDA_GBuffer
|
||||
{
|
||||
CUtexObject* pInAttrib[NVSDK_NGX_GBUFFERTYPE_NUM];
|
||||
} NVSDK_NGX_CUDA_GBuffer;
|
||||
|
||||
typedef struct NVSDK_NGX_CUDA_DLSSD_Create_Params
|
||||
{
|
||||
NVSDK_NGX_DLSSD_Create_Params Feature;
|
||||
void* InCUContext;
|
||||
void* InCUStream;
|
||||
} NVSDK_NGX_CUDA_DLSSD_Create_Params;
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_CUDA_CREATE_DLSSD_EXT(
|
||||
NVSDK_NGX_Handle** ppOutHandle,
|
||||
NVSDK_NGX_Parameter* pInParams,
|
||||
NVSDK_NGX_CUDA_DLSSD_Create_Params* pInDlssDCreateParams)
|
||||
{
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_Input1, pInDlssDCreateParams->InCUContext);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_Input2, pInDlssDCreateParams->InCUStream);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Width, pInDlssDCreateParams->Feature.InWidth);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Height, pInDlssDCreateParams->Feature.InHeight);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutWidth, pInDlssDCreateParams->Feature.InTargetWidth);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutHeight, pInDlssDCreateParams->Feature.InTargetHeight);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_PerfQualityValue, pInDlssDCreateParams->Feature.InPerfQualityValue);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Feature_Create_Flags, pInDlssDCreateParams->Feature.InFeatureCreateFlags);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Enable_Output_Subrects, pInDlssDCreateParams->Feature.InEnableOutputSubrects ? 1 : 0);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Denoise_Mode, NVSDK_NGX_DLSS_Denoise_Mode_DLUnified);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Roughness_Mode, pInDlssDCreateParams->Feature.InRoughnessMode);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Use_HW_Depth, pInDlssDCreateParams->Feature.InUseHWDepth);
|
||||
return NVSDK_NGX_CUDA_CreateFeature(NVSDK_NGX_Feature_RayReconstruction, pInParams, ppOutHandle);
|
||||
}
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_CUDA_CREATE_DLSSD_EXT1(
|
||||
NVSDK_NGX_CUDADevice *InDevice,
|
||||
NVSDK_NGX_Handle** ppOutHandle,
|
||||
NVSDK_NGX_Parameter* pInParams,
|
||||
NVSDK_NGX_CUDA_DLSSD_Create_Params* pInDlssDCreateParams)
|
||||
{
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_Input1, pInDlssDCreateParams->InCUContext);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_Input2, pInDlssDCreateParams->InCUStream);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Width, pInDlssDCreateParams->Feature.InWidth);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Height, pInDlssDCreateParams->Feature.InHeight);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutWidth, pInDlssDCreateParams->Feature.InTargetWidth);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutHeight, pInDlssDCreateParams->Feature.InTargetHeight);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_PerfQualityValue, pInDlssDCreateParams->Feature.InPerfQualityValue);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Feature_Create_Flags, pInDlssDCreateParams->Feature.InFeatureCreateFlags);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Enable_Output_Subrects, pInDlssDCreateParams->Feature.InEnableOutputSubrects ? 1 : 0);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Denoise_Mode, NVSDK_NGX_DLSS_Denoise_Mode_DLUnified);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Roughness_Mode, pInDlssDCreateParams->Feature.InRoughnessMode);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Use_HW_Depth, pInDlssDCreateParams->Feature.InUseHWDepth);
|
||||
return NVSDK_NGX_CUDA_CreateFeature1(InDevice, NVSDK_NGX_Feature_RayReconstruction, pInParams, ppOutHandle);
|
||||
}
|
||||
|
||||
typedef struct NVSDK_NGX_CUDA_DLSSD_Eval_Params
|
||||
{
|
||||
void* pInDiffuseAlbedo;
|
||||
void* pInSpecularAlbedo;
|
||||
void* pInNormals;
|
||||
void* pInRoughness;
|
||||
|
||||
void* pInColor;
|
||||
void* pInOutput;
|
||||
void* pInDepth;
|
||||
void* pInMotionVectors;
|
||||
float InJitterOffsetX; /* Jitter offset must be in input/render pixel space */
|
||||
float InJitterOffsetY;
|
||||
NVSDK_NGX_Dimensions InRenderSubrectDimensions;
|
||||
/*** OPTIONAL - leave to 0/0.0f if unused ***/
|
||||
int InReset; /* Set to 1 when scene changes completely (new level etc) */
|
||||
float InMVScaleX; /* If MVs need custom scaling to convert to pixel space */
|
||||
float InMVScaleY;
|
||||
void* pInTransparencyMask; /* Unused/Reserved for future use */
|
||||
void* pInExposureTexture;
|
||||
void* pInBiasCurrentColorMask;
|
||||
NVSDK_NGX_Coordinates InDiffuseAlbedoSubrectBase;
|
||||
NVSDK_NGX_Coordinates InSpecularAlbedoSubrectBase;
|
||||
NVSDK_NGX_Coordinates InNormalsSubrectBase;
|
||||
NVSDK_NGX_Coordinates InRoughnessSubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorSubrectBase;
|
||||
NVSDK_NGX_Coordinates InDepthSubrectBase;
|
||||
NVSDK_NGX_Coordinates InMVSubrectBase;
|
||||
NVSDK_NGX_Coordinates InTranslucencySubrectBase;
|
||||
NVSDK_NGX_Coordinates InBiasCurrentColorSubrectBase;
|
||||
NVSDK_NGX_Coordinates InOutputSubrectBase;
|
||||
|
||||
void* pInReflectedAlbedo;
|
||||
void* pInColorBeforeParticles;
|
||||
void* pInColorBeforeTransparency;
|
||||
void* pInColorBeforeFog;
|
||||
void* pInDiffuseHitDistance;
|
||||
void* pInSpecularHitDistance;
|
||||
void* pInDiffuseRayDirection;
|
||||
void* pInSpecularRayDirection;
|
||||
void* pInDiffuseRayDirectionHitDistance;
|
||||
void* pInSpecularRayDirectionHitDistance;
|
||||
NVSDK_NGX_Coordinates InReflectedAlbedoSubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorBeforeParticlesSubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorBeforeTransparencySubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorBeforeFogSubrectBase;
|
||||
NVSDK_NGX_Coordinates InDiffuseHitDistanceSubrectBase;
|
||||
NVSDK_NGX_Coordinates InSpecularHitDistanceSubrectBase;
|
||||
NVSDK_NGX_Coordinates InDiffuseRayDirectionSubrectBase;
|
||||
NVSDK_NGX_Coordinates InSpecularRayDirectionSubrectBase;
|
||||
NVSDK_NGX_Coordinates InDiffuseRayDirectionHitDistanceSubrectBase;
|
||||
NVSDK_NGX_Coordinates InSpecularRayDirectionHitDistanceSubrectBase;
|
||||
float* pInWorldToViewMatrix;
|
||||
float* pInViewToClipMatrix;
|
||||
|
||||
float InPreExposure;
|
||||
float InExposureScale;
|
||||
int InIndicatorInvertXAxis;
|
||||
int InIndicatorInvertYAxis;
|
||||
/*** OPTIONAL - only for research purposes ***/
|
||||
NVSDK_NGX_CUDA_GBuffer GBufferSurface;
|
||||
NVSDK_NGX_ToneMapperType InToneMapperType;
|
||||
void* pInMotionVectors3D;
|
||||
void* pInIsParticleMask; /* to identify which pixels contains particles, essentially that are not drawn as part of base pass */
|
||||
void* pInAnimatedTextureMask; /* a binary mask covering pixels occupied by animated textures */
|
||||
void* pInDepthHighRes;
|
||||
void* pInPositionViewSpace;
|
||||
float InFrameTimeDeltaInMsec; /* helps in determining the amount to denoise or anti-alias based on the speed of the object from motion vector magnitudes and fps as determined by this delta */
|
||||
void* pInRayTracingHitDistance; /* for each effect - approximation to the amount of noise in a ray-traced color */
|
||||
void* pInMotionVectorsReflections; /* motion vectors of reflected objects like for mirrored surfaces */
|
||||
void* pInTransparencyLayer; /* optional input res particle layer */
|
||||
NVSDK_NGX_Coordinates InTransparencyLayerSubrectBase;
|
||||
void* pInTransparencyLayerOpacity; /* optional input res particle opacity layer */
|
||||
NVSDK_NGX_Coordinates InTransparencyLayerOpacitySubrectBase;
|
||||
} NVSDK_NGX_CUDA_DLSSD_Eval_Params;
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_CUDA_EVALUATE_DLSSD_EXT(
|
||||
NVSDK_NGX_Handle* pInHandle,
|
||||
NVSDK_NGX_Parameter* pInParams,
|
||||
NVSDK_NGX_CUDA_DLSSD_Eval_Params* pInDlssDEvalParams)
|
||||
{
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_Color, pInDlssDEvalParams->pInColor);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_Output, pInDlssDEvalParams->pInOutput);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_Depth, pInDlssDEvalParams->pInDepth);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_MotionVectors, pInDlssDEvalParams->pInMotionVectors);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Jitter_Offset_X, pInDlssDEvalParams->InJitterOffsetX);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Jitter_Offset_Y, pInDlssDEvalParams->InJitterOffsetY);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_Reset, pInDlssDEvalParams->InReset);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_MV_Scale_X, pInDlssDEvalParams->InMVScaleX == 0.0f ? 1.0f : pInDlssDEvalParams->InMVScaleX);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_MV_Scale_Y, pInDlssDEvalParams->InMVScaleY == 0.0f ? 1.0f : pInDlssDEvalParams->InMVScaleY);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_TransparencyMask, pInDlssDEvalParams->pInTransparencyMask);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_ExposureTexture, pInDlssDEvalParams->pInExposureTexture);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_Mask, pInDlssDEvalParams->pInBiasCurrentColorMask);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Albedo, pInDlssDEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_ALBEDO]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Roughness, pInDlssDEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_ROUGHNESS]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Metallic, pInDlssDEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_METALLIC]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Specular, pInDlssDEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_SPECULAR]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Subsurface, pInDlssDEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_SUBSURFACE]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Normals, pInDlssDEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_NORMALS]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_ShadingModelId, pInDlssDEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_SHADINGMODELID]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_MaterialId, pInDlssDEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_MATERIALID]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_8, pInDlssDEvalParams->GBufferSurface.pInAttrib[8]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_9, pInDlssDEvalParams->GBufferSurface.pInAttrib[9]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_11, pInDlssDEvalParams->GBufferSurface.pInAttrib[11]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_12, pInDlssDEvalParams->GBufferSurface.pInAttrib[12]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_13, pInDlssDEvalParams->GBufferSurface.pInAttrib[13]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_14, pInDlssDEvalParams->GBufferSurface.pInAttrib[14]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_15, pInDlssDEvalParams->GBufferSurface.pInAttrib[15]);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_TonemapperType, pInDlssDEvalParams->InToneMapperType);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_MotionVectors3D, pInDlssDEvalParams->pInMotionVectors3D);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_IsParticleMask, pInDlssDEvalParams->pInIsParticleMask);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_AnimatedTextureMask, pInDlssDEvalParams->pInAnimatedTextureMask);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DepthHighRes, pInDlssDEvalParams->pInDepthHighRes);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_Position_ViewSpace, pInDlssDEvalParams->pInPositionViewSpace);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_FrameTimeDeltaInMsec, pInDlssDEvalParams->InFrameTimeDeltaInMsec);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_RayTracingHitDistance, pInDlssDEvalParams->pInRayTracingHitDistance);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_SpecularMvec, pInDlssDEvalParams->pInMotionVectorsReflections);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Color_Subrect_Base_X, pInDlssDEvalParams->InColorSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Color_Subrect_Base_Y, pInDlssDEvalParams->InColorSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Depth_Subrect_Base_X, pInDlssDEvalParams->InDepthSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Depth_Subrect_Base_Y, pInDlssDEvalParams->InDepthSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_MV_SubrectBase_X, pInDlssDEvalParams->InMVSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_MV_SubrectBase_Y, pInDlssDEvalParams->InMVSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Translucency_SubrectBase_X, pInDlssDEvalParams->InTranslucencySubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Translucency_SubrectBase_Y, pInDlssDEvalParams->InTranslucencySubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_SubrectBase_X, pInDlssDEvalParams->InBiasCurrentColorSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_SubrectBase_Y, pInDlssDEvalParams->InBiasCurrentColorSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Output_Subrect_Base_X, pInDlssDEvalParams->InOutputSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Output_Subrect_Base_Y, pInDlssDEvalParams->InOutputSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Render_Subrect_Dimensions_Width, pInDlssDEvalParams->InRenderSubrectDimensions.Width);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Render_Subrect_Dimensions_Height, pInDlssDEvalParams->InRenderSubrectDimensions.Height);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_DLSS_Pre_Exposure, pInDlssDEvalParams->InPreExposure == 0.0f ? 1.0f : pInDlssDEvalParams->InPreExposure);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_DLSS_Exposure_Scale, pInDlssDEvalParams->InExposureScale == 0.0f ? 1.0f : pInDlssDEvalParams->InExposureScale);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Indicator_Invert_X_Axis, pInDlssDEvalParams->InIndicatorInvertXAxis);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Indicator_Invert_Y_Axis, pInDlssDEvalParams->InIndicatorInvertYAxis);
|
||||
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Emissive, pInDlssDEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_EMISSIVE]);
|
||||
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DiffuseAlbedo, pInDlssDEvalParams->pInDiffuseAlbedo);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_SpecularAlbedo, pInDlssDEvalParams->pInSpecularAlbedo);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_DiffuseAlbedo_Subrect_Base_X, pInDlssDEvalParams->InDiffuseAlbedoSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_DiffuseAlbedo_Subrect_Base_Y, pInDlssDEvalParams->InDiffuseAlbedoSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_SpecularAlbedo_Subrect_Base_X, pInDlssDEvalParams->InSpecularAlbedoSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_SpecularAlbedo_Subrect_Base_Y, pInDlssDEvalParams->InSpecularAlbedoSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Normals_Subrect_Base_X, pInDlssDEvalParams->InNormalsSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Normals_Subrect_Base_Y, pInDlssDEvalParams->InNormalsSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Roughness_Subrect_Base_X, pInDlssDEvalParams->InRoughnessSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Roughness_Subrect_Base_Y, pInDlssDEvalParams->InRoughnessSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Normals, pInDlssDEvalParams->pInNormals);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Roughness, pInDlssDEvalParams->pInRoughness);
|
||||
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSD_ReflectedAlbedo, pInDlssDEvalParams->pInReflectedAlbedo);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeParticles, pInDlssDEvalParams->pInColorBeforeParticles);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeTransparency, pInDlssDEvalParams->pInColorBeforeTransparency);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeFog, pInDlssDEvalParams->pInColorBeforeFog);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSD_DiffuseHitDistance, pInDlssDEvalParams->pInDiffuseHitDistance);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSD_SpecularHitDistance, pInDlssDEvalParams->pInSpecularHitDistance);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSD_DiffuseRayDirection, pInDlssDEvalParams->pInDiffuseRayDirection);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSD_SpecularRayDirection, pInDlssDEvalParams->pInSpecularRayDirection);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSD_DiffuseRayDirectionHitDistance, pInDlssDEvalParams->pInDiffuseRayDirectionHitDistance);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSD_SpecularRayDirectionHitDistance, pInDlssDEvalParams->pInSpecularRayDirectionHitDistance);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ReflectedAlbedo_Subrect_Base_X, pInDlssDEvalParams->InReflectedAlbedoSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ReflectedAlbedo_Subrect_Base_Y, pInDlssDEvalParams->InReflectedAlbedoSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeParticles_Subrect_Base_X, pInDlssDEvalParams->InColorBeforeParticlesSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeParticles_Subrect_Base_Y, pInDlssDEvalParams->InColorBeforeParticlesSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeTransparency_Subrect_Base_X, pInDlssDEvalParams->InColorBeforeTransparencySubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeTransparency_Subrect_Base_Y, pInDlssDEvalParams->InColorBeforeTransparencySubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeFog_Subrect_Base_X, pInDlssDEvalParams->InColorBeforeFogSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeFog_Subrect_Base_Y, pInDlssDEvalParams->InColorBeforeFogSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_DiffuseHitDistance_Subrect_Base_X, pInDlssDEvalParams->InDiffuseHitDistanceSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_DiffuseHitDistance_Subrect_Base_Y, pInDlssDEvalParams->InDiffuseHitDistanceSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_SpecularHitDistance_Subrect_Base_X, pInDlssDEvalParams->InSpecularHitDistanceSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_SpecularHitDistance_Subrect_Base_Y, pInDlssDEvalParams->InSpecularHitDistanceSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_DiffuseRayDirection_Subrect_Base_X, pInDlssDEvalParams->InDiffuseRayDirectionSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_DiffuseRayDirection_Subrect_Base_Y, pInDlssDEvalParams->InDiffuseRayDirectionSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_SpecularRayDirection_Subrect_Base_X, pInDlssDEvalParams->InSpecularRayDirectionSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_SpecularRayDirection_Subrect_Base_Y, pInDlssDEvalParams->InSpecularRayDirectionSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_DiffuseRayDirectionHitDistance_Subrect_Base_X, pInDlssDEvalParams->InDiffuseRayDirectionHitDistanceSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_DiffuseRayDirectionHitDistance_Subrect_Base_Y, pInDlssDEvalParams->InDiffuseRayDirectionHitDistanceSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_SpecularRayDirectionHitDistance_Subrect_Base_X, pInDlssDEvalParams->InSpecularRayDirectionHitDistanceSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_SpecularRayDirectionHitDistance_Subrect_Base_Y, pInDlssDEvalParams->InSpecularRayDirectionHitDistanceSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSS_WORLD_TO_VIEW_MATRIX, pInDlssDEvalParams->pInWorldToViewMatrix);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSS_VIEW_TO_CLIP_MATRIX, pInDlssDEvalParams->pInViewToClipMatrix);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSS_TransparencyLayer, pInDlssDEvalParams->pInTransparencyLayer);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSS_TransparencyLayerOpacity, pInDlssDEvalParams->pInTransparencyLayerOpacity);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_TransparencyLayer_Subrect_Base_X, pInDlssDEvalParams->InTransparencyLayerSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_TransparencyLayer_Subrect_Base_Y, pInDlssDEvalParams->InTransparencyLayerSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_TransparencyLayerOpacity_Subrect_Base_X, pInDlssDEvalParams->InTransparencyLayerOpacitySubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_TransparencyLayerOpacity_Subrect_Base_Y, pInDlssDEvalParams->InTransparencyLayerOpacitySubrectBase.Y);
|
||||
|
||||
return NVSDK_NGX_CUDA_EvaluateFeature_C(pInHandle, pInParams, NULL);
|
||||
}
|
||||
|
||||
#endif // NVSDK_NGX_HELPERS_DLSSD_CUDA_H
|
||||
@@ -0,0 +1,721 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: LicenseRef-NvidiaProprietary
|
||||
*
|
||||
* NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
|
||||
* property and proprietary rights in and to this material, related
|
||||
* documentation and any modifications thereto. Any use, reproduction,
|
||||
* disclosure or distribution of this material and related documentation
|
||||
* without an express license agreement from NVIDIA CORPORATION or
|
||||
* its affiliates is strictly prohibited.
|
||||
*/
|
||||
|
||||
#ifndef NVSDK_NGX_HELPERS_DLSSD_H
|
||||
#define NVSDK_NGX_HELPERS_DLSSD_H
|
||||
#pragma once
|
||||
|
||||
#include "nvsdk_ngx_helpers.h"
|
||||
#include "nvsdk_ngx_defs_dlssd.h"
|
||||
#include "nvsdk_ngx_params_dlssd.h"
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_DLSSD_GET_STATS_2(
|
||||
NVSDK_NGX_Parameter* pInParams,
|
||||
unsigned long long* pVRAMAllocatedBytes,
|
||||
unsigned int* pOptLevel, unsigned int* IsDevSnippetBranch)
|
||||
{
|
||||
void* Callback = NULL;
|
||||
NVSDK_NGX_Parameter_GetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSDGetStatsCallback, &Callback);
|
||||
if (!Callback)
|
||||
{
|
||||
// Possible reasons for this:
|
||||
// - Installed DLSS is out of date and does not support the feature we need
|
||||
// - You used NVSDK_NGX_AllocateParameters() for creating InParams. Try using NVSDK_NGX_GetCapabilityParameters() instead
|
||||
return NVSDK_NGX_Result_FAIL_OutOfDate;
|
||||
}
|
||||
|
||||
NVSDK_NGX_Result Res = NVSDK_NGX_Result_Success;
|
||||
PFN_NVSDK_NGX_DLSS_GetStatsCallback PFNCallback = (PFN_NVSDK_NGX_DLSS_GetStatsCallback)Callback;
|
||||
Res = PFNCallback(pInParams);
|
||||
if (NVSDK_NGX_FAILED(Res))
|
||||
{
|
||||
return Res;
|
||||
}
|
||||
NVSDK_NGX_Parameter_GetULL(pInParams, NVSDK_NGX_Parameter_SizeInBytes, pVRAMAllocatedBytes);
|
||||
NVSDK_NGX_Parameter_GetUI(pInParams, NVSDK_NGX_EParameter_OptLevel, pOptLevel);
|
||||
NVSDK_NGX_Parameter_GetUI(pInParams, NVSDK_NGX_EParameter_IsDevSnippetBranch, IsDevSnippetBranch);
|
||||
return Res;
|
||||
}
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_DLSSD_GET_STATS_1(
|
||||
NVSDK_NGX_Parameter* pInParams,
|
||||
unsigned long long* pVRAMAllocatedBytes,
|
||||
unsigned int* pOptLevel)
|
||||
{
|
||||
unsigned int dummy = 0;
|
||||
return NGX_DLSSD_GET_STATS_2(pInParams, pVRAMAllocatedBytes, pOptLevel, &dummy);
|
||||
}
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_DLSSD_GET_STATS(
|
||||
NVSDK_NGX_Parameter* pInParams,
|
||||
unsigned long long* pVRAMAllocatedBytes)
|
||||
{
|
||||
unsigned int dummy = 0;
|
||||
return NGX_DLSSD_GET_STATS_2(pInParams, pVRAMAllocatedBytes, &dummy, &dummy);
|
||||
}
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_DLSSD_GET_OPTIMAL_SETTINGS(
|
||||
NVSDK_NGX_Parameter* pInParams,
|
||||
unsigned int InUserSelectedWidth,
|
||||
unsigned int InUserSelectedHeight,
|
||||
NVSDK_NGX_PerfQuality_Value InPerfQualityValue,
|
||||
unsigned int* pOutRenderOptimalWidth,
|
||||
unsigned int* pOutRenderOptimalHeight,
|
||||
unsigned int* pOutRenderMaxWidth,
|
||||
unsigned int* pOutRenderMaxHeight,
|
||||
unsigned int* pOutRenderMinWidth,
|
||||
unsigned int* pOutRenderMinHeight,
|
||||
float* pOutSharpness)
|
||||
{
|
||||
void* Callback = NULL;
|
||||
NVSDK_NGX_Parameter_GetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSDOptimalSettingsCallback, &Callback);
|
||||
if (!Callback)
|
||||
{
|
||||
// Possible reasons for this:
|
||||
// - Installed DLSS is out of date and does not support the feature we need
|
||||
// - You used NVSDK_NGX_AllocateParameters() for creating InParams. Try using NVSDK_NGX_GetCapabilityParameters() instead
|
||||
return NVSDK_NGX_Result_FAIL_OutOfDate;
|
||||
}
|
||||
|
||||
// These are selections made by user in UI
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Width, InUserSelectedWidth);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Height, InUserSelectedHeight);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_PerfQualityValue, InPerfQualityValue);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_RTXValue, false); // Some older DLSS dlls still expect this value to be set
|
||||
|
||||
NVSDK_NGX_Result Res = NVSDK_NGX_Result_Success;
|
||||
PFN_NVSDK_NGX_DLSS_GetOptimalSettingsCallback PFNCallback = (PFN_NVSDK_NGX_DLSS_GetOptimalSettingsCallback)Callback;
|
||||
Res = PFNCallback(pInParams);
|
||||
if (NVSDK_NGX_FAILED(Res))
|
||||
{
|
||||
return Res;
|
||||
}
|
||||
NVSDK_NGX_Parameter_GetUI(pInParams, NVSDK_NGX_Parameter_OutWidth, pOutRenderOptimalWidth);
|
||||
NVSDK_NGX_Parameter_GetUI(pInParams, NVSDK_NGX_Parameter_OutHeight, pOutRenderOptimalHeight);
|
||||
// If we have an older DLSS Dll those might need to be set to the optimal dimensions instead
|
||||
*pOutRenderMaxWidth = *pOutRenderOptimalWidth;
|
||||
*pOutRenderMaxHeight = *pOutRenderOptimalHeight;
|
||||
*pOutRenderMinWidth = *pOutRenderOptimalWidth;
|
||||
*pOutRenderMinHeight = *pOutRenderOptimalHeight;
|
||||
NVSDK_NGX_Parameter_GetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Get_Dynamic_Max_Render_Width, pOutRenderMaxWidth);
|
||||
NVSDK_NGX_Parameter_GetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Get_Dynamic_Max_Render_Height, pOutRenderMaxHeight);
|
||||
NVSDK_NGX_Parameter_GetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Get_Dynamic_Min_Render_Width, pOutRenderMinWidth);
|
||||
NVSDK_NGX_Parameter_GetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Get_Dynamic_Min_Render_Height, pOutRenderMinHeight);
|
||||
NVSDK_NGX_Parameter_GetF(pInParams, NVSDK_NGX_Parameter_Sharpness, pOutSharpness);
|
||||
return Res;
|
||||
}
|
||||
|
||||
typedef struct NVSDK_NGX_D3D11_DLSSD_Eval_Params
|
||||
{
|
||||
ID3D11Resource* pInDiffuseAlbedo;
|
||||
ID3D11Resource* pInSpecularAlbedo;
|
||||
ID3D11Resource* pInNormals;
|
||||
ID3D11Resource* pInRoughness;
|
||||
|
||||
ID3D11Resource* pInColor;
|
||||
ID3D11Resource* pInAlpha;
|
||||
ID3D11Resource* pInOutput;
|
||||
ID3D11Resource* pInOutputAlpha;
|
||||
ID3D11Resource* pInDepth;
|
||||
ID3D11Resource* pInMotionVectors;
|
||||
float InJitterOffsetX; /* Jitter offset must be in input/render pixel space */
|
||||
float InJitterOffsetY;
|
||||
NVSDK_NGX_Dimensions InRenderSubrectDimensions;
|
||||
/*** OPTIONAL - leave to 0/0.0f if unused ***/
|
||||
int InReset; /* Set to 1 when scene changes completely (new level etc) */
|
||||
float InMVScaleX; /* If MVs need custom scaling to convert to pixel space */
|
||||
float InMVScaleY;
|
||||
ID3D11Resource* pInTransparencyMask; /* Unused/Reserved for future use */
|
||||
ID3D11Resource* pInExposureTexture;
|
||||
ID3D11Resource* pInBiasCurrentColorMask;
|
||||
NVSDK_NGX_Coordinates InAlphaSubrectBase;
|
||||
NVSDK_NGX_Coordinates InOutputAlphaSubrectBase;
|
||||
NVSDK_NGX_Coordinates InDiffuseAlbedoSubrectBase;
|
||||
NVSDK_NGX_Coordinates InSpecularAlbedoSubrectBase;
|
||||
NVSDK_NGX_Coordinates InNormalsSubrectBase;
|
||||
NVSDK_NGX_Coordinates InRoughnessSubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorSubrectBase;
|
||||
NVSDK_NGX_Coordinates InDepthSubrectBase;
|
||||
NVSDK_NGX_Coordinates InMVSubrectBase;
|
||||
NVSDK_NGX_Coordinates InTranslucencySubrectBase;
|
||||
NVSDK_NGX_Coordinates InBiasCurrentColorSubrectBase;
|
||||
NVSDK_NGX_Coordinates InOutputSubrectBase;
|
||||
|
||||
ID3D11Resource* pInReflectedAlbedo;
|
||||
ID3D11Resource* pInColorBeforeParticles;
|
||||
ID3D11Resource* pInColorAfterParticles;
|
||||
ID3D11Resource* pInColorBeforeTransparency;
|
||||
ID3D11Resource* pInColorAfterTransparency;
|
||||
ID3D11Resource* pInColorBeforeFog;
|
||||
ID3D11Resource* pInColorAfterFog;
|
||||
ID3D11Resource* pInScreenSpaceSubsurfaceScatteringGuide;
|
||||
ID3D11Resource* pInColorBeforeScreenSpaceSubsurfaceScattering;
|
||||
ID3D11Resource* pInColorAfterScreenSpaceSubsurfaceScattering;
|
||||
ID3D11Resource* pInScreenSpaceRefractionGuide;
|
||||
ID3D11Resource* pInColorBeforeScreenSpaceRefraction;
|
||||
ID3D11Resource* pInColorAfterScreenSpaceRefraction;
|
||||
ID3D11Resource* pInDepthOfFieldGuide;
|
||||
ID3D11Resource* pInColorBeforeDepthOfField;
|
||||
ID3D11Resource* pInColorAfterDepthOfField;
|
||||
ID3D11Resource* pInDiffuseHitDistance;
|
||||
ID3D11Resource* pInSpecularHitDistance;
|
||||
ID3D11Resource* pInDiffuseRayDirection;
|
||||
ID3D11Resource* pInSpecularRayDirection;
|
||||
ID3D11Resource* pInDiffuseRayDirectionHitDistance;
|
||||
ID3D11Resource* pInSpecularRayDirectionHitDistance;
|
||||
NVSDK_NGX_Coordinates InReflectedAlbedoSubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorBeforeParticlesSubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorAfterParticlesSubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorBeforeTransparencySubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorAfterTransparencySubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorBeforeFogSubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorAfterFogSubrectBase;
|
||||
NVSDK_NGX_Coordinates InScreenSpaceSubsurfaceScatteringGuideSubrectBase;
|
||||
NVSDK_NGX_Coordinates InScreenSpaceRefractionGuideSubrectBase;
|
||||
NVSDK_NGX_Coordinates InDepthOfFieldGuideSubrectBase;
|
||||
NVSDK_NGX_Coordinates InDiffuseHitDistanceSubrectBase;
|
||||
NVSDK_NGX_Coordinates InSpecularHitDistanceSubrectBase;
|
||||
NVSDK_NGX_Coordinates InDiffuseRayDirectionSubrectBase;
|
||||
NVSDK_NGX_Coordinates InSpecularRayDirectionSubrectBase;
|
||||
NVSDK_NGX_Coordinates InDiffuseRayDirectionHitDistanceSubrectBase;
|
||||
NVSDK_NGX_Coordinates InSpecularRayDirectionHitDistanceSubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorBeforeScreenSpaceSubsurfaceScatteringSubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorAfterScreenSpaceSubsurfaceScatteringSubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorBeforeScreenSpaceRefractionSubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorAfterScreenSpaceRefractionSubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorBeforeDepthOfFieldSubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorAfterDepthOfFieldSubtectBase;
|
||||
float* pInWorldToViewMatrix;
|
||||
float* pInViewToClipMatrix;
|
||||
|
||||
float InPreExposure;
|
||||
float InExposureScale;
|
||||
int InIndicatorInvertXAxis;
|
||||
int InIndicatorInvertYAxis;
|
||||
/*** OPTIONAL - only for research purposes ***/
|
||||
NVSDK_NGX_D3D11_GBuffer GBufferSurface;
|
||||
NVSDK_NGX_ToneMapperType InToneMapperType;
|
||||
ID3D11Resource* pInMotionVectors3D;
|
||||
ID3D11Resource* pInIsParticleMask; /* to identify which pixels contains particles, essentially that are not drawn as part of base pass */
|
||||
ID3D11Resource* pInAnimatedTextureMask; /* a binary mask covering pixels occupied by animated textures */
|
||||
ID3D11Resource* pInDepthHighRes;
|
||||
ID3D11Resource* pInPositionViewSpace;
|
||||
float InFrameTimeDeltaInMsec; /* helps in determining the amount to denoise or anti-alias based on the speed of the object from motion vector magnitudes and fps as determined by this delta */
|
||||
ID3D11Resource* pInRayTracingHitDistance; /* for each effect - approximation to the amount of noise in a ray-traced color */
|
||||
ID3D11Resource* pInMotionVectorsReflections; /* motion vectors of reflected objects like for mirrored surfaces */
|
||||
ID3D11Resource* pInTransparencyLayer; /* optional input res particle layer */
|
||||
NVSDK_NGX_Coordinates InTransparencyLayerSubrectBase;
|
||||
ID3D11Resource* pInTransparencyLayerOpacity; /* optional input res particle opacity layer */
|
||||
NVSDK_NGX_Coordinates InTransparencyLayerOpacitySubrectBase;
|
||||
ID3D11Resource* pInTransparencyLayerMvecs; /* optional input res transparency layer mvecs */
|
||||
NVSDK_NGX_Coordinates InTransparencyLayerMvecsSubrectBase;
|
||||
ID3D11Resource* pInDisocclusionMask; /* optional input res disocclusion mask */
|
||||
NVSDK_NGX_Coordinates InDisocclusionMaskSubrectBase;
|
||||
ID3D11Resource* pInResponsivityMask; /* optional input res responsivity mask; one channel, API range [-1,1]; R16F or R8 SNORM */
|
||||
NVSDK_NGX_Coordinates InResponsivityMaskSubrectBase;
|
||||
} NVSDK_NGX_D3D11_DLSSD_Eval_Params;
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_D3D11_CREATE_DLSSD_EXT(
|
||||
ID3D11DeviceContext *pInCtx,
|
||||
NVSDK_NGX_Handle **ppOutHandle,
|
||||
NVSDK_NGX_Parameter *pInParams,
|
||||
NVSDK_NGX_DLSSD_Create_Params *pInDlssDCreateParams)
|
||||
{
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Width, pInDlssDCreateParams->InWidth);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Height, pInDlssDCreateParams->InHeight);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutWidth, pInDlssDCreateParams->InTargetWidth);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutHeight, pInDlssDCreateParams->InTargetHeight);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_PerfQualityValue, pInDlssDCreateParams->InPerfQualityValue);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Feature_Create_Flags, pInDlssDCreateParams->InFeatureCreateFlags);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Enable_Output_Subrects, pInDlssDCreateParams->InEnableOutputSubrects ? 1 : 0);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Denoise_Mode, NVSDK_NGX_DLSS_Denoise_Mode_DLUnified);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Roughness_Mode, pInDlssDCreateParams->InRoughnessMode);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Use_HW_Depth, pInDlssDCreateParams->InUseHWDepth);
|
||||
|
||||
return NVSDK_NGX_D3D11_CreateFeature(pInCtx, NVSDK_NGX_Feature_RayReconstruction, pInParams, ppOutHandle);
|
||||
}
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_D3D11_EVALUATE_DLSSD_EXT(
|
||||
ID3D11DeviceContext *pInCtx,
|
||||
NVSDK_NGX_Handle *pInHandle,
|
||||
NVSDK_NGX_Parameter *pInParams,
|
||||
NVSDK_NGX_D3D11_DLSSD_Eval_Params *pInDlssDEvalParams)
|
||||
{
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_Color, pInDlssDEvalParams->pInColor);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_Output, pInDlssDEvalParams->pInOutput);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_Depth, pInDlssDEvalParams->pInDepth);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_MotionVectors, pInDlssDEvalParams->pInMotionVectors);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Jitter_Offset_X, pInDlssDEvalParams->InJitterOffsetX);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Jitter_Offset_Y, pInDlssDEvalParams->InJitterOffsetY);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_Reset, pInDlssDEvalParams->InReset);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_MV_Scale_X, pInDlssDEvalParams->InMVScaleX == 0.0f ? 1.0f : pInDlssDEvalParams->InMVScaleX);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_MV_Scale_Y, pInDlssDEvalParams->InMVScaleY == 0.0f ? 1.0f : pInDlssDEvalParams->InMVScaleY);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_TransparencyMask, pInDlssDEvalParams->pInTransparencyMask);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_ExposureTexture, pInDlssDEvalParams->pInExposureTexture);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_Mask, pInDlssDEvalParams->pInBiasCurrentColorMask);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Albedo, pInDlssDEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_ALBEDO]);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Roughness, pInDlssDEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_ROUGHNESS]);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Metallic, pInDlssDEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_METALLIC]);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Specular, pInDlssDEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_SPECULAR]);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Subsurface, pInDlssDEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_SUBSURFACE]);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Normals, pInDlssDEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_NORMALS]);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_ShadingModelId, pInDlssDEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_SHADINGMODELID]);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_MaterialId, pInDlssDEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_MATERIALID]);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_8, pInDlssDEvalParams->GBufferSurface.pInAttrib[8]);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_9, pInDlssDEvalParams->GBufferSurface.pInAttrib[9]);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_SpecularMvec, pInDlssDEvalParams->pInMotionVectorsReflections);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_11, pInDlssDEvalParams->GBufferSurface.pInAttrib[11]);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_12, pInDlssDEvalParams->GBufferSurface.pInAttrib[12]);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_13, pInDlssDEvalParams->GBufferSurface.pInAttrib[13]);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_14, pInDlssDEvalParams->GBufferSurface.pInAttrib[14]);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_15, pInDlssDEvalParams->GBufferSurface.pInAttrib[15]);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_TonemapperType, pInDlssDEvalParams->InToneMapperType);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_MotionVectors3D, pInDlssDEvalParams->pInMotionVectors3D);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_IsParticleMask, pInDlssDEvalParams->pInIsParticleMask);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_AnimatedTextureMask, pInDlssDEvalParams->pInAnimatedTextureMask);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_DepthHighRes, pInDlssDEvalParams->pInDepthHighRes);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_Position_ViewSpace, pInDlssDEvalParams->pInPositionViewSpace);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_FrameTimeDeltaInMsec, pInDlssDEvalParams->InFrameTimeDeltaInMsec);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_RayTracingHitDistance, pInDlssDEvalParams->pInRayTracingHitDistance);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Color_Subrect_Base_X, pInDlssDEvalParams->InColorSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Color_Subrect_Base_Y, pInDlssDEvalParams->InColorSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Depth_Subrect_Base_X, pInDlssDEvalParams->InDepthSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Depth_Subrect_Base_Y, pInDlssDEvalParams->InDepthSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_MV_SubrectBase_X, pInDlssDEvalParams->InMVSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_MV_SubrectBase_Y, pInDlssDEvalParams->InMVSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Translucency_SubrectBase_X, pInDlssDEvalParams->InTranslucencySubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Translucency_SubrectBase_Y, pInDlssDEvalParams->InTranslucencySubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_SubrectBase_X, pInDlssDEvalParams->InBiasCurrentColorSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_SubrectBase_Y, pInDlssDEvalParams->InBiasCurrentColorSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Output_Subrect_Base_X, pInDlssDEvalParams->InOutputSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Output_Subrect_Base_Y, pInDlssDEvalParams->InOutputSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Render_Subrect_Dimensions_Width , pInDlssDEvalParams->InRenderSubrectDimensions.Width);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Render_Subrect_Dimensions_Height, pInDlssDEvalParams->InRenderSubrectDimensions.Height);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_DLSS_Pre_Exposure, pInDlssDEvalParams->InPreExposure == 0.0f ? 1.0f : pInDlssDEvalParams->InPreExposure);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_DLSS_Exposure_Scale, pInDlssDEvalParams->InExposureScale == 0.0f ? 1.0f : pInDlssDEvalParams->InExposureScale);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Indicator_Invert_X_Axis, pInDlssDEvalParams->InIndicatorInvertXAxis);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Indicator_Invert_Y_Axis, pInDlssDEvalParams->InIndicatorInvertYAxis);
|
||||
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_DiffuseAlbedo, pInDlssDEvalParams->pInDiffuseAlbedo);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_SpecularAlbedo, pInDlssDEvalParams->pInSpecularAlbedo);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_DiffuseAlbedo_Subrect_Base_X, pInDlssDEvalParams->InDiffuseAlbedoSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_DiffuseAlbedo_Subrect_Base_Y, pInDlssDEvalParams->InDiffuseAlbedoSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_SpecularAlbedo_Subrect_Base_X, pInDlssDEvalParams->InSpecularAlbedoSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_SpecularAlbedo_Subrect_Base_Y, pInDlssDEvalParams->InSpecularAlbedoSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Normals_Subrect_Base_X, pInDlssDEvalParams->InNormalsSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Normals_Subrect_Base_Y, pInDlssDEvalParams->InNormalsSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Roughness_Subrect_Base_X, pInDlssDEvalParams->InRoughnessSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Roughness_Subrect_Base_Y, pInDlssDEvalParams->InRoughnessSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Emissive, pInDlssDEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_EMISSIVE]);
|
||||
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_Alpha, pInDlssDEvalParams->pInAlpha);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_OutputAlpha, pInDlssDEvalParams->pInOutputAlpha);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_ReflectedAlbedo, pInDlssDEvalParams->pInReflectedAlbedo);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeParticles, pInDlssDEvalParams->pInColorBeforeParticles);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterParticles, pInDlssDEvalParams->pInColorAfterParticles);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeTransparency, pInDlssDEvalParams->pInColorBeforeTransparency);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterTransparency, pInDlssDEvalParams->pInColorAfterTransparency);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeFog, pInDlssDEvalParams->pInColorBeforeFog);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterFog, pInDlssDEvalParams->pInColorAfterFog);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_ScreenSpaceSubsurfaceScatteringGuide, pInDlssDEvalParams->pInScreenSpaceSubsurfaceScatteringGuide);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeScreenSpaceSubsurfaceScattering, pInDlssDEvalParams->pInColorBeforeScreenSpaceSubsurfaceScattering);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterScreenSpaceSubsurfaceScattering, pInDlssDEvalParams->pInColorAfterScreenSpaceSubsurfaceScattering);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_ScreenSpaceRefractionGuide, pInDlssDEvalParams->pInScreenSpaceRefractionGuide);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeScreenSpaceRefraction, pInDlssDEvalParams->pInColorBeforeScreenSpaceRefraction);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterScreenSpaceRefraction, pInDlssDEvalParams->pInColorAfterScreenSpaceRefraction);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_DepthOfFieldGuide, pInDlssDEvalParams->pInDepthOfFieldGuide);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeDepthOfField, pInDlssDEvalParams->pInColorBeforeDepthOfField);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterDepthOfField, pInDlssDEvalParams->pInColorAfterDepthOfField);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_DiffuseHitDistance, pInDlssDEvalParams->pInDiffuseHitDistance);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_SpecularHitDistance, pInDlssDEvalParams->pInSpecularHitDistance);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_DiffuseRayDirection, pInDlssDEvalParams->pInDiffuseRayDirection);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_SpecularRayDirection, pInDlssDEvalParams->pInSpecularRayDirection);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_DiffuseRayDirectionHitDistance, pInDlssDEvalParams->pInDiffuseRayDirectionHitDistance);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_SpecularRayDirectionHitDistance, pInDlssDEvalParams->pInSpecularRayDirectionHitDistance);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_Alpha_Subrect_Base_X, pInDlssDEvalParams->InAlphaSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_Alpha_Subrect_Base_Y, pInDlssDEvalParams->InAlphaSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_OutputAlpha_Subrect_Base_X, pInDlssDEvalParams->InOutputAlphaSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_OutputAlpha_Subrect_Base_Y, pInDlssDEvalParams->InOutputAlphaSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ReflectedAlbedo_Subrect_Base_X, pInDlssDEvalParams->InReflectedAlbedoSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ReflectedAlbedo_Subrect_Base_Y, pInDlssDEvalParams->InReflectedAlbedoSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterParticles_Subrect_Base_X, pInDlssDEvalParams->InColorAfterParticlesSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterParticles_Subrect_Base_Y, pInDlssDEvalParams->InColorAfterParticlesSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeParticles_Subrect_Base_X, pInDlssDEvalParams->InColorBeforeParticlesSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeParticles_Subrect_Base_Y, pInDlssDEvalParams->InColorBeforeParticlesSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeTransparency_Subrect_Base_X, pInDlssDEvalParams->InColorBeforeTransparencySubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeTransparency_Subrect_Base_Y, pInDlssDEvalParams->InColorBeforeTransparencySubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterTransparency_Subrect_Base_X, pInDlssDEvalParams->InColorAfterTransparencySubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterTransparency_Subrect_Base_Y, pInDlssDEvalParams->InColorAfterTransparencySubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeFog_Subrect_Base_X, pInDlssDEvalParams->InColorBeforeFogSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeFog_Subrect_Base_Y, pInDlssDEvalParams->InColorBeforeFogSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterFog_Subrect_Base_X, pInDlssDEvalParams->InColorAfterFogSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterFog_Subrect_Base_Y, pInDlssDEvalParams->InColorAfterFogSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ScreenSpaceSubsurfaceScatteringGuide_Subrect_Base_X, pInDlssDEvalParams->InScreenSpaceSubsurfaceScatteringGuideSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ScreenSpaceSubsurfaceScatteringGuide_Subrect_Base_Y, pInDlssDEvalParams->InScreenSpaceSubsurfaceScatteringGuideSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeScreenSpaceSubsurfaceScattering_Subrect_Base_X, pInDlssDEvalParams->InColorBeforeScreenSpaceSubsurfaceScatteringSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeScreenSpaceSubsurfaceScattering_Subrect_Base_Y, pInDlssDEvalParams->InColorBeforeScreenSpaceSubsurfaceScatteringSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterScreenSpaceSubsurfaceScattering_Subrect_Base_X, pInDlssDEvalParams->InColorAfterScreenSpaceSubsurfaceScatteringSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterScreenSpaceSubsurfaceScattering_Subrect_Base_Y, pInDlssDEvalParams->InColorAfterScreenSpaceSubsurfaceScatteringSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ScreenSpaceRefractionGuide_Subrect_Base_X, pInDlssDEvalParams->InScreenSpaceRefractionGuideSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ScreenSpaceRefractionGuide_Subrect_Base_Y, pInDlssDEvalParams->InScreenSpaceRefractionGuideSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeScreenSpaceRefraction_Subrect_Base_X, pInDlssDEvalParams->InColorBeforeScreenSpaceRefractionSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeScreenSpaceRefraction_Subrect_Base_Y, pInDlssDEvalParams->InColorBeforeScreenSpaceRefractionSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterScreenSpaceRefraction_Subrect_Base_X, pInDlssDEvalParams->InColorAfterScreenSpaceRefractionSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterScreenSpaceRefraction_Subrect_Base_Y, pInDlssDEvalParams->InColorAfterScreenSpaceRefractionSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_DepthOfFieldGuide_Subrect_Base_X, pInDlssDEvalParams->InDepthOfFieldGuideSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_DepthOfFieldGuide_Subrect_Base_Y, pInDlssDEvalParams->InDepthOfFieldGuideSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeDepthOfField_Subrect_Base_X, pInDlssDEvalParams->InColorBeforeDepthOfFieldSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeDepthOfField_Subrect_Base_Y, pInDlssDEvalParams->InColorBeforeDepthOfFieldSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterDepthOfField_Subrect_Base_X, pInDlssDEvalParams->InColorAfterDepthOfFieldSubtectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterDepthOfField_Subrect_Base_Y, pInDlssDEvalParams->InColorAfterDepthOfFieldSubtectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_DiffuseHitDistance_Subrect_Base_X, pInDlssDEvalParams->InDiffuseHitDistanceSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_DiffuseHitDistance_Subrect_Base_Y, pInDlssDEvalParams->InDiffuseHitDistanceSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_SpecularHitDistance_Subrect_Base_X, pInDlssDEvalParams->InSpecularHitDistanceSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_SpecularHitDistance_Subrect_Base_Y, pInDlssDEvalParams->InSpecularHitDistanceSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_DiffuseRayDirection_Subrect_Base_X, pInDlssDEvalParams->InDiffuseRayDirectionSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_DiffuseRayDirection_Subrect_Base_Y, pInDlssDEvalParams->InDiffuseRayDirectionSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_SpecularRayDirection_Subrect_Base_X, pInDlssDEvalParams->InSpecularRayDirectionSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_SpecularRayDirection_Subrect_Base_Y, pInDlssDEvalParams->InSpecularRayDirectionSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_DiffuseRayDirectionHitDistance_Subrect_Base_X, pInDlssDEvalParams->InDiffuseRayDirectionHitDistanceSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_DiffuseRayDirectionHitDistance_Subrect_Base_Y, pInDlssDEvalParams->InDiffuseRayDirectionHitDistanceSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_SpecularRayDirectionHitDistance_Subrect_Base_X, pInDlssDEvalParams->InSpecularRayDirectionHitDistanceSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_SpecularRayDirectionHitDistance_Subrect_Base_Y, pInDlssDEvalParams->InSpecularRayDirectionHitDistanceSubrectBase.Y);
|
||||
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSS_WORLD_TO_VIEW_MATRIX, pInDlssDEvalParams->pInWorldToViewMatrix);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSS_VIEW_TO_CLIP_MATRIX, pInDlssDEvalParams->pInViewToClipMatrix);
|
||||
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Normals, pInDlssDEvalParams->pInNormals);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Roughness, pInDlssDEvalParams->pInRoughness);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_DLSS_TransparencyLayer, pInDlssDEvalParams->pInTransparencyLayer);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_DLSS_TransparencyLayerOpacity, pInDlssDEvalParams->pInTransparencyLayerOpacity);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_DLSS_TransparencyLayerMvecs, pInDlssDEvalParams->pInTransparencyLayerMvecs);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_DLSS_DisocclusionMask, pInDlssDEvalParams->pInDisocclusionMask);
|
||||
NVSDK_NGX_Parameter_SetD3d11Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_ResponsivityMask, pInDlssDEvalParams->pInResponsivityMask);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_TransparencyLayer_Subrect_Base_X, pInDlssDEvalParams->InTransparencyLayerSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_TransparencyLayer_Subrect_Base_Y, pInDlssDEvalParams->InTransparencyLayerSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_TransparencyLayerOpacity_Subrect_Base_X, pInDlssDEvalParams->InTransparencyLayerOpacitySubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_TransparencyLayerOpacity_Subrect_Base_Y, pInDlssDEvalParams->InTransparencyLayerOpacitySubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_TransparencyLayerMvecs_Subrect_Base_X, pInDlssDEvalParams->InTransparencyLayerMvecsSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_TransparencyLayerMvecs_Subrect_Base_Y, pInDlssDEvalParams->InTransparencyLayerMvecsSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_DisocclusionMask_Subrect_Base_X, pInDlssDEvalParams->InDisocclusionMaskSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_DisocclusionMask_Subrect_Base_Y, pInDlssDEvalParams->InDisocclusionMaskSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ResponsivityMask_Subrect_Base_X, pInDlssDEvalParams->InResponsivityMaskSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ResponsivityMask_Subrect_Base_Y, pInDlssDEvalParams->InResponsivityMaskSubrectBase.Y);
|
||||
|
||||
|
||||
return NVSDK_NGX_D3D11_EvaluateFeature_C(pInCtx, pInHandle, pInParams, NULL);
|
||||
}
|
||||
|
||||
typedef struct NVSDK_NGX_D3D12_DLSSD_Eval_Params
|
||||
{
|
||||
ID3D12Resource* pInDiffuseAlbedo;
|
||||
ID3D12Resource* pInSpecularAlbedo;
|
||||
ID3D12Resource* pInNormals;
|
||||
ID3D12Resource* pInRoughness;
|
||||
|
||||
ID3D12Resource* pInColor;
|
||||
ID3D12Resource* pInAlpha;
|
||||
ID3D12Resource* pInOutput;
|
||||
ID3D12Resource* pInOutputAlpha;
|
||||
ID3D12Resource* pInDepth;
|
||||
ID3D12Resource* pInMotionVectors;
|
||||
float InJitterOffsetX; /* Jitter offset must be in input/render pixel space */
|
||||
float InJitterOffsetY;
|
||||
NVSDK_NGX_Dimensions InRenderSubrectDimensions;
|
||||
/*** OPTIONAL - leave to 0/0.0f if unused ***/
|
||||
int InReset; /* Set to 1 when scene changes completely (new level etc) */
|
||||
float InMVScaleX; /* If MVs need custom scaling to convert to pixel space */
|
||||
float InMVScaleY;
|
||||
ID3D12Resource* pInTransparencyMask; /* Unused/Reserved for future use */
|
||||
ID3D12Resource* pInExposureTexture;
|
||||
ID3D12Resource* pInBiasCurrentColorMask;
|
||||
NVSDK_NGX_Coordinates InAlphaSubrectBase;
|
||||
NVSDK_NGX_Coordinates InOutputAlphaSubrectBase;
|
||||
NVSDK_NGX_Coordinates InDiffuseAlbedoSubrectBase;
|
||||
NVSDK_NGX_Coordinates InSpecularAlbedoSubrectBase;
|
||||
NVSDK_NGX_Coordinates InNormalsSubrectBase;
|
||||
NVSDK_NGX_Coordinates InRoughnessSubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorSubrectBase;
|
||||
NVSDK_NGX_Coordinates InDepthSubrectBase;
|
||||
NVSDK_NGX_Coordinates InMVSubrectBase;
|
||||
NVSDK_NGX_Coordinates InTranslucencySubrectBase;
|
||||
NVSDK_NGX_Coordinates InBiasCurrentColorSubrectBase;
|
||||
NVSDK_NGX_Coordinates InOutputSubrectBase;
|
||||
|
||||
ID3D12Resource* pInReflectedAlbedo;
|
||||
ID3D12Resource* pInColorBeforeParticles;
|
||||
ID3D12Resource* pInColorAfterParticles;
|
||||
ID3D12Resource* pInColorBeforeTransparency;
|
||||
ID3D12Resource* pInColorAfterTransparency;
|
||||
ID3D12Resource* pInColorBeforeFog;
|
||||
ID3D12Resource* pInColorAfterFog;
|
||||
ID3D12Resource* pInScreenSpaceSubsurfaceScatteringGuide;
|
||||
ID3D12Resource* pInColorBeforeScreenSpaceSubsurfaceScattering;
|
||||
ID3D12Resource* pInColorAfterScreenSpaceSubsurfaceScattering;
|
||||
ID3D12Resource* pInScreenSpaceRefractionGuide;
|
||||
ID3D12Resource* pInColorBeforeScreenSpaceRefraction;
|
||||
ID3D12Resource* pInColorAfterScreenSpaceRefraction;
|
||||
ID3D12Resource* pInDepthOfFieldGuide;
|
||||
ID3D12Resource* pInColorBeforeDepthOfField;
|
||||
ID3D12Resource* pInColorAfterDepthOfField;
|
||||
ID3D12Resource* pInDiffuseHitDistance;
|
||||
ID3D12Resource* pInSpecularHitDistance;
|
||||
ID3D12Resource* pInDiffuseRayDirection;
|
||||
ID3D12Resource* pInSpecularRayDirection;
|
||||
ID3D12Resource* pInDiffuseRayDirectionHitDistance;
|
||||
ID3D12Resource* pInSpecularRayDirectionHitDistance;
|
||||
NVSDK_NGX_Coordinates InReflectedAlbedoSubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorBeforeParticlesSubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorAfterParticlesSubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorBeforeTransparencySubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorAfterTransparencySubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorBeforeFogSubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorAfterFogSubrectBase;
|
||||
NVSDK_NGX_Coordinates InScreenSpaceSubsurfaceScatteringGuideSubrectBase;
|
||||
NVSDK_NGX_Coordinates InScreenSpaceRefractionGuideSubrectBase;
|
||||
NVSDK_NGX_Coordinates InDepthOfFieldGuideSubrectBase;
|
||||
NVSDK_NGX_Coordinates InDiffuseHitDistanceSubrectBase;
|
||||
NVSDK_NGX_Coordinates InSpecularHitDistanceSubrectBase;
|
||||
NVSDK_NGX_Coordinates InDiffuseRayDirectionSubrectBase;
|
||||
NVSDK_NGX_Coordinates InSpecularRayDirectionSubrectBase;
|
||||
NVSDK_NGX_Coordinates InDiffuseRayDirectionHitDistanceSubrectBase;
|
||||
NVSDK_NGX_Coordinates InSpecularRayDirectionHitDistanceSubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorBeforeScreenSpaceSubsurfaceScatteringSubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorAfterScreenSpaceSubsurfaceScatteringSubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorBeforeScreenSpaceRefractionSubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorAfterScreenSpaceRefractionSubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorBeforeDepthOfFieldSubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorAfterDepthOfFieldSubtectBase;
|
||||
float* pInWorldToViewMatrix;
|
||||
float* pInViewToClipMatrix;
|
||||
|
||||
float InPreExposure;
|
||||
float InExposureScale;
|
||||
int InIndicatorInvertXAxis;
|
||||
int InIndicatorInvertYAxis;
|
||||
/*** OPTIONAL - only for research purposes ***/
|
||||
NVSDK_NGX_D3D12_GBuffer GBufferSurface;
|
||||
NVSDK_NGX_ToneMapperType InToneMapperType;
|
||||
ID3D12Resource* pInMotionVectors3D;
|
||||
ID3D12Resource* pInIsParticleMask; /* to identify which pixels contains particles, essentially that are not drawn as part of base pass */
|
||||
ID3D12Resource* pInAnimatedTextureMask; /* a binary mask covering pixels occupied by animated textures */
|
||||
ID3D12Resource* pInDepthHighRes;
|
||||
ID3D12Resource* pInPositionViewSpace;
|
||||
float InFrameTimeDeltaInMsec; /* helps in determining the amount to denoise or anti-alias based on the speed of the object from motion vector magnitudes and fps as determined by this delta */
|
||||
ID3D12Resource* pInRayTracingHitDistance; /* for each effect - approximation to the amount of noise in a ray-traced color */
|
||||
ID3D12Resource* pInMotionVectorsReflections; /* motion vectors of reflected objects like for mirrored surfaces */
|
||||
ID3D12Resource* pInTransparencyLayer; /* optional input res particle layer */
|
||||
NVSDK_NGX_Coordinates InTransparencyLayerSubrectBase;
|
||||
ID3D12Resource* pInTransparencyLayerOpacity; /* optional input res particle opacity layer */
|
||||
NVSDK_NGX_Coordinates InTransparencyLayerOpacitySubrectBase;
|
||||
ID3D12Resource* pInTransparencyLayerMvecs; /* optional input res transparency layer mvecs */
|
||||
NVSDK_NGX_Coordinates InTransparencyLayerMvecsSubrectBase;
|
||||
ID3D12Resource* pInDisocclusionMask; /* optional input res disocclusion mask */
|
||||
NVSDK_NGX_Coordinates InDisocclusionMaskSubrectBase;
|
||||
ID3D12Resource* pInResponsivityMask; /* optional input res responsivity mask; one channel, R16F or R8 SNORM */
|
||||
NVSDK_NGX_Coordinates InResponsivityMaskSubrectBase;
|
||||
|
||||
} NVSDK_NGX_D3D12_DLSSD_Eval_Params;
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_D3D12_CREATE_DLSSD_EXT(
|
||||
ID3D12GraphicsCommandList *pInCmdList,
|
||||
unsigned int InCreationNodeMask,
|
||||
unsigned int InVisibilityNodeMask,
|
||||
NVSDK_NGX_Handle **ppOutHandle,
|
||||
NVSDK_NGX_Parameter *pInParams,
|
||||
NVSDK_NGX_DLSSD_Create_Params *pInDlssDCreateParams)
|
||||
{
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_CreationNodeMask, InCreationNodeMask);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_VisibilityNodeMask, InVisibilityNodeMask);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Width, pInDlssDCreateParams->InWidth);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Height, pInDlssDCreateParams->InHeight);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutWidth, pInDlssDCreateParams->InTargetWidth);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutHeight, pInDlssDCreateParams->InTargetHeight);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_PerfQualityValue, pInDlssDCreateParams->InPerfQualityValue);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Feature_Create_Flags, pInDlssDCreateParams->InFeatureCreateFlags);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Enable_Output_Subrects, pInDlssDCreateParams->InEnableOutputSubrects ? 1 : 0);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Denoise_Mode, NVSDK_NGX_DLSS_Denoise_Mode_DLUnified);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Roughness_Mode, pInDlssDCreateParams->InRoughnessMode);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Use_HW_Depth, pInDlssDCreateParams->InUseHWDepth);
|
||||
return NVSDK_NGX_D3D12_CreateFeature(pInCmdList, NVSDK_NGX_Feature_RayReconstruction, pInParams, ppOutHandle);
|
||||
}
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_D3D12_EVALUATE_DLSSD_EXT(
|
||||
ID3D12GraphicsCommandList *pInCmdList,
|
||||
NVSDK_NGX_Handle *pInHandle,
|
||||
NVSDK_NGX_Parameter *pInParams,
|
||||
NVSDK_NGX_D3D12_DLSSD_Eval_Params *pInDlssDEvalParams)
|
||||
{
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_Color, pInDlssDEvalParams->pInColor);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_Output, pInDlssDEvalParams->pInOutput);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_Depth, pInDlssDEvalParams->pInDepth);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_MotionVectors, pInDlssDEvalParams->pInMotionVectors);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Jitter_Offset_X, pInDlssDEvalParams->InJitterOffsetX);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Jitter_Offset_Y, pInDlssDEvalParams->InJitterOffsetY);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_Reset, pInDlssDEvalParams->InReset);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_MV_Scale_X, pInDlssDEvalParams->InMVScaleX == 0.0f ? 1.0f : pInDlssDEvalParams->InMVScaleX);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_MV_Scale_Y, pInDlssDEvalParams->InMVScaleY == 0.0f ? 1.0f : pInDlssDEvalParams->InMVScaleY);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_TransparencyMask, pInDlssDEvalParams->pInTransparencyMask);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_ExposureTexture, pInDlssDEvalParams->pInExposureTexture);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_Mask, pInDlssDEvalParams->pInBiasCurrentColorMask);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Albedo, pInDlssDEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_ALBEDO]);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Roughness, pInDlssDEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_ROUGHNESS]);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Metallic, pInDlssDEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_METALLIC]);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Specular, pInDlssDEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_SPECULAR]);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Subsurface, pInDlssDEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_SUBSURFACE]);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Normals, pInDlssDEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_NORMALS]);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_ShadingModelId, pInDlssDEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_SHADINGMODELID]);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_MaterialId, pInDlssDEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_MATERIALID]);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_8, pInDlssDEvalParams->GBufferSurface.pInAttrib[8]);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_9, pInDlssDEvalParams->GBufferSurface.pInAttrib[9]);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_11, pInDlssDEvalParams->GBufferSurface.pInAttrib[11]);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_12, pInDlssDEvalParams->GBufferSurface.pInAttrib[12]);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_13, pInDlssDEvalParams->GBufferSurface.pInAttrib[13]);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_14, pInDlssDEvalParams->GBufferSurface.pInAttrib[14]);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_15, pInDlssDEvalParams->GBufferSurface.pInAttrib[15]);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_TonemapperType, pInDlssDEvalParams->InToneMapperType);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_MotionVectors3D, pInDlssDEvalParams->pInMotionVectors3D);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_IsParticleMask, pInDlssDEvalParams->pInIsParticleMask);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_AnimatedTextureMask, pInDlssDEvalParams->pInAnimatedTextureMask);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_DepthHighRes, pInDlssDEvalParams->pInDepthHighRes);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_Position_ViewSpace, pInDlssDEvalParams->pInPositionViewSpace);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_FrameTimeDeltaInMsec, pInDlssDEvalParams->InFrameTimeDeltaInMsec);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_RayTracingHitDistance, pInDlssDEvalParams->pInRayTracingHitDistance);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_SpecularMvec, pInDlssDEvalParams->pInMotionVectorsReflections);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Color_Subrect_Base_X, pInDlssDEvalParams->InColorSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Color_Subrect_Base_Y, pInDlssDEvalParams->InColorSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Depth_Subrect_Base_X, pInDlssDEvalParams->InDepthSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Depth_Subrect_Base_Y, pInDlssDEvalParams->InDepthSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_MV_SubrectBase_X, pInDlssDEvalParams->InMVSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_MV_SubrectBase_Y, pInDlssDEvalParams->InMVSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Translucency_SubrectBase_X, pInDlssDEvalParams->InTranslucencySubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Translucency_SubrectBase_Y, pInDlssDEvalParams->InTranslucencySubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_SubrectBase_X, pInDlssDEvalParams->InBiasCurrentColorSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_SubrectBase_Y, pInDlssDEvalParams->InBiasCurrentColorSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Output_Subrect_Base_X, pInDlssDEvalParams->InOutputSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Output_Subrect_Base_Y, pInDlssDEvalParams->InOutputSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Render_Subrect_Dimensions_Width , pInDlssDEvalParams->InRenderSubrectDimensions.Width);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Render_Subrect_Dimensions_Height, pInDlssDEvalParams->InRenderSubrectDimensions.Height);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_DLSS_Pre_Exposure, pInDlssDEvalParams->InPreExposure == 0.0f ? 1.0f : pInDlssDEvalParams->InPreExposure);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_DLSS_Exposure_Scale, pInDlssDEvalParams->InExposureScale == 0.0f ? 1.0f : pInDlssDEvalParams->InExposureScale);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Indicator_Invert_X_Axis, pInDlssDEvalParams->InIndicatorInvertXAxis);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Indicator_Invert_Y_Axis, pInDlssDEvalParams->InIndicatorInvertYAxis);
|
||||
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Emissive, pInDlssDEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_EMISSIVE]);
|
||||
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_DiffuseAlbedo, pInDlssDEvalParams->pInDiffuseAlbedo);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_SpecularAlbedo, pInDlssDEvalParams->pInSpecularAlbedo);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_DiffuseAlbedo_Subrect_Base_X, pInDlssDEvalParams->InDiffuseAlbedoSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_DiffuseAlbedo_Subrect_Base_Y, pInDlssDEvalParams->InDiffuseAlbedoSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_SpecularAlbedo_Subrect_Base_X, pInDlssDEvalParams->InSpecularAlbedoSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_SpecularAlbedo_Subrect_Base_Y, pInDlssDEvalParams->InSpecularAlbedoSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Normals_Subrect_Base_X, pInDlssDEvalParams->InNormalsSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Normals_Subrect_Base_Y, pInDlssDEvalParams->InNormalsSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Roughness_Subrect_Base_X, pInDlssDEvalParams->InRoughnessSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Roughness_Subrect_Base_Y, pInDlssDEvalParams->InRoughnessSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Normals, pInDlssDEvalParams->pInNormals);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_GBuffer_Roughness, pInDlssDEvalParams->pInRoughness);
|
||||
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_Alpha, pInDlssDEvalParams->pInAlpha);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_OutputAlpha, pInDlssDEvalParams->pInOutputAlpha);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_ReflectedAlbedo, pInDlssDEvalParams->pInReflectedAlbedo);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeParticles, pInDlssDEvalParams->pInColorBeforeParticles);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterParticles, pInDlssDEvalParams->pInColorAfterParticles);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeTransparency, pInDlssDEvalParams->pInColorBeforeTransparency);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterTransparency, pInDlssDEvalParams->pInColorAfterTransparency);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeFog, pInDlssDEvalParams->pInColorBeforeFog);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterFog, pInDlssDEvalParams->pInColorAfterFog);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_ScreenSpaceSubsurfaceScatteringGuide, pInDlssDEvalParams->pInScreenSpaceSubsurfaceScatteringGuide);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeScreenSpaceSubsurfaceScattering, pInDlssDEvalParams->pInColorBeforeScreenSpaceSubsurfaceScattering);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterScreenSpaceSubsurfaceScattering, pInDlssDEvalParams->pInColorAfterScreenSpaceSubsurfaceScattering);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_ScreenSpaceRefractionGuide, pInDlssDEvalParams->pInScreenSpaceRefractionGuide);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeScreenSpaceRefraction, pInDlssDEvalParams->pInColorBeforeScreenSpaceRefraction);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterScreenSpaceRefraction, pInDlssDEvalParams->pInColorAfterScreenSpaceRefraction);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_DepthOfFieldGuide, pInDlssDEvalParams->pInDepthOfFieldGuide);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeDepthOfField, pInDlssDEvalParams->pInColorBeforeDepthOfField);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterDepthOfField, pInDlssDEvalParams->pInColorAfterDepthOfField);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_DiffuseHitDistance, pInDlssDEvalParams->pInDiffuseHitDistance);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_SpecularHitDistance, pInDlssDEvalParams->pInSpecularHitDistance);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_DiffuseRayDirection, pInDlssDEvalParams->pInDiffuseRayDirection);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_SpecularRayDirection, pInDlssDEvalParams->pInSpecularRayDirection);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_DiffuseRayDirectionHitDistance, pInDlssDEvalParams->pInDiffuseRayDirectionHitDistance);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_SpecularRayDirectionHitDistance, pInDlssDEvalParams->pInSpecularRayDirectionHitDistance);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_Alpha_Subrect_Base_X, pInDlssDEvalParams->InAlphaSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_Alpha_Subrect_Base_Y, pInDlssDEvalParams->InAlphaSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_OutputAlpha_Subrect_Base_X, pInDlssDEvalParams->InOutputAlphaSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_OutputAlpha_Subrect_Base_Y, pInDlssDEvalParams->InOutputAlphaSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ReflectedAlbedo_Subrect_Base_X, pInDlssDEvalParams->InReflectedAlbedoSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ReflectedAlbedo_Subrect_Base_Y, pInDlssDEvalParams->InReflectedAlbedoSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterParticles_Subrect_Base_X, pInDlssDEvalParams->InColorAfterParticlesSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterParticles_Subrect_Base_Y, pInDlssDEvalParams->InColorAfterParticlesSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeParticles_Subrect_Base_X, pInDlssDEvalParams->InColorBeforeParticlesSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeParticles_Subrect_Base_Y, pInDlssDEvalParams->InColorBeforeParticlesSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeTransparency_Subrect_Base_X, pInDlssDEvalParams->InColorBeforeTransparencySubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeTransparency_Subrect_Base_Y, pInDlssDEvalParams->InColorBeforeTransparencySubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterTransparency_Subrect_Base_X, pInDlssDEvalParams->InColorAfterTransparencySubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterTransparency_Subrect_Base_Y, pInDlssDEvalParams->InColorAfterTransparencySubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterFog_Subrect_Base_X, pInDlssDEvalParams->InColorAfterFogSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterFog_Subrect_Base_Y, pInDlssDEvalParams->InColorAfterFogSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeFog_Subrect_Base_X, pInDlssDEvalParams->InColorBeforeFogSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeFog_Subrect_Base_Y, pInDlssDEvalParams->InColorBeforeFogSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ScreenSpaceSubsurfaceScatteringGuide_Subrect_Base_X, pInDlssDEvalParams->InScreenSpaceSubsurfaceScatteringGuideSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ScreenSpaceSubsurfaceScatteringGuide_Subrect_Base_Y, pInDlssDEvalParams->InScreenSpaceSubsurfaceScatteringGuideSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeScreenSpaceSubsurfaceScattering_Subrect_Base_X, pInDlssDEvalParams->InColorBeforeScreenSpaceSubsurfaceScatteringSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeScreenSpaceSubsurfaceScattering_Subrect_Base_Y, pInDlssDEvalParams->InColorBeforeScreenSpaceSubsurfaceScatteringSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterScreenSpaceSubsurfaceScattering_Subrect_Base_X, pInDlssDEvalParams->InColorAfterScreenSpaceSubsurfaceScatteringSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterScreenSpaceSubsurfaceScattering_Subrect_Base_Y, pInDlssDEvalParams->InColorAfterScreenSpaceSubsurfaceScatteringSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ScreenSpaceRefractionGuide_Subrect_Base_X, pInDlssDEvalParams->InScreenSpaceRefractionGuideSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ScreenSpaceRefractionGuide_Subrect_Base_Y, pInDlssDEvalParams->InScreenSpaceRefractionGuideSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeScreenSpaceRefraction_Subrect_Base_X, pInDlssDEvalParams->InColorBeforeScreenSpaceRefractionSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeScreenSpaceRefraction_Subrect_Base_Y, pInDlssDEvalParams->InColorBeforeScreenSpaceRefractionSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterScreenSpaceRefraction_Subrect_Base_X, pInDlssDEvalParams->InColorAfterScreenSpaceRefractionSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterScreenSpaceRefraction_Subrect_Base_Y, pInDlssDEvalParams->InColorAfterScreenSpaceRefractionSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_DepthOfFieldGuide_Subrect_Base_X, pInDlssDEvalParams->InDepthOfFieldGuideSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_DepthOfFieldGuide_Subrect_Base_Y, pInDlssDEvalParams->InDepthOfFieldGuideSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeDepthOfField_Subrect_Base_X, pInDlssDEvalParams->InColorBeforeDepthOfFieldSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeDepthOfField_Subrect_Base_Y, pInDlssDEvalParams->InColorBeforeDepthOfFieldSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterDepthOfField_Subrect_Base_X, pInDlssDEvalParams->InColorAfterDepthOfFieldSubtectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterDepthOfField_Subrect_Base_Y, pInDlssDEvalParams->InColorAfterDepthOfFieldSubtectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_DiffuseHitDistance_Subrect_Base_X, pInDlssDEvalParams->InDiffuseHitDistanceSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_DiffuseHitDistance_Subrect_Base_Y, pInDlssDEvalParams->InDiffuseHitDistanceSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_SpecularHitDistance_Subrect_Base_X, pInDlssDEvalParams->InSpecularHitDistanceSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_SpecularHitDistance_Subrect_Base_Y, pInDlssDEvalParams->InSpecularHitDistanceSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_DiffuseRayDirection_Subrect_Base_X, pInDlssDEvalParams->InDiffuseRayDirectionSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_DiffuseRayDirection_Subrect_Base_Y, pInDlssDEvalParams->InDiffuseRayDirectionSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_SpecularRayDirection_Subrect_Base_X, pInDlssDEvalParams->InSpecularRayDirectionSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_SpecularRayDirection_Subrect_Base_Y, pInDlssDEvalParams->InSpecularRayDirectionSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_DiffuseRayDirectionHitDistance_Subrect_Base_X, pInDlssDEvalParams->InDiffuseRayDirectionHitDistanceSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_DiffuseRayDirectionHitDistance_Subrect_Base_Y, pInDlssDEvalParams->InDiffuseRayDirectionHitDistanceSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_SpecularRayDirectionHitDistance_Subrect_Base_X, pInDlssDEvalParams->InSpecularRayDirectionHitDistanceSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_SpecularRayDirectionHitDistance_Subrect_Base_Y, pInDlssDEvalParams->InSpecularRayDirectionHitDistanceSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSS_WORLD_TO_VIEW_MATRIX, pInDlssDEvalParams->pInWorldToViewMatrix);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSS_VIEW_TO_CLIP_MATRIX, pInDlssDEvalParams->pInViewToClipMatrix);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_DLSS_TransparencyLayer, pInDlssDEvalParams->pInTransparencyLayer);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_DLSS_TransparencyLayerOpacity, pInDlssDEvalParams->pInTransparencyLayerOpacity);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_DLSS_TransparencyLayerMvecs, pInDlssDEvalParams->pInTransparencyLayerMvecs);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_DLSS_DisocclusionMask, pInDlssDEvalParams->pInDisocclusionMask);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_Parameter_DLSSD_ResponsivityMask, pInDlssDEvalParams->pInResponsivityMask);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_TransparencyLayer_Subrect_Base_X, pInDlssDEvalParams->InTransparencyLayerSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_TransparencyLayer_Subrect_Base_Y, pInDlssDEvalParams->InTransparencyLayerSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_TransparencyLayerOpacity_Subrect_Base_X, pInDlssDEvalParams->InTransparencyLayerOpacitySubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_TransparencyLayerOpacity_Subrect_Base_Y, pInDlssDEvalParams->InTransparencyLayerOpacitySubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_TransparencyLayerMvecs_Subrect_Base_X, pInDlssDEvalParams->InTransparencyLayerMvecsSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_TransparencyLayerMvecs_Subrect_Base_Y, pInDlssDEvalParams->InTransparencyLayerMvecsSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_DisocclusionMask_Subrect_Base_X, pInDlssDEvalParams->InDisocclusionMaskSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_DisocclusionMask_Subrect_Base_Y, pInDlssDEvalParams->InDisocclusionMaskSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ResponsivityMask_Subrect_Base_X, pInDlssDEvalParams->InResponsivityMaskSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ResponsivityMask_Subrect_Base_Y, pInDlssDEvalParams->InResponsivityMaskSubrectBase.Y);
|
||||
|
||||
return NVSDK_NGX_D3D12_EvaluateFeature_C(pInCmdList, pInHandle, pInParams, NULL);
|
||||
}
|
||||
|
||||
#endif // NVSDK_NGX_HELPERS_DLSSD_H
|
||||
@@ -0,0 +1,379 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: LicenseRef-NvidiaProprietary
|
||||
*
|
||||
* NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
|
||||
* property and proprietary rights in and to this material, related
|
||||
* documentation and any modifications thereto. Any use, reproduction,
|
||||
* disclosure or distribution of this material and related documentation
|
||||
* without an express license agreement from NVIDIA CORPORATION or
|
||||
* its affiliates is strictly prohibited.
|
||||
*/
|
||||
|
||||
#ifndef NVSDK_NGX_HELPERS_DLSSD_VK_H
|
||||
#define NVSDK_NGX_HELPERS_DLSSD_VK_H
|
||||
#pragma once
|
||||
|
||||
#include "nvsdk_ngx_vk.h"
|
||||
#include "nvsdk_ngx_defs_dlssd.h"
|
||||
#include "nvsdk_ngx_params_dlssd.h"
|
||||
|
||||
typedef struct NVSDK_NGX_VK_DLSSD_Eval_Params
|
||||
{
|
||||
NVSDK_NGX_Resource_VK* pInDiffuseAlbedo;
|
||||
NVSDK_NGX_Resource_VK* pInSpecularAlbedo;
|
||||
NVSDK_NGX_Resource_VK* pInNormals;
|
||||
NVSDK_NGX_Resource_VK* pInRoughness;
|
||||
|
||||
NVSDK_NGX_Resource_VK* pInColor;
|
||||
NVSDK_NGX_Resource_VK* pInAlpha;
|
||||
NVSDK_NGX_Resource_VK* pInOutput;
|
||||
NVSDK_NGX_Resource_VK* pInOutputAlpha;
|
||||
NVSDK_NGX_Resource_VK * pInDepth;
|
||||
NVSDK_NGX_Resource_VK * pInMotionVectors;
|
||||
float InJitterOffsetX; /* Jitter offset must be in input/render pixel space */
|
||||
float InJitterOffsetY;
|
||||
NVSDK_NGX_Dimensions InRenderSubrectDimensions;
|
||||
/*** OPTIONAL - leave to 0/0.0f if unused ***/
|
||||
int InReset; /* Set to 1 when scene changes completely (new level etc) */
|
||||
float InMVScaleX; /* If MVs need custom scaling to convert to pixel space */
|
||||
float InMVScaleY;
|
||||
NVSDK_NGX_Resource_VK * pInTransparencyMask; /* Unused/Reserved for future use */
|
||||
NVSDK_NGX_Resource_VK * pInExposureTexture;
|
||||
NVSDK_NGX_Resource_VK * pInBiasCurrentColorMask;
|
||||
NVSDK_NGX_Coordinates InAlphaSubrectBase;
|
||||
NVSDK_NGX_Coordinates InOutputAlphaSubrectBase;
|
||||
NVSDK_NGX_Coordinates InDiffuseAlbedoSubrectBase;
|
||||
NVSDK_NGX_Coordinates InSpecularAlbedoSubrectBase;
|
||||
NVSDK_NGX_Coordinates InNormalsSubrectBase;
|
||||
NVSDK_NGX_Coordinates InRoughnessSubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorSubrectBase;
|
||||
NVSDK_NGX_Coordinates InDepthSubrectBase;
|
||||
NVSDK_NGX_Coordinates InMVSubrectBase;
|
||||
NVSDK_NGX_Coordinates InTranslucencySubrectBase;
|
||||
NVSDK_NGX_Coordinates InBiasCurrentColorSubrectBase;
|
||||
NVSDK_NGX_Coordinates InOutputSubrectBase;
|
||||
float InPreExposure;
|
||||
float InExposureScale;
|
||||
int InIndicatorInvertXAxis;
|
||||
int InIndicatorInvertYAxis;
|
||||
/*** OPTIONAL - only for research purposes ***/
|
||||
|
||||
NVSDK_NGX_Resource_VK* pInReflectedAlbedo;
|
||||
NVSDK_NGX_Resource_VK* pInColorBeforeParticles;
|
||||
NVSDK_NGX_Resource_VK* pInColorAfterParticles;
|
||||
NVSDK_NGX_Resource_VK* pInColorBeforeTransparency;
|
||||
NVSDK_NGX_Resource_VK* pInColorAfterTransparency;
|
||||
NVSDK_NGX_Resource_VK* pInColorBeforeFog;
|
||||
NVSDK_NGX_Resource_VK* pInColorAfterFog;
|
||||
NVSDK_NGX_Resource_VK* pInScreenSpaceSubsurfaceScatteringGuide;
|
||||
NVSDK_NGX_Resource_VK* pInColorBeforeScreenSpaceSubsurfaceScattering;
|
||||
NVSDK_NGX_Resource_VK* pInColorAfterScreenSpaceSubsurfaceScattering;
|
||||
NVSDK_NGX_Resource_VK* pInScreenSpaceRefractionGuide;
|
||||
NVSDK_NGX_Resource_VK* pInColorBeforeScreenSpaceRefraction;
|
||||
NVSDK_NGX_Resource_VK* pInColorAfterScreenSpaceRefraction;
|
||||
NVSDK_NGX_Resource_VK* pInDepthOfFieldGuide;
|
||||
NVSDK_NGX_Resource_VK* pInColorBeforeDepthOfField;
|
||||
NVSDK_NGX_Resource_VK* pInColorAfterDepthOfField;
|
||||
NVSDK_NGX_Resource_VK* pInDiffuseHitDistance;
|
||||
NVSDK_NGX_Resource_VK* pInSpecularHitDistance;
|
||||
NVSDK_NGX_Resource_VK* pInDiffuseRayDirection;
|
||||
NVSDK_NGX_Resource_VK* pInSpecularRayDirection;
|
||||
NVSDK_NGX_Resource_VK* pInDiffuseRayDirectionHitDistance;
|
||||
NVSDK_NGX_Resource_VK* pInSpecularRayDirectionHitDistance;
|
||||
NVSDK_NGX_Coordinates InReflectedAlbedoSubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorBeforeParticlesSubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorAfterParticlesSubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorBeforeTransparencySubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorAfterTransparencySubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorBeforeFogSubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorAfterFogSubrectBase;
|
||||
NVSDK_NGX_Coordinates InScreenSpaceSubsurfaceScatteringGuideSubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorBeforeScreenSpaceSubsurfaceScatteringSubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorAfterScreenSpaceSubsurfaceScatteringSubrectBase;
|
||||
NVSDK_NGX_Coordinates InScreenSpaceRefractionGuideSubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorBeforeScreenSpaceRefractionSubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorAfterScreenSpaceRefractionSubrectBase;
|
||||
NVSDK_NGX_Coordinates InDepthOfFieldGuideSubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorBeforeDepthOfFieldSubrectBase;
|
||||
NVSDK_NGX_Coordinates InColorAfterDepthOfFieldSubrectBase;
|
||||
NVSDK_NGX_Coordinates InDiffuseHitDistanceSubrectBase;
|
||||
NVSDK_NGX_Coordinates InSpecularHitDistanceSubrectBase;
|
||||
NVSDK_NGX_Coordinates InDiffuseRayDirectionSubrectBase;
|
||||
NVSDK_NGX_Coordinates InSpecularRayDirectionSubrectBase;
|
||||
NVSDK_NGX_Coordinates InDiffuseRayDirectionHitDistanceSubrectBase;
|
||||
NVSDK_NGX_Coordinates InSpecularRayDirectionHitDistanceSubrectBase;
|
||||
float* pInWorldToViewMatrix;
|
||||
float* pInViewToClipMatrix;
|
||||
|
||||
NVSDK_NGX_VK_GBuffer GBufferSurface;
|
||||
NVSDK_NGX_ToneMapperType InToneMapperType;
|
||||
NVSDK_NGX_Resource_VK * pInMotionVectors3D;
|
||||
NVSDK_NGX_Resource_VK * pInIsParticleMask; /* to identify which pixels contains particles, essentially that are not drawn as part of base pass */
|
||||
NVSDK_NGX_Resource_VK * pInAnimatedTextureMask; /* a binary mask covering pixels occupied by animated textures */
|
||||
NVSDK_NGX_Resource_VK * pInDepthHighRes;
|
||||
NVSDK_NGX_Resource_VK * pInPositionViewSpace;
|
||||
float InFrameTimeDeltaInMsec; /* helps in determining the amount to denoise or anti-alias based on the speed of the object from motion vector magnitudes and fps as determined by this delta */
|
||||
NVSDK_NGX_Resource_VK * pInRayTracingHitDistance; /* for each effect - approximation to the amount of noise in a ray-traced color */
|
||||
NVSDK_NGX_Resource_VK * pInMotionVectorsReflections; /* motion vectors of reflected objects like for mirrored surfaces */
|
||||
NVSDK_NGX_Resource_VK* pInTransparencyLayer; /* optional input res particle layer */
|
||||
NVSDK_NGX_Coordinates InTransparencyLayerSubrectBase;
|
||||
NVSDK_NGX_Resource_VK* pInTransparencyLayerOpacity; /* optional input res particle opacity layer */
|
||||
NVSDK_NGX_Coordinates InTransparencyLayerOpacitySubrectBase;
|
||||
NVSDK_NGX_Resource_VK* pInTransparencyLayerMvecs; /* optional input res transparency layer mvecs */
|
||||
NVSDK_NGX_Coordinates InTransparencyLayerMvecsSubrectBase;
|
||||
NVSDK_NGX_Resource_VK* pInDisocclusionMask; /* optional input res disocclusion mask */
|
||||
NVSDK_NGX_Coordinates InDisocclusionMaskSubrectBase;
|
||||
NVSDK_NGX_Resource_VK* pInResponsivityMask; /* optional input res responsivity mask; one channel, R16F or R8 SNORM */
|
||||
NVSDK_NGX_Coordinates InResponsivityMaskSubrectBase;
|
||||
} NVSDK_NGX_VK_DLSSD_Eval_Params;
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_VULKAN_CREATE_DLSSD_EXT1(
|
||||
VkDevice InDevice,
|
||||
VkCommandBuffer InCmdList,
|
||||
unsigned int InCreationNodeMask,
|
||||
unsigned int InVisibilityNodeMask,
|
||||
NVSDK_NGX_Handle **ppOutHandle,
|
||||
NVSDK_NGX_Parameter *pInParams,
|
||||
NVSDK_NGX_DLSSD_Create_Params *pInDlssDCreateParams)
|
||||
{
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_CreationNodeMask, InCreationNodeMask);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_VisibilityNodeMask, InVisibilityNodeMask);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Width, pInDlssDCreateParams->InWidth);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Height, pInDlssDCreateParams->InHeight);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutWidth, pInDlssDCreateParams->InTargetWidth);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutHeight, pInDlssDCreateParams->InTargetHeight);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_PerfQualityValue, pInDlssDCreateParams->InPerfQualityValue);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Feature_Create_Flags, pInDlssDCreateParams->InFeatureCreateFlags);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Enable_Output_Subrects, pInDlssDCreateParams->InEnableOutputSubrects ? 1 : 0);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Denoise_Mode, NVSDK_NGX_DLSS_Denoise_Mode_DLUnified);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Roughness_Mode, pInDlssDCreateParams->InRoughnessMode);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Use_HW_Depth, pInDlssDCreateParams->InUseHWDepth);
|
||||
|
||||
if (InDevice) return NVSDK_NGX_VULKAN_CreateFeature1(InDevice, InCmdList, NVSDK_NGX_Feature_RayReconstruction, pInParams, ppOutHandle);
|
||||
else return NVSDK_NGX_VULKAN_CreateFeature(InCmdList, NVSDK_NGX_Feature_RayReconstruction, pInParams, ppOutHandle);
|
||||
}
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_VULKAN_EVALUATE_DLSSD_EXT(
|
||||
VkCommandBuffer InCmdList,
|
||||
NVSDK_NGX_Handle *pInHandle,
|
||||
NVSDK_NGX_Parameter *pInParams,
|
||||
NVSDK_NGX_VK_DLSSD_Eval_Params *pInDlssDEvalParams)
|
||||
{
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInColor);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInAlpha);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInMotionVectors);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInOutput);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInOutputAlpha);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInDepth);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInDiffuseAlbedo);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInSpecularAlbedo);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInTransparencyMask);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInExposureTexture);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInBiasCurrentColorMask);
|
||||
for (size_t i = 0; i <= 15; i++)
|
||||
{
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->GBufferSurface.pInAttrib[i]);
|
||||
}
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInMotionVectors3D);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInIsParticleMask);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInAnimatedTextureMask);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInDepthHighRes);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInPositionViewSpace);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInRayTracingHitDistance);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInMotionVectorsReflections);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInReflectedAlbedo);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInColorBeforeParticles);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInColorAfterParticles);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInColorBeforeTransparency);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInColorAfterTransparency);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInColorBeforeFog);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInColorAfterFog);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInScreenSpaceSubsurfaceScatteringGuide);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInColorBeforeScreenSpaceSubsurfaceScattering);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInColorAfterScreenSpaceSubsurfaceScattering);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInScreenSpaceRefractionGuide);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInColorBeforeScreenSpaceRefraction);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInColorAfterScreenSpaceRefraction);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInDepthOfFieldGuide);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInColorBeforeDepthOfField);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInColorAfterDepthOfField);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInDiffuseHitDistance);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInSpecularHitDistance);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInDiffuseRayDirection);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInSpecularRayDirection);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInDiffuseRayDirectionHitDistance);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInSpecularRayDirectionHitDistance);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInTransparencyLayer);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInTransparencyLayerOpacity);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInTransparencyLayerMvecs);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInDisocclusionMask);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssDEvalParams->pInResponsivityMask);
|
||||
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_Color, pInDlssDEvalParams->pInColor);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_Output, pInDlssDEvalParams->pInOutput);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_Depth, pInDlssDEvalParams->pInDepth);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_MotionVectors, pInDlssDEvalParams->pInMotionVectors);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Jitter_Offset_X, pInDlssDEvalParams->InJitterOffsetX);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Jitter_Offset_Y, pInDlssDEvalParams->InJitterOffsetY);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_Reset, pInDlssDEvalParams->InReset);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_MV_Scale_X, pInDlssDEvalParams->InMVScaleX == 0.0f ? 1.0f : pInDlssDEvalParams->InMVScaleX);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_MV_Scale_Y, pInDlssDEvalParams->InMVScaleY == 0.0f ? 1.0f : pInDlssDEvalParams->InMVScaleY);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_TransparencyMask, pInDlssDEvalParams->pInTransparencyMask);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_ExposureTexture, pInDlssDEvalParams->pInExposureTexture);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_Mask, pInDlssDEvalParams->pInBiasCurrentColorMask);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Albedo, pInDlssDEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_ALBEDO]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Roughness, pInDlssDEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_ROUGHNESS]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Metallic, pInDlssDEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_METALLIC]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Specular, pInDlssDEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_SPECULAR]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Subsurface, pInDlssDEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_SUBSURFACE]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Normals, pInDlssDEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_NORMALS]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_ShadingModelId, pInDlssDEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_SHADINGMODELID]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_MaterialId, pInDlssDEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_MATERIALID]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_8, pInDlssDEvalParams->GBufferSurface.pInAttrib[8]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_9, pInDlssDEvalParams->GBufferSurface.pInAttrib[9]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_SpecularMvec, pInDlssDEvalParams->pInMotionVectorsReflections);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_11, pInDlssDEvalParams->GBufferSurface.pInAttrib[11]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_12, pInDlssDEvalParams->GBufferSurface.pInAttrib[12]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_13, pInDlssDEvalParams->GBufferSurface.pInAttrib[13]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_14, pInDlssDEvalParams->GBufferSurface.pInAttrib[14]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_15, pInDlssDEvalParams->GBufferSurface.pInAttrib[15]);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_TonemapperType, pInDlssDEvalParams->InToneMapperType);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_MotionVectors3D, pInDlssDEvalParams->pInMotionVectors3D);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_IsParticleMask, pInDlssDEvalParams->pInIsParticleMask);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_AnimatedTextureMask, pInDlssDEvalParams->pInAnimatedTextureMask);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DepthHighRes, pInDlssDEvalParams->pInDepthHighRes);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_Position_ViewSpace, pInDlssDEvalParams->pInPositionViewSpace);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_FrameTimeDeltaInMsec, pInDlssDEvalParams->InFrameTimeDeltaInMsec);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_RayTracingHitDistance, pInDlssDEvalParams->pInRayTracingHitDistance);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Color_Subrect_Base_X, pInDlssDEvalParams->InColorSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Color_Subrect_Base_Y, pInDlssDEvalParams->InColorSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Depth_Subrect_Base_X, pInDlssDEvalParams->InDepthSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Depth_Subrect_Base_Y, pInDlssDEvalParams->InDepthSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_MV_SubrectBase_X, pInDlssDEvalParams->InMVSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_MV_SubrectBase_Y, pInDlssDEvalParams->InMVSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Translucency_SubrectBase_X, pInDlssDEvalParams->InTranslucencySubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Translucency_SubrectBase_Y, pInDlssDEvalParams->InTranslucencySubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_SubrectBase_X, pInDlssDEvalParams->InBiasCurrentColorSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_SubrectBase_Y, pInDlssDEvalParams->InBiasCurrentColorSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Output_Subrect_Base_X, pInDlssDEvalParams->InOutputSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Output_Subrect_Base_Y, pInDlssDEvalParams->InOutputSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Render_Subrect_Dimensions_Width , pInDlssDEvalParams->InRenderSubrectDimensions.Width);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Render_Subrect_Dimensions_Height, pInDlssDEvalParams->InRenderSubrectDimensions.Height);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_DLSS_Pre_Exposure, pInDlssDEvalParams->InPreExposure == 0.0f ? 1.0f : pInDlssDEvalParams->InPreExposure);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_DLSS_Exposure_Scale, pInDlssDEvalParams->InExposureScale == 0.0f ? 1.0f : pInDlssDEvalParams->InExposureScale);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Indicator_Invert_X_Axis, pInDlssDEvalParams->InIndicatorInvertXAxis);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Indicator_Invert_Y_Axis, pInDlssDEvalParams->InIndicatorInvertYAxis);
|
||||
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Emissive, pInDlssDEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_EMISSIVE]);
|
||||
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DiffuseAlbedo, pInDlssDEvalParams->pInDiffuseAlbedo);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_SpecularAlbedo, pInDlssDEvalParams->pInSpecularAlbedo);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Normals, pInDlssDEvalParams->pInNormals);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Roughness, pInDlssDEvalParams->pInRoughness);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_DiffuseAlbedo_Subrect_Base_X, pInDlssDEvalParams->InDiffuseAlbedoSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_DiffuseAlbedo_Subrect_Base_Y, pInDlssDEvalParams->InDiffuseAlbedoSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_SpecularAlbedo_Subrect_Base_X, pInDlssDEvalParams->InSpecularAlbedoSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_SpecularAlbedo_Subrect_Base_Y, pInDlssDEvalParams->InSpecularAlbedoSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Normals_Subrect_Base_X, pInDlssDEvalParams->InNormalsSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Normals_Subrect_Base_Y, pInDlssDEvalParams->InNormalsSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Roughness_Subrect_Base_X, pInDlssDEvalParams->InRoughnessSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Roughness_Subrect_Base_Y, pInDlssDEvalParams->InRoughnessSubrectBase.Y);
|
||||
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSD_Alpha, pInDlssDEvalParams->pInAlpha);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSD_OutputAlpha, pInDlssDEvalParams->pInOutputAlpha);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSD_ReflectedAlbedo, pInDlssDEvalParams->pInReflectedAlbedo);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeParticles, pInDlssDEvalParams->pInColorBeforeParticles);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterParticles, pInDlssDEvalParams->pInColorAfterParticles);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeTransparency, pInDlssDEvalParams->pInColorBeforeTransparency);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterTransparency, pInDlssDEvalParams->pInColorAfterTransparency);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeFog, pInDlssDEvalParams->pInColorBeforeFog);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterFog, pInDlssDEvalParams->pInColorAfterFog);
|
||||
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSD_ScreenSpaceSubsurfaceScatteringGuide, pInDlssDEvalParams->pInScreenSpaceSubsurfaceScatteringGuide);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeScreenSpaceSubsurfaceScattering, pInDlssDEvalParams->pInColorBeforeScreenSpaceSubsurfaceScattering);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterScreenSpaceSubsurfaceScattering, pInDlssDEvalParams->pInColorAfterScreenSpaceSubsurfaceScattering);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSD_ScreenSpaceRefractionGuide, pInDlssDEvalParams->pInScreenSpaceRefractionGuide);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeScreenSpaceRefraction, pInDlssDEvalParams->pInColorBeforeScreenSpaceRefraction);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterScreenSpaceRefraction, pInDlssDEvalParams->pInColorAfterScreenSpaceRefraction);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSD_DepthOfFieldGuide, pInDlssDEvalParams->pInDepthOfFieldGuide);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeDepthOfField, pInDlssDEvalParams->pInColorBeforeDepthOfField);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterDepthOfField, pInDlssDEvalParams->pInColorAfterDepthOfField);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSD_DiffuseHitDistance, pInDlssDEvalParams->pInDiffuseHitDistance);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSD_SpecularHitDistance, pInDlssDEvalParams->pInSpecularHitDistance);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSD_DiffuseRayDirection, pInDlssDEvalParams->pInDiffuseRayDirection);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSD_SpecularRayDirection, pInDlssDEvalParams->pInSpecularRayDirection);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSD_DiffuseRayDirectionHitDistance, pInDlssDEvalParams->pInDiffuseRayDirectionHitDistance);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSD_SpecularRayDirectionHitDistance, pInDlssDEvalParams->pInSpecularRayDirectionHitDistance);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_Alpha_Subrect_Base_X, pInDlssDEvalParams->InAlphaSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_Alpha_Subrect_Base_Y, pInDlssDEvalParams->InAlphaSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_OutputAlpha_Subrect_Base_X, pInDlssDEvalParams->InOutputAlphaSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_OutputAlpha_Subrect_Base_Y, pInDlssDEvalParams->InOutputAlphaSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ReflectedAlbedo_Subrect_Base_X, pInDlssDEvalParams->InReflectedAlbedoSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ReflectedAlbedo_Subrect_Base_Y, pInDlssDEvalParams->InReflectedAlbedoSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeParticles_Subrect_Base_X, pInDlssDEvalParams->InColorBeforeParticlesSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeParticles_Subrect_Base_Y, pInDlssDEvalParams->InColorBeforeParticlesSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterParticles_Subrect_Base_X, pInDlssDEvalParams->InColorAfterParticlesSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterParticles_Subrect_Base_Y, pInDlssDEvalParams->InColorAfterParticlesSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeTransparency_Subrect_Base_X, pInDlssDEvalParams->InColorBeforeTransparencySubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeTransparency_Subrect_Base_Y, pInDlssDEvalParams->InColorBeforeTransparencySubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterTransparency_Subrect_Base_X, pInDlssDEvalParams->InColorAfterTransparencySubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterTransparency_Subrect_Base_Y, pInDlssDEvalParams->InColorAfterTransparencySubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeFog_Subrect_Base_X, pInDlssDEvalParams->InColorBeforeFogSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeFog_Subrect_Base_Y, pInDlssDEvalParams->InColorBeforeFogSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterFog_Subrect_Base_X, pInDlssDEvalParams->InColorAfterFogSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterFog_Subrect_Base_Y, pInDlssDEvalParams->InColorAfterFogSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ScreenSpaceSubsurfaceScatteringGuide_Subrect_Base_X, pInDlssDEvalParams->InScreenSpaceSubsurfaceScatteringGuideSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ScreenSpaceSubsurfaceScatteringGuide_Subrect_Base_Y, pInDlssDEvalParams->InScreenSpaceSubsurfaceScatteringGuideSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeScreenSpaceSubsurfaceScattering_Subrect_Base_X, pInDlssDEvalParams->InColorBeforeScreenSpaceSubsurfaceScatteringSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeScreenSpaceSubsurfaceScattering_Subrect_Base_Y, pInDlssDEvalParams->InColorBeforeScreenSpaceSubsurfaceScatteringSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterScreenSpaceSubsurfaceScattering_Subrect_Base_X, pInDlssDEvalParams->InColorAfterScreenSpaceSubsurfaceScatteringSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterScreenSpaceSubsurfaceScattering_Subrect_Base_Y, pInDlssDEvalParams->InColorAfterScreenSpaceSubsurfaceScatteringSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ScreenSpaceRefractionGuide_Subrect_Base_X, pInDlssDEvalParams->InScreenSpaceRefractionGuideSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ScreenSpaceRefractionGuide_Subrect_Base_Y, pInDlssDEvalParams->InScreenSpaceRefractionGuideSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeScreenSpaceRefraction_Subrect_Base_X, pInDlssDEvalParams->InColorBeforeScreenSpaceRefractionSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeScreenSpaceRefraction_Subrect_Base_Y, pInDlssDEvalParams->InColorBeforeScreenSpaceRefractionSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterScreenSpaceRefraction_Subrect_Base_X, pInDlssDEvalParams->InColorAfterScreenSpaceRefractionSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterScreenSpaceRefraction_Subrect_Base_Y, pInDlssDEvalParams->InColorAfterScreenSpaceRefractionSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_DepthOfFieldGuide_Subrect_Base_X, pInDlssDEvalParams->InDepthOfFieldGuideSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_DepthOfFieldGuide_Subrect_Base_Y, pInDlssDEvalParams->InDepthOfFieldGuideSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeDepthOfField_Subrect_Base_X, pInDlssDEvalParams->InColorBeforeDepthOfFieldSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorBeforeDepthOfField_Subrect_Base_Y, pInDlssDEvalParams->InColorBeforeDepthOfFieldSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterDepthOfField_Subrect_Base_X, pInDlssDEvalParams->InColorAfterDepthOfFieldSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ColorAfterDepthOfField_Subrect_Base_Y, pInDlssDEvalParams->InColorAfterDepthOfFieldSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_DiffuseHitDistance_Subrect_Base_X, pInDlssDEvalParams->InDiffuseHitDistanceSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_DiffuseHitDistance_Subrect_Base_Y, pInDlssDEvalParams->InDiffuseHitDistanceSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_SpecularHitDistance_Subrect_Base_X, pInDlssDEvalParams->InSpecularHitDistanceSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_SpecularHitDistance_Subrect_Base_Y, pInDlssDEvalParams->InSpecularHitDistanceSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_DiffuseRayDirection_Subrect_Base_X, pInDlssDEvalParams->InDiffuseRayDirectionSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_DiffuseRayDirection_Subrect_Base_Y, pInDlssDEvalParams->InDiffuseRayDirectionSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_SpecularRayDirection_Subrect_Base_X, pInDlssDEvalParams->InSpecularRayDirectionSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_SpecularRayDirection_Subrect_Base_Y, pInDlssDEvalParams->InSpecularRayDirectionSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_DiffuseRayDirectionHitDistance_Subrect_Base_X, pInDlssDEvalParams->InDiffuseRayDirectionHitDistanceSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_DiffuseRayDirectionHitDistance_Subrect_Base_Y, pInDlssDEvalParams->InDiffuseRayDirectionHitDistanceSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_SpecularRayDirectionHitDistance_Subrect_Base_X, pInDlssDEvalParams->InSpecularRayDirectionHitDistanceSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_SpecularRayDirectionHitDistance_Subrect_Base_Y, pInDlssDEvalParams->InSpecularRayDirectionHitDistanceSubrectBase.Y);
|
||||
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSS_WORLD_TO_VIEW_MATRIX, pInDlssDEvalParams->pInWorldToViewMatrix);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSS_VIEW_TO_CLIP_MATRIX, pInDlssDEvalParams->pInViewToClipMatrix);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSS_TransparencyLayer, pInDlssDEvalParams->pInTransparencyLayer);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSS_TransparencyLayerOpacity, pInDlssDEvalParams->pInTransparencyLayerOpacity);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSS_TransparencyLayerMvecs, pInDlssDEvalParams->pInTransparencyLayerMvecs);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSS_DisocclusionMask, pInDlssDEvalParams->pInDisocclusionMask);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSSD_ResponsivityMask, pInDlssDEvalParams->pInResponsivityMask);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_TransparencyLayer_Subrect_Base_X, pInDlssDEvalParams->InTransparencyLayerSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_TransparencyLayer_Subrect_Base_Y, pInDlssDEvalParams->InTransparencyLayerSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_TransparencyLayerOpacity_Subrect_Base_X, pInDlssDEvalParams->InTransparencyLayerOpacitySubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_TransparencyLayerOpacity_Subrect_Base_Y, pInDlssDEvalParams->InTransparencyLayerOpacitySubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_TransparencyLayerMvecs_Subrect_Base_X, pInDlssDEvalParams->InTransparencyLayerMvecsSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_TransparencyLayerMvecs_Subrect_Base_Y, pInDlssDEvalParams->InTransparencyLayerMvecsSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_DisocclusionMask_Subrect_Base_X, pInDlssDEvalParams->InDisocclusionMaskSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_DisocclusionMask_Subrect_Base_Y, pInDlssDEvalParams->InDisocclusionMaskSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ResponsivityMask_Subrect_Base_X, pInDlssDEvalParams->InResponsivityMaskSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSSD_ResponsivityMask_Subrect_Base_Y, pInDlssDEvalParams->InResponsivityMaskSubrectBase.Y);
|
||||
|
||||
|
||||
return NVSDK_NGX_VULKAN_EvaluateFeature_C(InCmdList, pInHandle, pInParams, NULL);
|
||||
}
|
||||
|
||||
#endif // NVSDK_NGX_HELPERS_DLSSD_VK_H
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: LicenseRef-NvidiaProprietary
|
||||
*
|
||||
* NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
|
||||
* property and proprietary rights in and to this material, related
|
||||
* documentation and any modifications thereto. Any use, reproduction,
|
||||
* disclosure or distribution of this material and related documentation
|
||||
* without an express license agreement from NVIDIA CORPORATION or
|
||||
* its affiliates is strictly prohibited.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#pragma message("nvsdk_ngx_helpers_dlssg.h is deprecated; #include \"nvsdk_ngx_helpers_dlssg_d3d.h\" instead")
|
||||
|
||||
#include "nvsdk_ngx_helpers_dlssg_d3d.h"
|
||||
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2025 NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* NVIDIA Corporation and its licensors retain all intellectual property and proprietary
|
||||
* rights in and to this software, related documentation and any modifications thereto.
|
||||
* Any use, reproduction, disclosure or distribution of this software and related
|
||||
* documentation without an express license agreement from NVIDIA Corporation is strictly
|
||||
* prohibited.
|
||||
*
|
||||
* TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED *AS IS*
|
||||
* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS OR IMPLIED,
|
||||
* INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT
|
||||
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF
|
||||
* BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR
|
||||
* INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NVSDK_NGX_HELPERS_DLSSG_H
|
||||
#define NVSDK_NGX_HELPERS_DLSSG_H
|
||||
|
||||
#include <stdint.h> // for uint64_t
|
||||
|
||||
#include "nvsdk_ngx.h" // DX11/12 here
|
||||
#include "nvsdk_ngx_defs_dlssg.h"
|
||||
#include "nvsdk_ngx_params_dlssg.h"
|
||||
|
||||
typedef struct NVSDK_NGX_D3D12_DLSSG_Eval_Params
|
||||
{
|
||||
ID3D12Resource* pBackbuffer;
|
||||
ID3D12Resource* pDepth;
|
||||
ID3D12Resource* pMVecs;
|
||||
ID3D12Resource* pHudless; // Optional
|
||||
ID3D12Resource* pUI; // Optional
|
||||
ID3D12Resource* pUIAlpha; // Optional
|
||||
ID3D12Resource* pBidirectionalDistortionField; // Optional
|
||||
ID3D12Resource* pOutputInterpFrame;
|
||||
ID3D12Resource* pOutputRealFrame; // Optional. In some cases, the feature may modify this frame (e.g. debugging)
|
||||
ID3D12Resource* pOutputDisableInterpolation; // Optional
|
||||
} NVSDK_NGX_D3D12_DLSSG_Eval_Params;
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_D3D12_CREATE_DLSSG(
|
||||
ID3D12GraphicsCommandList* pInCmdList,
|
||||
unsigned int InCreationNodeMask,
|
||||
unsigned int InVisibilityNodeMask,
|
||||
NVSDK_NGX_Handle** ppOutHandle,
|
||||
NVSDK_NGX_Parameter* pInParams,
|
||||
NVSDK_NGX_DLSSG_Create_Params* pInDlssgCreateParams)
|
||||
{
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_CreationNodeMask, InCreationNodeMask);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_VisibilityNodeMask, InVisibilityNodeMask);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Width, pInDlssgCreateParams->Width);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Height, pInDlssgCreateParams->Height);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_BackbufferFormat, pInDlssgCreateParams->NativeBackbufferFormat);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_InternalWidth, pInDlssgCreateParams->RenderWidth);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_InternalHeight, pInDlssgCreateParams->RenderHeight);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_DynamicResolution, pInDlssgCreateParams->DynamicResolutionScaling);
|
||||
|
||||
return NVSDK_NGX_D3D12_CreateFeature(pInCmdList, NVSDK_NGX_Feature_FrameGeneration, pInParams, ppOutHandle);
|
||||
}
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_D3D12_EVALUATE_DLSSG(
|
||||
ID3D12GraphicsCommandList* pInCmdList,
|
||||
NVSDK_NGX_Handle* pInHandle,
|
||||
NVSDK_NGX_Parameter* pInParams,
|
||||
NVSDK_NGX_D3D12_DLSSG_Eval_Params* pInDlssgEvalParams,
|
||||
NVSDK_NGX_DLSSG_Opt_Eval_Params* pInDlssgOptEvalParams)
|
||||
{
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_DLSSG_Parameter_Backbuffer, pInDlssgEvalParams->pBackbuffer);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_DLSSG_Parameter_MVecs, pInDlssgEvalParams->pMVecs);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_DLSSG_Parameter_Depth, pInDlssgEvalParams->pDepth);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_DLSSG_Parameter_HUDLess, pInDlssgEvalParams->pHudless);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_DLSSG_Parameter_UI, pInDlssgEvalParams->pUI);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_DLSSG_Parameter_UIAlpha, pInDlssgEvalParams->pUIAlpha);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_DLSSG_Parameter_BidirectionalDistortionField, pInDlssgEvalParams->pBidirectionalDistortionField);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_DLSSG_Parameter_OutputInterpolated, pInDlssgEvalParams->pOutputInterpFrame);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_DLSSG_Parameter_OutputReal, pInDlssgEvalParams->pOutputRealFrame);
|
||||
NVSDK_NGX_Parameter_SetD3d12Resource(pInParams, NVSDK_NGX_DLSSG_Parameter_OutputDisableInterpolation, pInDlssgEvalParams->pOutputDisableInterpolation);
|
||||
|
||||
if (pInDlssgOptEvalParams)
|
||||
{
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_MultiFrameCount, pInDlssgOptEvalParams->multiFrameCount);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_MultiFrameIndex, pInDlssgOptEvalParams->multiFrameIndex);
|
||||
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraViewToClip, pInDlssgOptEvalParams->cameraViewToClip);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_DLSSG_Parameter_ClipToCameraView, pInDlssgOptEvalParams->clipToCameraView);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_DLSSG_Parameter_ClipToLensClip, pInDlssgOptEvalParams->clipToLensClip);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_DLSSG_Parameter_ClipToPrevClip, pInDlssgOptEvalParams->clipToPrevClip);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_DLSSG_Parameter_PrevClipToClip, pInDlssgOptEvalParams->prevClipToClip);
|
||||
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_JitterOffsetX, pInDlssgOptEvalParams->jitterOffset[0]);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_JitterOffsetY, pInDlssgOptEvalParams->jitterOffset[1]);
|
||||
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_MvecScaleX, pInDlssgOptEvalParams->mvecScale[0]);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_MvecScaleY, pInDlssgOptEvalParams->mvecScale[1]);
|
||||
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraPinholeOffsetX, pInDlssgOptEvalParams->cameraPinholeOffset[0]);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraPinholeOffsetY, pInDlssgOptEvalParams->cameraPinholeOffset[1]);
|
||||
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraPosX, pInDlssgOptEvalParams->cameraPos[0]);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraPosY, pInDlssgOptEvalParams->cameraPos[1]);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraPosZ, pInDlssgOptEvalParams->cameraPos[2]);
|
||||
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraUpX, pInDlssgOptEvalParams->cameraUp[0]);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraUpY, pInDlssgOptEvalParams->cameraUp[1]);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraUpZ, pInDlssgOptEvalParams->cameraUp[2]);
|
||||
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraRightX, pInDlssgOptEvalParams->cameraRight[0]);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraRightY, pInDlssgOptEvalParams->cameraRight[1]);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraRightZ, pInDlssgOptEvalParams->cameraRight[2]);
|
||||
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraFwdX, pInDlssgOptEvalParams->cameraFwd[0]);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraFwdY, pInDlssgOptEvalParams->cameraFwd[1]);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraFwdZ, pInDlssgOptEvalParams->cameraFwd[2]);
|
||||
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraNear, pInDlssgOptEvalParams->cameraNear);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraFar, pInDlssgOptEvalParams->cameraFar);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraFOV, pInDlssgOptEvalParams->cameraFOV);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraAspectRatio, pInDlssgOptEvalParams->cameraAspectRatio);
|
||||
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_ColorBuffersHDR, pInDlssgOptEvalParams->colorBuffersHDR);
|
||||
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_DepthInverted, pInDlssgOptEvalParams->depthInverted);
|
||||
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraMotionIncluded, pInDlssgOptEvalParams->cameraMotionIncluded);
|
||||
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_Reset, pInDlssgOptEvalParams->reset);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_AutomodeOverrideReset, pInDlssgOptEvalParams->automodeOverrideReset);
|
||||
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_NotRenderingGameFrames, pInDlssgOptEvalParams->notRenderingGameFrames);
|
||||
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_OrthoProjection, pInDlssgOptEvalParams->orthoProjection);
|
||||
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_MvecInvalidValue, pInDlssgOptEvalParams->motionVectorsInvalidValue);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_MvecDilated, pInDlssgOptEvalParams->motionVectorsDilated);
|
||||
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_MenuDetectionEnabled, pInDlssgOptEvalParams->menuDetectionEnabled);
|
||||
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_MVecsSubrectBaseX, pInDlssgOptEvalParams->mvecsSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_MVecsSubrectBaseY, pInDlssgOptEvalParams->mvecsSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_MVecsSubrectWidth, pInDlssgOptEvalParams->mvecsSubrectSize.Width);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_MVecsSubrectHeight, pInDlssgOptEvalParams->mvecsSubrectSize.Height);
|
||||
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_DepthSubrectBaseX, pInDlssgOptEvalParams->depthSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_DepthSubrectBaseY, pInDlssgOptEvalParams->depthSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_DepthSubrectWidth, pInDlssgOptEvalParams->depthSubrectSize.Width);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_DepthSubrectHeight, pInDlssgOptEvalParams->depthSubrectSize.Height);
|
||||
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_HUDLessSubrectBaseX, pInDlssgOptEvalParams->hudLessSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_HUDLessSubrectBaseY, pInDlssgOptEvalParams->hudLessSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_HUDLessSubrectWidth, pInDlssgOptEvalParams->hudLessSubrectSize.Width);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_HUDLessSubrectHeight, pInDlssgOptEvalParams->hudLessSubrectSize.Height);
|
||||
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_UISubrectBaseX, pInDlssgOptEvalParams->uiSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_UISubrectBaseY, pInDlssgOptEvalParams->uiSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_UISubrectWidth, pInDlssgOptEvalParams->uiSubrectSize.Width);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_UISubrectHeight, pInDlssgOptEvalParams->uiSubrectSize.Height);
|
||||
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_UIAlphaSubrectBaseX, pInDlssgOptEvalParams->uiAlphaSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_UIAlphaSubrectBaseY, pInDlssgOptEvalParams->uiAlphaSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_UIAlphaSubrectWidth, pInDlssgOptEvalParams->uiAlphaSubrectSize.Width);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_UIAlphaSubrectHeight, pInDlssgOptEvalParams->uiAlphaSubrectSize.Height);
|
||||
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_BidirectionalDistortionFieldSubrectBaseX, pInDlssgOptEvalParams->bidirectionalDistFieldSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_BidirectionalDistortionFieldSubrectBaseY, pInDlssgOptEvalParams->bidirectionalDistFieldSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_BidirectionalDistortionFieldSubrectWidth, pInDlssgOptEvalParams->bidirectionalDistFieldSubrectSize.Width);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_BidirectionalDistortionFieldSubrectHeight, pInDlssgOptEvalParams->bidirectionalDistFieldSubrectSize.Height);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_BidirectionalDistortionField_LowPrecision_IsLowPrecision, pInDlssgOptEvalParams->bidirectionalDistFieldPrecisionInfo.IsLowPrecision);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_BidirectionalDistortionField_LowPrecision_Bias, pInDlssgOptEvalParams->bidirectionalDistFieldPrecisionInfo.Bias);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_BidirectionalDistortionField_LowPrecision_Scale, pInDlssgOptEvalParams->bidirectionalDistFieldPrecisionInfo.Scale);
|
||||
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_MinRelativeLinearDepthObjectSeparation, pInDlssgOptEvalParams->minRelativeLinearDepthObjectSeparation);
|
||||
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_InputBackbufferSubrectBaseX, pInDlssgOptEvalParams->backbufferSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_InputBackbufferSubrectBaseY, pInDlssgOptEvalParams->backbufferSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_InputBackbufferSubrectWidth, pInDlssgOptEvalParams->backbufferSubrectSize.Width);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_InputBackbufferSubrectHeight, pInDlssgOptEvalParams->backbufferSubrectSize.Height);
|
||||
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_OutputInterpolatedSubrectBaseX, pInDlssgOptEvalParams->outputInterpSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_OutputInterpolatedSubrectBaseY, pInDlssgOptEvalParams->outputInterpSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_OutputInterpolatedSubrectWidth, pInDlssgOptEvalParams->outputInterpSubrectSize.Width);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_OutputInterpolatedSubrectHeight, pInDlssgOptEvalParams->outputInterpSubrectSize.Height);
|
||||
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_OutputRealSubrectBaseX, pInDlssgOptEvalParams->outputRealSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_OutputRealSubrectBaseY, pInDlssgOptEvalParams->outputRealSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_OutputRealSubrectWidth, pInDlssgOptEvalParams->outputRealSubrectSize.Width);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_OutputRealSubrectHeight, pInDlssgOptEvalParams->outputRealSubrectSize.Height);
|
||||
}
|
||||
|
||||
return NVSDK_NGX_D3D12_EvaluateFeature_C(pInCmdList, pInHandle, pInParams, NULL);
|
||||
}
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_D3D12_ESTIMATE_VRAM_DLSSG(
|
||||
NVSDK_NGX_Parameter* InParams,
|
||||
uint32_t mvecDepthWidth, uint32_t mvecDepthHeight,
|
||||
uint32_t colorWidth, uint32_t colorHeight,
|
||||
uint32_t colorBufferFormat,
|
||||
uint32_t mvecBufferFormat, uint32_t depthBufferFormat,
|
||||
uint32_t hudLessBufferFormat, uint32_t uiBufferFormat,
|
||||
size_t* estimatedVRAMInBytes
|
||||
)
|
||||
{
|
||||
void* Callback = NULL;
|
||||
NVSDK_NGX_Parameter_GetVoidPointer(InParams, NVSDK_NGX_DLSSG_Parameter_EstimateVRAMCallback, &Callback);
|
||||
if (!Callback)
|
||||
{
|
||||
// Possible reasons for this:
|
||||
// - Installed feature is out of date and does not support the feature we need
|
||||
// - You used NVSDK_NGX_AllocateParameters() for creating InParams. Try using NVSDK_NGX_GetCapabilityParameters() instead
|
||||
return NVSDK_NGX_Result_FAIL_OutOfDate;
|
||||
}
|
||||
|
||||
NVSDK_NGX_Result Res = NVSDK_NGX_Result_Success;
|
||||
PFN_NVSDK_NGX_DLSSG_EstimateVRAMCallback PFNCallback = (PFN_NVSDK_NGX_DLSSG_EstimateVRAMCallback)Callback;
|
||||
Res = PFNCallback(mvecDepthWidth, mvecDepthHeight, colorWidth, colorHeight,
|
||||
colorBufferFormat, mvecBufferFormat, depthBufferFormat, hudLessBufferFormat, uiBufferFormat, estimatedVRAMInBytes);
|
||||
if (NVSDK_NGX_FAILED(Res))
|
||||
{
|
||||
return Res;
|
||||
}
|
||||
|
||||
return NVSDK_NGX_Result_Success;
|
||||
}
|
||||
|
||||
#endif // NVSDK_NGX_HELPERS_DLSSG_H
|
||||
@@ -0,0 +1,227 @@
|
||||
#pragma once
|
||||
/*
|
||||
* Copyright (c) 2021-2024 NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* NVIDIA Corporation and its licensors retain all intellectual property and proprietary
|
||||
* rights in and to this software, related documentation and any modifications thereto.
|
||||
* Any use, reproduction, disclosure or distribution of this software and related
|
||||
* documentation without an express license agreement from NVIDIA Corporation is strictly
|
||||
* prohibited.
|
||||
*
|
||||
* TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED *AS IS*
|
||||
* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS OR IMPLIED,
|
||||
* INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT
|
||||
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF
|
||||
* BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR
|
||||
* INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef NVSDK_NGX_HELPERS_DLSSG_VK_H
|
||||
#define NVSDK_NGX_HELPERS_DLSSG_VK_H
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
#include "nvsdk_ngx_defs_dlssg.h"
|
||||
#include "nvsdk_ngx_params_dlssg.h"
|
||||
#include "nvsdk_ngx_vk.h" // VK here
|
||||
|
||||
typedef struct NVSDK_NGX_VK_DLSSG_Eval_Params
|
||||
{
|
||||
NVSDK_NGX_Resource_VK* pBackbuffer;
|
||||
NVSDK_NGX_Resource_VK* pDepth;
|
||||
NVSDK_NGX_Resource_VK* pMVecs;
|
||||
NVSDK_NGX_Resource_VK* pHudless; // Optional
|
||||
NVSDK_NGX_Resource_VK* pUI; // Optional
|
||||
NVSDK_NGX_Resource_VK* pUIAlpha; // Optional
|
||||
NVSDK_NGX_Resource_VK* pBidirectionalDistortionField; // Optional
|
||||
NVSDK_NGX_Resource_VK* pOutputInterpFrame;
|
||||
NVSDK_NGX_Resource_VK* pOutputRealFrame; // Optional. In some cases, the feature may modify this frame (e.g. debugging)
|
||||
NVSDK_NGX_Resource_VK* pOutputDisableInterpolation; // Optional
|
||||
} NVSDK_NGX_VK_DLSSG_Eval_Params;
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_VK_CREATE_DLSSG(
|
||||
VkCommandBuffer pInCmdBuf,
|
||||
unsigned int InCreationNodeMask,
|
||||
unsigned int InVisibilityNodeMask,
|
||||
NVSDK_NGX_Handle** ppOutHandle,
|
||||
NVSDK_NGX_Parameter* pInParams,
|
||||
NVSDK_NGX_DLSSG_Create_Params* pInDlssgCreateParams)
|
||||
{
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_CreationNodeMask, InCreationNodeMask);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_VisibilityNodeMask, InVisibilityNodeMask);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Width, pInDlssgCreateParams->Width);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Height, pInDlssgCreateParams->Height);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_BackbufferFormat, pInDlssgCreateParams->NativeBackbufferFormat);
|
||||
|
||||
return NVSDK_NGX_VULKAN_CreateFeature(pInCmdBuf, NVSDK_NGX_Feature_FrameGeneration, pInParams, ppOutHandle);
|
||||
}
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_VK_EVALUATE_DLSSG(
|
||||
VkCommandBuffer pInCmdBuf,
|
||||
NVSDK_NGX_Handle* pInHandle,
|
||||
NVSDK_NGX_Parameter* pInParams,
|
||||
NVSDK_NGX_VK_DLSSG_Eval_Params* pInDlssgEvalParams,
|
||||
NVSDK_NGX_DLSSG_Opt_Eval_Params* pInDlssgOptEvalParams)
|
||||
{
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_DLSSG_Parameter_Backbuffer, pInDlssgEvalParams->pBackbuffer);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_DLSSG_Parameter_MVecs, pInDlssgEvalParams->pMVecs);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_DLSSG_Parameter_Depth, pInDlssgEvalParams->pDepth);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_DLSSG_Parameter_HUDLess, pInDlssgEvalParams->pHudless);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_DLSSG_Parameter_UI, pInDlssgEvalParams->pUI);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_DLSSG_Parameter_UIAlpha, pInDlssgEvalParams->pUIAlpha);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_DLSSG_Parameter_BidirectionalDistortionField, pInDlssgEvalParams->pBidirectionalDistortionField);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_DLSSG_Parameter_OutputInterpolated, pInDlssgEvalParams->pOutputInterpFrame);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_DLSSG_Parameter_OutputReal, pInDlssgEvalParams->pOutputRealFrame);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_DLSSG_Parameter_OutputDisableInterpolation, pInDlssgEvalParams->pOutputDisableInterpolation);
|
||||
|
||||
if (pInDlssgOptEvalParams)
|
||||
{
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_MultiFrameCount, pInDlssgOptEvalParams->multiFrameCount);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_MultiFrameIndex, pInDlssgOptEvalParams->multiFrameIndex);
|
||||
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraViewToClip, pInDlssgOptEvalParams->cameraViewToClip);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_DLSSG_Parameter_ClipToCameraView, pInDlssgOptEvalParams->clipToCameraView);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_DLSSG_Parameter_ClipToLensClip, pInDlssgOptEvalParams->clipToLensClip);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_DLSSG_Parameter_ClipToPrevClip, pInDlssgOptEvalParams->clipToPrevClip);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_DLSSG_Parameter_PrevClipToClip, pInDlssgOptEvalParams->prevClipToClip);
|
||||
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_JitterOffsetX, pInDlssgOptEvalParams->jitterOffset[0]);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_JitterOffsetY, pInDlssgOptEvalParams->jitterOffset[1]);
|
||||
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_MvecScaleX, pInDlssgOptEvalParams->mvecScale[0]);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_MvecScaleY, pInDlssgOptEvalParams->mvecScale[1]);
|
||||
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraPinholeOffsetX, pInDlssgOptEvalParams->cameraPinholeOffset[0]);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraPinholeOffsetY, pInDlssgOptEvalParams->cameraPinholeOffset[1]);
|
||||
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraPosX, pInDlssgOptEvalParams->cameraPos[0]);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraPosY, pInDlssgOptEvalParams->cameraPos[1]);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraPosZ, pInDlssgOptEvalParams->cameraPos[2]);
|
||||
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraUpX, pInDlssgOptEvalParams->cameraUp[0]);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraUpY, pInDlssgOptEvalParams->cameraUp[1]);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraUpZ, pInDlssgOptEvalParams->cameraUp[2]);
|
||||
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraRightX, pInDlssgOptEvalParams->cameraRight[0]);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraRightY, pInDlssgOptEvalParams->cameraRight[1]);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraRightZ, pInDlssgOptEvalParams->cameraRight[2]);
|
||||
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraFwdX, pInDlssgOptEvalParams->cameraFwd[0]);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraFwdY, pInDlssgOptEvalParams->cameraFwd[1]);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraFwdZ, pInDlssgOptEvalParams->cameraFwd[2]);
|
||||
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraNear, pInDlssgOptEvalParams->cameraNear);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraFar, pInDlssgOptEvalParams->cameraFar);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraFOV, pInDlssgOptEvalParams->cameraFOV);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraAspectRatio, pInDlssgOptEvalParams->cameraAspectRatio);
|
||||
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_ColorBuffersHDR, pInDlssgOptEvalParams->colorBuffersHDR);
|
||||
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_DepthInverted, pInDlssgOptEvalParams->depthInverted);
|
||||
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_CameraMotionIncluded, pInDlssgOptEvalParams->cameraMotionIncluded);
|
||||
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_Reset, pInDlssgOptEvalParams->reset);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_AutomodeOverrideReset, pInDlssgOptEvalParams->automodeOverrideReset);
|
||||
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_NotRenderingGameFrames, pInDlssgOptEvalParams->notRenderingGameFrames);
|
||||
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_OrthoProjection, pInDlssgOptEvalParams->orthoProjection);
|
||||
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_MvecInvalidValue, pInDlssgOptEvalParams->motionVectorsInvalidValue);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_MvecDilated, pInDlssgOptEvalParams->motionVectorsDilated);
|
||||
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_MenuDetectionEnabled, pInDlssgOptEvalParams->menuDetectionEnabled);
|
||||
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_MVecsSubrectBaseX, pInDlssgOptEvalParams->mvecsSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_MVecsSubrectBaseY, pInDlssgOptEvalParams->mvecsSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_MVecsSubrectWidth, pInDlssgOptEvalParams->mvecsSubrectSize.Width);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_MVecsSubrectHeight, pInDlssgOptEvalParams->mvecsSubrectSize.Height);
|
||||
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_DepthSubrectBaseX, pInDlssgOptEvalParams->depthSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_DepthSubrectBaseY, pInDlssgOptEvalParams->depthSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_DepthSubrectWidth, pInDlssgOptEvalParams->depthSubrectSize.Width);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_DepthSubrectHeight, pInDlssgOptEvalParams->depthSubrectSize.Height);
|
||||
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_HUDLessSubrectBaseX, pInDlssgOptEvalParams->hudLessSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_HUDLessSubrectBaseY, pInDlssgOptEvalParams->hudLessSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_HUDLessSubrectWidth, pInDlssgOptEvalParams->hudLessSubrectSize.Width);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_HUDLessSubrectHeight, pInDlssgOptEvalParams->hudLessSubrectSize.Height);
|
||||
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_UISubrectBaseX, pInDlssgOptEvalParams->uiSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_UISubrectBaseY, pInDlssgOptEvalParams->uiSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_UISubrectWidth, pInDlssgOptEvalParams->uiSubrectSize.Width);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_UISubrectHeight, pInDlssgOptEvalParams->uiSubrectSize.Height);
|
||||
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_UIAlphaSubrectBaseX, pInDlssgOptEvalParams->uiAlphaSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_UIAlphaSubrectBaseY, pInDlssgOptEvalParams->uiAlphaSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_UIAlphaSubrectWidth, pInDlssgOptEvalParams->uiAlphaSubrectSize.Width);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_UIAlphaSubrectHeight, pInDlssgOptEvalParams->uiAlphaSubrectSize.Height);
|
||||
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_BidirectionalDistortionFieldSubrectBaseX, pInDlssgOptEvalParams->bidirectionalDistFieldSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_BidirectionalDistortionFieldSubrectBaseY, pInDlssgOptEvalParams->bidirectionalDistFieldSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_BidirectionalDistortionFieldSubrectWidth, pInDlssgOptEvalParams->bidirectionalDistFieldSubrectSize.Width);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_BidirectionalDistortionFieldSubrectHeight, pInDlssgOptEvalParams->bidirectionalDistFieldSubrectSize.Height);
|
||||
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_BidirectionalDistortionField_LowPrecision_IsLowPrecision, pInDlssgOptEvalParams->bidirectionalDistFieldPrecisionInfo.IsLowPrecision);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_BidirectionalDistortionField_LowPrecision_Bias, pInDlssgOptEvalParams->bidirectionalDistFieldPrecisionInfo.Bias);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_BidirectionalDistortionField_LowPrecision_Scale, pInDlssgOptEvalParams->bidirectionalDistFieldPrecisionInfo.Scale);
|
||||
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_DLSSG_Parameter_MinRelativeLinearDepthObjectSeparation, pInDlssgOptEvalParams->minRelativeLinearDepthObjectSeparation);
|
||||
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_InputBackbufferSubrectBaseX, pInDlssgOptEvalParams->backbufferSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_InputBackbufferSubrectBaseY, pInDlssgOptEvalParams->backbufferSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_InputBackbufferSubrectWidth, pInDlssgOptEvalParams->backbufferSubrectSize.Width);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_InputBackbufferSubrectHeight, pInDlssgOptEvalParams->backbufferSubrectSize.Height);
|
||||
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_OutputInterpolatedSubrectBaseX, pInDlssgOptEvalParams->outputInterpSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_OutputInterpolatedSubrectBaseY, pInDlssgOptEvalParams->outputInterpSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_OutputInterpolatedSubrectWidth, pInDlssgOptEvalParams->outputInterpSubrectSize.Width);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_OutputInterpolatedSubrectHeight, pInDlssgOptEvalParams->outputInterpSubrectSize.Height);
|
||||
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_OutputRealSubrectBaseX, pInDlssgOptEvalParams->outputRealSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_OutputRealSubrectBaseY, pInDlssgOptEvalParams->outputRealSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_OutputRealSubrectWidth, pInDlssgOptEvalParams->outputRealSubrectSize.Width);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_DLSSG_Parameter_OutputRealSubrectHeight, pInDlssgOptEvalParams->outputRealSubrectSize.Height);
|
||||
}
|
||||
|
||||
// C version or cpp?
|
||||
return NVSDK_NGX_VULKAN_EvaluateFeature_C(pInCmdBuf, pInHandle, pInParams, NULL);
|
||||
}
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_VK_ESTIMATE_VRAM_DLSSG(
|
||||
NVSDK_NGX_Parameter* InParams,
|
||||
uint32_t mvecDepthWidth, uint32_t mvecDepthHeight,
|
||||
uint32_t colorWidth, uint32_t colorHeight,
|
||||
uint32_t colorBufferFormat,
|
||||
uint32_t mvecBufferFormat, uint32_t depthBufferFormat,
|
||||
uint32_t hudLessBufferFormat, uint32_t uiBufferFormat,
|
||||
size_t* estimatedVRAMInBytes
|
||||
)
|
||||
{
|
||||
void* Callback = NULL;
|
||||
NVSDK_NGX_Parameter_GetVoidPointer(InParams, NVSDK_NGX_DLSSG_Parameter_EstimateVRAMCallback, &Callback);
|
||||
if (!Callback)
|
||||
{
|
||||
// Possible reasons for this:
|
||||
// - Installed feature is out of date and does not support the feature we need
|
||||
// - You used NVSDK_NGX_AllocateParameters() for creating InParams. Try using NVSDK_NGX_GetCapabilityParameters() instead
|
||||
return NVSDK_NGX_Result_FAIL_OutOfDate;
|
||||
}
|
||||
|
||||
NVSDK_NGX_Result Res = NVSDK_NGX_Result_Success;
|
||||
PFN_NVSDK_NGX_DLSSG_EstimateVRAMCallback PFNCallback = (PFN_NVSDK_NGX_DLSSG_EstimateVRAMCallback)Callback;
|
||||
Res = PFNCallback(mvecDepthWidth, mvecDepthHeight, colorWidth, colorHeight,
|
||||
colorBufferFormat, mvecBufferFormat, depthBufferFormat, hudLessBufferFormat, uiBufferFormat, estimatedVRAMInBytes);
|
||||
if (NVSDK_NGX_FAILED(Res))
|
||||
{
|
||||
return Res;
|
||||
}
|
||||
|
||||
return NVSDK_NGX_Result_Success;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,275 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: LicenseRef-NvidiaProprietary
|
||||
*
|
||||
* NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
|
||||
* property and proprietary rights in and to this material, related
|
||||
* documentation and any modifications thereto. Any use, reproduction,
|
||||
* disclosure or distribution of this material and related documentation
|
||||
* without an express license agreement from NVIDIA CORPORATION or
|
||||
* its affiliates is strictly prohibited.
|
||||
*/
|
||||
|
||||
#ifndef NVSDK_NGX_HELPERS_VK_H
|
||||
#define NVSDK_NGX_HELPERS_VK_H
|
||||
#pragma once
|
||||
|
||||
#include "nvsdk_ngx_vk.h"
|
||||
|
||||
#define NVSDK_NGX_ENSURE_VK_IMAGEVIEW(InResource) if ((InResource) && (InResource)->Type != NVSDK_NGX_RESOURCE_VK_TYPE_VK_IMAGEVIEW) { return NVSDK_NGX_Result_FAIL_InvalidParameter; }
|
||||
|
||||
static inline NVSDK_NGX_Resource_VK NVSDK_NGX_Create_ImageView_Resource_VK(VkImageView imageView, VkImage image, VkImageSubresourceRange subresourceRange, VkFormat format, unsigned int width, unsigned int height, bool readWrite)
|
||||
{
|
||||
NVSDK_NGX_Resource_VK resourceVK = {0};
|
||||
resourceVK.Type = NVSDK_NGX_RESOURCE_VK_TYPE_VK_IMAGEVIEW;
|
||||
resourceVK.Resource.ImageViewInfo.ImageView = imageView;
|
||||
resourceVK.Resource.ImageViewInfo.Image = image;
|
||||
resourceVK.Resource.ImageViewInfo.SubresourceRange = subresourceRange;
|
||||
resourceVK.Resource.ImageViewInfo.Height = height;
|
||||
resourceVK.Resource.ImageViewInfo.Width = width;
|
||||
resourceVK.Resource.ImageViewInfo.Format = format;
|
||||
resourceVK.ReadWrite = readWrite;
|
||||
return resourceVK;
|
||||
}
|
||||
|
||||
static inline NVSDK_NGX_Resource_VK NVSDK_NGX_Create_Buffer_Resource_VK(VkBuffer buffer, unsigned int sizeInBytes, bool readWrite)
|
||||
{
|
||||
NVSDK_NGX_Resource_VK resourceVK = {0};
|
||||
resourceVK.Type = NVSDK_NGX_RESOURCE_VK_TYPE_VK_BUFFER;
|
||||
resourceVK.Resource.BufferInfo.Buffer = buffer;
|
||||
resourceVK.Resource.BufferInfo.SizeInBytes = sizeInBytes;
|
||||
resourceVK.ReadWrite = readWrite;
|
||||
return resourceVK;
|
||||
}
|
||||
|
||||
typedef struct NVSDK_NGX_VK_Feature_Eval_Params
|
||||
{
|
||||
NVSDK_NGX_Resource_VK *pInColor;
|
||||
NVSDK_NGX_Resource_VK *pInOutput;
|
||||
/*** OPTIONAL for DLSS ***/
|
||||
float InSharpness;
|
||||
} NVSDK_NGX_VK_Feature_Eval_Params;
|
||||
|
||||
typedef struct NVSDK_NGX_VK_GBuffer
|
||||
{
|
||||
NVSDK_NGX_Resource_VK *pInAttrib[NVSDK_NGX_GBUFFERTYPE_NUM];
|
||||
} NVSDK_NGX_VK_GBuffer;
|
||||
|
||||
typedef struct NVSDK_NGX_Coordinates_VK
|
||||
{
|
||||
unsigned int X;
|
||||
unsigned int Y;
|
||||
} NVSDK_NGX_Coordinates_VK;
|
||||
|
||||
typedef struct NVSDK_NGX_VK_DLSS_Eval_Params
|
||||
{
|
||||
NVSDK_NGX_VK_Feature_Eval_Params Feature;
|
||||
NVSDK_NGX_Resource_VK * pInDepth;
|
||||
NVSDK_NGX_Resource_VK * pInMotionVectors;
|
||||
float InJitterOffsetX; /* Jitter offset must be in input/render pixel space */
|
||||
float InJitterOffsetY;
|
||||
NVSDK_NGX_Dimensions InRenderSubrectDimensions;
|
||||
/*** OPTIONAL - leave to 0/0.0f if unused ***/
|
||||
int InReset; /* Set to 1 when scene changes completely (new level etc) */
|
||||
float InMVScaleX; /* If MVs need custom scaling to convert to pixel space */
|
||||
float InMVScaleY;
|
||||
NVSDK_NGX_Resource_VK * pInTransparencyMask; /* Unused/Reserved for future use */
|
||||
NVSDK_NGX_Resource_VK * pInExposureTexture;
|
||||
NVSDK_NGX_Resource_VK * pInBiasCurrentColorMask;
|
||||
NVSDK_NGX_Coordinates InColorSubrectBase;
|
||||
NVSDK_NGX_Coordinates InDepthSubrectBase;
|
||||
NVSDK_NGX_Coordinates InMVSubrectBase;
|
||||
NVSDK_NGX_Coordinates InTranslucencySubrectBase;
|
||||
NVSDK_NGX_Coordinates InBiasCurrentColorSubrectBase;
|
||||
NVSDK_NGX_Coordinates InOutputSubrectBase;
|
||||
float InPreExposure;
|
||||
float InExposureScale;
|
||||
int InIndicatorInvertXAxis;
|
||||
int InIndicatorInvertYAxis;
|
||||
/*** OPTIONAL - only for research purposes ***/
|
||||
NVSDK_NGX_VK_GBuffer GBufferSurface;
|
||||
NVSDK_NGX_ToneMapperType InToneMapperType;
|
||||
NVSDK_NGX_Resource_VK * pInMotionVectors3D;
|
||||
NVSDK_NGX_Resource_VK * pInIsParticleMask; /* to identify which pixels contains particles, essentially that are not drawn as part of base pass */
|
||||
NVSDK_NGX_Resource_VK * pInAnimatedTextureMask; /* a binary mask covering pixels occupied by animated textures */
|
||||
NVSDK_NGX_Resource_VK * pInDepthHighRes;
|
||||
NVSDK_NGX_Resource_VK * pInPositionViewSpace;
|
||||
float InFrameTimeDeltaInMsec; /* helps in determining the amount to denoise or anti-alias based on the speed of the object from motion vector magnitudes and fps as determined by this delta */
|
||||
NVSDK_NGX_Resource_VK * pInRayTracingHitDistance; /* for each effect - approximation to the amount of noise in a ray-traced color */
|
||||
NVSDK_NGX_Resource_VK * pInMotionVectorsReflections; /* motion vectors of reflected objects like for mirrored surfaces */
|
||||
} NVSDK_NGX_VK_DLSS_Eval_Params;
|
||||
|
||||
typedef struct NVSDK_NGX_VK_DLISP_Eval_Params
|
||||
{
|
||||
NVSDK_NGX_VK_Feature_Eval_Params Feature;
|
||||
/*** OPTIONAL - leave to 0/0.0f if unused ***/
|
||||
unsigned int InRectX;
|
||||
unsigned int InRectY;
|
||||
unsigned int InRectW;
|
||||
unsigned int InRectH;
|
||||
float InDenoise;
|
||||
} NVSDK_NGX_VK_DLISP_Eval_Params;
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_VULKAN_CREATE_DLSS_EXT1(
|
||||
VkDevice InDevice,
|
||||
VkCommandBuffer InCmdList,
|
||||
unsigned int InCreationNodeMask,
|
||||
unsigned int InVisibilityNodeMask,
|
||||
NVSDK_NGX_Handle **ppOutHandle,
|
||||
NVSDK_NGX_Parameter *pInParams,
|
||||
NVSDK_NGX_DLSS_Create_Params *pInDlssCreateParams)
|
||||
{
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_CreationNodeMask, InCreationNodeMask);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_VisibilityNodeMask, InVisibilityNodeMask);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Width, pInDlssCreateParams->Feature.InWidth);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Height, pInDlssCreateParams->Feature.InHeight);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutWidth, pInDlssCreateParams->Feature.InTargetWidth);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutHeight, pInDlssCreateParams->Feature.InTargetHeight);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_PerfQualityValue, pInDlssCreateParams->Feature.InPerfQualityValue);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Feature_Create_Flags, pInDlssCreateParams->InFeatureCreateFlags);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Enable_Output_Subrects, pInDlssCreateParams->InEnableOutputSubrects ? 1 : 0);
|
||||
|
||||
if (InDevice) return NVSDK_NGX_VULKAN_CreateFeature1(InDevice, InCmdList, NVSDK_NGX_Feature_SuperSampling, pInParams, ppOutHandle);
|
||||
else return NVSDK_NGX_VULKAN_CreateFeature(InCmdList, NVSDK_NGX_Feature_SuperSampling, pInParams, ppOutHandle);
|
||||
}
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_VULKAN_CREATE_DLSS_EXT(
|
||||
VkCommandBuffer InCmdList,
|
||||
unsigned int InCreationNodeMask,
|
||||
unsigned int InVisibilityNodeMask,
|
||||
NVSDK_NGX_Handle **ppOutHandle,
|
||||
NVSDK_NGX_Parameter *pInParams,
|
||||
NVSDK_NGX_DLSS_Create_Params *pInDlssCreateParams)
|
||||
{
|
||||
return NGX_VULKAN_CREATE_DLSS_EXT1(NULL, InCmdList, InCreationNodeMask, InVisibilityNodeMask, ppOutHandle, pInParams, pInDlssCreateParams);
|
||||
}
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_VULKAN_EVALUATE_DLSS_EXT(
|
||||
VkCommandBuffer InCmdList,
|
||||
NVSDK_NGX_Handle *pInHandle,
|
||||
NVSDK_NGX_Parameter *pInParams,
|
||||
NVSDK_NGX_VK_DLSS_Eval_Params *pInDlssEvalParams)
|
||||
{
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssEvalParams->Feature.pInColor);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssEvalParams->pInMotionVectors);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssEvalParams->Feature.pInOutput);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssEvalParams->pInDepth);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssEvalParams->pInTransparencyMask);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssEvalParams->pInExposureTexture);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssEvalParams->pInBiasCurrentColorMask);
|
||||
for (size_t i = 0; i <= 15; i++)
|
||||
{
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssEvalParams->GBufferSurface.pInAttrib[i]);
|
||||
}
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssEvalParams->pInMotionVectors3D);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssEvalParams->pInIsParticleMask);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssEvalParams->pInAnimatedTextureMask);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssEvalParams->pInDepthHighRes);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssEvalParams->pInPositionViewSpace);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssEvalParams->pInRayTracingHitDistance);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlssEvalParams->pInMotionVectorsReflections);
|
||||
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_Color, pInDlssEvalParams->Feature.pInColor);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_Output, pInDlssEvalParams->Feature.pInOutput);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_Depth, pInDlssEvalParams->pInDepth);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_MotionVectors, pInDlssEvalParams->pInMotionVectors);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Jitter_Offset_X, pInDlssEvalParams->InJitterOffsetX);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Jitter_Offset_Y, pInDlssEvalParams->InJitterOffsetY);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Sharpness, pInDlssEvalParams->Feature.InSharpness);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_Reset, pInDlssEvalParams->InReset);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_MV_Scale_X, pInDlssEvalParams->InMVScaleX == 0.0f ? 1.0f : pInDlssEvalParams->InMVScaleX);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_MV_Scale_Y, pInDlssEvalParams->InMVScaleY == 0.0f ? 1.0f : pInDlssEvalParams->InMVScaleY);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_TransparencyMask, pInDlssEvalParams->pInTransparencyMask);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_ExposureTexture, pInDlssEvalParams->pInExposureTexture);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_Mask, pInDlssEvalParams->pInBiasCurrentColorMask);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Albedo, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_ALBEDO]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Roughness, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_ROUGHNESS]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Metallic, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_METALLIC]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Specular, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_SPECULAR]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Subsurface, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_SUBSURFACE]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Normals, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_NORMALS]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_ShadingModelId, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_SHADINGMODELID]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_MaterialId, pInDlssEvalParams->GBufferSurface.pInAttrib[NVSDK_NGX_GBUFFER_MATERIALID]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_8, pInDlssEvalParams->GBufferSurface.pInAttrib[8]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_9, pInDlssEvalParams->GBufferSurface.pInAttrib[9]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_10, pInDlssEvalParams->GBufferSurface.pInAttrib[10]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_11, pInDlssEvalParams->GBufferSurface.pInAttrib[11]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_12, pInDlssEvalParams->GBufferSurface.pInAttrib[12]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_13, pInDlssEvalParams->GBufferSurface.pInAttrib[13]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_14, pInDlssEvalParams->GBufferSurface.pInAttrib[14]);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_GBuffer_Atrrib_15, pInDlssEvalParams->GBufferSurface.pInAttrib[15]);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_TonemapperType, pInDlssEvalParams->InToneMapperType);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_MotionVectors3D, pInDlssEvalParams->pInMotionVectors3D);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_IsParticleMask, pInDlssEvalParams->pInIsParticleMask);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_AnimatedTextureMask, pInDlssEvalParams->pInAnimatedTextureMask);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_DepthHighRes, pInDlssEvalParams->pInDepthHighRes);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_Position_ViewSpace, pInDlssEvalParams->pInPositionViewSpace);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_FrameTimeDeltaInMsec, pInDlssEvalParams->InFrameTimeDeltaInMsec);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_RayTracingHitDistance, pInDlssEvalParams->pInRayTracingHitDistance);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_MotionVectorsReflection, pInDlssEvalParams->pInMotionVectorsReflections);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Color_Subrect_Base_X, pInDlssEvalParams->InColorSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Color_Subrect_Base_Y, pInDlssEvalParams->InColorSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Depth_Subrect_Base_X, pInDlssEvalParams->InDepthSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Depth_Subrect_Base_Y, pInDlssEvalParams->InDepthSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_MV_SubrectBase_X, pInDlssEvalParams->InMVSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_MV_SubrectBase_Y, pInDlssEvalParams->InMVSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Translucency_SubrectBase_X, pInDlssEvalParams->InTranslucencySubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Translucency_SubrectBase_Y, pInDlssEvalParams->InTranslucencySubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_SubrectBase_X, pInDlssEvalParams->InBiasCurrentColorSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_SubrectBase_Y, pInDlssEvalParams->InBiasCurrentColorSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Output_Subrect_Base_X, pInDlssEvalParams->InOutputSubrectBase.X);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Output_Subrect_Base_Y, pInDlssEvalParams->InOutputSubrectBase.Y);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Render_Subrect_Dimensions_Width , pInDlssEvalParams->InRenderSubrectDimensions.Width);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_DLSS_Render_Subrect_Dimensions_Height, pInDlssEvalParams->InRenderSubrectDimensions.Height);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_DLSS_Pre_Exposure, pInDlssEvalParams->InPreExposure == 0.0f ? 1.0f : pInDlssEvalParams->InPreExposure);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_DLSS_Exposure_Scale, pInDlssEvalParams->InExposureScale == 0.0f ? 1.0f : pInDlssEvalParams->InExposureScale);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Indicator_Invert_X_Axis, pInDlssEvalParams->InIndicatorInvertXAxis);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_DLSS_Indicator_Invert_Y_Axis, pInDlssEvalParams->InIndicatorInvertYAxis);
|
||||
|
||||
return NVSDK_NGX_VULKAN_EvaluateFeature_C(InCmdList, pInHandle, pInParams, NULL);
|
||||
}
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_VULKAN_CREATE_DLISP_EXT(
|
||||
VkCommandBuffer InCmdList,
|
||||
unsigned int InCreationNodeMask,
|
||||
unsigned int InVisibilityNodeMask,
|
||||
NVSDK_NGX_Handle **ppOutHandle,
|
||||
NVSDK_NGX_Parameter *pInParams,
|
||||
NVSDK_NGX_Feature_Create_Params *pInDlispCreateParams)
|
||||
{
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_CreationNodeMask, InCreationNodeMask);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_VisibilityNodeMask, InVisibilityNodeMask);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Width, pInDlispCreateParams->InWidth);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Height, pInDlispCreateParams->InHeight);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutWidth, pInDlispCreateParams->InTargetWidth);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_OutHeight, pInDlispCreateParams->InTargetHeight);
|
||||
NVSDK_NGX_Parameter_SetI(pInParams, NVSDK_NGX_Parameter_PerfQualityValue, pInDlispCreateParams->InPerfQualityValue);
|
||||
|
||||
return NVSDK_NGX_VULKAN_CreateFeature(InCmdList, NVSDK_NGX_Feature_ImageSignalProcessing, pInParams, ppOutHandle);
|
||||
}
|
||||
|
||||
static inline NVSDK_NGX_Result NGX_VULKAN_EVALUATE_DLISP_EXT(
|
||||
VkCommandBuffer InCmdList,
|
||||
NVSDK_NGX_Handle *InHandle,
|
||||
NVSDK_NGX_Parameter *pInParams,
|
||||
NVSDK_NGX_VK_DLISP_Eval_Params *pInDlispEvalParams)
|
||||
{
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlispEvalParams->Feature.pInColor);
|
||||
NVSDK_NGX_ENSURE_VK_IMAGEVIEW(pInDlispEvalParams->Feature.pInOutput);
|
||||
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_Color, pInDlispEvalParams->Feature.pInColor);
|
||||
NVSDK_NGX_Parameter_SetVoidPointer(pInParams, NVSDK_NGX_Parameter_Output, pInDlispEvalParams->Feature.pInOutput);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Sharpness, pInDlispEvalParams->Feature.InSharpness);
|
||||
NVSDK_NGX_Parameter_SetF(pInParams, NVSDK_NGX_Parameter_Denoise, pInDlispEvalParams->InDenoise);
|
||||
// If input is atlas - use RECT to upscale only the required area
|
||||
if (pInDlispEvalParams->InRectW)
|
||||
{
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Rect_X, pInDlispEvalParams->InRectX);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Rect_Y, pInDlispEvalParams->InRectY);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Rect_W, pInDlispEvalParams->InRectW);
|
||||
NVSDK_NGX_Parameter_SetUI(pInParams, NVSDK_NGX_Parameter_Rect_H, pInDlispEvalParams->InRectH);
|
||||
}
|
||||
|
||||
return NVSDK_NGX_VULKAN_EvaluateFeature_C(InCmdList, InHandle, pInParams, NULL);
|
||||
}
|
||||
#endif // NVSDK_NGX_HELPERS_VK_H
|
||||
@@ -0,0 +1,425 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: LicenseRef-NvidiaProprietary
|
||||
*
|
||||
* NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
|
||||
* property and proprietary rights in and to this material, related
|
||||
* documentation and any modifications thereto. Any use, reproduction,
|
||||
* disclosure or distribution of this material and related documentation
|
||||
* without an express license agreement from NVIDIA CORPORATION or
|
||||
* its affiliates is strictly prohibited.
|
||||
*/
|
||||
|
||||
#ifndef NVSDK_NGX_LOADER_H
|
||||
#define NVSDK_NGX_LOADER_H
|
||||
|
||||
#include "nvsdk_ngx_defs.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
#include <vector>
|
||||
#include <Winternl.h>
|
||||
#include <dxgi.h>
|
||||
#include <d3dkmthk.h>
|
||||
|
||||
#else // defined(_WIN32)
|
||||
|
||||
#include <algorithm>
|
||||
#include <string.h>
|
||||
#include <dlfcn.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
#if defined(NVSDK_NGX_LOG)
|
||||
#define NGX_LOADER_LOG NVSDK_NGX_LOG
|
||||
#define NGX_LOADER_LOGV NVSDK_NGX_LOG
|
||||
#else // defined(_WIN32)
|
||||
#define NGX_LOADER_LOG
|
||||
#define NGX_LOADER_LOGV
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
typedef LUID NVSDK_NGX_LUID;
|
||||
typedef HMODULE NGXLibHandle;
|
||||
typedef FARPROC NGXLibSymPtr;
|
||||
|
||||
#else // defined(_WIN32)
|
||||
|
||||
typedef struct {
|
||||
unsigned int lowPart;
|
||||
int highPart;
|
||||
} NVSDK_NGX_LUID;
|
||||
|
||||
typedef void *NGXLibHandle;
|
||||
typedef void (*NGXLibSymPtr)(void);
|
||||
|
||||
#define NGX_CORE_LIBRARY_NAME "libnvidia-ngx.so.1"
|
||||
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
#if defined(NVSDK_NGX_HEADER_ONLY)
|
||||
|
||||
bool NGXCloseLibrary(NGXLibHandle handle)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return FreeLibrary(handle) == TRUE;
|
||||
#else // defined(_WIN32)
|
||||
return (dlclose(handle) == 0);
|
||||
#endif // defined(_WIN32)
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
static LONG GetStringRegKey(HKEY InKey, const WCHAR *InValueName, WCHAR *OutValue, DWORD dwBufferSize)
|
||||
{
|
||||
ULONG nError = RegQueryValueExW(InKey, InValueName, 0, NULL, (LPBYTE)OutValue, &dwBufferSize);
|
||||
return nError;
|
||||
}
|
||||
|
||||
static bool IsValidDirectoryPath(const WCHAR *path)
|
||||
{
|
||||
if (path == nullptr || path[0] == L'\0')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD attrs = GetFileAttributesW(path);
|
||||
return (attrs != INVALID_FILE_ATTRIBUTES) && (attrs & FILE_ATTRIBUTE_DIRECTORY);
|
||||
}
|
||||
|
||||
static LONG NGXGetPathFromRegistry(const WCHAR *InRegKeyHive, const WCHAR *InRegKeyName, WCHAR *OutPath)
|
||||
{
|
||||
HKEY Key;
|
||||
NGX_LOADER_LOGV("Trying registry key %ls in %ls", InRegKeyName, InRegKeyHive);
|
||||
LONG Res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, InRegKeyHive, 0, KEY_READ, &Key);
|
||||
if (Res == ERROR_SUCCESS)
|
||||
{
|
||||
Res = GetStringRegKey(Key, InRegKeyName, OutPath, MAX_PATH);
|
||||
if (Res == ERROR_SUCCESS)
|
||||
{
|
||||
NGX_LOADER_LOGV("Found registry key %ls in %ls", InRegKeyName, InRegKeyHive);
|
||||
if (!IsValidDirectoryPath(OutPath))
|
||||
{
|
||||
NGX_LOADER_LOGV("Registry path is not a valid directory: %ls", OutPath);
|
||||
Res = ERROR_PATH_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
RegCloseKey(Key);
|
||||
}
|
||||
return Res;
|
||||
}
|
||||
|
||||
static HRESULT NGXGetPathUsingQAI(const LUID adapterLUID, WCHAR* pathToDriverStore)
|
||||
{
|
||||
HRESULT ret = S_OK;
|
||||
NGX_LOADER_LOGV("Checking for path to NGX using QueryAdapterInfo");
|
||||
|
||||
D3DKMT_HANDLE hAdapter = 0;
|
||||
|
||||
const wchar_t *dllName = L"gdi32.dll";
|
||||
HMODULE hModule = LoadLibraryW(dllName);
|
||||
if (!hModule) {
|
||||
return E_UNEXPECTED;
|
||||
}
|
||||
|
||||
PFND3DKMT_ENUMADAPTERS2 pfnEnumAdapters2;
|
||||
PFND3DKMT_CLOSEADAPTER pfnCloseAdapter;
|
||||
PFND3DKMT_QUERYADAPTERINFO pfnQueryAdapterInfo;
|
||||
|
||||
pfnEnumAdapters2 = (PFND3DKMT_ENUMADAPTERS2) GetProcAddress(hModule, "D3DKMTEnumAdapters2");
|
||||
pfnCloseAdapter = (PFND3DKMT_CLOSEADAPTER) GetProcAddress(hModule, "D3DKMTCloseAdapter");
|
||||
pfnQueryAdapterInfo = (PFND3DKMT_QUERYADAPTERINFO) GetProcAddress(hModule, "D3DKMTQueryAdapterInfo");
|
||||
|
||||
if (!pfnEnumAdapters2 || !pfnCloseAdapter || !pfnQueryAdapterInfo)
|
||||
{
|
||||
NGXCloseLibrary(hModule);
|
||||
return E_UNEXPECTED;
|
||||
}
|
||||
|
||||
D3DKMT_ENUMADAPTERS2 enumAdapters2 = {};
|
||||
enumAdapters2.NumAdapters = 0;
|
||||
enumAdapters2.pAdapters = NULL;
|
||||
|
||||
// Get the max number of adapters
|
||||
NTSTATUS nt = pfnEnumAdapters2(&enumAdapters2);
|
||||
if (!NT_SUCCESS(nt))
|
||||
{
|
||||
NGXCloseLibrary(hModule);
|
||||
return HRESULT_FROM_NT(nt);
|
||||
}
|
||||
|
||||
if (enumAdapters2.NumAdapters <= 0) {
|
||||
NGXCloseLibrary(hModule);
|
||||
return E_UNEXPECTED;
|
||||
}
|
||||
|
||||
// Get actual valid adapters
|
||||
D3DKMT_ADAPTERINFO * adapterInfos = (D3DKMT_ADAPTERINFO*) ::malloc(sizeof(D3DKMT_ADAPTERINFO) * enumAdapters2.NumAdapters);
|
||||
if (!adapterInfos)
|
||||
{
|
||||
NGXCloseLibrary(hModule);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
enumAdapters2.pAdapters = adapterInfos;
|
||||
nt = pfnEnumAdapters2(&enumAdapters2);
|
||||
if (!NT_SUCCESS(nt))
|
||||
{
|
||||
NGXCloseLibrary(hModule);
|
||||
::free(adapterInfos);
|
||||
return HRESULT_FROM_NT(nt);
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < enumAdapters2.NumAdapters; i++)
|
||||
{
|
||||
if (adapterInfos[i].AdapterLuid.HighPart == adapterLUID.HighPart && adapterInfos[i].AdapterLuid.LowPart == adapterLUID.LowPart)
|
||||
{
|
||||
hAdapter = adapterInfos[i].hAdapter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (hAdapter)
|
||||
{
|
||||
// The OS has a bug where it under-estimates the required amount of space.
|
||||
// As a result, just passing a buffer of size = sizeof(D3DDDI_QUERYREGISTRY_INFO) is not enough to hold all the data.
|
||||
// Use malloc here so as to ensure that enough space is allocated.
|
||||
D3DDDI_QUERYREGISTRY_INFO* pArgs = (D3DDDI_QUERYREGISTRY_INFO*) malloc(sizeof(D3DDDI_QUERYREGISTRY_INFO) + MAX_PATH * sizeof(WCHAR));
|
||||
if (pArgs)
|
||||
{
|
||||
const wchar_t *pathKeys[2] = {
|
||||
L"Parameters\\NGXCore\\NGXPath",
|
||||
L"NGXCore\\NGXPath",
|
||||
};
|
||||
|
||||
for (int i = 0; i < sizeof(pathKeys) / sizeof(wchar_t *); i++)
|
||||
{
|
||||
ZeroMemory(pArgs, sizeof(D3DDDI_QUERYREGISTRY_INFO) + MAX_PATH * sizeof(WCHAR));
|
||||
|
||||
NGX_LOADER_LOG("Attempting to read from %ls", pathKeys[i]);
|
||||
|
||||
pArgs->QueryType = D3DDDI_QUERYREGISTRY_SERVICEKEY;
|
||||
pArgs->QueryFlags.TranslatePath = 0;
|
||||
pArgs->ValueType = REG_SZ;
|
||||
wcscpy_s(pArgs->ValueName, MAX_PATH, pathKeys[i]);
|
||||
|
||||
D3DKMT_QUERYADAPTERINFO Args1 = {};
|
||||
Args1.hAdapter = hAdapter;
|
||||
Args1.Type = KMTQAITYPE_QUERYREGISTRY;
|
||||
Args1.pPrivateDriverData = pArgs;
|
||||
Args1.PrivateDriverDataSize = sizeof(D3DDDI_QUERYREGISTRY_INFO) + MAX_PATH * sizeof(WCHAR);
|
||||
|
||||
NTSTATUS Status = pfnQueryAdapterInfo(&Args1);
|
||||
if (NT_SUCCESS(Status) && pArgs->Status == D3DDDI_QUERYREGISTRY_STATUS_SUCCESS)
|
||||
{
|
||||
wcscpy_s(pathToDriverStore, MAX_PATH, pArgs->OutputString);
|
||||
if (!IsValidDirectoryPath(pathToDriverStore))
|
||||
{
|
||||
NGX_LOADER_LOG("QAI path is not a valid directory: %ls", pathToDriverStore);
|
||||
ret = E_FAIL;
|
||||
}
|
||||
else
|
||||
{
|
||||
NGX_LOADER_LOG("Path to driverStore found using QAI: %ls", pathToDriverStore);
|
||||
ret = S_OK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
free(pArgs);
|
||||
}
|
||||
else
|
||||
{
|
||||
NGX_LOADER_LOG("error: out of memory... unable to query adapter info");
|
||||
ret = E_FAIL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NGX_LOADER_LOG("error: no matching adapter found");
|
||||
ret = E_INVALIDARG;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < enumAdapters2.NumAdapters; i++)
|
||||
{
|
||||
D3DKMT_CLOSEADAPTER closeAdapter = {};
|
||||
closeAdapter.hAdapter = adapterInfos[i].hAdapter;
|
||||
pfnCloseAdapter(&closeAdapter);
|
||||
}
|
||||
::free(adapterInfos);
|
||||
|
||||
NGXCloseLibrary(hModule);
|
||||
return ret;
|
||||
}
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
NGXLibSymPtr NGXGetLibrarySymbol(NGXLibHandle handle, const char *symbol)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return GetProcAddress(handle, symbol);
|
||||
#else // defined(_WIN32)
|
||||
return (NGXLibSymPtr)dlsym(handle, symbol);
|
||||
#endif // defined(_WIN32)
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
NGXLibHandle NGXLoadLibrary(const wchar_t *filename)
|
||||
{
|
||||
HMODULE Lib = LoadLibraryW(filename);
|
||||
if (Lib)
|
||||
{
|
||||
NGX_LOADER_LOGV("Loaded NGXCore from path (%ls)", filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
NGX_LOADER_LOG("error: failed to load NGXCore: %d (%ls)", GetLastError(), filename);
|
||||
}
|
||||
|
||||
return Lib;
|
||||
}
|
||||
#else // defined(_WIN32)
|
||||
NGXLibHandle NGXLoadLibrary(const char *filename)
|
||||
{
|
||||
NGXLibHandle handle = nullptr;
|
||||
|
||||
handle = dlopen(filename, RTLD_NOW);
|
||||
if (handle) {
|
||||
NGX_LOADER_LOGV("Loaded library from path (%s)", filename);
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
NGXLibHandle NGXLoadCoreLibrary(NVSDK_NGX_LUID adapterLUID)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
NGXLibHandle Lib = nullptr;
|
||||
WCHAR Path[MAX_PATH];
|
||||
|
||||
std::vector<const wchar_t*> dll_filenames;
|
||||
|
||||
#if defined(_M_ARM64)
|
||||
dll_filenames.push_back(L"\\_arm64_nvngx.dll");
|
||||
#else
|
||||
// drivers 471.11 and later have to use "_nvngx.dll" instead of "nvngx.dll" - so check both names
|
||||
dll_filenames.push_back(L"\\_nvngx.dll");
|
||||
dll_filenames.push_back(L"\\nvngx.dll");
|
||||
#endif
|
||||
|
||||
// Modified to comply with DCH changes https://confluence.nvidia.com/display/MSTET/NGX
|
||||
// First, check if NGXCore is present next to the app binary
|
||||
DWORD ret = GetModuleFileNameW(NULL, Path, MAX_PATH);
|
||||
if (ret)
|
||||
{
|
||||
for (size_t i = 0; Lib == nullptr && i < dll_filenames.size(); ++i)
|
||||
{
|
||||
// Remove the name of the app
|
||||
wchar_t* PSTR = wcsrchr(Path, L'\\');
|
||||
if (PSTR)
|
||||
{
|
||||
*PSTR = L'\0';
|
||||
}
|
||||
wcscat_s(Path, dll_filenames[i]);
|
||||
Lib = NGXLoadLibrary(Path);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NGX_LOADER_LOGV("warning: unable to find filename for the application");
|
||||
}
|
||||
|
||||
if (!Lib)
|
||||
{
|
||||
// Now check the regkeys and look for NGXCore in the production folders
|
||||
NGX_LOADER_LOGV("NGXCore not found next to the application");
|
||||
|
||||
LONG Res = ERROR_FUNCTION_FAILED;
|
||||
|
||||
// First try using QueryAdapterInfo to read the regkey set by driver installer (would only work for NGX installed via declarative INF)
|
||||
HRESULT hr = NGXGetPathUsingQAI(adapterLUID, Path);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
// Perhaps there was an error while trying to use QAI. So, try the raw OS regkey read function (would only work for NGX installed via declarative INF)
|
||||
Res = NGXGetPathFromRegistry(L"System\\CurrentControlSet\\Services\\nvlddmkm\\Parameters\\NGXCore", L"NGXPath", Path);
|
||||
if (Res != ERROR_SUCCESS)
|
||||
{
|
||||
Res = NGXGetPathFromRegistry(L"System\\CurrentControlSet\\Services\\nvlddmkm\\NGXCore", L"NGXPath", Path);
|
||||
if (Res != ERROR_SUCCESS)
|
||||
{
|
||||
// Finally, fall back to legacy location (all non-DCH drivers should have this regkey present)
|
||||
// NOTE: Do not remove! This regkey is actively used by
|
||||
// Proton/Wine which don't have a concept of DCH drivers or a
|
||||
// "Driver Store".
|
||||
// See: https://github.com/ValveSoftware/wine/commit/0bff1b4fc6929694b706bd7e659ed0b58ff51f2d
|
||||
Res = NGXGetPathFromRegistry(L"SOFTWARE\\NVIDIA Corporation\\Global\\NGXCore", L"FullPath", Path);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (SUCCEEDED(hr) || Res == ERROR_SUCCESS)
|
||||
{
|
||||
for (size_t i = 0; i < dll_filenames.size(); ++i)
|
||||
{
|
||||
wcscat_s(Path, dll_filenames[i]);
|
||||
Lib = NGXLoadLibrary(Path);
|
||||
if (Lib)
|
||||
{
|
||||
NGX_LOADER_LOG("Loading %ls succeeded", Path);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
NGX_LOADER_LOG("warning: failed to load %ls", Path);
|
||||
// Remove the name of the DLL that has failed to load
|
||||
wchar_t *PSTR = wcsrchr(Path, L'\\');
|
||||
if (PSTR)
|
||||
{
|
||||
*PSTR = L'\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!Lib)
|
||||
{
|
||||
NGX_LOADER_LOG("error: failed to load nvngx");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NGX_LOADER_LOG("error: failed to locate NGX core path via registry key - error %ld", Res);
|
||||
}
|
||||
}
|
||||
return Lib;
|
||||
#else // defined(_WIN32)
|
||||
(void)adapterLUID;
|
||||
|
||||
NGXLibHandle handle = nullptr;
|
||||
|
||||
handle = NGXLoadLibrary(NGX_CORE_LIBRARY_NAME);
|
||||
if (handle) {
|
||||
NGX_LOADER_LOGV("Loaded NGXCore from global search paths");
|
||||
return handle;
|
||||
}
|
||||
return nullptr;
|
||||
#endif // defined(_WIN32)
|
||||
}
|
||||
|
||||
#endif /* NVSDK_NGX_HEADER_ONLY */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* NVSDK_NGX_LOADER_H */
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: LicenseRef-NvidiaProprietary
|
||||
*
|
||||
* NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
|
||||
* property and proprietary rights in and to this material, related
|
||||
* documentation and any modifications thereto. Any use, reproduction,
|
||||
* disclosure or distribution of this material and related documentation
|
||||
* without an express license agreement from NVIDIA CORPORATION or
|
||||
* its affiliates is strictly prohibited.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef NVSDK_NGX_PARAMS_H
|
||||
#define NVSDK_NGX_PARAMS_H
|
||||
|
||||
#include "nvsdk_ngx_defs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef struct ID3D11Resource ID3D11Resource;
|
||||
typedef struct ID3D12Resource ID3D12Resource;
|
||||
|
||||
typedef struct NVSDK_NGX_Feature_Create_Params
|
||||
{
|
||||
unsigned int InWidth;
|
||||
unsigned int InHeight;
|
||||
unsigned int InTargetWidth;
|
||||
unsigned int InTargetHeight;
|
||||
/*** OPTIONAL ***/
|
||||
NVSDK_NGX_PerfQuality_Value InPerfQualityValue;
|
||||
} NVSDK_NGX_Feature_Create_Params;
|
||||
|
||||
typedef struct NVSDK_NGX_DLSS_Create_Params
|
||||
{
|
||||
NVSDK_NGX_Feature_Create_Params Feature;
|
||||
/*** OPTIONAL ***/
|
||||
int InFeatureCreateFlags;
|
||||
bool InEnableOutputSubrects;
|
||||
} NVSDK_NGX_DLSS_Create_Params;
|
||||
|
||||
typedef struct NVSDK_NGX_DLDenoise_Create_Params
|
||||
{
|
||||
NVSDK_NGX_Feature_Create_Params Feature;
|
||||
/*** OPTIONAL ***/
|
||||
int InFeatureCreateFlags;
|
||||
} NVSDK_NGX_DLDenoise_Create_Params;
|
||||
|
||||
#ifdef __cplusplus
|
||||
typedef struct NVSDK_NGX_Parameter
|
||||
{
|
||||
virtual void Set(const char * InName, unsigned long long InValue) = 0;
|
||||
virtual void Set(const char * InName, float InValue) = 0;
|
||||
virtual void Set(const char * InName, double InValue) = 0;
|
||||
virtual void Set(const char * InName, unsigned int InValue) = 0;
|
||||
virtual void Set(const char * InName, int InValue) = 0;
|
||||
virtual void Set(const char * InName, ID3D11Resource *InValue) = 0;
|
||||
virtual void Set(const char * InName, ID3D12Resource *InValue) = 0;
|
||||
virtual void Set(const char * InName, void *InValue) = 0;
|
||||
|
||||
virtual NVSDK_NGX_Result Get(const char * InName, unsigned long long *OutValue) const = 0;
|
||||
virtual NVSDK_NGX_Result Get(const char * InName, float *OutValue) const = 0;
|
||||
virtual NVSDK_NGX_Result Get(const char * InName, double *OutValue) const = 0;
|
||||
virtual NVSDK_NGX_Result Get(const char * InName, unsigned int *OutValue) const = 0;
|
||||
virtual NVSDK_NGX_Result Get(const char * InName, int *OutValue) const = 0;
|
||||
virtual NVSDK_NGX_Result Get(const char * InName, ID3D11Resource **OutValue) const = 0;
|
||||
virtual NVSDK_NGX_Result Get(const char * InName, ID3D12Resource **OutValue) const = 0;
|
||||
virtual NVSDK_NGX_Result Get(const char * InName, void **OutValue) const = 0;
|
||||
|
||||
virtual void Reset() = 0;
|
||||
} NVSDK_NGX_Parameter;
|
||||
#else
|
||||
typedef struct NVSDK_NGX_Parameter NVSDK_NGX_Parameter;
|
||||
#endif // _cplusplus
|
||||
|
||||
typedef void (NVSDK_CONV *PFN_NVSDK_NGX_Parameter_SetULL)(NVSDK_NGX_Parameter *InParameter, const char * InName, unsigned long long InValue);
|
||||
NVSDK_NGX_API void NVSDK_CONV NVSDK_NGX_Parameter_SetULL(NVSDK_NGX_Parameter *InParameter, const char * InName, unsigned long long InValue);
|
||||
typedef void (NVSDK_CONV *PFN_NVSDK_NGX_Parameter_SetF)(NVSDK_NGX_Parameter *InParameter, const char * InName, float InValue);
|
||||
NVSDK_NGX_API void NVSDK_CONV NVSDK_NGX_Parameter_SetF(NVSDK_NGX_Parameter *InParameter, const char * InName, float InValue);
|
||||
typedef void (NVSDK_CONV *PFN_NVSDK_NGX_Parameter_SetD)(NVSDK_NGX_Parameter *InParameter, const char * InName, double InValue);
|
||||
NVSDK_NGX_API void NVSDK_CONV NVSDK_NGX_Parameter_SetD(NVSDK_NGX_Parameter *InParameter, const char * InName, double InValue);
|
||||
typedef void (NVSDK_CONV *PFN_NVSDK_NGX_Parameter_SetUI)(NVSDK_NGX_Parameter *InParameter, const char * InName, unsigned int InValue);
|
||||
NVSDK_NGX_API void NVSDK_CONV NVSDK_NGX_Parameter_SetUI(NVSDK_NGX_Parameter *InParameter, const char * InName, unsigned int InValue);
|
||||
typedef void (NVSDK_CONV *PFN_NVSDK_NGX_Parameter_SetI)(NVSDK_NGX_Parameter *InParameter, const char * InName, int InValue);
|
||||
NVSDK_NGX_API void NVSDK_CONV NVSDK_NGX_Parameter_SetI(NVSDK_NGX_Parameter *InParameter, const char * InName, int InValue);
|
||||
typedef void (NVSDK_CONV *PFN_NVSDK_NGX_Parameter_SetD3d11Resource)(NVSDK_NGX_Parameter *InParameter, const char * InName, ID3D11Resource *InValue);
|
||||
NVSDK_NGX_API void NVSDK_CONV NVSDK_NGX_Parameter_SetD3d11Resource(NVSDK_NGX_Parameter *InParameter, const char * InName, ID3D11Resource *InValue);
|
||||
typedef void (NVSDK_CONV *PFN_NVSDK_NGX_Parameter_SetD3d12Resource)(NVSDK_NGX_Parameter *InParameter, const char * InName, ID3D12Resource *InValue);
|
||||
NVSDK_NGX_API void NVSDK_CONV NVSDK_NGX_Parameter_SetD3d12Resource(NVSDK_NGX_Parameter *InParameter, const char * InName, ID3D12Resource *InValue);
|
||||
typedef void (NVSDK_CONV *PFN_NVSDK_NGX_Parameter_SetVoidPointer)(NVSDK_NGX_Parameter *InParameter, const char * InName, void *InValue);
|
||||
NVSDK_NGX_API void NVSDK_CONV NVSDK_NGX_Parameter_SetVoidPointer(NVSDK_NGX_Parameter *InParameter, const char * InName, void *InValue);
|
||||
typedef NVSDK_NGX_Result (NVSDK_CONV *PFN_NVSDK_NGX_Parameter_GetULL)(NVSDK_NGX_Parameter *InParameter, const char * InName, unsigned long long *OutValue);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_Parameter_GetULL(NVSDK_NGX_Parameter *InParameter, const char * InName, unsigned long long *OutValue);
|
||||
typedef NVSDK_NGX_Result (NVSDK_CONV *PFN_NVSDK_NGX_Parameter_GetF)(NVSDK_NGX_Parameter *InParameter, const char * InName, float *OutValue);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_Parameter_GetF(NVSDK_NGX_Parameter *InParameter, const char * InName, float *OutValue);
|
||||
typedef NVSDK_NGX_Result (NVSDK_CONV *PFN_NVSDK_NGX_Parameter_GetD)(NVSDK_NGX_Parameter *InParameter, const char * InName, double *OutValue);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_Parameter_GetD(NVSDK_NGX_Parameter *InParameter, const char * InName, double *OutValue);
|
||||
typedef NVSDK_NGX_Result (NVSDK_CONV *PFN_NVSDK_NGX_Parameter_GetUI)(NVSDK_NGX_Parameter *InParameter, const char * InName, unsigned int *OutValue);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_Parameter_GetUI(NVSDK_NGX_Parameter *InParameter, const char * InName, unsigned int *OutValue);
|
||||
typedef NVSDK_NGX_Result (NVSDK_CONV *PFN_NVSDK_NGX_Parameter_GetI)(NVSDK_NGX_Parameter *InParameter, const char * InName, int *OutValue);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_Parameter_GetI(NVSDK_NGX_Parameter *InParameter, const char * InName, int *OutValue);
|
||||
typedef NVSDK_NGX_Result (NVSDK_CONV *PFN_NVSDK_NGX_Parameter_GetD3d11Resource)(NVSDK_NGX_Parameter *InParameter, const char * InName, ID3D11Resource **OutValue);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_Parameter_GetD3d11Resource(NVSDK_NGX_Parameter *InParameter, const char * InName, ID3D11Resource **OutValue);
|
||||
typedef NVSDK_NGX_Result (NVSDK_CONV *PFN_NVSDK_NGX_Parameter_GetD3d12Resource)(NVSDK_NGX_Parameter *InParameter, const char * InName, ID3D12Resource **OutValue);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_Parameter_GetD3d12Resource(NVSDK_NGX_Parameter *InParameter, const char * InName, ID3D12Resource **OutValue);
|
||||
typedef NVSDK_NGX_Result (NVSDK_CONV *PFN_NVSDK_NGX_Parameter_GetVoidPointer)(NVSDK_NGX_Parameter *InParameter, const char * InName, void **OutValue);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_Parameter_GetVoidPointer(NVSDK_NGX_Parameter *InParameter, const char * InName, void **OutValue);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // #define NVSDK_NGX_PARAMS_H
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: LicenseRef-NvidiaProprietary
|
||||
*
|
||||
* NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
|
||||
* property and proprietary rights in and to this material, related
|
||||
* documentation and any modifications thereto. Any use, reproduction,
|
||||
* disclosure or distribution of this material and related documentation
|
||||
* without an express license agreement from NVIDIA CORPORATION or
|
||||
* its affiliates is strictly prohibited.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef NVSDK_NGX_PARAMS_DLSSD_H
|
||||
#define NVSDK_NGX_PARAMS_DLSSD_H
|
||||
|
||||
#include "nvsdk_ngx_defs_dlssd.h"
|
||||
|
||||
typedef struct NVSDK_NGX_DLSSD_Create_Params
|
||||
{
|
||||
NVSDK_NGX_DLSS_Denoise_Mode InDenoiseMode;
|
||||
NVSDK_NGX_DLSS_Roughness_Mode InRoughnessMode;
|
||||
NVSDK_NGX_DLSS_Depth_Type InUseHWDepth;
|
||||
|
||||
unsigned int InWidth;
|
||||
unsigned int InHeight;
|
||||
unsigned int InTargetWidth;
|
||||
unsigned int InTargetHeight;
|
||||
/*** OPTIONAL ***/
|
||||
NVSDK_NGX_PerfQuality_Value InPerfQualityValue;
|
||||
int InFeatureCreateFlags;
|
||||
bool InEnableOutputSubrects;
|
||||
} NVSDK_NGX_DLSSD_Create_Params;
|
||||
|
||||
|
||||
#endif // #define NVSDK_NGX_PARAMS_DLSSD_H
|
||||
@@ -0,0 +1,138 @@
|
||||
#pragma once
|
||||
/*
|
||||
* Copyright (c) 2021-2024 NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* NVIDIA Corporation and its licensors retain all intellectual property and proprietary
|
||||
* rights in and to this software, related documentation and any modifications thereto.
|
||||
* Any use, reproduction, disclosure or distribution of this software and related
|
||||
* documentation without an express license agreement from NVIDIA Corporation is strictly
|
||||
* prohibited.
|
||||
*
|
||||
* TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED *AS IS*
|
||||
* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS OR IMPLIED,
|
||||
* INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT
|
||||
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF
|
||||
* BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR
|
||||
* INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef NVSDK_NGX_PARAMS_DLSSG_H
|
||||
#define NVSDK_NGX_PARAMS_DLSSG_H
|
||||
|
||||
#include <stdint.h> // for uint64_t
|
||||
|
||||
#include "nvsdk_ngx.h" // DX11/12 here
|
||||
#include "nvsdk_ngx_defs.h"
|
||||
|
||||
typedef struct NVSDK_NGX_DLSSG_Create_Params
|
||||
{
|
||||
unsigned int Width;
|
||||
unsigned int Height;
|
||||
unsigned int NativeBackbufferFormat;
|
||||
unsigned int RenderWidth;
|
||||
unsigned int RenderHeight;
|
||||
bool DynamicResolutionScaling;
|
||||
} NVSDK_NGX_DLSSG_Create_Params;
|
||||
|
||||
typedef struct NVSDK_NGX_DLSSG_Opt_Eval_Params
|
||||
{
|
||||
//! Number of intermediate frames to generate between rendered frames
|
||||
//! (1 = 2x, 2 = 3x, etc.)
|
||||
unsigned int multiFrameCount = 1;
|
||||
//! The index (starting at 1) of the intermediate frame being generated, up
|
||||
//! to multiFrameCount (inclusive)
|
||||
unsigned int multiFrameIndex = 1;
|
||||
|
||||
//! IMPORTANT: All matrices should NOT contain temporal AA jitter offset
|
||||
//! Specifies matrix transformation from the camera view to the clip space.
|
||||
float cameraViewToClip[4][4];
|
||||
//! Specifies matrix transformation from the clip space to the camera view space.
|
||||
float clipToCameraView[4][4];
|
||||
//! Specifies matrix transformation describing lens distortion in clip space.
|
||||
float clipToLensClip[4][4];
|
||||
//! Specifies matrix transformation from the current clip to the previous clip space.
|
||||
float clipToPrevClip[4][4];
|
||||
//! Specifies matrix transformation from the previous clip to the current clip space.
|
||||
float prevClipToClip[4][4];
|
||||
|
||||
//! Specifies clip space jitter offset
|
||||
float jitterOffset[2];
|
||||
//! Specifies scale factors used to normalize motion vectors (so the values are in [-1,1] range)
|
||||
float mvecScale[2];
|
||||
//! Specifies camera pinhole offset.
|
||||
float cameraPinholeOffset[2];
|
||||
//! Specifies camera position in world space.
|
||||
float cameraPos[3];
|
||||
//! Specifies camera up vector in world space.
|
||||
float cameraUp[3];
|
||||
//! Specifies camera right vector in world space.
|
||||
float cameraRight[3];
|
||||
//! Specifies camera forward vector in world space.
|
||||
float cameraFwd[3];
|
||||
|
||||
//! Specifies camera near view plane distance.
|
||||
float cameraNear;
|
||||
//! Specifies camera far view plane distance.
|
||||
float cameraFar;
|
||||
//! Specifies camera field of view in radians.
|
||||
float cameraFOV;
|
||||
//! Specifies camera aspect ratio defined as view space width divided by height.
|
||||
float cameraAspectRatio;
|
||||
|
||||
//! Specifies if tagged color buffers are full HDR (rendering to an HDR monitor) or not
|
||||
bool colorBuffersHDR;
|
||||
//! Specifies if depth values are inverted (value closer to the camera is higher) or not.
|
||||
bool depthInverted;
|
||||
//! Specifies if camera motion is included in the MVec buffer.
|
||||
bool cameraMotionIncluded;
|
||||
//! Specifies if previous frame has no connection to the current one (motion vectors are invalid)
|
||||
bool reset;
|
||||
//! Specifies if Automode overrode the input Reset flag to true.
|
||||
bool automodeOverrideReset;
|
||||
//! Specifies if application is not currently rendering game frames (paused in menu, playing video cut-scenes)
|
||||
bool notRenderingGameFrames;
|
||||
//! Specifies if orthographic projection is used or not.
|
||||
bool orthoProjection;
|
||||
|
||||
//! Specifies which value represents an invalid (un-initialized) value in the motion vectors buffer
|
||||
float motionVectorsInvalidValue;
|
||||
//! Specifies if motion vectors are already dilated or not.
|
||||
bool motionVectorsDilated;
|
||||
|
||||
//! Specifies whether or not fullscreen menu detection should be run
|
||||
bool menuDetectionEnabled;
|
||||
|
||||
NVSDK_NGX_Coordinates mvecsSubrectBase = { 0, 0 };
|
||||
NVSDK_NGX_Dimensions mvecsSubrectSize = { 0, 0 };
|
||||
NVSDK_NGX_Coordinates depthSubrectBase = { 0, 0 };
|
||||
NVSDK_NGX_Dimensions depthSubrectSize = { 0, 0 };
|
||||
|
||||
NVSDK_NGX_Coordinates hudLessSubrectBase = { 0, 0 };
|
||||
NVSDK_NGX_Dimensions hudLessSubrectSize = { 0, 0 };
|
||||
NVSDK_NGX_Coordinates uiSubrectBase = { 0, 0 };
|
||||
NVSDK_NGX_Dimensions uiSubrectSize = { 0, 0 };
|
||||
NVSDK_NGX_Coordinates uiAlphaSubrectBase = { 0, 0 };
|
||||
NVSDK_NGX_Dimensions uiAlphaSubrectSize = { 0, 0 };
|
||||
|
||||
NVSDK_NGX_Coordinates bidirectionalDistFieldSubrectBase = { 0, 0 };
|
||||
NVSDK_NGX_Dimensions bidirectionalDistFieldSubrectSize = { 0, 0 };
|
||||
NVSDK_NGX_PrecisionInfo bidirectionalDistFieldPrecisionInfo = { 0, 0.0f, 0.0f };
|
||||
|
||||
//! Optional heuristic that specifies the minimum depth difference between two objects in screen-space.
|
||||
//! See comment above NVSDK_NGX_DLSSG_Parameter_MinRelativeLinearDepthObjectSeparation for details.
|
||||
float minRelativeLinearDepthObjectSeparation = 40.0f;
|
||||
|
||||
NVSDK_NGX_Coordinates backbufferSubrectBase = { 0, 0 };
|
||||
NVSDK_NGX_Dimensions backbufferSubrectSize = { 0, 0 };
|
||||
|
||||
NVSDK_NGX_Coordinates outputInterpSubrectBase = { 0, 0 };
|
||||
NVSDK_NGX_Dimensions outputInterpSubrectSize = { 0, 0 };
|
||||
NVSDK_NGX_Coordinates outputRealSubrectBase = { 0, 0 };
|
||||
NVSDK_NGX_Dimensions outputRealSubrectSize = { 0, 0 };
|
||||
} NVSDK_NGX_DLSSG_Opt_Eval_Params;
|
||||
|
||||
#endif // NVSDK_NGX_PARAMS_DLSSG_H
|
||||
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: LicenseRef-NvidiaProprietary
|
||||
*
|
||||
* NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
|
||||
* property and proprietary rights in and to this material, related
|
||||
* documentation and any modifications thereto. Any use, reproduction,
|
||||
* disclosure or distribution of this material and related documentation
|
||||
* without an express license agreement from NVIDIA CORPORATION or
|
||||
* its affiliates is strictly prohibited.
|
||||
*/
|
||||
|
||||
#ifndef NVSDK_NGX_STANDALONE_COMMON_H
|
||||
#define NVSDK_NGX_STANDALONE_COMMON_H
|
||||
|
||||
#if defined(NVSDK_NGX_HEADER_ONLY)
|
||||
|
||||
#include <mutex>
|
||||
typedef std::recursive_mutex NGXMutex;
|
||||
typedef std::lock_guard<std::recursive_mutex> NGXLock;
|
||||
|
||||
#define NGX_CONCAT_IMPL(A, B) A##B
|
||||
#define NGX_CONCAT(A, B) NGX_CONCAT_IMPL(A, B)
|
||||
#define NGX_CONCAT_3_IMPL(A, B, C) A##B##C
|
||||
#define NGX_CONCAT_3(A, B, C) NGX_CONCAT_3_IMPL(A, B, C)
|
||||
#define NGX_CONCAT_4_IMPL(A, B, C, D) A##B##C##D
|
||||
#define NGX_CONCAT_4(A, B, C, D) NGX_CONCAT_4_IMPL(A, B, C, D)
|
||||
#define NGX_EXPAND(x) x
|
||||
#define NGX_STR_IMPL(x) #x
|
||||
#define NGX_STR(x) NGX_STR_IMPL(x)
|
||||
|
||||
/**
|
||||
* Recursively applies a target macro for each pair of arguments in a supplied list.
|
||||
*
|
||||
* This chain of macros allows iterating over a variadic list of arguments in pairs.
|
||||
* Each macro invokes the target macro X with the current pair (a, b), and then passes
|
||||
* the remaining arguments to the next macro down the chain.
|
||||
*
|
||||
* Supports processing up to 40 total arguments (20 pairs).
|
||||
*/
|
||||
#define NGX_FE_2(X, a, b) X(a, b)
|
||||
#define NGX_FE_4(X, a, b, ...) X(a, b) NGX_FE_2(X, __VA_ARGS__)
|
||||
#define NGX_FE_6(X, a, b, ...) X(a, b) NGX_FE_4(X, __VA_ARGS__)
|
||||
#define NGX_FE_8(X, a, b, ...) X(a, b) NGX_FE_6(X, __VA_ARGS__)
|
||||
#define NGX_FE_10(X, a, b, ...) X(a, b) NGX_FE_8(X, __VA_ARGS__)
|
||||
#define NGX_FE_12(X, a, b, ...) X(a, b) NGX_FE_10(X, __VA_ARGS__)
|
||||
#define NGX_FE_14(X, a, b, ...) X(a, b) NGX_FE_12(X, __VA_ARGS__)
|
||||
#define NGX_FE_16(X, a, b, ...) X(a, b) NGX_FE_14(X, __VA_ARGS__)
|
||||
#define NGX_FE_18(X, a, b, ...) X(a, b) NGX_FE_16(X, __VA_ARGS__)
|
||||
#define NGX_FE_20(X, a, b, ...) X(a, b) NGX_FE_18(X, __VA_ARGS__)
|
||||
#define NGX_FE_22(X, a, b, ...) X(a, b) NGX_FE_20(X, __VA_ARGS__)
|
||||
#define NGX_FE_24(X, a, b, ...) X(a, b) NGX_FE_22(X, __VA_ARGS__)
|
||||
#define NGX_FE_26(X, a, b, ...) X(a, b) NGX_FE_24(X, __VA_ARGS__)
|
||||
#define NGX_FE_28(X, a, b, ...) X(a, b) NGX_FE_26(X, __VA_ARGS__)
|
||||
#define NGX_FE_30(X, a, b, ...) X(a, b) NGX_FE_28(X, __VA_ARGS__)
|
||||
#define NGX_FE_32(X, a, b, ...) X(a, b) NGX_FE_30(X, __VA_ARGS__)
|
||||
#define NGX_FE_34(X, a, b, ...) X(a, b) NGX_FE_32(X, __VA_ARGS__)
|
||||
#define NGX_FE_36(X, a, b, ...) X(a, b) NGX_FE_34(X, __VA_ARGS__)
|
||||
#define NGX_FE_38(X, a, b, ...) X(a, b) NGX_FE_36(X, __VA_ARGS__)
|
||||
#define NGX_FE_40(X, a, b, ...) X(a, b) NGX_FE_38(X, __VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Internal helper to extract the argument count passed to a macro
|
||||
*/
|
||||
#define NGX_FE_NARGS_I(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \
|
||||
_11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \
|
||||
_21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \
|
||||
_31, _32, _33, _34, _35, _36, _37, _38, _39, _40, N, ...) N
|
||||
|
||||
/**
|
||||
* Returns the number of arguments passed in a variadic list up to a maximum of 40 arguments
|
||||
*/
|
||||
#define NGX_FE_NARGS(...) NGX_EXPAND(NGX_FE_NARGS_I(__VA_ARGS__, \
|
||||
40, 39, 38, 37, 36, 35, 34, 33, 32, 31, \
|
||||
30, 29, 28, 27, 26, 25, 24, 23, 22, 21, \
|
||||
20, 19, 18, 17, 16, 15, 14, 13, 12, 11, \
|
||||
10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))
|
||||
|
||||
#define NGX_FOREACH_N(N, X, ...) NGX_CONCAT(NGX_FE_, N)(X, __VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Iterates over a variadic list of arguments in pairs, applying macro X to each pair.
|
||||
*/
|
||||
#define NGX_FOREACH(X, ...) NGX_FOREACH_N(NGX_FE_NARGS(__VA_ARGS__), X, __VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Helper macro to generate default initialiser code for all NGX function pointers passed
|
||||
* into NVSDK_NGX_DEFINE_API.
|
||||
*/
|
||||
#define NGX_PFNS_DECL(namespace, name) NGX_CONCAT_4(PFN_NVSDK_NGX_, namespace, _, name) name = nullptr;
|
||||
|
||||
/**
|
||||
* Generates a backend-specific bootstrap code that defines the main struct holding all
|
||||
* the function pointers for this backend.
|
||||
*
|
||||
* The list of functions passed into this macro are tuples of the form (namespace, name).
|
||||
*
|
||||
* "namespace" is the prefix to apply to this function when named internally. This is
|
||||
* typically the name of the backend (e.g. "CUDA" or "D3D12"), but may differ if the function
|
||||
* as exported from the SDK is different to the symbol as exported from NGX Core.
|
||||
*
|
||||
* "name" is the name of the function as exported from NGX Core without any prefixes,
|
||||
* e.g. "Init" or "GetFeatureRequirements".
|
||||
*
|
||||
* This requires setting NVSDK_NGX_BACKEND_NAME first to get the overall backend name.
|
||||
*/
|
||||
#define NVSDK_NGX_DEFINE_API(is_inited, ...) \
|
||||
struct NGX_CONCAT_3(NGX_API_, NVSDK_NGX_BACKEND_NAME, _Lib) \
|
||||
{ \
|
||||
NGX_FOREACH(NGX_PFNS_DECL, __VA_ARGS__) \
|
||||
bool isInited() const \
|
||||
{ \
|
||||
return is_inited; \
|
||||
} \
|
||||
}; \
|
||||
struct NGX_CONCAT_3(NGX_Context_, NVSDK_NGX_BACKEND_NAME, _Lib) \
|
||||
{ \
|
||||
NGX_CONCAT_3(NGX_API_, NVSDK_NGX_BACKEND_NAME, _Lib) \
|
||||
API; \
|
||||
}; \
|
||||
static NGX_CONCAT_3(NGX_Context_, NVSDK_NGX_BACKEND_NAME, _Lib) GContext; \
|
||||
static NGXLibHandle GLib = nullptr; \
|
||||
static NGXMutex NGX_CONCAT(g_sdkLibMutex, NVSDK_NGX_BACKEND_NAME);
|
||||
|
||||
/**
|
||||
* Helper macro to generate initialiser code for all NGX function pointers passed into
|
||||
* NVSDK_NGX_DEFINE_INIT_COMMON.
|
||||
*/
|
||||
#define NGX_PFNS_GETSYMBOL(namespace, name) \
|
||||
GContext.API.name = (NGX_CONCAT_4(PFN_NVSDK_NGX_, namespace, _, name))NGXGetLibrarySymbol(GLib, NGX_STR(NGX_CONCAT_4(NVSDK_NGX_, NVSDK_NGX_BACKEND_NAME, _, name)));
|
||||
|
||||
/**
|
||||
* Generates a backend-specific Init_Common() function that loads the NGX Core library
|
||||
* and assigns the function pointers set up by NVSDK_NGX_DEFINE_API() to the exported
|
||||
* functions from NGX Core.
|
||||
*
|
||||
* This requires setting NVSDK_NGX_BACKEND_NAME first to get the overall backend name,
|
||||
* and takes the same list of functions that NVSDK_NGX_DEFINE_API() does.
|
||||
*/
|
||||
#define NVSDK_NGX_DEFINE_INIT_COMMON(...) \
|
||||
NVSDK_NGX_Result NGX_CONCAT_3(NVSDK_NGX_, NVSDK_NGX_BACKEND_NAME, _Init_Common()) \
|
||||
{ \
|
||||
if (GContext.API.isInited()) \
|
||||
{ \
|
||||
return NVSDK_NGX_Result_Success; \
|
||||
} \
|
||||
GContext = NGX_CONCAT_3(NGX_Context_, NVSDK_NGX_BACKEND_NAME, _Lib()); \
|
||||
\
|
||||
NVSDK_NGX_LUID luid = {0}; \
|
||||
\
|
||||
if (GLib == nullptr) \
|
||||
{ \
|
||||
GLib = NGXLoadCoreLibrary(luid); \
|
||||
} \
|
||||
\
|
||||
if (GLib) \
|
||||
{ \
|
||||
NGX_FOREACH(NGX_PFNS_GETSYMBOL, __VA_ARGS__) \
|
||||
} \
|
||||
\
|
||||
if (!GContext.API.isInited()) \
|
||||
{ \
|
||||
GContext = NGX_CONCAT_3(NGX_Context_, NVSDK_NGX_BACKEND_NAME, _Lib()); \
|
||||
return NVSDK_NGX_Result_FAIL_FeatureNotSupported; \
|
||||
} \
|
||||
\
|
||||
return NVSDK_NGX_Result_Success; \
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a wrapper for a given API that checks if the SDK is initialised, and if
|
||||
* so forwards the API call to the function pointer on NGX Core.
|
||||
*/
|
||||
#define NVSDK_NGX_DEFINE_WRAPPER(fn, params, args) \
|
||||
NVSDK_NGX_Result NVSDK_CONV NGX_CONCAT_4(NVSDK_NGX_, NVSDK_NGX_BACKEND_NAME, _, fn) params \
|
||||
{ \
|
||||
if (!GContext.API.isInited()) \
|
||||
return NVSDK_NGX_Result_FAIL_NotInitialized; \
|
||||
if (!GContext.API.fn) \
|
||||
return NVSDK_NGX_Result_FAIL_OutOfDate; \
|
||||
return GContext.API.fn args; \
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define NGXThreadLocal __declspec(thread)
|
||||
#else
|
||||
#define NGXThreadLocal __thread
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Helper struct to safely manage and dispatch NGX progress callbacks.
|
||||
*
|
||||
* This structure bridges the gap between the expected internal NGX callback signature
|
||||
* (which uses a bool reference for cancellation) and the user-provided C-style callback
|
||||
* (which expects a pointer). It safely stores the user's callback in thread-local storage
|
||||
* during feature evaluation to ensure thread safety across concurrent API calls.
|
||||
*/
|
||||
struct NGXProgressCallbackHelper
|
||||
{
|
||||
static NGXThreadLocal PFN_NVSDK_NGX_ProgressCallback_C tls_OriginalCallback;
|
||||
static void s_ReplacementCallback(float InProgress, bool &OutShouldCancel)
|
||||
{
|
||||
if (tls_OriginalCallback)
|
||||
{
|
||||
return tls_OriginalCallback(InProgress, &OutShouldCancel);
|
||||
}
|
||||
}
|
||||
|
||||
template<class FuncType, class CmdListType >
|
||||
static NVSDK_NGX_Result EvaluateFeature(FuncType EvaluateFeatureFunc, CmdListType InStream,
|
||||
const NVSDK_NGX_Handle *InHandle, const NVSDK_NGX_Parameter *InParameters,
|
||||
PFN_NVSDK_NGX_ProgressCallback_C InCallback)
|
||||
{
|
||||
NGXProgressCallbackHelper::tls_OriginalCallback = InCallback;
|
||||
NVSDK_NGX_Result Result = EvaluateFeatureFunc(InStream, InHandle, InParameters,
|
||||
InCallback ? NGXProgressCallbackHelper::s_ReplacementCallback : nullptr);
|
||||
NGXProgressCallbackHelper::tls_OriginalCallback = nullptr;
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<class FuncType>
|
||||
static NVSDK_NGX_Result EvaluateFeature(FuncType EvaluateFeatureFunc,
|
||||
const NVSDK_NGX_Handle *InHandle, const NVSDK_NGX_Parameter *InParameters,
|
||||
PFN_NVSDK_NGX_ProgressCallback_C InCallback)
|
||||
{
|
||||
NGXProgressCallbackHelper::tls_OriginalCallback = InCallback;
|
||||
NVSDK_NGX_Result Result = EvaluateFeatureFunc(InHandle, InParameters,
|
||||
InCallback ? NGXProgressCallbackHelper::s_ReplacementCallback : nullptr);
|
||||
NGXProgressCallbackHelper::tls_OriginalCallback = nullptr;
|
||||
return Result;
|
||||
}
|
||||
};
|
||||
|
||||
NGXThreadLocal PFN_NVSDK_NGX_ProgressCallback_C NGXProgressCallbackHelper::tls_OriginalCallback = nullptr;
|
||||
|
||||
#endif /* NVSDK_NGX_HEADER_ONLY */
|
||||
#endif /* NVSDK_NGX_STANDALONE_COMMON_H */
|
||||
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: LicenseRef-NvidiaProprietary
|
||||
*
|
||||
* NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
|
||||
* property and proprietary rights in and to this material, related
|
||||
* documentation and any modifications thereto. Any use, reproduction,
|
||||
* disclosure or distribution of this material and related documentation
|
||||
* without an express license agreement from NVIDIA CORPORATION or
|
||||
* its affiliates is strictly prohibited.
|
||||
*/
|
||||
|
||||
#ifndef NVSDK_NGX_STANDALONE_CUDA_H
|
||||
#define NVSDK_NGX_STANDALONE_CUDA_H
|
||||
|
||||
#if defined(NVSDK_NGX_HEADER_ONLY)
|
||||
|
||||
#include "nvsdk_ngx_loader.h"
|
||||
#include "nvsdk_ngx_standalone_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef NVSDK_NGX_Result(NVSDK_CONV *PFN_NVSDK_NGX_CORE_CUDA_Init)(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, NVSDK_NGX_Version InSDKVersion);
|
||||
typedef NVSDK_NGX_Result(NVSDK_CONV *PFN_NVSDK_NGX_CORE_CUDA_Init_Ext)(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, NVSDK_NGX_Version InSDKVersion, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo);
|
||||
typedef NVSDK_NGX_Result(NVSDK_CONV *PFN_NVSDK_NGX_CORE_CUDA_Init_Ext1)(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, NVSDK_NGX_CUDADevice *InDevice, NVSDK_NGX_Version InSDKVersion, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo);
|
||||
typedef NVSDK_NGX_Result(NVSDK_CONV *PFN_NVSDK_NGX_CORE_CUDA_Init_ProjectID)(const char *InProjectId, NVSDK_NGX_EngineType InEngineType, const char *InEngineVersion, const wchar_t *InApplicationDataPath, NVSDK_NGX_Version InSDKVersion, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo);
|
||||
typedef NVSDK_NGX_Result(NVSDK_CONV *PFN_NVSDK_NGX_CUDA_Shutdown)();
|
||||
typedef NVSDK_NGX_Result(NVSDK_CONV *PFN_NVSDK_NGX_CUDA_Shutdown1)(NVSDK_NGX_CUDADevice *pDevice, unsigned int &outNDevicesLeft);
|
||||
typedef NVSDK_NGX_Result(NVSDK_CONV *PFN_NVSDK_NGX_CUDA_GetParameters)(NVSDK_NGX_Parameter **OutParameters);
|
||||
typedef NVSDK_NGX_Result(NVSDK_CONV *PFN_NVSDK_NGX_CUDA_GetScratchBufferSize)(NVSDK_NGX_Feature InFeatureId, const NVSDK_NGX_Parameter *InParameters, size_t *OutSizeInBytes);
|
||||
typedef NVSDK_NGX_Result(NVSDK_CONV *PFN_NVSDK_NGX_CUDA_CreateFeature)(NVSDK_NGX_Feature InFeatureId, const NVSDK_NGX_Parameter *InParameters, NVSDK_NGX_Handle **OutHandle);
|
||||
typedef NVSDK_NGX_Result(NVSDK_CONV *PFN_NVSDK_NGX_CUDA_CreateFeature1)(NVSDK_NGX_CUDADevice *InDevice, NVSDK_NGX_Feature InFeatureId, const NVSDK_NGX_Parameter *InParameters, NVSDK_NGX_Handle **OutHandle);
|
||||
typedef NVSDK_NGX_Result(NVSDK_CONV *PFN_NVSDK_NGX_CUDA_EvaluateFeature)(const NVSDK_NGX_Handle *InFeature, const NVSDK_NGX_Parameter *InParameters, PFN_NVSDK_NGX_ProgressCallback InCallback);
|
||||
typedef NVSDK_NGX_Result(NVSDK_CONV *PFN_NVSDK_NGX_CUDA_ReleaseFeature)(NVSDK_NGX_Handle *InHandle);
|
||||
typedef NVSDK_NGX_Result(NVSDK_CONV *PFN_NVSDK_NGX_CUDA_GetFeatureRequirements)(int CudaDevice, const NVSDK_NGX_FeatureDiscoveryInfo *FeatureDiscoveryInfo, NVSDK_NGX_FeatureRequirement *OutSupported);
|
||||
typedef NVSDK_NGX_Result(NVSDK_CONV *PFN_NVSDK_NGX_CUDA_AllocateParameters)(NVSDK_NGX_Parameter **OutParameters);
|
||||
typedef NVSDK_NGX_Result(NVSDK_CONV *PFN_NVSDK_NGX_CUDA_GetCapabilityParameters)(NVSDK_NGX_Parameter **OutParameters);
|
||||
typedef NVSDK_NGX_Result(NVSDK_CONV *PFN_NVSDK_NGX_CUDA_DestroyParameters)(NVSDK_NGX_Parameter *InParameters);
|
||||
|
||||
#define CUDA_IS_INITED \
|
||||
((Init != nullptr || Init_Ext != nullptr || Init_Ext1 != nullptr) && \
|
||||
(Shutdown != nullptr || Shutdown1 != nullptr) && \
|
||||
(GetParameters != nullptr || GetCapabilityParameters != nullptr) && \
|
||||
(CreateFeature != nullptr || CreateFeature1 != nullptr) && \
|
||||
EvaluateFeature != nullptr && \
|
||||
ReleaseFeature != nullptr)
|
||||
|
||||
#define CUDA_FNS \
|
||||
CORE_CUDA, Init, \
|
||||
CORE_CUDA, Init_Ext, \
|
||||
CORE_CUDA, Init_Ext1, \
|
||||
CORE_CUDA, Init_ProjectID, \
|
||||
CUDA, Shutdown, \
|
||||
CUDA, Shutdown1, \
|
||||
CUDA, GetParameters, \
|
||||
CUDA, GetScratchBufferSize, \
|
||||
CUDA, CreateFeature, \
|
||||
CUDA, CreateFeature1, \
|
||||
CUDA, EvaluateFeature, \
|
||||
CUDA, ReleaseFeature, \
|
||||
CUDA, GetFeatureRequirements, \
|
||||
CUDA, AllocateParameters, \
|
||||
CUDA, GetCapabilityParameters, \
|
||||
CUDA, DestroyParameters
|
||||
|
||||
#define NVSDK_NGX_BACKEND_NAME CUDA
|
||||
|
||||
NVSDK_NGX_DEFINE_API(CUDA_IS_INITED, CUDA_FNS)
|
||||
NVSDK_NGX_DEFINE_INIT_COMMON(CUDA_FNS)
|
||||
|
||||
NVSDK_NGX_Result NVSDK_NGX_CUDA_Init(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo, NVSDK_NGX_Version InSDKVersion)
|
||||
{
|
||||
NGXLock lock(g_sdkLibMutexCUDA);
|
||||
NVSDK_NGX_Result res = NVSDK_NGX_CUDA_Init_Common();
|
||||
if (res != NVSDK_NGX_Result_Success)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
|
||||
if (GContext.API.Init_Ext)
|
||||
{
|
||||
return GContext.API.Init_Ext(InApplicationId, InApplicationDataPath, InSDKVersion, InFeatureInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (InFeatureInfo != nullptr && InFeatureInfo->PathListInfo.Path != nullptr && InFeatureInfo->PathListInfo.Length > 0)
|
||||
{
|
||||
// App has sent a non-empty list of extra paths to check for the feature binary but Init_Ext entrypoint to Core doesn't exist.
|
||||
// Fail with OUT_OF_DATE.
|
||||
return NVSDK_NGX_Result_FAIL_OutOfDate;
|
||||
}
|
||||
return GContext.API.Init(InApplicationId, InApplicationDataPath, InSDKVersion);
|
||||
}
|
||||
}
|
||||
|
||||
NVSDK_NGX_Result NVSDK_NGX_CUDA_Init1(unsigned long long InApplicationId, const wchar_t* InApplicationDataPath, NVSDK_NGX_CUDADevice* InDevice, const NVSDK_NGX_FeatureCommonInfo* InFeatureInfo, NVSDK_NGX_Version InSDKVersion)
|
||||
{
|
||||
NGXLock lock(g_sdkLibMutexCUDA);
|
||||
NVSDK_NGX_Result res = NVSDK_NGX_CUDA_Init_Common();
|
||||
if (res != NVSDK_NGX_Result_Success)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
if (!InDevice)
|
||||
{
|
||||
return NVSDK_NGX_Result_FAIL_InvalidParameter;
|
||||
}
|
||||
|
||||
if (GContext.API.Init_Ext1)
|
||||
{
|
||||
return GContext.API.Init_Ext1(InApplicationId, InApplicationDataPath, InDevice, InSDKVersion, InFeatureInfo);
|
||||
}
|
||||
// Do not failback as Init_Ext1 is needed for multi-threaded which is the reason for NVSDK_NGX_CUDA_Init1.
|
||||
return NVSDK_NGX_Result_FAIL_OutOfDate;
|
||||
}
|
||||
|
||||
NVSDK_NGX_Result NVSDK_NGX_CUDA_Init_with_ProjectID(const char *InProjectId, NVSDK_NGX_EngineType InEngineType, const char *InEngineVersion, const wchar_t *InApplicationDataPath, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo, NVSDK_NGX_Version InSDKVersion)
|
||||
{
|
||||
NGXLock lock(g_sdkLibMutexCUDA);
|
||||
NVSDK_NGX_Result res = NVSDK_NGX_CUDA_Init_Common();
|
||||
if (res != NVSDK_NGX_Result_Success)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
|
||||
if (GContext.API.Init_ProjectID)
|
||||
{
|
||||
return GContext.API.Init_ProjectID(InProjectId, InEngineType, InEngineVersion, InApplicationDataPath, InSDKVersion, InFeatureInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
// New SDK, but old driver, with no support for project ID
|
||||
return NVSDK_NGX_Result_FAIL_OutOfDate;
|
||||
}
|
||||
}
|
||||
|
||||
NVSDK_NGX_Result NVSDK_NGX_CUDA_Shutdown1(NVSDK_NGX_CUDADevice *pDevice)
|
||||
{
|
||||
NGXLock lock(g_sdkLibMutexCUDA);
|
||||
|
||||
NVSDK_NGX_Result result = NVSDK_NGX_Result_Success;
|
||||
unsigned int nDevicesLeft = 0;
|
||||
if (pDevice)
|
||||
{
|
||||
if (!GContext.API.Shutdown1) return NVSDK_NGX_Result_FAIL_NotInitialized;
|
||||
result = GContext.API.Shutdown1(pDevice, nDevicesLeft);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GContext.API.Shutdown1)
|
||||
result = GContext.API.Shutdown1(nullptr, nDevicesLeft);
|
||||
else if (GContext.API.Shutdown)
|
||||
result = GContext.API.Shutdown();
|
||||
else return NVSDK_NGX_Result_FAIL_NotInitialized;
|
||||
}
|
||||
if (result == NVSDK_NGX_Result_Success && nDevicesLeft == 0)
|
||||
{
|
||||
GContext = NGX_Context_CUDA_Lib();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
NVSDK_NGX_Result NVSDK_NGX_CUDA_Shutdown()
|
||||
{
|
||||
return NVSDK_NGX_CUDA_Shutdown1(nullptr);
|
||||
}
|
||||
|
||||
NVSDK_NGX_DEFINE_WRAPPER(GetParameters, (NVSDK_NGX_Parameter **OutParameters), (OutParameters))
|
||||
NVSDK_NGX_DEFINE_WRAPPER(AllocateParameters, (NVSDK_NGX_Parameter **OutParameters), (OutParameters))
|
||||
NVSDK_NGX_DEFINE_WRAPPER(GetCapabilityParameters, (NVSDK_NGX_Parameter **OutParameters), (OutParameters))
|
||||
NVSDK_NGX_DEFINE_WRAPPER(DestroyParameters, (NVSDK_NGX_Parameter* InParameters), (InParameters))
|
||||
NVSDK_NGX_DEFINE_WRAPPER(GetScratchBufferSize, (NVSDK_NGX_Feature InFeatureId, const NVSDK_NGX_Parameter *InParameters, size_t *OutSizeInBytes), (InFeatureId, InParameters, OutSizeInBytes))
|
||||
NVSDK_NGX_DEFINE_WRAPPER(CreateFeature, (NVSDK_NGX_Feature InFeatureId, const NVSDK_NGX_Parameter *InParameters, NVSDK_NGX_Handle **OutHandle), (InFeatureId, InParameters, OutHandle))
|
||||
NVSDK_NGX_DEFINE_WRAPPER(CreateFeature1, (NVSDK_NGX_CUDADevice *InDevice, NVSDK_NGX_Feature InFeatureId, const NVSDK_NGX_Parameter *InParameters, NVSDK_NGX_Handle **OutHandle), (InDevice, InFeatureId, InParameters, OutHandle))
|
||||
NVSDK_NGX_DEFINE_WRAPPER(ReleaseFeature, (NVSDK_NGX_Handle *InHandle), (InHandle))
|
||||
|
||||
// GetFeatureRequirements can be called before Init, so it loads the library
|
||||
// on demand using a zero LUID (registry fallback), matching the behavior in
|
||||
// nvsdk_ngx_cuda_lib.cpp:420-441.
|
||||
NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_GetFeatureRequirements(
|
||||
int CudaDevice, const NVSDK_NGX_FeatureDiscoveryInfo *FeatureDiscoveryInfo,
|
||||
NVSDK_NGX_FeatureRequirement *OutSupported)
|
||||
{
|
||||
if (!GLib)
|
||||
{
|
||||
NVSDK_NGX_LUID luid = {};
|
||||
GLib = NGXLoadCoreLibrary(luid);
|
||||
if (!GLib) return NVSDK_NGX_Result_FAIL_PlatformError;
|
||||
GContext.API.GetFeatureRequirements =
|
||||
(PFN_NVSDK_NGX_CUDA_GetFeatureRequirements)NGXGetLibrarySymbol(GLib, "NVSDK_NGX_CUDA_GetFeatureRequirements");
|
||||
}
|
||||
if (!GContext.API.GetFeatureRequirements) return NVSDK_NGX_Result_FAIL_NotImplemented;
|
||||
return GContext.API.GetFeatureRequirements(CudaDevice, FeatureDiscoveryInfo, OutSupported);
|
||||
}
|
||||
|
||||
NVSDK_NGX_DEFINE_WRAPPER(EvaluateFeature, (const NVSDK_NGX_Handle *InHandle, const NVSDK_NGX_Parameter *InParameters, PFN_NVSDK_NGX_ProgressCallback InCallback), (InHandle, InParameters, InCallback))
|
||||
|
||||
NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_CUDA_EvaluateFeature_C(
|
||||
const NVSDK_NGX_Handle *InHandle, const NVSDK_NGX_Parameter *InParameters,
|
||||
PFN_NVSDK_NGX_ProgressCallback_C InCallback)
|
||||
{
|
||||
if (!GContext.API.isInited()) return NVSDK_NGX_Result_FAIL_NotInitialized;
|
||||
if (!GContext.API.EvaluateFeature) return NVSDK_NGX_Result_FAIL_OutOfDate;
|
||||
return NGXProgressCallbackHelper::EvaluateFeature(GContext.API.EvaluateFeature, InHandle, InParameters, InCallback);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* NVSDK_NGX_HEADER_ONLY */
|
||||
#endif /* NVSDK_NGX_STANDALONE_CUDA_H */
|
||||
@@ -0,0 +1,768 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: LicenseRef-NvidiaProprietary
|
||||
*
|
||||
* NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
|
||||
* property and proprietary rights in and to this material, related
|
||||
* documentation and any modifications thereto. Any use, reproduction,
|
||||
* disclosure or distribution of this material and related documentation
|
||||
* without an express license agreement from NVIDIA CORPORATION or
|
||||
* its affiliates is strictly prohibited.
|
||||
*/
|
||||
|
||||
/*
|
||||
* HOW TO USE:
|
||||
*
|
||||
* IMPORTANT: Methods in this library are NOT thread safe. It is up to the
|
||||
* client to ensure that thread safety is enforced as needed.
|
||||
*
|
||||
* 1) Call NVSDK_CONV NVSDK_NGX_D3D11/D3D12/CUDA_Init and pass your app Id
|
||||
* and other parameters. This will initialize SDK or return an error code
|
||||
* if SDK cannot run on target machine. Depending on error user might
|
||||
* need to update drivers. Please note that application Id is provided
|
||||
* by NVIDIA so if you do not have one please contact us.
|
||||
*
|
||||
* 2) Call NVSDK_NGX_D3D11/D3D12/CUDA_GetParameters to obtain pointer to
|
||||
* interface used to pass parameters to SDK. Interface instance is
|
||||
* allocated and released by SDK so there is no need to do any memory
|
||||
* management on client side.
|
||||
*
|
||||
* 3) Set key parameters for the feature you want to use. For example,
|
||||
* width and height are required for all features and they can be
|
||||
* set like this:
|
||||
* Params->Set(NVSDK_NGX_Parameter_Width,MY_WIDTH);
|
||||
* Params->Set(NVSDK_NGX_Parameter_Height,MY_HEIGHT);
|
||||
*
|
||||
* Please refer to samples since different features need different
|
||||
* parameters and hints.
|
||||
*
|
||||
* 4) Call NVSDK_NGX_D3D11/D3D12/CUDA_GetScratchBufferSize to obtain size of
|
||||
* the scratch buffer needed by specific feature. This D3D or CUDA buffer
|
||||
* should be allocated by client and passed as:
|
||||
* Params->Set(NVSDK_NGX_Parameter_Scratch,MY_SCRATCH_POINTER)
|
||||
* Params->Set(NVSDK_NGX_Parameter_Scratch_SizeInBytes,MY_SCRATCH_SIZE_IN_BYTES)
|
||||
* NOTE: Returned size can be 0 if feature does not use any scratch buffer.
|
||||
* It is OK to use bigger buffer or reuse buffers across features as long
|
||||
* as minimum size requirement is met.
|
||||
*
|
||||
* 5) Call NVSDK_NGX_D3D11/D3D12/CUDA_CreateFeature to create feature you need.
|
||||
* On success SDK will return a handle which must be used in any successive
|
||||
* calls to SDK which require feature handle. SDK will use all parameters
|
||||
* and hints provided by client to generate feature. If feature with the same
|
||||
* parameters already exists and error code will be returned.
|
||||
*
|
||||
* 6) Call NVSDK_NGX_D3D11/D3D12/CUDA_EvaluateFeature to invoke execution of
|
||||
* specific feature. Before feature can be evaluated input parameters must
|
||||
* be specified (like for example color/albedo buffer, motion vectors etc)
|
||||
*
|
||||
* 6) Call NVSDK_NGX_D3D11/D3D12/CUDA_ReleaseFeature when feature is no longer
|
||||
* needed. After this call feature handle becomes invalid and cannot be used.
|
||||
*
|
||||
* 7) Call NVSDK_NGX_D3D11/D3D12/CUDA_Shutdown when SDK is no longer needed to
|
||||
* release all resources.
|
||||
|
||||
* Contact: [email protected]
|
||||
*/
|
||||
|
||||
|
||||
#ifndef NVSDK_NGX_VK_H
|
||||
#define NVSDK_NGX_VK_H
|
||||
|
||||
#include "nvsdk_ngx_defs.h"
|
||||
#include "nvsdk_ngx_defs_vk.h"
|
||||
#include "nvsdk_ngx_params.h"
|
||||
#ifndef __cplusplus
|
||||
#include <stdbool.h>
|
||||
#include <wchar.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NVSDK_NGX_VULKAN_RequiredExtensions [Vulkan only]
|
||||
// -------------------------------------
|
||||
// DEPRECATED: Use NVSDK_NGX_VULKAN_GetFeatureInstanceExtensionRequirements() and
|
||||
// NVSDK_NGX_VULKAN_GetFeatureRequirements() instead.
|
||||
//
|
||||
// Retrieves the instance and device extensions required by NGX.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// This function returns the instance and device extensions required by
|
||||
// NGX. It is deprecated and should be replaced with
|
||||
// NVSDK_NGX_VULKAN_GetFeatureInstanceExtensionRequirements() and
|
||||
// NVSDK_NGX_VULKAN_GetFeatureRequirements().
|
||||
//
|
||||
// PARAMETERS:
|
||||
// OutInstanceExtCount:
|
||||
// Returns the number of instance extensions NGX requires.
|
||||
//
|
||||
// OutInstanceExts:
|
||||
// Returns a pointer to *OutInstanceExtCount strings of instance extensions.
|
||||
//
|
||||
// OutDeviceExtCount:
|
||||
// Returns the number of device extensions NGX requires.
|
||||
//
|
||||
// OutDeviceExts:
|
||||
// Returns a pointer to *OutDeviceExtCount strings of device extensions.
|
||||
//
|
||||
// RETURNS:
|
||||
// NVSDK_NGX_Result indicating success or failure.
|
||||
//
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_RequiredExtensions(unsigned int *OutInstanceExtCount, const char ***OutInstanceExts, unsigned int *OutDeviceExtCount, const char ***OutDeviceExts);
|
||||
|
||||
// NOTE: Functions under the same name and different function signatures exist
|
||||
// between the NGX SDK, NGX Core (driver), and NGX Snippets. To discern the
|
||||
// different signatures here we check if NGX_SNIPPET_BUILD is defined. When that
|
||||
// is the case we know that the function signature in-use should be that of
|
||||
// between NGX Core and the Snippet. Otherwise the signature should be between
|
||||
// NGX SDK and NGX Core.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NVSDK_NGX_Init
|
||||
// -----------------------------------------------------------------------------
|
||||
// Initializes a new SDK instance.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Initializes a new SDK instance. Most NGX SDK functions require the NGX
|
||||
// SDK to be initialized for the corresponding graphics API and device to
|
||||
// function properly.
|
||||
//
|
||||
// NVSDK_NGX_Init requires an application ID provided by NVIDIA. If an
|
||||
// application ID is not available, use NVSDK_NGX_Init_with_ProjectID to
|
||||
// supply your own identifier.
|
||||
//
|
||||
// Be sure to call NVSDK_NGX_Shutdown to shut down the SDK when it is no
|
||||
// longer needed.
|
||||
//
|
||||
// PARAMETERS:
|
||||
// InApplicationId:
|
||||
// Unique ID provided by NVIDIA.
|
||||
//
|
||||
// InApplicationDataPath:
|
||||
// Directory to store logs and other temporary files. Write access is
|
||||
// required. Typically, this would be next to the application executable,
|
||||
// or in a location like Documents or ProgramData.
|
||||
//
|
||||
// InInstance/InPD/InDevice:
|
||||
// Vulkan Instance, PhysicalDevice, and Device to use.
|
||||
//
|
||||
// InGIPA/InGDPA:
|
||||
// Optional Vulkan function pointers to vkGetInstanceProcAddr and
|
||||
// vkGetDeviceProcAddr.
|
||||
//
|
||||
// InFeatureInfo:
|
||||
// Contains information common to all features, including a list of paths
|
||||
// where feature DLLs can be located, other than the default path (application directory).
|
||||
//
|
||||
// InSDKVersion:
|
||||
// Version of the SDK currently in use. Typically, this should be left as
|
||||
// the default value, NVSDK_NGX_Version_API.
|
||||
//
|
||||
// RETURNS:
|
||||
// NVSDK_NGX_Result indicating success or failure. Common values include:
|
||||
// - NVSDK_NGX_Result_Success if the function executed successfully
|
||||
// - NVSDK_NGX_Result_FAIL_FeatureNotSupported if the NGX SDK is not
|
||||
// supported on the current system
|
||||
// Check the NGX logs for additional information about any failures.
|
||||
//
|
||||
#if defined(NGX_SNIPPET_BUILD)
|
||||
#ifdef __cplusplus
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_Init(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, VkInstance InInstance, VkPhysicalDevice InPD, VkDevice InDevice, NVSDK_NGX_Version InSDKVersion = NVSDK_NGX_Version_API);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_Init_Ext(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, VkInstance InInstance, VkPhysicalDevice InPD, VkDevice InDevice, NVSDK_NGX_Version InSDKVersion = NVSDK_NGX_Version_API, const NVSDK_NGX_Parameter *InParameters = nullptr);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_Init_Ext2(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, VkInstance InInstance, VkPhysicalDevice InPD, VkDevice InDevice, PFN_vkGetInstanceProcAddr InGIPA = nullptr, PFN_vkGetDeviceProcAddr InGDPA = nullptr, NVSDK_NGX_Version InSDKVersion = NVSDK_NGX_Version_API, const NVSDK_NGX_Parameter *InParameters = nullptr);
|
||||
#else
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_Init(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, VkInstance InInstance, VkPhysicalDevice InPD, VkDevice InDevice, NVSDK_NGX_Version InSDKVersion);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_Init_Ext(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, VkInstance InInstance, VkPhysicalDevice InPD, VkDevice InDevice, NVSDK_NGX_Version InSDKVersion, const NVSDK_NGX_Parameter *InParameters);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_Init_Ext2(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, VkInstance InInstance, VkPhysicalDevice InPD, VkDevice InDevice, PFN_vkGetInstanceProcAddr InGIPA, PFN_vkGetDeviceProcAddr InGDPA, NVSDK_NGX_Version InSDKVersion, const NVSDK_NGX_Parameter *InParameters);
|
||||
#endif
|
||||
#else
|
||||
#ifdef __cplusplus
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_Init(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, VkInstance InInstance, VkPhysicalDevice InPD, VkDevice InDevice, PFN_vkGetInstanceProcAddr InGIPA = nullptr, PFN_vkGetDeviceProcAddr InGDPA = nullptr, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo = nullptr, NVSDK_NGX_Version InSDKVersion = NVSDK_NGX_Version_API);
|
||||
#else
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_Init(unsigned long long InApplicationId, const wchar_t *InApplicationDataPath, VkInstance InInstance, VkPhysicalDevice InPD, VkDevice InDevice, PFN_vkGetInstanceProcAddr InGIPA, PFN_vkGetDeviceProcAddr InGDPA, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo, NVSDK_NGX_Version InSDKVersion);
|
||||
#endif
|
||||
#endif // defined(NGX_SNIPPET_BUILD)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NVSDK_NGX_Init_with_ProjectID
|
||||
// -----------------------------------------------------------------------------
|
||||
// Initializes a new SDK instance using a project ID.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Initializes a new SDK instance. Most NGX SDK functions require the NGX
|
||||
// SDK to be initialized for the corresponding graphics API and device to
|
||||
// function properly.
|
||||
//
|
||||
// Applications must provide a unique identifier to initialize the NGX SDK.
|
||||
// If an identifier was provided by NVIDIA, use NVSDK_NGX_Init instead.
|
||||
//
|
||||
// For projects using third-party engines such as Unreal Engine or
|
||||
// Omniverse, the integration for those engines should handle providing the
|
||||
// correct Project ID to NGX. Ensure that the project ID is set in the
|
||||
// engine's editor.
|
||||
//
|
||||
// For other engines, use NVSDK_NGX_EngineType CUSTOM. The driver will
|
||||
// validate that the Project ID is GUID-like, for example,
|
||||
// "a0f57b54-1daf-4934-90ae-c4035c19df04". Ensure your project ID matches
|
||||
// this format.
|
||||
//
|
||||
// Be sure to call NVSDK_NGX_Shutdown to shut down the SDK when it is no
|
||||
// longer needed.
|
||||
//
|
||||
// PARAMETERS:
|
||||
// InProjectId:
|
||||
// Unique ID provided by the rendering engine used. Must be a GUID-like
|
||||
// string.
|
||||
//
|
||||
// InEngineType:
|
||||
// Rendering engine used by the application/plugin. Use NVSDK_NGX_EngineType
|
||||
// CUSTOM if the specific engine type is not explicitly supported.
|
||||
//
|
||||
// InEngineVersion:
|
||||
// Version number of the rendering engine used by the application/plugin.
|
||||
//
|
||||
// InApplicationDataPath:
|
||||
// Directory to store logs and other temporary files (write access required).
|
||||
//
|
||||
// InInstance/InPD/InDevice:
|
||||
// Vulkan Instance, PhysicalDevice, and Device to use.
|
||||
//
|
||||
// InGIPA/InGDPA:
|
||||
// Optional Vulkan function pointers to vkGetInstanceProcAddr and
|
||||
// vkGetDeviceProcAddr.
|
||||
//
|
||||
// InFeatureInfo:
|
||||
// Contains information common to all features, including a list of paths
|
||||
// where feature DLLs can be located in addition to the default path
|
||||
// (the application directory).
|
||||
//
|
||||
// InSDKVersion:
|
||||
// Version of the SDK currently in use. Typically, this should be left as
|
||||
// the default value, NVSDK_NGX_Version_API.
|
||||
//
|
||||
// RETURNS:
|
||||
// NVSDK_NGX_Result indicating success or failure. Common values include:
|
||||
// - NVSDK_NGX_Result_Success if the function executed successfully
|
||||
// - NVSDK_NGX_Result_InvalidParameter if the provided project ID is in
|
||||
// an invalid format
|
||||
// - NVSDK_NGX_Result_FAIL_FeatureNotSupported if the NGX SDK is not
|
||||
// supported on the current system
|
||||
// Check the NGX logs for additional information about any failures.
|
||||
//
|
||||
#if defined(NGX_SNIPPET_BUILD)
|
||||
// No NGX Core <---> Snippet interfaces
|
||||
#else
|
||||
#ifdef __cplusplus
|
||||
NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_Init_with_ProjectID(const char *InProjectId, NVSDK_NGX_EngineType InEngineType, const char *InEngineVersion, const wchar_t *InApplicationDataPath, VkInstance InInstance, VkPhysicalDevice InPD, VkDevice InDevice, PFN_vkGetInstanceProcAddr InGIPA = nullptr, PFN_vkGetDeviceProcAddr InGDPA = nullptr, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo = nullptr, NVSDK_NGX_Version InSDKVersion = NVSDK_NGX_Version_API);
|
||||
#else
|
||||
NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_Init_with_ProjectID(const char *InProjectId, NVSDK_NGX_EngineType InEngineType, const char *InEngineVersion, const wchar_t *InApplicationDataPath, VkInstance InInstance, VkPhysicalDevice InPD, VkDevice InDevice, PFN_vkGetInstanceProcAddr InGIPA, PFN_vkGetDeviceProcAddr InGDPA, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo, NVSDK_NGX_Version InSDKVersion);
|
||||
#endif
|
||||
#endif // defined(NGX_SNIPPET_BUILD)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NVSDK_NGX_Shutdown
|
||||
// -----------------------------------------------------------------------------
|
||||
// Shuts down the current SDK instance and releases all resources.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Shuts down the current SDK instance and releases all resources. If a
|
||||
// device is provided, NVSDK_NGX_Shutdown1 shuts down the instance
|
||||
// corresponding to the specified device. If nullptr is provided, all
|
||||
// instances are shut down.
|
||||
//
|
||||
// Deprecation Notice: The use of Shutdown() is deprecated. Please use
|
||||
// Shutdown1(nullptr) instead.
|
||||
//
|
||||
// PARAMETERS:
|
||||
// InDevice:
|
||||
// Device to shut down. If nullptr, the SDK is shut down for all devices.
|
||||
//
|
||||
// RETURNS:
|
||||
// NVSDK_NGX_Result indicating success or failure.
|
||||
//
|
||||
#ifdef NGX_ENABLE_DEPRECATED_SHUTDOWN
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_Shutdown(void);
|
||||
#endif
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_Shutdown1(VkDevice InDevice);
|
||||
|
||||
#ifdef NGX_ENABLE_DEPRECATED_GET_PARAMETERS
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NVSDK_NGX_GetParameters
|
||||
// -----------------------------------------------------------------------------
|
||||
// Retrieves a parameter map used to set parameters needed by the SDK.
|
||||
//
|
||||
// DEPRECATED: Use NVSDK_NGX_AllocateParameters or
|
||||
// NVSDK_NGX_GetCapabilityParameters instead.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Retrieves the common NVSDK_NGX_Parameter map for providing parameters to
|
||||
// the SDK. The NVSDK_NGX_Parameter interface allows simple parameter setup
|
||||
// using named fields. For example, set the width by calling
|
||||
// Parameters->Set(NVSDK_NGX_Parameter_Width, 100) or provide a resource
|
||||
// pointer by calling Parameters->Set(NVSDK_NGX_Parameter_Color, resource).
|
||||
// For more details, see the sample code.
|
||||
//
|
||||
// Parameter maps returned by NVSDK_NGX_GetParameters are pre-populated
|
||||
// with NGX capabilities and available features. Unlike
|
||||
// NVSDK_NGX_AllocateParameters, parameter maps returned by
|
||||
// NVSDK_NGX_GetParameters have their lifetimes managed by NGX and must not
|
||||
// be destroyed by the application using NVSDK_NGX_DestroyParameters.
|
||||
//
|
||||
// This function may only be called after a successful call to
|
||||
// NVSDK_NGX_Init.
|
||||
//
|
||||
// Note: Allocated memory will be freed by NGX, so do not use the
|
||||
// free/delete operator.
|
||||
//
|
||||
// Deprecation Notice: NVSDK_NGX_GetParameters is deprecated. Applications
|
||||
// should use NVSDK_NGX_AllocateParameters and
|
||||
// NVSDK_NGX_GetCapabilityParameters when possible. However, if there is a
|
||||
// possibility that the user may be using an older driver version (driver
|
||||
// version 445 or older), NVSDK_NGX_GetParameters may still be used as a
|
||||
// fallback if NVSDK_NGX_AllocateParameters or
|
||||
// NVSDK_NGX_GetCapabilityParameters return
|
||||
// NVSDK_NGX_Result_FAIL_OutOfDate.
|
||||
//
|
||||
// PARAMETERS:
|
||||
// OutParameters:
|
||||
// Output pointer that will be populated with an NVSDK_NGX_Parameter
|
||||
// interface.
|
||||
//
|
||||
// RETURNS:
|
||||
// NVSDK_NGX_Result indicating success or failure.
|
||||
//
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_GetParameters(NVSDK_NGX_Parameter **OutParameters);
|
||||
#endif // NGX_ENABLE_DEPRECATED_GET_PARAMETERS
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NVSDK_NGX_AllocateParameters
|
||||
// -----------------------------------------------------------------------------
|
||||
// Allocates a parameter map used to set parameters needed by the SDK.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Allocates a new NVSDK_NGX_Parameter map for providing parameters to the
|
||||
// SDK. The lifetime of this parameter map must be managed by the
|
||||
// application. The NVSDK_NGX_Parameter interface allows simple parameter
|
||||
// setup using named fields. For example, set the width by calling
|
||||
// Parameters->Set(NVSDK_NGX_Parameter_Width, 100) or provide a resource
|
||||
// pointer by calling Parameters->Set(NVSDK_NGX_Parameter_Color, resource).
|
||||
// For more details, see the sample code.
|
||||
//
|
||||
// Use NVSDK_NGX_DestroyParameters to free a parameter map created by
|
||||
// NVSDK_NGX_AllocateParameters. Parameter maps created by
|
||||
// NVSDK_NGX_AllocateParameters must NOT be freed using the free/delete
|
||||
// operator.
|
||||
//
|
||||
// Parameter maps created by NVSDK_NGX_AllocateParameters do not come
|
||||
// pre-populated with NGX capabilities and available features. To create a
|
||||
// new parameter map pre-populated with such information, use
|
||||
// NVSDK_NGX_GetCapabilityParameters instead.
|
||||
//
|
||||
// This function may return NVSDK_NGX_Result_FAIL_OutOfDate if using an
|
||||
// older driver that does not support this API call. In such a case,
|
||||
// NVSDK_NGX_GetParameters may be used as a fallback.
|
||||
//
|
||||
// This function may only be called after a successful call to
|
||||
// NVSDK_NGX_Init.
|
||||
//
|
||||
// PARAMETERS:
|
||||
// OutParameters:
|
||||
// Output pointer that will be populated with the newly-allocated
|
||||
// NVSDK_NGX_Parameter interface.
|
||||
//
|
||||
// RETURNS:
|
||||
// NVSDK_NGX_Result indicating success or failure. Common values include:
|
||||
// - NVSDK_NGX_Result_Success if the function executed successfully
|
||||
// - NVSDK_NGX_Result_FAIL_OutOfDate if this function is not supported by
|
||||
// the current display driver
|
||||
// Check the NGX logs for additional information about any failures.
|
||||
//
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_AllocateParameters(NVSDK_NGX_Parameter** OutParameters);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NVSDK_NGX_GetCapabilityParameters
|
||||
// -----------------------------------------------------------------------------
|
||||
// Allocates a parameter map populated with NGX and feature capabilities.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Allocates a new NVSDK_NGX_Parameter map pre-populated with NGX
|
||||
// capabilities and information about available features. The output
|
||||
// parameter map can also be used in the same ways as a parameter map
|
||||
// allocated with NVSDK_NGX_AllocateParameters. However, it is not
|
||||
// recommended to use NVSDK_NGX_GetCapabilityParameters unless querying NGX
|
||||
// capabilities due to the overhead associated with pre-populating the
|
||||
// parameter map.
|
||||
//
|
||||
// Use NVSDK_NGX_DestroyParameters to free a parameter map created by
|
||||
// NVSDK_NGX_GetCapabilityParameters. Parameter maps created by
|
||||
// NVSDK_NGX_GetCapabilityParameters must NOT be freed using the
|
||||
// free/delete operator.
|
||||
//
|
||||
// This function may return NVSDK_NGX_Result_FAIL_OutOfDate if using an
|
||||
// older driver that does not support this API call. In such a case,
|
||||
// NVSDK_NGX_GetParameters may be used as a fallback.
|
||||
//
|
||||
// This function may only be called after a successful call to
|
||||
// NVSDK_NGX_Init.
|
||||
//
|
||||
// PARAMETERS:
|
||||
// OutParameters:
|
||||
// Output pointer that will be populated with the newly-allocated
|
||||
// NVSDK_NGX_Parameter interface.
|
||||
//
|
||||
// RETURNS:
|
||||
// NVSDK_NGX_Result indicating success or failure. Common values include:
|
||||
// - NVSDK_NGX_Result_Success if the function executed successfully
|
||||
// - NVSDK_NGX_Result_FAIL_OutOfDate if this function is not supported by
|
||||
// the current display driver
|
||||
// Check the NGX logs for additional information about any failures.
|
||||
//
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_GetCapabilityParameters(NVSDK_NGX_Parameter** OutParameters);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NVSDK_NGX_DestroyParameters
|
||||
// -----------------------------------------------------------------------------
|
||||
// Destroys the specified parameter map.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Destroys the input parameter map. Once NVSDK_NGX_DestroyParameters is
|
||||
// called on a parameter map, it must not be used again.
|
||||
//
|
||||
// NVSDK_NGX_DestroyParameters must not be called on any parameter map
|
||||
// returned by NVSDK_NGX_GetParameters; NGX will manage the lifetime of
|
||||
// those parameter maps.
|
||||
//
|
||||
// This function may only be called after a successful call to
|
||||
// NVSDK_NGX_Init.
|
||||
//
|
||||
// PARAMETERS:
|
||||
// InParameters:
|
||||
// The parameter map to be destroyed.
|
||||
//
|
||||
// RETURNS:
|
||||
// NVSDK_NGX_Result indicating success or failure.
|
||||
//
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_DestroyParameters(NVSDK_NGX_Parameter* InParameters);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NVSDK_NGX_GetScratchBufferSize
|
||||
// -----------------------------------------------------------------------------
|
||||
// Retrieves the size of the scratch buffer needed for the specified feature.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// The SDK requires a buffer of a certain size provided by the client to
|
||||
// initialize some NGX features. Once the feature is no longer needed, the
|
||||
// buffer can be released. It is safe to reuse the same scratch buffer for
|
||||
// different features as long as the minimum size requirement is met for
|
||||
// all features. Some features might not need a scratch buffer, so a return
|
||||
// size of 0 is completely valid.
|
||||
//
|
||||
// Note: Most current NGX features do not use scratch buffers. Please check
|
||||
// the documentation for the particular feature in use to determine whether
|
||||
// a scratch buffer needs to be created.
|
||||
//
|
||||
// PARAMETERS:
|
||||
// InFeatureId:
|
||||
// Identifier of the feature to query.
|
||||
//
|
||||
// InParameters:
|
||||
// Parameters used by the feature to determine scratch buffer size.
|
||||
//
|
||||
// OutSizeInBytes:
|
||||
// Number of bytes needed for the scratch buffer for the specified feature.
|
||||
//
|
||||
// RETURNS:
|
||||
// NVSDK_NGX_Result indicating success or failure.
|
||||
//
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_GetScratchBufferSize(NVSDK_NGX_Feature InFeatureId, const NVSDK_NGX_Parameter *InParameters, size_t *OutSizeInBytes);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NVSDK_NGX_CreateFeature
|
||||
// -----------------------------------------------------------------------------
|
||||
// Creates and initializes an instance of the specified NGX feature.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Each feature needs to be created before it can be used. The parameters
|
||||
// required to create the feature vary. Refer to the feature's
|
||||
// documentation and/or sample code to find out which input parameters are
|
||||
// needed to create a specific feature.
|
||||
//
|
||||
// NVSDK_NGX_CreateFeature creates an NVSDK_NGX_Handle to the feature, which
|
||||
// is needed to reference the feature in later calls to
|
||||
// NVSDK_NGX_EvaluateFeature. Multiple instances of the same feature may be
|
||||
// created, and evaluating one instance of a feature should not change the
|
||||
// state of other instances.
|
||||
//
|
||||
// When a feature instance is no longer needed, it should be freed using
|
||||
// NVSDK_NGX_ReleaseFeature.
|
||||
//
|
||||
// If multiple devices are in use, the device to create the
|
||||
// feature on must be specified using CreateFeature1().
|
||||
//
|
||||
// PARAMETERS:
|
||||
// InCmdBuffer:
|
||||
// Command buffer to use to execute GPU commands. Must be open and
|
||||
// recording.
|
||||
//
|
||||
// InDevice:
|
||||
// Vulkan device on which to create the feature.
|
||||
//
|
||||
// InFeatureID:
|
||||
// Identifier of the feature to initialize.
|
||||
//
|
||||
// InParameters:
|
||||
// Parameters used to create the feature.
|
||||
//
|
||||
// OutHandle:
|
||||
// Handle which uniquely identifies the feature.
|
||||
//
|
||||
// RETURNS:
|
||||
// NVSDK_NGX_Result indicating success or failure. Common values include:
|
||||
// - NVSDK_NGX_Result_Success if the function executed successfully
|
||||
// - NVSDK_NGX_Result_FAIL_UnableToInitializeFeature if the feature
|
||||
// cannot be created, for example, because the feature is not supported
|
||||
// on the current hardware, or because the DLL could not be found
|
||||
// - NVSDK_NGX_Result_FAIL_InvalidParameter if any of the input
|
||||
// parameters are invalid
|
||||
// - NVSDK_NGX_Result_FAIL_FeatureAlreadyExists if a feature instance
|
||||
// with the same parameters has already been created, and the feature
|
||||
// doesn't allow multiple instances to be created with the same
|
||||
// parameters.
|
||||
// Check the NGX logs for additional information about any failures.
|
||||
//
|
||||
#if defined(NGX_SNIPPET_BUILD)
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_CreateFeature(VkCommandBuffer InCmdList, NVSDK_NGX_Feature InFeatureID, const NVSDK_NGX_Parameter *InParameters, NVSDK_NGX_Handle **OutHandle);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_CreateFeature1(VkDevice InDevice, VkCommandBuffer InCmdList, NVSDK_NGX_Feature InFeatureID, const NVSDK_NGX_Parameter *InParameters, NVSDK_NGX_Handle **OutHandle);
|
||||
#else
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_CreateFeature(VkCommandBuffer InCmdBuffer, NVSDK_NGX_Feature InFeatureID, NVSDK_NGX_Parameter *InParameters, NVSDK_NGX_Handle **OutHandle);
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_CreateFeature1(VkDevice InDevice, VkCommandBuffer InCmdList, NVSDK_NGX_Feature InFeatureID, NVSDK_NGX_Parameter *InParameters, NVSDK_NGX_Handle **OutHandle);
|
||||
#endif // defined(NGX_SNIPPET_BUILD)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NVSDK_NGX_ReleaseFeature
|
||||
// -----------------------------------------------------------------------------
|
||||
// Releases the specified NGX feature.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Releases the feature associated with the given handle and frees its
|
||||
// memory. Handles are not reference counted, so after this call, it is
|
||||
// invalid to use the provided handle.
|
||||
//
|
||||
// PARAMETERS:
|
||||
// InHandle:
|
||||
// Handle to the feature to be released.
|
||||
//
|
||||
// RETURNS:
|
||||
// NVSDK_NGX_Result indicating success or failure.
|
||||
//
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_ReleaseFeature(NVSDK_NGX_Handle *InHandle);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NVSDK_NGX_GetFeatureRequirements
|
||||
// -----------------------------------------------------------------------------
|
||||
// Identifies system requirements to support a given NGX feature.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Utility function used to identify system requirements to support a given
|
||||
// NGX feature on a system, given its display device subsystem adapter
|
||||
// information that will be subsequently used for creating the graphics
|
||||
// device. The output parameter OutSupported will be populated with
|
||||
// requirements and is valid if and only if the function returns
|
||||
// NVSDK_NGX_Result_Success. The result includes:
|
||||
// - FeatureSupported: Bitfield of reasons why the feature is
|
||||
// unsupported, as specified in NVSDK_NGX_Feature_Support_Result. 0 if
|
||||
// the feature is supported
|
||||
// - MinHWArchitecture: The hardware architecture version corresponding
|
||||
// to an NV_GPU_ARCHITECTURE_ID value defined in the NvAPI GPU
|
||||
// Framework
|
||||
// - MinOSVersion: The minimum OS version required for the provided
|
||||
// feature
|
||||
//
|
||||
// NVSDK_NGX_Init does NOT need to be called before calling this function.
|
||||
// Applications may wish to use this function to determine whether a
|
||||
// desired feature is supported before initializing the complete SDK.
|
||||
//
|
||||
// PARAMETERS:
|
||||
// Instance:
|
||||
// VkInstance in use by the application.
|
||||
//
|
||||
// InPhysicalDevice:
|
||||
// VkPhysicalDevice in use by the application.
|
||||
//
|
||||
// FeatureDiscoveryInfo:
|
||||
// Struct containing information about the feature to query and how it is
|
||||
// expected to be initialized, including the feature ID and information
|
||||
// that would be provided to NVSDK_NGX_Init.
|
||||
//
|
||||
// OutSupported:
|
||||
// Populated with the requirements for the specified feature.
|
||||
//
|
||||
// RETURNS:
|
||||
// NVSDK_NGX_Result indicating success or failure.
|
||||
//
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_GetFeatureRequirements(const VkInstance Instance,
|
||||
const VkPhysicalDevice PhysicalDevice,
|
||||
const NVSDK_NGX_FeatureDiscoveryInfo *FeatureDiscoveryInfo,
|
||||
NVSDK_NGX_FeatureRequirement *OutSupported);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NVSDK_NGX_VULKAN_GetFeatureInstanceExtensionRequirements
|
||||
// -----------------------------------------------------------------------------
|
||||
// Identifies Vulkan instance extensions required for NGX feature support.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// This utility function identifies the Vulkan instance extensions required
|
||||
// for a specific NGX feature, specified by its feature ID. The function
|
||||
// populates OutExtensionCount with the number of extensions required for
|
||||
// the NGX feature. It also populates OutExtensionProperties with a pointer
|
||||
// to an array of VkExtensionProperties structures, which contains details
|
||||
// about each required extension. The size of this array is equal to
|
||||
// OutExtensionCount.
|
||||
//
|
||||
// NVSDK_NGX_Init does NOT need to be called before calling this function.
|
||||
// This function should be called before the VkInstance for the application
|
||||
// is created so that the correct extensions can be enabled.
|
||||
//
|
||||
// PARAMETERS:
|
||||
// FeatureDiscoveryInfo:
|
||||
// Struct containing information about the feature to query and how it is
|
||||
// expected to be initialized, including the feature ID and information
|
||||
// that would be provided to NVSDK_NGX_Init.
|
||||
//
|
||||
// OutExtensionCount:
|
||||
// Output pointer that will be populated with the number of required
|
||||
// instance extensions.
|
||||
//
|
||||
// OutExtensionProperties:
|
||||
// Output pointer that will be populated with an array of
|
||||
// VkExtensionProperties structures required by the given feature.
|
||||
//
|
||||
// RETURNS:
|
||||
// NVSDK_NGX_Result indicating success or failure.
|
||||
//
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_GetFeatureInstanceExtensionRequirements(const NVSDK_NGX_FeatureDiscoveryInfo *FeatureDiscoveryInfo,
|
||||
uint32_t *OutExtensionCount,
|
||||
VkExtensionProperties **OutExtensionProperties);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NVSDK_NGX_VULKAN_GetFeatureDeviceExtensionRequirements
|
||||
// -----------------------------------------------------------------------------
|
||||
// Identifies Vulkan device extensions required for NGX feature support.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// This utility function identifies the Vulkan device extensions required
|
||||
// for a specific NGX feature, specified by its feature ID, and a given
|
||||
// VkInstance and VkPhysicalDevice. The function populates
|
||||
// OutExtensionCount with the number of extensions required for the NGX
|
||||
// feature. It also populates OutExtensionProperties with a pointer to an
|
||||
// array of VkExtensionProperties structures, which contains details about
|
||||
// each required extension. The size of this array is equal to
|
||||
// OutExtensionCount.
|
||||
//
|
||||
// NVSDK_NGX_Init does NOT need to be called before calling this function.
|
||||
// This function should be called before the VkDevice for the application
|
||||
// is created so that the correct extensions can be enabled.
|
||||
//
|
||||
// PARAMETERS:
|
||||
// Instance:
|
||||
// VkInstance in use by the application.
|
||||
//
|
||||
// InPhysicalDevice:
|
||||
// VkPhysicalDevice in use by the application.
|
||||
//
|
||||
// FeatureDiscoveryInfo:
|
||||
// Struct containing information about the feature to query and how it is
|
||||
// expected to be initialized, including the feature ID and information
|
||||
// that would be provided to NVSDK_NGX_Init.
|
||||
//
|
||||
// OutExtensionCount:
|
||||
// Output pointer that will be populated with the number of required
|
||||
// device extensions.
|
||||
//
|
||||
// OutExtensionProperties:
|
||||
// Output pointer that will be populated with an array of
|
||||
// VkExtensionProperties structures required by the given feature.
|
||||
//
|
||||
// RETURNS:
|
||||
// NVSDK_NGX_Result indicating success or failure.
|
||||
//
|
||||
#if defined(NGX_SNIPPET_BUILD)
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_GetFeatureDeviceExtensionRequirements(const VkInstance Instance,
|
||||
const VkPhysicalDevice PhysicalDevice,
|
||||
const NVSDK_NGX_FeatureDiscoveryInfo *FeatureDiscoveryInfo,
|
||||
uint32_t *OutExtensionCount,
|
||||
VkExtensionProperties **OutExtensionProperties);
|
||||
#else
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_GetFeatureDeviceExtensionRequirements(VkInstance Instance,
|
||||
VkPhysicalDevice PhysicalDevice,
|
||||
const NVSDK_NGX_FeatureDiscoveryInfo *FeatureDiscoveryInfo,
|
||||
uint32_t *OutExtensionCount,
|
||||
VkExtensionProperties **OutExtensionProperties);
|
||||
#endif // defined(NGX_SNIPPET_BUILD)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NVSDK_NGX_EvaluateFeature
|
||||
// -----------------------------------------------------------------------------
|
||||
// Evaluates the specified NGX feature using the provided parameters.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Evaluates the given feature using the provided parameters. The
|
||||
// parameters required to evaluate a feature vary. Refer to the feature's
|
||||
// documentation and sample code to determine which input parameters are
|
||||
// needed.
|
||||
//
|
||||
// To evaluate a feature, an NVSDK_NGX_Handle to an instance of that
|
||||
// feature, created with NVSDK_NGX_CreateFeature, must be provided.
|
||||
//
|
||||
// For most features, it is beneficial to pass as many input buffers and
|
||||
// parameters as possible (e.g., provide all render targets like color,
|
||||
// albedo, normals, depth, etc.). This will ensure maximum future
|
||||
// compatibility with new updates.
|
||||
//
|
||||
// PARAMETERS:
|
||||
// InCmdBuffer:
|
||||
// Command buffer to use to execute GPU commands. Must be open and
|
||||
// recording.
|
||||
//
|
||||
// InFeatureHandle:
|
||||
// Handle representing the feature to be evaluated.
|
||||
//
|
||||
// InParameters:
|
||||
// List of parameters required to evaluate the feature.
|
||||
//
|
||||
// InCallback:
|
||||
// Optional callback for features that might take longer to execute. If
|
||||
// specified, the SDK will call it with progress values in the range 0.0f -
|
||||
// 1.0f. Not all features support progress callbacks. Refer to the
|
||||
// documentation for the specific feature to determine whether or not
|
||||
// progress callbacks are supported.
|
||||
//
|
||||
// RETURNS:
|
||||
// NVSDK_NGX_Result indicating success or failure. Common values include:
|
||||
// - NVSDK_NGX_Result_Success if the function executed successfully.
|
||||
// - NVSDK_NGX_Result_FAIL_InvalidParameter if any of the input
|
||||
// parameters are missing or invalid.
|
||||
// - NVSDK_NGX_Result_FAIL_FeatureNotFound if a feature with the provided
|
||||
// handle could not be found.
|
||||
// Check the NGX logs for additional information about any failures.
|
||||
//
|
||||
#ifdef __cplusplus
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_EvaluateFeature(VkCommandBuffer InCmdList, const NVSDK_NGX_Handle *InFeatureHandle, const NVSDK_NGX_Parameter *InParameters, PFN_NVSDK_NGX_ProgressCallback InCallback = NULL);
|
||||
#endif
|
||||
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_EvaluateFeature_C(VkCommandBuffer InCmdList, const NVSDK_NGX_Handle *InFeatureHandle, const NVSDK_NGX_Parameter *InParameters, PFN_NVSDK_NGX_ProgressCallback_C InCallback);
|
||||
|
||||
#if defined(NGX_SNIPPET_BUILD)
|
||||
// No NGX Core <---> Snippet interfaces
|
||||
#else
|
||||
// NGX return-code conversion-to-string utility only as a helper for debugging/logging - not for official use.
|
||||
const wchar_t* NVSDK_CONV GetNGXResultAsString(NVSDK_NGX_Result InNGXResult);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // #define NVSDK_NGX_VK_H
|
||||
Binary file not shown.
@@ -0,0 +1,227 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
// bbport Windows: "Power management mode" of this executable in the NVIDIA driver's profiles.
|
||||
|
||||
#include "platform/win32/nvidia_profile.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <cwchar>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "shim/bb_env.h"
|
||||
|
||||
namespace BbNvidiaProfile {
|
||||
|
||||
namespace {
|
||||
|
||||
using NvStatus = int;
|
||||
using Session = void*;
|
||||
using Profile = void*;
|
||||
constexpr NvStatus Ok = 0, SettingNotFound = -160, ProfileNotFound = -163,
|
||||
ExecutableNotFound = -166;
|
||||
constexpr std::uint32_t PreferredPstateId = 0x1057EB71;
|
||||
constexpr std::uint32_t PreferMax = 1;
|
||||
constexpr int StringMax = 2048;
|
||||
using UnicodeString = std::uint16_t[StringMax];
|
||||
|
||||
#pragma pack(push, 4)
|
||||
struct Setting {
|
||||
std::uint32_t version;
|
||||
UnicodeString name;
|
||||
std::uint32_t id;
|
||||
std::uint32_t type; // 0: DWORD
|
||||
std::uint32_t location; // 0: this profile, 1: global, 2: base, 3: default
|
||||
std::uint32_t is_current_predefined;
|
||||
std::uint32_t is_predefined_valid;
|
||||
union {
|
||||
std::uint32_t u32;
|
||||
std::uint8_t binary[4 + 4096];
|
||||
UnicodeString wide;
|
||||
std::uint64_t u64;
|
||||
} predefined;
|
||||
union {
|
||||
std::uint32_t u32;
|
||||
std::uint8_t binary[4 + 4096];
|
||||
UnicodeString wide;
|
||||
std::uint64_t u64;
|
||||
} current;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
struct Application {
|
||||
std::uint32_t version;
|
||||
std::uint32_t is_predefined;
|
||||
UnicodeString app_name;
|
||||
UnicodeString friendly_name;
|
||||
UnicodeString launcher;
|
||||
UnicodeString file_in_folder;
|
||||
std::uint32_t flags; // isMetro:1, isCommandLine:1
|
||||
UnicodeString command_line;
|
||||
};
|
||||
|
||||
struct ProfileInfo {
|
||||
std::uint32_t version;
|
||||
UnicodeString name;
|
||||
std::uint32_t gpu_support;
|
||||
std::uint32_t is_predefined;
|
||||
std::uint32_t num_apps;
|
||||
std::uint32_t num_settings;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
constexpr std::uint32_t Version(std::uint32_t v) {
|
||||
return std::uint32_t(sizeof(T)) | (v << 16);
|
||||
}
|
||||
|
||||
void Copy(std::uint16_t* dst, const wchar_t* src) {
|
||||
std::size_t i = 0;
|
||||
for (; src[i] && i + 1 < StringMax; ++i) {
|
||||
dst[i] = std::uint16_t(src[i]);
|
||||
}
|
||||
dst[i] = 0;
|
||||
}
|
||||
|
||||
struct Api {
|
||||
using Query = void*(__cdecl*)(std::uint32_t);
|
||||
NvStatus(__cdecl* initialize)();
|
||||
NvStatus(__cdecl* create_session)(Session*);
|
||||
NvStatus(__cdecl* destroy_session)(Session);
|
||||
NvStatus(__cdecl* load_settings)(Session);
|
||||
NvStatus(__cdecl* save_settings)(Session);
|
||||
NvStatus(__cdecl* find_application)(Session, UnicodeString, Profile*, Application*);
|
||||
NvStatus(__cdecl* find_profile)(Session, UnicodeString, Profile*);
|
||||
NvStatus(__cdecl* create_profile)(Session, ProfileInfo*, Profile*);
|
||||
NvStatus(__cdecl* create_application)(Session, Profile, Application*);
|
||||
NvStatus(__cdecl* get_setting)(Session, Profile, std::uint32_t, Setting*);
|
||||
NvStatus(__cdecl* set_setting)(Session, Profile, Setting*);
|
||||
|
||||
bool Load() {
|
||||
HMODULE module = LoadLibraryA("nvapi64.dll");
|
||||
if (!module) {
|
||||
return false;
|
||||
}
|
||||
const auto query = reinterpret_cast<Query>(GetProcAddress(module, "nvapi_QueryInterface"));
|
||||
if (!query) {
|
||||
return false;
|
||||
}
|
||||
const auto get = [&](auto& fn, std::uint32_t id) {
|
||||
fn = reinterpret_cast<std::remove_reference_t<decltype(fn)>>(query(id));
|
||||
return fn != nullptr;
|
||||
};
|
||||
return get(initialize, 0x0150E828) && get(create_session, 0x0694D52E) &&
|
||||
get(destroy_session, 0xDAD9CFF8) && get(load_settings, 0x375DBD6B) &&
|
||||
get(save_settings, 0xFCBC7E14) && get(find_application, 0xEEE566B2) &&
|
||||
get(find_profile, 0x7E4A9A0B) && get(create_profile, 0xCC176068) &&
|
||||
get(create_application, 0x4347A9DE) && get(get_setting, 0x73BF8338) &&
|
||||
get(set_setting, 0x577DD202);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
void Apply() {
|
||||
static bool applied = false;
|
||||
if (applied || bb_env_off("BB_NV_POWER")) {
|
||||
return;
|
||||
}
|
||||
applied = true;
|
||||
Api api{};
|
||||
if (!api.Load() || api.initialize() != Ok) {
|
||||
return; // no NVIDIA driver
|
||||
}
|
||||
Session session = nullptr;
|
||||
if (api.create_session(&session) != Ok) {
|
||||
return;
|
||||
}
|
||||
const auto done = [&](const char* what, NvStatus status) {
|
||||
if (what) {
|
||||
std::printf("NVIDIA profile: %s (NVAPI status %d)\n", what, status);
|
||||
}
|
||||
api.destroy_session(session);
|
||||
};
|
||||
NvStatus status = api.load_settings(session);
|
||||
if (status != Ok) {
|
||||
return done("could not read the driver settings", status);
|
||||
}
|
||||
wchar_t path[MAX_PATH];
|
||||
const DWORD n = GetModuleFileNameW(nullptr, path, MAX_PATH);
|
||||
if (n == 0 || n >= MAX_PATH) {
|
||||
return done("no executable name", 0);
|
||||
}
|
||||
const wchar_t* exe = std::wcsrchr(path, L'\\') ? std::wcsrchr(path, L'\\') + 1 : path;
|
||||
|
||||
auto app = std::make_unique<Application>();
|
||||
std::vector<std::uint16_t> name(StringMax);
|
||||
Profile profile = nullptr;
|
||||
std::memset(app.get(), 0, sizeof(Application));
|
||||
app->version = Version<Application>(4);
|
||||
Copy(name.data(), exe);
|
||||
status = api.find_application(session, name.data(), &profile, app.get());
|
||||
if (status == ExecutableNotFound) {
|
||||
std::vector<std::uint16_t> profile_name(StringMax);
|
||||
Copy(profile_name.data(), L"bbport");
|
||||
status = api.find_profile(session, profile_name.data(), &profile);
|
||||
if (status == ProfileNotFound) {
|
||||
auto info = std::make_unique<ProfileInfo>();
|
||||
std::memset(info.get(), 0, sizeof(ProfileInfo));
|
||||
info->version = Version<ProfileInfo>(1);
|
||||
Copy(info->name, L"bbport");
|
||||
status = api.create_profile(session, info.get(), &profile);
|
||||
}
|
||||
if (status != Ok) {
|
||||
return done("could not make the bbport profile", status);
|
||||
}
|
||||
std::memset(app.get(), 0, sizeof(Application));
|
||||
app->version = Version<Application>(4);
|
||||
Copy(app->app_name, exe);
|
||||
Copy(app->friendly_name, L"bbport");
|
||||
status = api.create_application(session, profile, app.get());
|
||||
if (status != Ok) {
|
||||
return done("could not add the executable to the bbport profile", status);
|
||||
}
|
||||
} else if (status != Ok) {
|
||||
return done("could not look up the executable's profile", status);
|
||||
}
|
||||
|
||||
auto setting = std::make_unique<Setting>();
|
||||
std::memset(setting.get(), 0, sizeof(Setting));
|
||||
setting->version = Version<Setting>(1);
|
||||
status = api.get_setting(session, profile, PreferredPstateId, setting.get());
|
||||
const bool user_set = status == Ok && setting->location == 0 && !setting->is_current_predefined;
|
||||
if (status == Ok && setting->current.u32 == PreferMax) {
|
||||
std::printf("NVIDIA profile: power management already prefers maximum performance\n");
|
||||
return done(nullptr, 0);
|
||||
}
|
||||
if (user_set) {
|
||||
std::printf("NVIDIA profile: power management mode %u chosen by the user for %ls, kept\n",
|
||||
setting->current.u32, exe);
|
||||
return done(nullptr, 0);
|
||||
}
|
||||
if (status != Ok && status != SettingNotFound) {
|
||||
return done("could not read the power management mode", status);
|
||||
}
|
||||
const std::uint32_t was = status == Ok ? setting->current.u32 : 5;
|
||||
std::memset(setting.get(), 0, sizeof(Setting));
|
||||
setting->version = Version<Setting>(1);
|
||||
setting->id = PreferredPstateId;
|
||||
setting->type = 0;
|
||||
setting->current.u32 = PreferMax;
|
||||
status = api.set_setting(session, profile, setting.get());
|
||||
if (status == Ok) {
|
||||
status = api.save_settings(session);
|
||||
}
|
||||
if (status != Ok) {
|
||||
return done("could not set prefer maximum performance", status);
|
||||
}
|
||||
std::printf("NVIDIA profile: power management for %ls: mode %u -> prefer maximum performance "
|
||||
"(BB_NV_POWER=0: leave it)\n",
|
||||
exe, was);
|
||||
done(nullptr, 0);
|
||||
}
|
||||
|
||||
} // namespace BbNvidiaProfile
|
||||
@@ -0,0 +1,8 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
namespace BbNvidiaProfile {
|
||||
|
||||
void Apply();
|
||||
|
||||
} // namespace BbNvidiaProfile
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
#include "common/assert.h"
|
||||
#include "bbport_settings.h"
|
||||
#include "bbport_toggles.h"
|
||||
#include "video_core/renderer_vulkan/vk_frame_capture.h"
|
||||
#include "common/debug.h"
|
||||
@@ -639,12 +640,16 @@ void VideoOutDriver::PresentThread(std::stop_token token) {
|
||||
|
||||
// bbport: frame limit (see EmulatorSettings::GetFrameLimit). A request waits in the queue
|
||||
// until its slot; slots advance by one period (no drift) but never lag behind by more.
|
||||
const u32 frame_limit = EmulatorSettings.GetFrameLimit();
|
||||
const auto frame_period = frame_limit ? std::chrono::nanoseconds(1000000000 / frame_limit)
|
||||
: std::chrono::nanoseconds(0);
|
||||
// With the live clock hook the target can change in the overlay: read it every iteration.
|
||||
const u32 startup_frame_limit = EmulatorSettings.GetFrameLimit();
|
||||
u32 frame_limit = BbSettings::LiveFrameLimitActive() ? BbSettings::LiveFrameLimit()
|
||||
: startup_frame_limit;
|
||||
auto frame_period = frame_limit ? std::chrono::nanoseconds(1000000000 / frame_limit)
|
||||
: std::chrono::nanoseconds(0);
|
||||
auto next_flip = std::chrono::steady_clock::now();
|
||||
std::printf("VideoOut: vblank %u Hz, frame limit %u FPS\n",
|
||||
EmulatorSettings.GetVblankFrequency(), frame_limit);
|
||||
std::printf("VideoOut: vblank %u Hz, frame limit %u FPS%s\n",
|
||||
EmulatorSettings.GetVblankFrequency(), frame_limit,
|
||||
BbSettings::LiveFrameLimitActive() ? " (live)" : "");
|
||||
|
||||
const auto receive_request = [this] -> Request {
|
||||
std::scoped_lock lk{mutex};
|
||||
@@ -658,12 +663,26 @@ void VideoOutDriver::PresentThread(std::stop_token token) {
|
||||
|
||||
// bbport: with a frame limit (uncapped presets) a queued flip is presented as soon as it
|
||||
// arrives and its slot allows, between vblanks, instead of on the next vblank tick.
|
||||
const bool immediate_flips = frame_limit != 0;
|
||||
|
||||
while (!token.stop_requested()) {
|
||||
timer.Start();
|
||||
const auto tick_deadline = std::chrono::steady_clock::now() + vblank_period;
|
||||
|
||||
// Live clock: the overlay can change the target without a restart. Recompute the slot
|
||||
// period when it changes; reset next_flip so a faster target is not stuck behind the
|
||||
// old one. One relaxed atomic read per iteration when live mode is off.
|
||||
const u32 live_frame_limit = BbSettings::LiveFrameLimitActive()
|
||||
? BbSettings::LiveFrameLimit()
|
||||
: startup_frame_limit;
|
||||
if (live_frame_limit != frame_limit) {
|
||||
frame_limit = live_frame_limit;
|
||||
frame_period = frame_limit ? std::chrono::nanoseconds(1000000000 / frame_limit)
|
||||
: std::chrono::nanoseconds(0);
|
||||
next_flip = std::chrono::steady_clock::now();
|
||||
std::printf("VideoOut: frame limit %u FPS%s\n", frame_limit,
|
||||
BbSettings::LiveFrameLimitActive() ? " (live)" : "");
|
||||
}
|
||||
const bool immediate_flips = frame_limit != 0;
|
||||
|
||||
if (DebugState.IsGuestThreadsPaused()) {
|
||||
DrawLastFrame();
|
||||
timer.End();
|
||||
|
||||
@@ -591,6 +591,9 @@ void SetupRoundingMode(EmitContext& ctx, const Profile& profile, const RuntimeIn
|
||||
|
||||
void SetupInfNanPreserveMode(EmitContext& ctx, const Profile& profile,
|
||||
const RuntimeInfo& runtime_info, Id main_func) {
|
||||
if (profile.fast_shader_math) {
|
||||
return;
|
||||
}
|
||||
if (profile.support_fp16_signed_zero_inf_nan_preserve ||
|
||||
profile.support_fp32_signed_zero_inf_nan_preserve ||
|
||||
profile.support_fp64_signed_zero_inf_nan_preserve) {
|
||||
|
||||
@@ -7,7 +7,12 @@
|
||||
namespace Shader::Backend::SPIRV {
|
||||
|
||||
Id Decorate(EmitContext& ctx, IR::Inst* inst, Id op) {
|
||||
ctx.Decorate(op, spv::Decoration::NoContraction);
|
||||
// Pre-rasterization stages keep it, so position math stays the same across pipelines.
|
||||
const bool can_contract = ctx.profile.fast_shader_math && (ctx.sw_stage == SwStage::Fragment ||
|
||||
ctx.sw_stage == SwStage::Compute);
|
||||
if (!can_contract) {
|
||||
ctx.Decorate(op, spv::Decoration::NoContraction);
|
||||
}
|
||||
return op;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,8 +38,8 @@ Id EmitUndefF32(EmitContext& ctx) {
|
||||
return ctx.OpUndef(ctx.F32[1]);
|
||||
}
|
||||
|
||||
Id EmitUndefU64(EmitContext&) {
|
||||
UNREACHABLE_MSG("SPIR-V Instruction");
|
||||
Id EmitUndefU64(EmitContext& ctx) {
|
||||
return ctx.OpUndef(ctx.U64);
|
||||
}
|
||||
|
||||
} // namespace Shader::Backend::SPIRV
|
||||
@@ -323,6 +323,7 @@ void CFG::LinkBlocks() {
|
||||
// need to link with the next block.
|
||||
if (!end_inst.IsTerminateInstruction()) {
|
||||
auto* next_block = get_block(block.end);
|
||||
block.cond = IR::Condition::True;
|
||||
block.branch_true = next_block;
|
||||
block.end_class = EndClass::Branch;
|
||||
next_block->num_predecessors++;
|
||||
|
||||
@@ -55,6 +55,9 @@ std::optional<FetchShaderData> ParseFetchShader(const Shader::Info& info) {
|
||||
}
|
||||
|
||||
const auto* code = GetFetchShaderCode(info, info.fetch_shader_sgpr_base);
|
||||
if (guest_read_hook) {
|
||||
guest_read_hook(code, 0);
|
||||
}
|
||||
|
||||
// bbport: the pipeline cache parses the fetch shader on every draw. Results are cached
|
||||
// per thread by code address and revalidated against a copy of the code, which is
|
||||
|
||||
@@ -4032,11 +4032,11 @@ constexpr std::array<InstFormat, 114> InstructionFormatMUBUF = {{
|
||||
{},
|
||||
{},
|
||||
// 112 = BUFFER_WBINVL1_SC
|
||||
{InstClass::VectorMemL1Cache, InstCategory::VectorMemory, 4, 1, ScalarType::Undefined,
|
||||
ScalarType::Undefined},
|
||||
{InstClass::VectorMemL1Cache, InstCategory::VectorMemory, 0, 0, ScalarType::Any,
|
||||
ScalarType::Any},
|
||||
// 113 = BUFFER_WBINVL1
|
||||
{InstClass::VectorMemL1Cache, InstCategory::VectorMemory, 4, 1, ScalarType::Undefined,
|
||||
ScalarType::Undefined},
|
||||
{InstClass::VectorMemL1Cache, InstCategory::VectorMemory, 0, 0, ScalarType::Any,
|
||||
ScalarType::Any},
|
||||
}};
|
||||
|
||||
constexpr std::array<InstFormat, 8> InstructionFormatMTBUF = {{
|
||||
|
||||
@@ -2697,6 +2697,8 @@ struct SendMsgSimm {
|
||||
|
||||
Message msg : 4;
|
||||
GsOp op : 2;
|
||||
u32 : 2;
|
||||
u32 stream : 2;
|
||||
};
|
||||
|
||||
} // namespace Shader::Gcn
|
||||
|
||||
@@ -573,6 +573,11 @@ private:
|
||||
if (forward_node->type == StatementType::Code) {
|
||||
return &*forward_node;
|
||||
}
|
||||
if (forward_node->type == StatementType::Break ||
|
||||
forward_node->type == StatementType::Return ||
|
||||
forward_node->type == StatementType::Unreachable) {
|
||||
return nullptr;
|
||||
}
|
||||
++forward_node;
|
||||
}
|
||||
return nullptr;
|
||||
@@ -628,6 +633,9 @@ private:
|
||||
// Labels can be ignored
|
||||
break;
|
||||
case StatementType::Code: {
|
||||
if (current_block && current_block != stmt.block->ir_block) {
|
||||
current_block->AddBranch(stmt.block->ir_block);
|
||||
}
|
||||
current_block = stmt.block->ir_block;
|
||||
insert_point = current_block->end();
|
||||
for (auto& node : syntax_list) {
|
||||
|
||||
@@ -19,6 +19,12 @@ void Translator::EmitFlowControl(const GcnInst& inst) {
|
||||
case Opcode::S_TRAP:
|
||||
LOG_WARNING(Render_Vulkan, "S_TRAP instruction!");
|
||||
return;
|
||||
case Opcode::S_SLEEP:
|
||||
LOG_WARNING(Render_Vulkan,
|
||||
"S_SLEEP instruction ignored (wave scheduling delay is not emulated).");
|
||||
return;
|
||||
case Opcode::S_GETREG_B32:
|
||||
return S_GETREG_B32(inst);
|
||||
case Opcode::S_GETPC_B64:
|
||||
return S_GETPC_B64(inst);
|
||||
case Opcode::S_SETPC_B64:
|
||||
@@ -45,6 +51,19 @@ void Translator::S_BARRIER() {
|
||||
ir.Barrier();
|
||||
}
|
||||
|
||||
void Translator::S_GETREG_B32(const GcnInst& inst) {
|
||||
const u32 selector = static_cast<u16>(inst.control.sopk.simm);
|
||||
const u32 register_id = selector & 0x3f;
|
||||
const u32 offset = (selector >> 6) & 0x1f;
|
||||
const u32 width = ((selector >> 11) & 0x1f) + 1;
|
||||
if (register_id != 4 || offset < 13 || offset + width > 15) {
|
||||
UNREACHABLE_MSG("Unsupported S_GETREG_B32 register={} offset={} width={}", register_id,
|
||||
offset, width);
|
||||
}
|
||||
// Vulkan exposes no shader-engine placement; use one virtual shader engine.
|
||||
SetDst(inst.dst[0], ir.Imm32(0));
|
||||
}
|
||||
|
||||
void Translator::S_GETPC_B64(const GcnInst& inst) {
|
||||
const IR::ScalarReg dst{inst.dst[0].code};
|
||||
ir.SetScalarReg(dst, ir.GetPcLo(ir.Imm32(pc)));
|
||||
@@ -64,6 +83,10 @@ void Translator::S_SENDMSG(const GcnInst& inst) {
|
||||
case SendMsgSimm::GsOp::Emit:
|
||||
ir.EmitVertex();
|
||||
break;
|
||||
case SendMsgSimm::GsOp::EmitCut:
|
||||
ir.EmitVertex();
|
||||
ir.EmitPrimitive();
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
@@ -133,6 +133,7 @@ public:
|
||||
void S_FLBIT_I32_B64(const GcnInst& inst);
|
||||
void S_BITSET_B32(const GcnInst& inst, u32 bit_value);
|
||||
void S_BITSET_B64(const GcnInst& inst, u32 bit_value);
|
||||
void S_GETREG_B32(const GcnInst& inst);
|
||||
void S_GETPC_B64(const GcnInst& inst);
|
||||
void S_SAVEEXEC_B64(NegateMode negate, bool is_or, const GcnInst& inst);
|
||||
void S_ABS_I32(const GcnInst& inst);
|
||||
|
||||
@@ -7,6 +7,10 @@ namespace Shader::Gcn {
|
||||
|
||||
void Translator::EmitVectorMemory(const GcnInst& inst) {
|
||||
switch (inst.opcode) {
|
||||
case Opcode::BUFFER_WBINVL1_SC:
|
||||
case Opcode::BUFFER_WBINVL1:
|
||||
ir.DeviceMemoryBarrier();
|
||||
return;
|
||||
// MUBUF / MTBUF
|
||||
|
||||
// Buffer load operations
|
||||
|
||||
@@ -35,6 +35,12 @@ enum class Qualifier : u8 {
|
||||
Sample,
|
||||
};
|
||||
|
||||
/// BB_SHADER_CAPTURE: told of guest memory the compiler reads (size 0: a program).
|
||||
inline thread_local void (*guest_read_hook)(const void* address, std::size_t size) = nullptr;
|
||||
/// Shader corpus replay: the flattened user data the SRT walker produced in the game,
|
||||
/// used instead of running the walker (it reads guest memory the record does not hold).
|
||||
inline thread_local const std::vector<u32>* flat_buf_replay = nullptr;
|
||||
|
||||
/**
|
||||
* Contains general information generated by the shader recompiler for an input program.
|
||||
*/
|
||||
@@ -189,6 +195,9 @@ struct Info : InfoPersistent {
|
||||
return user_data;
|
||||
}
|
||||
std::span<const u32> FlatUserData() const noexcept {
|
||||
if (flat_buf_replay) {
|
||||
return *flat_buf_replay;
|
||||
}
|
||||
if (const auto* snapshot = Snapshot()) [[unlikely]] {
|
||||
return {snapshot->flat, snapshot->flat_size};
|
||||
}
|
||||
@@ -220,6 +229,9 @@ struct Info : InfoPersistent {
|
||||
if (!base) {
|
||||
return T{};
|
||||
}
|
||||
if (guest_read_hook) {
|
||||
guest_read_hook(base + dword_offset, sizeof(T));
|
||||
}
|
||||
std::memcpy(&data, base + dword_offset, sizeof(T));
|
||||
return data;
|
||||
}
|
||||
@@ -255,6 +267,10 @@ struct Info : InfoPersistent {
|
||||
auto buf = ReadUdReg<AmdGpu::Buffer>(static_cast<u32>(tess_consts_ptr_base),
|
||||
static_cast<u32>(tess_consts_dword_offset));
|
||||
VAddr tess_constants_addr = buf.base_address;
|
||||
if (guest_read_hook) {
|
||||
guest_read_hook(reinterpret_cast<const void*>(tess_constants_addr),
|
||||
sizeof(tess_constants));
|
||||
}
|
||||
memcpy(&tess_constants,
|
||||
reinterpret_cast<TessellationDataConstantBuffer*>(tess_constants_addr),
|
||||
sizeof(tess_constants));
|
||||
|
||||
@@ -41,7 +41,7 @@ static bool IsCompositeExtract(IR::Opcode opcode) {
|
||||
}
|
||||
|
||||
static bool IsDisallowedOp(IR::Opcode op) {
|
||||
return op == IR::Opcode::InverseBallot;
|
||||
return op == IR::Opcode::InverseBallot || op == IR::Opcode::GetUserData;
|
||||
}
|
||||
|
||||
using InstList = boost::container::small_vector<IR::Inst*, 4>;
|
||||
@@ -352,11 +352,10 @@ static void DeduplicateSccs(std::vector<PhiScc>& sccs) {
|
||||
|
||||
std::vector<SccGroup*> worklist;
|
||||
worklist.reserve(scc_groups.size());
|
||||
for (auto it = scc_groups.begin(); it != scc_groups.end(); ++it) {
|
||||
auto& group = it->second;
|
||||
if (group.sccs.size() > 1) {
|
||||
for (const auto& scc : sccs) {
|
||||
auto& group = scc_groups.at(scc.hash);
|
||||
if (group.sccs.size() > 1 && !std::exchange(group.queued, true)) {
|
||||
worklist.push_back(&group);
|
||||
group.queued = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -70,11 +70,14 @@ static void EmitBarrierAtBlockStart(IR::Block* block) {
|
||||
ir.Barrier();
|
||||
}
|
||||
|
||||
static bool IsDivergent(const IR::U1& cond) {
|
||||
return IR::BreadthFirstSearch(cond, [](IR::Inst* inst) -> std::optional<bool> {
|
||||
static bool IsDivergent(const IR::U1& cond, const RuntimeInfo& runtime_info) {
|
||||
return IR::BreadthFirstSearch(cond, [&runtime_info](IR::Inst* inst) -> std::optional<bool> {
|
||||
if (inst->GetOpcode() == IR::Opcode::GetAttributeU32 &&
|
||||
inst->Arg(0).Attribute() == IR::Attribute::LocalInvocationId) {
|
||||
return true;
|
||||
const u32 component = inst->Arg(1).U32();
|
||||
if (runtime_info.hw.cs.workgroup_size[component] > 1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}) == true;
|
||||
@@ -83,9 +86,10 @@ static bool IsDivergent(const IR::U1& cond) {
|
||||
// Inserts a barrier after divergent conditional blocks to avoid undefined
|
||||
// behavior when some threads write and others read from shared memory.
|
||||
static void EmitBarrierInMergeBlock(const IR::AbstractSyntaxNode::Data& data,
|
||||
NodeSet& divergence_end, u32& divergence_depth) {
|
||||
NodeSet& divergence_end, u32& divergence_depth,
|
||||
const RuntimeInfo& runtime_info) {
|
||||
const IR::U1 cond = data.if_node.cond;
|
||||
if (IsDivergent(cond)) {
|
||||
if (IsDivergent(cond, runtime_info)) {
|
||||
if (divergence_depth == 0) {
|
||||
EmitBarrierAtBlockStart(data.if_node.merge);
|
||||
}
|
||||
@@ -96,17 +100,18 @@ static void EmitBarrierInMergeBlock(const IR::AbstractSyntaxNode::Data& data,
|
||||
|
||||
// A barrier inside a loop is invalid when different invocations leave on different iterations.
|
||||
// Mark such loops so their shared-memory synchronization can be deferred to the merge block.
|
||||
static NodeSet FindDivergentLoops(const IR::AbstractSyntaxList& syntax_list) {
|
||||
static NodeSet FindDivergentLoops(const IR::AbstractSyntaxList& syntax_list,
|
||||
const RuntimeInfo& runtime_info) {
|
||||
NodeSet divergent_loops;
|
||||
for (const IR::AbstractSyntaxNode& node : syntax_list) {
|
||||
switch (node.type) {
|
||||
case IR::AbstractSyntaxNode::Type::Repeat:
|
||||
if (IsDivergent(node.data.repeat.cond)) {
|
||||
if (IsDivergent(node.data.repeat.cond, runtime_info)) {
|
||||
divergent_loops.emplace(node.data.repeat.merge);
|
||||
}
|
||||
break;
|
||||
case IR::AbstractSyntaxNode::Type::Break:
|
||||
if (IsDivergent(node.data.break_node.cond)) {
|
||||
if (IsDivergent(node.data.break_node.cond, runtime_info)) {
|
||||
divergent_loops.emplace(node.data.break_node.merge);
|
||||
}
|
||||
break;
|
||||
@@ -147,7 +152,7 @@ void SharedMemoryBarrierPass(IR::Program& program, const RuntimeInfo& runtime_in
|
||||
using Type = IR::AbstractSyntaxNode::Type;
|
||||
u32 divergence_depth{};
|
||||
NodeSet divergence_end;
|
||||
const NodeSet divergent_loops = FindDivergentLoops(program.syntax_list);
|
||||
const NodeSet divergent_loops = FindDivergentLoops(program.syntax_list, runtime_info);
|
||||
for (const IR::AbstractSyntaxNode& node : program.syntax_list) {
|
||||
if (node.type == Type::EndIf) {
|
||||
if (divergence_end.contains(node.data.end_if.merge)) {
|
||||
@@ -158,7 +163,7 @@ void SharedMemoryBarrierPass(IR::Program& program, const RuntimeInfo& runtime_in
|
||||
// Check if branch depth is zero, we don't want to insert barrier in potentially divergent
|
||||
// code.
|
||||
if (node.type == Type::If) {
|
||||
EmitBarrierInMergeBlock(node.data, divergence_end, divergence_depth);
|
||||
EmitBarrierInMergeBlock(node.data, divergence_end, divergence_depth, runtime_info);
|
||||
continue;
|
||||
}
|
||||
if (node.type == Type::Loop && divergent_loops.contains(node.data.loop.merge)) {
|
||||
|
||||
@@ -54,6 +54,7 @@ struct Profile {
|
||||
bool needs_unorm_fixup{};
|
||||
bool needs_clip_distance_emulation{};
|
||||
bool supports_shader_stencil_export{};
|
||||
bool fast_shader_math{};
|
||||
|
||||
bool operator==(const Profile&) const = default;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <pthread.h>
|
||||
#ifdef _WIN32
|
||||
@@ -18,6 +20,7 @@
|
||||
#include <boost/preprocessor/stringize.hpp>
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/scope_exit.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/polyfill_thread.h"
|
||||
#include "common/thread.h"
|
||||
@@ -80,6 +83,35 @@ static std::span<const u32> NextPacket(std::span<const u32> span, size_t offset)
|
||||
return span.subspan(offset);
|
||||
}
|
||||
|
||||
/* bbport: a PM4 stream that cannot be parsed (wrong packet type, unknown opcode) is malformed or
|
||||
* desynced: the following dwords are not packets, so parsing on executes garbage - that is the
|
||||
* "Wrong PM4 type 1"/"5026 vs 3273" desync that used to end in UNREACHABLE_MSG (exit code 23) or
|
||||
* a fault. Dump the packet head once per occurrence (rate limited) and let the caller abandon
|
||||
* the submission or skip the packet; one wrong frame instead of a dead process. */
|
||||
static void ReportBadPm4(const char* what, u32 value, std::span<const u32> words, bool abandon) {
|
||||
static std::atomic<u32> reported{0};
|
||||
if (reported.fetch_add(1, std::memory_order_relaxed) >= 32) {
|
||||
return;
|
||||
}
|
||||
std::array<u32, 8> dwords{};
|
||||
const size_t count = words.size() < dwords.size() ? words.size() : dwords.size();
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
dwords[i] = words[i];
|
||||
}
|
||||
LOG_CRITICAL(Render,
|
||||
"PM4: {} ({:#x}){}; dwords: {:08x} {:08x} {:08x} {:08x} {:08x} {:08x} {:08x} "
|
||||
"{:08x}",
|
||||
what, value, abandon ? " - abandoning the rest of the submission" : "", dwords[0],
|
||||
dwords[1], dwords[2], dwords[3], dwords[4], dwords[5], dwords[6], dwords[7]);
|
||||
}
|
||||
|
||||
/// bbport: true while a malformed-packet message may still be logged (the packet loop can repeat
|
||||
/// the same issue every submission, and a log line per frame costs more than the skipped work).
|
||||
static bool ReportPm4Issue() {
|
||||
static std::atomic<u32> reported{0};
|
||||
return reported.fetch_add(1, std::memory_order_relaxed) < 16;
|
||||
}
|
||||
|
||||
Liverpool::Liverpool() : guest_markers_enabled{EmulatorSettings.IsVkGuestMarkersEnabled()} {
|
||||
num_counter_pairs = Libraries::Kernel::sceKernelIsNeoMode() ? 16 : 8;
|
||||
process_thread = std::jthread{std::bind_front(&Liverpool::Process, this)};
|
||||
@@ -88,6 +120,37 @@ Liverpool::Liverpool() : guest_markers_enabled{EmulatorSettings.IsVkGuestMarkers
|
||||
Liverpool::~Liverpool() {
|
||||
process_thread.request_stop();
|
||||
process_thread.join();
|
||||
while (!ce_submits.empty()) {
|
||||
ce_submits.front().destroy();
|
||||
ce_submits.pop();
|
||||
}
|
||||
for (auto& queue : mapped_queues) {
|
||||
while (!queue.submits.empty()) {
|
||||
queue.submits.front().destroy();
|
||||
queue.submits.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Liverpool::ProcessCeQueue() {
|
||||
auto& queue = mapped_queues[GfxQueueId];
|
||||
Task::Handle task{};
|
||||
{
|
||||
std::scoped_lock lock{queue.m_access};
|
||||
if (ce_submits.empty()) {
|
||||
return;
|
||||
}
|
||||
task = ce_submits.front();
|
||||
}
|
||||
task.resume();
|
||||
if (task.done()) {
|
||||
task.destroy();
|
||||
std::scoped_lock lock{queue.m_access};
|
||||
ce_submits.pop();
|
||||
--num_submits;
|
||||
std::scoped_lock lock2{submit_mutex};
|
||||
submit_cv.notify_all();
|
||||
}
|
||||
}
|
||||
|
||||
void Liverpool::ProcessCommands() {
|
||||
@@ -140,8 +203,9 @@ void Liverpool::Process(std::stop_token stoken) {
|
||||
|
||||
curr_qid = -1;
|
||||
|
||||
while (num_submits || num_commands) {
|
||||
while ((num_submits || num_commands) && !stoken.stop_requested()) {
|
||||
ProcessCommands();
|
||||
ProcessCeQueue();
|
||||
|
||||
curr_qid = (curr_qid + 1) % num_mapped_queues;
|
||||
|
||||
@@ -338,8 +402,14 @@ void RunDmaData(Vulkan::Rasterizer& rasterizer, const u8* data) {
|
||||
dma_data->SrcAddress<VAddr>(), dma_data->NumBytes(),
|
||||
false, false);
|
||||
} else {
|
||||
UNREACHABLE_MSG("WriteData src_sel = {}, dst_sel = {}", u32(dma_data->src_sel),
|
||||
u32(dma_data->dst_sel));
|
||||
/* bbport: an unimplemented DMA source/destination pair. Skipping this one copy cannot
|
||||
* corrupt unrelated state, while UNREACHABLE_MSG ended the process (exit code 23). */
|
||||
static std::atomic<u32> reported{0};
|
||||
if (reported.fetch_add(1, std::memory_order_relaxed) < 8) {
|
||||
LOG_ERROR(Render,
|
||||
"WriteData: unsupported transfer src_sel = {}, dst_sel = {}; copy skipped",
|
||||
u32(dma_data->src_sel), u32(dma_data->dst_sel));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -378,7 +448,15 @@ void RunEventWriteEos(Vulkan::Rasterizer& rasterizer, const u8* data) {
|
||||
}
|
||||
});
|
||||
if (event_eos.command == PM4CmdEventWriteEos::Command::GdsStore) {
|
||||
ASSERT(event_eos.size == 1);
|
||||
/* bbport: the GDS store below assumes one dword. Skipping it is safe; the old ASSERT
|
||||
* ended the process. */
|
||||
if (event_eos.size != 1) {
|
||||
if (ReportPm4Issue()) {
|
||||
LOG_ERROR(Render, "EventWriteEos GdsStore: unexpected size {}; store skipped",
|
||||
u32(event_eos.size));
|
||||
}
|
||||
return;
|
||||
}
|
||||
rasterizer.Finish();
|
||||
const u32 value = rasterizer.ReadDataFromGds(event_eos.gds_index);
|
||||
*event_eos.Address() = value;
|
||||
@@ -437,12 +515,21 @@ Liverpool::Task Liverpool::ProcessCeUpdate(std::span<const u32> ccb) {
|
||||
|
||||
const auto* header = reinterpret_cast<const PM4Header*>(ccb.data());
|
||||
const u32 type = header->type;
|
||||
if (type == 2) {
|
||||
ccb = NextPacket(ccb, 1);
|
||||
continue;
|
||||
}
|
||||
if (type != 3) {
|
||||
// No other types of packets were spotted so far
|
||||
UNREACHABLE_MSG("Invalid PM4 type {}", type);
|
||||
// No other types of packets were spotted so far: the stream is desynced.
|
||||
ReportBadPm4("Invalid PM4 type (CE)", type, ccb, true);
|
||||
ccb = {};
|
||||
break;
|
||||
}
|
||||
|
||||
const PM4ItOpcode opcode = header->type3.opcode;
|
||||
// Read the size before running the packet: once it signals the guest, the guest may
|
||||
// already reuse the buffer.
|
||||
const u32 packet_words = header->type3.NumWords() + 1;
|
||||
const auto* it_body = reinterpret_cast<const u32*>(header) + 1;
|
||||
switch (opcode) {
|
||||
case PM4ItOpcode::Nop: {
|
||||
@@ -471,7 +558,8 @@ Liverpool::Task Liverpool::ProcessCeUpdate(std::span<const u32> ccb) {
|
||||
}
|
||||
case PM4ItOpcode::WaitOnDeCounterDiff: {
|
||||
const auto diff = it_body[0];
|
||||
while ((cblock.de_count - cblock.ce_count) >= diff) {
|
||||
while (cblock.ce_count >= cblock.de_count &&
|
||||
(cblock.ce_count - cblock.de_count) >= diff) {
|
||||
YIELD_CE();
|
||||
}
|
||||
break;
|
||||
@@ -480,21 +568,32 @@ Liverpool::Task Liverpool::ProcessCeUpdate(std::span<const u32> ccb) {
|
||||
const auto* indirect_buffer = reinterpret_cast<const PM4CmdIndirectBuffer*>(header);
|
||||
auto task =
|
||||
ProcessCeUpdate({indirect_buffer->Address<const u32>(), indirect_buffer->ib_size});
|
||||
SCOPE_EXIT {
|
||||
task.handle.destroy();
|
||||
};
|
||||
RESUME_CE(task);
|
||||
|
||||
while (!task.handle.done()) {
|
||||
YIELD_CE();
|
||||
RESUME_CE(task);
|
||||
}
|
||||
task.handle.destroy();
|
||||
break;
|
||||
}
|
||||
case PM4ItOpcode::Rewind: {
|
||||
if (!rasterizer) {
|
||||
break;
|
||||
}
|
||||
const auto* rewind = reinterpret_cast<const PM4CmdRewind*>(header);
|
||||
while (!rewind->Valid()) {
|
||||
YIELD_CE();
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
const u32 count = header->type3.NumWords();
|
||||
UNREACHABLE_MSG("Unknown PM4 type 3 opcode {:#x} with count {}",
|
||||
static_cast<u32>(opcode), count);
|
||||
// The header is well formed (type 3 with a known length): skip this packet only.
|
||||
ReportBadPm4("Unknown PM4 type 3 opcode (CE)", static_cast<u32>(opcode), ccb, false);
|
||||
}
|
||||
ccb = NextPacket(ccb, header->type3.NumWords() + 1);
|
||||
ccb = NextPacket(ccb, packet_words);
|
||||
}
|
||||
|
||||
FIBER_EXIT;
|
||||
@@ -736,8 +835,7 @@ void ScanDcb(std::span<const u32> dcb, int depth) {
|
||||
}
|
||||
} // namespace
|
||||
|
||||
Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<const u32> ccb,
|
||||
u64 seq) {
|
||||
Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, u64 seq) {
|
||||
FIBER_ENTER(dcb_task_name);
|
||||
// Top-level buffers enqueued for the draw preparation workers (nested IBs are not).
|
||||
Vulkan::DrawPreparation* draw_prep =
|
||||
@@ -751,19 +849,7 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
||||
ScanDcb(dcb, dcb_depth);
|
||||
}
|
||||
|
||||
cblock.Reset();
|
||||
|
||||
// TODO: potentially, ASCs also can depend on CE and in this case the
|
||||
// CE task should be moved into more global scope
|
||||
Task ce_task{};
|
||||
|
||||
if (!ccb.empty()) {
|
||||
// In case of CCB provided kick off CE asap to have the constant heap ready to use
|
||||
ce_task = ProcessCeUpdate(ccb);
|
||||
RESUME_GFX(ce_task);
|
||||
}
|
||||
|
||||
const auto base_addr = reinterpret_cast<uintptr_t>(dcb.data());
|
||||
auto base_addr = reinterpret_cast<uintptr_t>(dcb.data());
|
||||
while (!dcb.empty()) {
|
||||
ProcessCommands();
|
||||
|
||||
@@ -772,7 +858,9 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
||||
|
||||
switch (type) {
|
||||
default:
|
||||
UNREACHABLE_MSG("Wrong PM4 type {}", type);
|
||||
// There is no length to trust for an unknown type: drop the rest of this submission.
|
||||
ReportBadPm4("Wrong PM4 type (graphics)", type, dcb, true);
|
||||
dcb = {};
|
||||
break;
|
||||
case 0: {
|
||||
// A zero dword is often padding (alignment or trailing) in command chunks.
|
||||
@@ -901,9 +989,10 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
||||
ASSERT(col_buf_id < NUM_COLOR_BUFFERS);
|
||||
|
||||
const auto nop_offset = header->type3.count;
|
||||
if (nop_offset == 0x0e || nop_offset == 0x0d || nop_offset == 0x0b) {
|
||||
ASSERT_MSG(payload[nop_offset] == 0xc0001000,
|
||||
"NOP hint is missing in CB setup sequence");
|
||||
/* bbport: a missing trailing NOP hint only means the extent is unknown;
|
||||
* clear it instead of aborting the process (exit code 23). */
|
||||
if ((nop_offset == 0x0e || nop_offset == 0x0d || nop_offset == 0x0b) &&
|
||||
payload[nop_offset] == 0xc0001000) {
|
||||
last_cb_extent[col_buf_id].raw = payload[nop_offset + 1];
|
||||
} else {
|
||||
last_cb_extent[col_buf_id].raw = 0;
|
||||
@@ -924,17 +1013,13 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
||||
ASSERT(col_buf_id < NUM_COLOR_BUFFERS);
|
||||
|
||||
const auto nop_offset = header->type3.count;
|
||||
if (nop_offset == 0x04) {
|
||||
ASSERT_MSG(payload[nop_offset] == 0xc0001000,
|
||||
"NOP hint is missing in CB setup sequence");
|
||||
if (nop_offset == 0x04 && payload[nop_offset] == 0xc0001000) {
|
||||
last_cb_extent[col_buf_id].raw = payload[nop_offset + 1];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ContextRegs::DbZInfo: {
|
||||
if (header->type3.count == 8) {
|
||||
ASSERT_MSG(payload[20] == 0xc0001000,
|
||||
"NOP hint is missing in DB setup sequence");
|
||||
if (header->type3.count == 8 && payload[20] == 0xc0001000) {
|
||||
last_db_extent.raw = payload[21];
|
||||
} else {
|
||||
last_db_extent.raw = 0;
|
||||
@@ -952,7 +1037,17 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
||||
|
||||
if (set_data->reg_offset >= 0x200 &&
|
||||
set_data->reg_offset <= (0x200 + sizeof(ComputeProgram) / 4)) {
|
||||
ASSERT(set_size <= sizeof(ComputeProgram));
|
||||
/* bbport: never memcpy past cs_state. A packet claiming more than the
|
||||
* program block holds is malformed; skip it instead of overflowing. */
|
||||
if (set_size > sizeof(ComputeProgram)) {
|
||||
if (ReportPm4Issue()) {
|
||||
LOG_WARNING(Render,
|
||||
"SetShReg (graphics): packet size {} exceeds the compute "
|
||||
"program block; skipped",
|
||||
set_size);
|
||||
}
|
||||
break;
|
||||
}
|
||||
auto* addr = reinterpret_cast<u32*>(&mapped_queues[GfxQueueId].cs_state) +
|
||||
(set_data->reg_offset - 0x200);
|
||||
std::memcpy(addr, header + 2, set_size);
|
||||
@@ -1159,7 +1254,14 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
||||
}
|
||||
case PM4ItOpcode::SetBase: {
|
||||
const auto* set_base = reinterpret_cast<const PM4CmdSetBase*>(header);
|
||||
ASSERT(set_base->base_index == PM4CmdSetBase::BaseIndex::DrawIndexIndirPatchTable);
|
||||
if (set_base->base_index != PM4CmdSetBase::BaseIndex::DrawIndexIndirPatchTable) {
|
||||
if (ReportPm4Issue()) {
|
||||
LOG_WARNING(Render,
|
||||
"SetBase: unexpected base index {}; packet skipped",
|
||||
magic_enum::enum_name(set_base->base_index.Value()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
indirect_args_addr = set_base->Address<u64>();
|
||||
break;
|
||||
}
|
||||
@@ -1224,8 +1326,28 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
||||
}
|
||||
case PM4ItOpcode::WriteData: {
|
||||
const auto* write_data = reinterpret_cast<const PM4CmdWriteData*>(header);
|
||||
ASSERT(write_data->dst_sel.Value() == 2 || write_data->dst_sel.Value() == 5);
|
||||
ASSERT(!write_data->wr_one_addr.Value());
|
||||
/* bbport: only the two memory destination encodings and the "data in packet"
|
||||
* form below are understood. Anything else used to abort (exit code 23);
|
||||
* skipping one write keeps the process alive. */
|
||||
if ((write_data->dst_sel.Value() != 2 && write_data->dst_sel.Value() != 5) ||
|
||||
write_data->wr_one_addr.Value()) {
|
||||
if (ReportPm4Issue()) {
|
||||
LOG_WARNING(Render,
|
||||
"WriteData: unsupported dst_sel = {}, wr_one_addr = {}; packet "
|
||||
"skipped",
|
||||
write_data->dst_sel.Value(), write_data->wr_one_addr.Value());
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* bbport: the data size below is (count - 2) dwords; a shorter packet would
|
||||
* underflow to a huge memcpy (access violation) - skip it. */
|
||||
if (count < 2) {
|
||||
if (ReportPm4Issue()) {
|
||||
LOG_WARNING(Render, "WriteData: packet too short (count {}); skipped",
|
||||
count);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (rasterizer) {
|
||||
// In order with the draws (on the draw recording thread when in use).
|
||||
BbWriteLog::NoteIntent(write_data->Address<u64>(), write_data->data,
|
||||
@@ -1316,8 +1438,16 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
||||
}
|
||||
case PM4ItOpcode::IndirectBuffer: {
|
||||
const auto* indirect_buffer = reinterpret_cast<const PM4CmdIndirectBuffer*>(header);
|
||||
if (indirect_buffer->chain) {
|
||||
dcb = {indirect_buffer->Address<const u32>(), indirect_buffer->ib_size};
|
||||
base_addr = reinterpret_cast<uintptr_t>(dcb.data());
|
||||
continue;
|
||||
}
|
||||
auto task = ProcessGraphics(
|
||||
{indirect_buffer->Address<const u32>(), indirect_buffer->ib_size}, {});
|
||||
{indirect_buffer->Address<const u32>(), indirect_buffer->ib_size});
|
||||
SCOPE_EXIT {
|
||||
task.handle.destroy();
|
||||
};
|
||||
// Tasks start suspended: the nested body (and its scan) runs on this resume.
|
||||
g_dcb_depth = dcb_depth + 1;
|
||||
RESUME_GFX(task);
|
||||
@@ -1327,7 +1457,6 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
||||
YIELD_GFX();
|
||||
RESUME_GFX(task);
|
||||
}
|
||||
task.handle.destroy();
|
||||
break;
|
||||
}
|
||||
case PM4ItOpcode::IncrementDeCounter: {
|
||||
@@ -1335,8 +1464,8 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
||||
break;
|
||||
}
|
||||
case PM4ItOpcode::WaitOnCeCounter: {
|
||||
while (cblock.ce_count <= cblock.de_count && !ce_task.handle.done()) {
|
||||
RESUME_GFX(ce_task);
|
||||
while (cblock.ce_count <= cblock.de_count) {
|
||||
YIELD_GFX();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1345,16 +1474,49 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
||||
}
|
||||
case PM4ItOpcode::StrmoutBufferUpdate: {
|
||||
const auto* strmout = reinterpret_cast<const PM4CmdStrmoutBufferUpdate*>(header);
|
||||
LOG_WARNING(Render_Vulkan,
|
||||
"Unimplemented IT_STRMOUT_BUFFER_UPDATE, update_memory = {}, "
|
||||
"source_select = {}, buffer_select = {}",
|
||||
strmout->update_memory.Value(),
|
||||
magic_enum::enum_name(strmout->source_select.Value()),
|
||||
strmout->buffer_select.Value());
|
||||
const u32 buf_idx = strmout->buffer_select.Value();
|
||||
LOG_DEBUG(Render,
|
||||
"IT_STRMOUT_BUFFER_UPDATE buffer_select = {}, source_select = {}, "
|
||||
"update_memory = {}",
|
||||
buf_idx, magic_enum::enum_name(strmout->source_select.Value()),
|
||||
strmout->update_memory.Value());
|
||||
u32 offset = vgt_strmout_buffer_filled_size[buf_idx];
|
||||
switch (strmout->source_select.Value()) {
|
||||
case SourceSelect::BufferOffset:
|
||||
offset = strmout->buffer_offset;
|
||||
break;
|
||||
case SourceSelect::VgtStrmoutBufferFilledSize:
|
||||
offset = vgt_strmout_buffer_filled_size[buf_idx];
|
||||
break;
|
||||
case SourceSelect::SrcAddress: {
|
||||
const VAddr src_addr = strmout->SrcAddress<VAddr>();
|
||||
auto* memory = Core::Memory::Instance();
|
||||
if (src_addr && memory && memory->IsValidGpuMapping(src_addr, sizeof(offset))) {
|
||||
std::memcpy(&offset, reinterpret_cast<const void*>(src_addr),
|
||||
sizeof(offset));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SourceSelect::None:
|
||||
break;
|
||||
}
|
||||
if (strmout->source_select.Value() != SourceSelect::None) {
|
||||
vgt_strmout_buffer_filled_size[buf_idx] = offset;
|
||||
}
|
||||
if (strmout->update_memory.Value()) {
|
||||
const VAddr dst_addr = strmout->DstAddress<VAddr>();
|
||||
auto* memory = Core::Memory::Instance();
|
||||
if (dst_addr && memory && memory->IsValidGpuMapping(dst_addr, sizeof(offset))) {
|
||||
std::memcpy(reinterpret_cast<void*>(dst_addr),
|
||||
&vgt_strmout_buffer_filled_size[buf_idx], sizeof(offset));
|
||||
}
|
||||
}
|
||||
regs.cp_strmout_cntl.offset_update_done = 1;
|
||||
break;
|
||||
}
|
||||
case PM4ItOpcode::GetLodStats: {
|
||||
LOG_WARNING(Render_Vulkan, "Unimplemented IT_GET_LOD_STATS");
|
||||
const auto* get_lod = reinterpret_cast<const PM4CmdGetLodStats*>(header);
|
||||
HandleGetLodStats(get_lod);
|
||||
break;
|
||||
}
|
||||
case PM4ItOpcode::CondExec: {
|
||||
@@ -1371,21 +1533,17 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE_MSG("Unknown PM4 type 3 opcode {:#x} with count {}",
|
||||
static_cast<u32>(opcode), count);
|
||||
// Type-3 header with a known length: skip this packet and keep the submission.
|
||||
ReportBadPm4("Unknown PM4 type 3 opcode (graphics)", static_cast<u32>(opcode), dcb,
|
||||
false);
|
||||
}
|
||||
dcb = NextPacket(dcb, header->type3.NumWords() + 1);
|
||||
// The size read before running the packet: a flip or an EOP interrupt lets the guest
|
||||
// reuse this buffer while we are still on it, so the header may be gone by now.
|
||||
dcb = NextPacket(dcb, count + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ce_task.handle) {
|
||||
while (!ce_task.handle.done()) {
|
||||
RESUME_GFX(ce_task);
|
||||
}
|
||||
ce_task.handle.destroy();
|
||||
}
|
||||
|
||||
if (rasterizer && seq != NoSeq) {
|
||||
rasterizer->RetireSubmission(); // prepared draws live until the recording thread is past
|
||||
}
|
||||
@@ -1488,8 +1646,13 @@ Liverpool::Task Liverpool::ProcessCompute(std::span<const u32> acb, u32 vqid) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
// No other types of packets were spotted so far
|
||||
UNREACHABLE_MSG("Invalid PM4 type {}", header->type.Value());
|
||||
// No other types of packets were spotted so far: the stream is desynced.
|
||||
ReportBadPm4("Invalid PM4 type (compute)", header->type.Value(), acb, true);
|
||||
if constexpr (!is_indirect) {
|
||||
*queue.read_addr += acb.size();
|
||||
*queue.read_addr %= queue.ring_size_dw;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
const PM4ItOpcode opcode = header->type3.opcode;
|
||||
@@ -1502,15 +1665,25 @@ Liverpool::Task Liverpool::ProcessCompute(std::span<const u32> acb, u32 vqid) {
|
||||
}
|
||||
case PM4ItOpcode::IndirectBuffer: {
|
||||
const auto* indirect_buffer = reinterpret_cast<const PM4CmdIndirectBuffer*>(header);
|
||||
if constexpr (is_indirect) {
|
||||
if (indirect_buffer->chain) {
|
||||
acb = {indirect_buffer->Address<const u32>(), indirect_buffer->ib_size};
|
||||
base_addr = reinterpret_cast<VAddr>(acb.data());
|
||||
acb_size = acb.size_bytes();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
auto task = ProcessCompute<true>(
|
||||
{indirect_buffer->Address<const u32>(), indirect_buffer->ib_size}, vqid);
|
||||
SCOPE_EXIT {
|
||||
task.handle.destroy();
|
||||
};
|
||||
RESUME_ASC(task, vqid);
|
||||
|
||||
while (!task.handle.done()) {
|
||||
YIELD_ASC(vqid);
|
||||
RESUME_ASC(task, vqid);
|
||||
}
|
||||
task.handle.destroy();
|
||||
break;
|
||||
}
|
||||
case PM4ItOpcode::DmaData: {
|
||||
@@ -1518,7 +1691,15 @@ Liverpool::Task Liverpool::ProcessCompute(std::span<const u32> acb, u32 vqid) {
|
||||
if (dma_data->dst_addr_lo == 0x3022C || !rasterizer) {
|
||||
break;
|
||||
}
|
||||
ASSERT(dma_data->command.das == 0);
|
||||
/* bbport: `das` selects an unsupported data-size/layout form. Skipping this one
|
||||
* transfer is safe; the old ASSERT ended the process. */
|
||||
if (dma_data->command.das != 0) {
|
||||
if (ReportPm4Issue()) {
|
||||
LOG_WARNING(Render, "DmaData: unsupported data-size field {}; packet skipped",
|
||||
dma_data->command.das);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (dma_data->src_sel == DmaDataSrc::Data && dma_data->dst_sel == DmaDataDst::Gds) {
|
||||
rasterizer->FillBuffer(dma_data->dst_addr_lo, dma_data->NumBytes(), dma_data->data,
|
||||
true);
|
||||
@@ -1554,8 +1735,13 @@ Liverpool::Task Liverpool::ProcessCompute(std::span<const u32> acb, u32 vqid) {
|
||||
rasterizer->CopyBuffer(dst_addr, src_addr, num_bytes, false, false);
|
||||
}
|
||||
} else {
|
||||
UNREACHABLE_MSG("WriteData src_sel = {}, dst_sel = {}", u32(dma_data->src_sel),
|
||||
u32(dma_data->dst_sel));
|
||||
// bbport: unimplemented transfer pair; skip it instead of exiting.
|
||||
if (ReportPm4Issue()) {
|
||||
LOG_WARNING(Render,
|
||||
"DmaData: unsupported transfer src_sel = {}, dst_sel = {}; "
|
||||
"packet skipped",
|
||||
u32(dma_data->src_sel), u32(dma_data->dst_sel));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1578,7 +1764,16 @@ Liverpool::Task Liverpool::ProcessCompute(std::span<const u32> acb, u32 vqid) {
|
||||
|
||||
if (set_data->reg_offset >= 0x200 &&
|
||||
set_data->reg_offset <= (0x200 + sizeof(ComputeProgram) / 4)) {
|
||||
ASSERT(set_size <= sizeof(ComputeProgram));
|
||||
/* bbport: never memcpy past cs_state; skip a malformed packet instead. */
|
||||
if (set_size > sizeof(ComputeProgram)) {
|
||||
if (ReportPm4Issue()) {
|
||||
LOG_WARNING(Render,
|
||||
"SetShReg (compute): packet size {} exceeds the compute "
|
||||
"program block; skipped",
|
||||
set_size);
|
||||
}
|
||||
break;
|
||||
}
|
||||
auto* addr = reinterpret_cast<u32*>(&mapped_queues[vqid + 1].cs_state) +
|
||||
(set_data->reg_offset - 0x200);
|
||||
std::memcpy(addr, header + 2, set_size);
|
||||
@@ -1652,13 +1847,29 @@ Liverpool::Task Liverpool::ProcessCompute(std::span<const u32> acb, u32 vqid) {
|
||||
rasterizer->WaitDeferredSignals();
|
||||
}
|
||||
const auto* write_data = reinterpret_cast<const PM4CmdWriteData*>(header);
|
||||
ASSERT(write_data->dst_sel.Value() == 2 || write_data->dst_sel.Value() == 5);
|
||||
const u32 data_size = (header->type3.count.Value() - 2) * 4;
|
||||
if (!write_data->wr_one_addr.Value()) {
|
||||
std::memcpy(write_data->Address<void*>(), write_data->data, data_size);
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
/* bbport: only the two memory destination encodings and the "data in packet" form
|
||||
* are understood. Anything else used to abort; skip this write instead. */
|
||||
if ((write_data->dst_sel.Value() != 2 && write_data->dst_sel.Value() != 5) ||
|
||||
write_data->wr_one_addr.Value()) {
|
||||
if (ReportPm4Issue()) {
|
||||
LOG_WARNING(Render,
|
||||
"WriteData (compute): unsupported dst_sel = {}, wr_one_addr = {}; "
|
||||
"packet skipped",
|
||||
write_data->dst_sel.Value(), write_data->wr_one_addr.Value());
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* bbport: the data size below is (count - 2) dwords; a shorter packet would
|
||||
* underflow to a huge memcpy (access violation) - skip it. */
|
||||
if (header->type3.count.Value() < 2) {
|
||||
if (ReportPm4Issue()) {
|
||||
LOG_WARNING(Render, "WriteData (compute): packet too short (count {}); skipped",
|
||||
header->type3.count.Value());
|
||||
}
|
||||
break;
|
||||
}
|
||||
const u32 data_size = (header->type3.count.Value() - 2) * 4;
|
||||
std::memcpy(write_data->Address<void*>(), write_data->data, data_size);
|
||||
break;
|
||||
}
|
||||
case PM4ItOpcode::MemSemaphore: {
|
||||
@@ -1675,7 +1886,15 @@ Liverpool::Task Liverpool::ProcessCompute(std::span<const u32> acb, u32 vqid) {
|
||||
}
|
||||
case PM4ItOpcode::WaitRegMem: {
|
||||
const auto* wait_reg_mem = reinterpret_cast<const PM4CmdWaitRegMem*>(header);
|
||||
ASSERT(wait_reg_mem->engine.Value() == PM4CmdWaitRegMem::Engine::Me);
|
||||
/* bbport: Test() only reads the register file for engine Me; for any other engine
|
||||
* the loop below would test the wrong state and could spin forever. Skip it. */
|
||||
if (wait_reg_mem->engine.Value() != PM4CmdWaitRegMem::Engine::Me) {
|
||||
if (ReportPm4Issue()) {
|
||||
LOG_WARNING(Render, "WaitRegMem: unsupported engine {}; packet skipped",
|
||||
magic_enum::enum_name(wait_reg_mem->engine.Value()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
while (!wait_reg_mem->Test(regs.reg_array)) {
|
||||
YIELD_ASC(vqid);
|
||||
}
|
||||
@@ -1705,9 +1924,15 @@ Liverpool::Task Liverpool::ProcessCompute(std::span<const u32> acb, u32 vqid) {
|
||||
// const auto* event = reinterpret_cast<const PM4CmdEventWrite*>(header);
|
||||
break;
|
||||
}
|
||||
case PM4ItOpcode::GetLodStats: {
|
||||
const auto* get_lod = reinterpret_cast<const PM4CmdGetLodStats*>(header);
|
||||
HandleGetLodStats(get_lod);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE_MSG("Unknown PM4 type 3 opcode {:#x} with count {}",
|
||||
static_cast<u32>(opcode), header->type3.NumWords());
|
||||
// Type-3 header with a known length: skip this packet and keep the submission.
|
||||
ReportBadPm4("Unknown PM4 type 3 opcode (compute)", static_cast<u32>(opcode), acb,
|
||||
false);
|
||||
}
|
||||
|
||||
acb = NextPacket(acb, next_dw_off);
|
||||
@@ -1721,12 +1946,33 @@ Liverpool::Task Liverpool::ProcessCompute(std::span<const u32> acb, u32 vqid) {
|
||||
FIBER_EXIT;
|
||||
}
|
||||
|
||||
void Liverpool::HandleGetLodStats(const PM4CmdGetLodStats* get_lod) {
|
||||
LOG_DEBUG(Render, "IT_GET_LOD_STATS: buffer = {:#x}, offset = {:#x}", get_lod->Address(),
|
||||
get_lod->DataOffset());
|
||||
}
|
||||
|
||||
Liverpool::CmdBuffer Liverpool::CopyCmdBuffers(std::span<const u32> dcb, std::span<const u32> ccb) {
|
||||
auto& queue = mapped_queues[GfxQueueId];
|
||||
ASSERT_MSG(queue.dcb_buffer.capacity() >= queue.dcb_buffer_offset + dcb.size(),
|
||||
"dcb copy buffer out of reserved space");
|
||||
ASSERT_MSG(queue.ccb_buffer.capacity() >= queue.ccb_buffer_offset + ccb.size(),
|
||||
"ccb copy buffer out of reserved space");
|
||||
/* bbport: the reserved capacity is sized for the largest submission the guest was seen to
|
||||
* send, but it can exceed that. The assert ended the process; growing may reallocate these
|
||||
* buffers, and the incoming spans can point into them, so copy the input first in that case. */
|
||||
std::vector<u32> dcb_keep, ccb_keep;
|
||||
if (queue.dcb_buffer.capacity() < queue.dcb_buffer_offset + dcb.size()) {
|
||||
if (ReportPm4Issue()) {
|
||||
LOG_WARNING(Render, "dcb copy buffer too small ({} > {}), growing",
|
||||
queue.dcb_buffer_offset + dcb.size(), queue.dcb_buffer.capacity());
|
||||
}
|
||||
dcb_keep.assign(dcb.begin(), dcb.end());
|
||||
dcb = dcb_keep;
|
||||
}
|
||||
if (queue.ccb_buffer.capacity() < queue.ccb_buffer_offset + ccb.size()) {
|
||||
if (ReportPm4Issue()) {
|
||||
LOG_WARNING(Render, "ccb copy buffer too small ({} > {}), growing",
|
||||
queue.ccb_buffer_offset + ccb.size(), queue.ccb_buffer.capacity());
|
||||
}
|
||||
ccb_keep.assign(ccb.begin(), ccb.end());
|
||||
ccb = ccb_keep;
|
||||
}
|
||||
|
||||
queue.dcb_buffer.resize(
|
||||
std::max(queue.dcb_buffer.size(), queue.dcb_buffer_offset + dcb.size()));
|
||||
@@ -1767,25 +2013,35 @@ void Liverpool::SubmitGfx(std::span<const u32> dcb, std::span<const u32> ccb) {
|
||||
auto prep_submission = draw_prep ? draw_prep->Build(dcb) : nullptr;
|
||||
{
|
||||
// Numbering, enqueueing and queueing under one lock keep the three orders identical.
|
||||
std::scoped_lock lock{queue.m_access};
|
||||
std::scoped_lock lock{submit_mutex, queue.m_access};
|
||||
u64 seq = NoSeq;
|
||||
if (draw_prep) {
|
||||
seq = gfx_submit_seq++;
|
||||
draw_prep->Enqueue(seq, std::move(prep_submission));
|
||||
}
|
||||
auto task = ProcessGraphics(dcb, ccb, seq);
|
||||
if (!ccb.empty()) {
|
||||
ce_submits.emplace(ProcessCeUpdate(ccb).handle);
|
||||
++num_submits;
|
||||
}
|
||||
auto task = ProcessGraphics(dcb, seq);
|
||||
queue.submits.emplace(task.handle);
|
||||
++num_submits;
|
||||
BbStats::submissions.fetch_add(1, std::memory_order_relaxed);
|
||||
work_retired = false;
|
||||
submit_cv.notify_one();
|
||||
}
|
||||
|
||||
std::scoped_lock lk{submit_mutex};
|
||||
++num_submits;
|
||||
BbStats::submissions.fetch_add(1, std::memory_order_relaxed);
|
||||
work_retired = false;
|
||||
submit_cv.notify_one();
|
||||
}
|
||||
|
||||
void Liverpool::SubmitAsc(u32 gnm_vqid, std::span<const u32> acb) {
|
||||
ASSERT_MSG(gnm_vqid > 0 && gnm_vqid < NumTotalQueues, "Invalid virtual ASC queue index");
|
||||
/* bbport: the queue index comes from the guest; an out-of-range one used to abort and would
|
||||
* otherwise index mapped_queues out of bounds. Drop that submission instead. */
|
||||
if (gnm_vqid == 0 || gnm_vqid >= NumTotalQueues) {
|
||||
if (ReportPm4Issue()) {
|
||||
LOG_ERROR(Render, "SubmitAsc: invalid virtual queue {} (max {}), submission dropped",
|
||||
gnm_vqid, u32{NumTotalQueues});
|
||||
}
|
||||
return;
|
||||
}
|
||||
auto& queue = mapped_queues[gnm_vqid];
|
||||
|
||||
const auto vqid = gnm_vqid - 1;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "common/types.h"
|
||||
#include "common/unique_function.h"
|
||||
#include "video_core/amdgpu/cb_db_extent.h"
|
||||
#include "video_core/amdgpu/pm4_cmds.h"
|
||||
#include "video_core/amdgpu/regs.h"
|
||||
|
||||
namespace Vulkan {
|
||||
@@ -224,13 +225,15 @@ private:
|
||||
|
||||
using CmdBuffer = std::pair<std::span<const u32>, std::span<const u32>>;
|
||||
CmdBuffer CopyCmdBuffers(std::span<const u32> dcb, std::span<const u32> ccb);
|
||||
Task ProcessGraphics(std::span<const u32> dcb, std::span<const u32> ccb, u64 seq = NoSeq);
|
||||
Task ProcessGraphics(std::span<const u32> dcb, u64 seq = NoSeq);
|
||||
Task ProcessCeUpdate(std::span<const u32> ccb);
|
||||
template <bool is_indirect = false>
|
||||
Task ProcessCompute(std::span<const u32> acb, u32 vqid);
|
||||
|
||||
void ProcessCommands();
|
||||
void ProcessCeQueue();
|
||||
void Process(std::stop_token stoken);
|
||||
void HandleGetLodStats(const PM4CmdGetLodStats* get_lod);
|
||||
|
||||
struct GpuQueue {
|
||||
std::mutex m_access{};
|
||||
@@ -242,25 +245,20 @@ private:
|
||||
ComputeProgram cs_state{};
|
||||
};
|
||||
std::array<GpuQueue, NumTotalQueues> mapped_queues{};
|
||||
std::queue<Task::Handle> ce_submits;
|
||||
u32 num_mapped_queues{1u}; // GFX is always available
|
||||
|
||||
VAddr indirect_args_addr{};
|
||||
u32 num_counter_pairs{};
|
||||
u64 pixel_counter{};
|
||||
u32 vgt_strmout_buffer_filled_size[4]{};
|
||||
|
||||
struct ConstantEngine {
|
||||
void Reset() {
|
||||
ce_count = 0;
|
||||
de_count = 0;
|
||||
ce_compare_count = 0;
|
||||
}
|
||||
|
||||
[[nodiscard]] u32 Diff() const {
|
||||
ASSERT_MSG(ce_count >= de_count, "DE counter is ahead of CE");
|
||||
return ce_count - de_count;
|
||||
}
|
||||
|
||||
u32 ce_compare_count{};
|
||||
u32 ce_count{};
|
||||
u32 de_count{};
|
||||
static std::array<u8, 48_KB> constants_heap;
|
||||
|
||||
@@ -105,7 +105,7 @@ std::string_view NameOf(NumberFormat fmt) {
|
||||
case NumberFormat::Ubint:
|
||||
return "Ubint";
|
||||
case NumberFormat::Ubscaled:
|
||||
return "Unscaled";
|
||||
return "Ubscaled";
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <cstring>
|
||||
#include "common/assert.h"
|
||||
#include "common/bit_field.h"
|
||||
@@ -258,6 +259,7 @@ struct PM4CmdStrmoutBufferUpdate {
|
||||
union {
|
||||
BitField<0, 1, u32> update_memory;
|
||||
BitField<1, 2, SourceSelect> source_select;
|
||||
BitField<7, 1, u32> data_type;
|
||||
BitField<8, 2, u32> buffer_select;
|
||||
u32 control;
|
||||
};
|
||||
@@ -276,13 +278,13 @@ struct PM4CmdStrmoutBufferUpdate {
|
||||
template <typename T = u64>
|
||||
T DstAddress() const {
|
||||
ASSERT(update_memory.Value() == 1);
|
||||
return reinterpret_cast<T>(dst_address_lo.Value() | u64(dst_address_hi & 0xFFFF) << 32);
|
||||
return reinterpret_cast<T>((dst_address_lo.Value() << 2) | u64(dst_address_hi & 0xFFFF) << 32);
|
||||
}
|
||||
|
||||
template <typename T = u64>
|
||||
T SrcAddress() const {
|
||||
ASSERT(source_select.Value() == SourceSelect::SrcAddress);
|
||||
return reinterpret_cast<T>(src_address_lo.Value() | u64(src_address_hi & 0xFFFF) << 32);
|
||||
return reinterpret_cast<T>((src_address_lo.Value() << 2) | u64(src_address_hi & 0xFFFF) << 32);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -651,7 +653,8 @@ struct PM4CmdRewind {
|
||||
};
|
||||
|
||||
bool Valid() const {
|
||||
return valid;
|
||||
return (std::atomic_ref<u32>{const_cast<u32&>(raw)}.load(std::memory_order_acquire) >>
|
||||
31) != 0;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1239,4 +1242,30 @@ struct PM4CmdCondExec {
|
||||
}
|
||||
};
|
||||
|
||||
struct PM4CmdGetLodStats {
|
||||
PM4Type3Header header;
|
||||
union {
|
||||
BitField<0, 16, u32> data_offset;
|
||||
BitField<16, 16, u32> control_flags;
|
||||
u32 control;
|
||||
};
|
||||
u32 addr_lo;
|
||||
u32 addr_hi;
|
||||
|
||||
template <typename T = VAddr>
|
||||
[[nodiscard]] T Address() const {
|
||||
const u64 addr = (static_cast<u64>(addr_hi) << 32) | static_cast<u64>(addr_lo);
|
||||
if constexpr (std::is_pointer_v<T>) {
|
||||
return reinterpret_cast<T>(addr);
|
||||
} else {
|
||||
return static_cast<T>(addr);
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] u32 DataOffset() const {
|
||||
return data_offset.Value();
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(PM4CmdGetLodStats) == 0x10);
|
||||
|
||||
} // namespace AmdGpu
|
||||
@@ -186,6 +186,32 @@ union Regs {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// Screen, window and generic scissors combined, with the window offset applied and
|
||||
/// negative values clamped to 0.
|
||||
Scissor GetCombinedScissor() const {
|
||||
const bool enable_offset = !window_scissor.window_offset_disable;
|
||||
const s16 x_offset = enable_offset ? window_offset.window_x_offset : 0;
|
||||
const s16 y_offset = enable_offset ? window_offset.window_y_offset : 0;
|
||||
const auto top_left = [](s16 scr, s16 win, s16 gen, s16 offset) {
|
||||
return Scissor::Clamp(std::max({scr, s16(win + offset), s16(gen + offset)}));
|
||||
};
|
||||
const auto bottom_right = [](s16 scr, s16 win, s16 gen, s16 offset) {
|
||||
return Scissor::Clamp(std::min({scr, s16(win + offset), s16(gen + offset)}));
|
||||
};
|
||||
Scissor scissor{};
|
||||
scissor.top_left_x = top_left(screen_scissor.top_left_x, window_scissor.top_left_x,
|
||||
generic_scissor.top_left_x, x_offset);
|
||||
scissor.top_left_y = top_left(screen_scissor.top_left_y, window_scissor.top_left_y,
|
||||
generic_scissor.top_left_y, y_offset);
|
||||
scissor.bottom_right_x =
|
||||
bottom_right(screen_scissor.bottom_right_x, window_scissor.bottom_right_x,
|
||||
generic_scissor.bottom_right_x, x_offset);
|
||||
scissor.bottom_right_y =
|
||||
bottom_right(screen_scissor.bottom_right_y, window_scissor.bottom_right_y,
|
||||
generic_scissor.bottom_right_y, y_offset);
|
||||
return scissor;
|
||||
}
|
||||
|
||||
bool IsClipDisabled() const {
|
||||
return clipper_control.clip_disable || primitive_type == PrimitiveType::RectList;
|
||||
}
|
||||
|
||||
@@ -269,15 +269,31 @@ struct DepthBuffer {
|
||||
}
|
||||
|
||||
u32 NumBits() const {
|
||||
return z_info.format == ZFormat::Z32Float ? 32 : 16;
|
||||
switch (z_info.format) {
|
||||
case ZFormat::Z32Float:
|
||||
return 32;
|
||||
case ZFormat::Z16:
|
||||
return 16;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
u32 GetDepthSliceSize() const {
|
||||
ASSERT(z_info.format != ZFormat::Invalid);
|
||||
if (z_info.format == ZFormat::Invalid) {
|
||||
return 0;
|
||||
}
|
||||
const auto bpe = NumBits() >> 3; // in bytes
|
||||
return (depth_slice.tile_max + 1) * 64 * bpe * NumSamples();
|
||||
}
|
||||
|
||||
u32 GetStencilSliceSize() const {
|
||||
if (stencil_info.format == StencilFormat::Invalid) {
|
||||
return 0;
|
||||
}
|
||||
return (depth_slice.tile_max + 1) * 64 * 1 * NumSamples();
|
||||
}
|
||||
|
||||
TileMode GetTileMode() const {
|
||||
return static_cast<TileMode>(z_info.tile_mode_index);
|
||||
}
|
||||
|
||||
@@ -17,10 +17,12 @@
|
||||
#include "video_core/buffer_cache/buffer.h"
|
||||
#include "video_core/buffer_cache/buffer_cache.h"
|
||||
#include "video_core/buffer_cache/memory_tracker.h"
|
||||
#include "video_core/page_manager.h"
|
||||
#include "video_core/renderer_vulkan/vk_graphics_pipeline.h"
|
||||
#include "video_core/renderer_vulkan/vk_instance.h"
|
||||
#include "video_core/renderer_vulkan/vk_runtime.h"
|
||||
#include "video_core/renderer_vulkan/vk_scheduler.h"
|
||||
#include "video_core/texture_cache/image.h"
|
||||
#include "video_core/texture_cache/texture_cache.h"
|
||||
|
||||
#include <vk_mem_alloc.h>
|
||||
@@ -102,7 +104,7 @@ BufferCache::~BufferCache() = default;
|
||||
|
||||
void BufferCache::InvalidateMemory(VAddr device_addr, u64 size, bool assume_locks) {
|
||||
memory_tracker->InvalidateRegion(device_addr, size, [this, device_addr, size, assume_locks] {
|
||||
ReadMemory(device_addr, size, true, assume_locks);
|
||||
ReadMemory(device_addr, size, true, false, assume_locks);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -146,8 +148,20 @@ void BufferCache::ExtendWriteFault(VAddr device_addr) {
|
||||
memory_tracker->ExtendWriteFault(Common::AlignDown(device_addr, window), window);
|
||||
}
|
||||
|
||||
void BufferCache::ReadMemory(VAddr device_addr, u64 size, bool is_write, bool assume_locks) {
|
||||
const auto flush_request = [this, device_addr, size, is_write] {
|
||||
void BufferCache::MakeWriteFaultSticky(VAddr device_addr) {
|
||||
// One byte: pin only the page the faulting access touched, even when the address is not
|
||||
// page aligned (the caller passes the fault address itself).
|
||||
memory_tracker->MakeSticky(device_addr, 1);
|
||||
}
|
||||
|
||||
void BufferCache::UnmarkRegionAsGpuModified(VAddr device_addr, u64 size, bool is_write) {
|
||||
memory_tracker->UnmarkRegionAsGpuModified(device_addr, size);
|
||||
gpu_modified_ranges.Subtract(device_addr, size);
|
||||
}
|
||||
|
||||
void BufferCache::ReadMemory(VAddr device_addr, u64 size, bool is_write, bool async,
|
||||
bool assume_locks) {
|
||||
const auto flush_request = [this, device_addr, size, is_write, async] {
|
||||
const u32 first_block = device_addr >> block_shift;
|
||||
const u32 last_block = (device_addr + size - 1) >> block_shift;
|
||||
const auto* arena = GetArena(first_block, last_block);
|
||||
@@ -160,10 +174,7 @@ void BufferCache::ReadMemory(VAddr device_addr, u64 size, bool is_write, bool as
|
||||
std::max<VAddr>(Common::AlignDown(device_addr, WindowSize), arena->cpu_addr);
|
||||
const VAddr window_end = std::min<VAddr>(
|
||||
std::max<VAddr>(window_start + WindowSize, device_addr + size), arena_end);
|
||||
DownloadMemory(arena, window_start, window_end - window_start);
|
||||
if (is_write) {
|
||||
memory_tracker->MarkRegionAsCpuModified(device_addr, size);
|
||||
}
|
||||
DownloadMemory(arena, window_start, window_end - window_start, is_write, async);
|
||||
};
|
||||
if (assume_locks) {
|
||||
flush_request();
|
||||
@@ -172,7 +183,8 @@ void BufferCache::ReadMemory(VAddr device_addr, u64 size, bool is_write, bool as
|
||||
}
|
||||
}
|
||||
|
||||
void BufferCache::DownloadMemory(const Buffer* arena, VAddr device_addr, u64 size) {
|
||||
void BufferCache::DownloadMemory(const Buffer* arena, VAddr device_addr, u64 size, bool is_write,
|
||||
bool async) {
|
||||
boost::container::small_vector<vk::BufferCopy, 1> copies;
|
||||
u64 total_size_bytes = 0;
|
||||
const VAddr arena_base = arena->cpu_addr;
|
||||
@@ -196,20 +208,37 @@ void BufferCache::DownloadMemory(const Buffer* arena, VAddr device_addr, u64 siz
|
||||
if (total_size_bytes == 0) {
|
||||
return;
|
||||
}
|
||||
const auto download = staging_pool.Request(total_size_bytes, VideoCore::MemoryType::HostCached);
|
||||
const auto download =
|
||||
staging_pool.Request(total_size_bytes, VideoCore::MemoryType::HostCached, 16, async);
|
||||
for (auto& copy : copies) {
|
||||
copy.dstOffset += download.offset;
|
||||
}
|
||||
runtime.CopyBuffer(arena, download.buffer, copies);
|
||||
scheduler.Finish();
|
||||
|
||||
download.buffer->Invalidate(download.offset, download.size);
|
||||
for (const auto& copy : copies) {
|
||||
auto* dst_addr = std::bit_cast<u8*>(arena_base + copy.srcOffset);
|
||||
memory->TryWriteBacking(dst_addr, download.mapped + (copy.dstOffset - download.offset),
|
||||
copy.size);
|
||||
const auto write_data = [this, arena_base, device_addr, size, download, is_write, async,
|
||||
copies = std::move(copies)] {
|
||||
download.Invalidate();
|
||||
for (const auto& copy : copies) {
|
||||
auto* dst_addr = std::bit_cast<u8*>(arena_base + copy.srcOffset);
|
||||
memory->TryWriteBacking(dst_addr, download.mapped + (copy.dstOffset - download.offset),
|
||||
copy.size);
|
||||
}
|
||||
memory_tracker->UnmarkRegionAsGpuModified(device_addr, size);
|
||||
if (is_write) {
|
||||
memory_tracker->MarkRegionAsCpuModified(device_addr, size);
|
||||
}
|
||||
|
||||
if (async) {
|
||||
staging_pool.FreeDeferred(download);
|
||||
}
|
||||
};
|
||||
|
||||
if (async) {
|
||||
scheduler.DeferOperation(std::move(write_data));
|
||||
} else {
|
||||
scheduler.Finish();
|
||||
write_data();
|
||||
}
|
||||
memory_tracker->UnmarkRegionAsGpuModified(device_addr, size);
|
||||
}
|
||||
|
||||
namespace {
|
||||
@@ -343,6 +372,7 @@ std::pair<const Buffer*, u64> BufferCache::ObtainBuffer(VAddr device_addr, u32 s
|
||||
BbStats::buffer_upload_bytes.load(std::memory_order_relaxed) - uploaded_before;
|
||||
}
|
||||
if (is_written) {
|
||||
texture_cache.MarkAsMaybeGpuDirty(device_addr, size);
|
||||
gpu_modified_ranges.Add(device_addr, size);
|
||||
}
|
||||
return {arena, arena->Offset(device_addr)};
|
||||
@@ -389,6 +419,63 @@ bool BufferCache::IsRegionGpuModified(VAddr addr, size_t size) {
|
||||
return memory_tracker->IsRegionGpuModified(addr, size);
|
||||
}
|
||||
|
||||
void BufferCache::ReadEdgeImagePages(const Image& image) {
|
||||
// May happen that after downloading the image and invalidating region,
|
||||
// that there were GPU modified ranges that are lost due to CPU reuploading.
|
||||
// This doesn't change tracker state and it is expected to call DownloadImageMemory after this.
|
||||
const VAddr image_addr = image.info.guest_address;
|
||||
const u64 image_size = image.info.guest_size;
|
||||
const VAddr image_end = image_addr + image_size;
|
||||
const VAddr page_start = PageManager::GetPageAddr(image_addr);
|
||||
const VAddr page_end = PageManager::GetNextPageAddr(image_end - 1);
|
||||
boost::container::small_vector<vk::BufferCopy, 2> copies;
|
||||
u64 total_size_bytes = 0;
|
||||
const auto [buffer, offset] =
|
||||
ObtainBuffer(page_start, static_cast<u32>(page_end - page_start), false, false);
|
||||
if (!buffer) {
|
||||
return;
|
||||
}
|
||||
const auto add_download = [&](VAddr start, VAddr end) {
|
||||
const u64 new_offset = start - buffer->CpuAddr();
|
||||
const u64 new_size = end - start;
|
||||
copies.push_back(vk::BufferCopy{
|
||||
.srcOffset = new_offset,
|
||||
.dstOffset = total_size_bytes,
|
||||
.size = new_size,
|
||||
});
|
||||
// Align up to avoid cache conflicts
|
||||
constexpr u64 align = 64ULL;
|
||||
constexpr u64 mask = ~(align - 1ULL);
|
||||
total_size_bytes += (new_size + align - 1) & mask;
|
||||
};
|
||||
gpu_modified_ranges.ForEachInRange(page_start, image_addr - page_start, add_download);
|
||||
gpu_modified_ranges.ForEachInRange(image_end, page_end - image_end, add_download);
|
||||
gpu_modified_ranges.Subtract(page_start, page_end - page_start);
|
||||
if (total_size_bytes == 0) {
|
||||
return;
|
||||
}
|
||||
const auto download =
|
||||
staging_pool.Request(total_size_bytes, VideoCore::MemoryType::HostCached, 16, true);
|
||||
for (auto& copy : copies) {
|
||||
// Modify copies to have the staging offset in mind
|
||||
copy.dstOffset += download.offset;
|
||||
}
|
||||
scheduler.EndRendering();
|
||||
runtime.CopyBuffer(buffer, download.buffer, copies);
|
||||
scheduler.DeferOperation(
|
||||
[this, base = buffer->CpuAddr(), download, copies = std::move(copies)]() {
|
||||
download.Invalidate();
|
||||
auto* memory = Core::Memory::Instance();
|
||||
for (const auto& copy : copies) {
|
||||
const VAddr copy_device_addr = base + copy.srcOffset;
|
||||
const u64 dst_offset = copy.dstOffset - download.offset;
|
||||
memory->TryWriteBacking(std::bit_cast<u8*>(copy_device_addr),
|
||||
download.mapped + dst_offset, copy.size);
|
||||
}
|
||||
staging_pool.FreeDeferred(download);
|
||||
});
|
||||
}
|
||||
|
||||
void BufferCache::ProcessFaultBuffer() {
|
||||
fault_manager->ProcessFaultBuffer();
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ namespace VideoCore {
|
||||
class TextureCache;
|
||||
class MemoryTracker;
|
||||
class PageManager;
|
||||
struct Image;
|
||||
|
||||
class BufferCache {
|
||||
static constexpr u64 ADDRESS_SPACE_BITS = 40;
|
||||
@@ -88,8 +89,17 @@ public:
|
||||
/// bbport: a guest write fault at `device_addr` was handled; unprotect its neighbourhood.
|
||||
void ExtendWriteFault(VAddr device_addr);
|
||||
|
||||
/// bbport: pin the page a red-zone vertex generator wrote (see RegionManager::MakeSticky).
|
||||
void MakeWriteFaultSticky(VAddr device_addr);
|
||||
|
||||
/// Flushes any GPU modified buffer in the logical page range back to CPU memory.
|
||||
void ReadMemory(VAddr device_addr, u64 size, bool is_write = false, bool assume_locks = false);
|
||||
void ReadMemory(VAddr device_addr, u64 size, bool is_write = false, bool async = false, bool assume_locks = false);
|
||||
|
||||
/// Unmarks a region as GPU modified.
|
||||
void UnmarkRegionAsGpuModified(VAddr device_addr, u64 size, bool is_write = false);
|
||||
|
||||
/// Flushes GPU modified ranges of the uncovered part of the edge pages of an image.
|
||||
void ReadEdgeImagePages(const Image& image);
|
||||
|
||||
/// Finds a buffer for the specified region.
|
||||
[[nodiscard]] std::pair<const Buffer*, u64> ObtainBuffer(VAddr device_addr, u32 size,
|
||||
@@ -132,7 +142,8 @@ private:
|
||||
|
||||
void EnsureResident(const Buffer* arena, u64 first_block, u64 last_block);
|
||||
|
||||
void DownloadMemory(const Buffer* arena, VAddr device_addr, u64 size);
|
||||
void DownloadMemory(const Buffer* arena, VAddr device_addr, u64 size, bool is_write = false,
|
||||
bool async = false);
|
||||
|
||||
bool SynchronizeMemory(const Buffer* arena, VAddr device_addr, u32 size, bool is_written,
|
||||
bool is_texel_buffer);
|
||||
|
||||
@@ -62,6 +62,15 @@ public:
|
||||
});
|
||||
}
|
||||
|
||||
/// bbport: see RegionManager::MakeSticky (red-zone vertex generators).
|
||||
void MakeSticky(VAddr fault_addr, u64 size) {
|
||||
IteratePages<false>(fault_addr, size,
|
||||
[](RegionManager* manager, u64 offset, size_t size) {
|
||||
std::scoped_lock lk{manager->lock};
|
||||
manager->MakeSticky(manager->GetCpuAddr() + offset, size);
|
||||
});
|
||||
}
|
||||
|
||||
/// Unmark region as modified from the host GPU
|
||||
void UnmarkRegionAsGpuModified(VAddr dirty_cpu_addr, u64 query_size) noexcept {
|
||||
IteratePages<false>(dirty_cpu_addr, query_size,
|
||||
|
||||
@@ -4,8 +4,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <cstdlib>
|
||||
#include <algorithm>
|
||||
|
||||
#include "bbport_toggles.h"
|
||||
#include "common/div_ceil.h"
|
||||
@@ -30,6 +32,20 @@ using LockType = Common::AdaptiveMutex;
|
||||
using LockType = Common::SpinLock;
|
||||
#endif
|
||||
|
||||
/// bbport: pages pinned by the red-zone generator workaround. A pinned page is never re-protected
|
||||
/// and counts as CPU modified, so it is uploaded on every binding; the cap (BB_STICKY_FAULT_PAGES,
|
||||
/// default 2048 pages = 8 MiB) keeps a runaway set from turning into the 14k-page hot set that
|
||||
/// cost 33 FPS (see RegionManager::HotPagesEnabled).
|
||||
inline std::atomic<u32> g_sticky_fault_pages{0};
|
||||
inline u32 StickyFaultPageBudget() {
|
||||
static const u32 budget = [] {
|
||||
const char* env = std::getenv("BB_STICKY_FAULT_PAGES");
|
||||
const long value = env ? std::strtol(env, nullptr, 10) : 2048;
|
||||
return static_cast<u32>(value > 0 ? value : 0);
|
||||
}();
|
||||
return budget;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows tracking CPU and GPU modification of pages in a contigious 16MB virtual address region.
|
||||
* Information is stored in bitsets for spacial locality and fast update of single pages.
|
||||
@@ -126,6 +142,59 @@ public:
|
||||
UpdateProtection<false, false>();
|
||||
}
|
||||
|
||||
/// bbport: keep the page a red-zone generator just wrote permanently writable. Windows x64
|
||||
/// has no System V red zone: every exception dispatch writes its CONTEXT below RSP and
|
||||
/// destroys the generator's locals, so each additional write-tracking fault on the same page
|
||||
/// is a chance to corrupt the generator (the REDZONE GUARD HIT stutter). Pinned pages count
|
||||
/// as CPU modified forever, so they are uploaded whenever bound instead of faulting again.
|
||||
/// `size` is the faulting access size; only the touched page is pinned.
|
||||
void MakeSticky(VAddr fault_addr, u64 size) {
|
||||
if (BbToggle::Disabled2(BbToggle::StickyFaultPages)) {
|
||||
return;
|
||||
}
|
||||
const size_t offset = fault_addr - cpu_addr;
|
||||
const size_t start_page = SanitizeAddress(offset) / TRACKER_BYTES_PER_PAGE;
|
||||
const size_t end_page =
|
||||
Common::DivCeil(SanitizeAddress(offset + size), TRACKER_BYTES_PER_PAGE);
|
||||
if (start_page >= NUM_PAGES_PER_REGION || end_page <= start_page) {
|
||||
return;
|
||||
}
|
||||
RegionBits add(~sticky, start_page, end_page);
|
||||
if (add.None()) {
|
||||
return;
|
||||
}
|
||||
u32 num_new = 0;
|
||||
for (const auto& [start, end] : add) {
|
||||
num_new += static_cast<u32>(end - start);
|
||||
}
|
||||
const u32 budget = StickyFaultPageBudget();
|
||||
const u32 used = g_sticky_fault_pages.load(std::memory_order_relaxed);
|
||||
if (used >= budget) {
|
||||
return;
|
||||
}
|
||||
if (num_new > budget - used) {
|
||||
// Take as many of the new pages as the budget still allows.
|
||||
const u32 remaining_budget = budget - used;
|
||||
RegionBits limited{};
|
||||
u32 remaining = remaining_budget;
|
||||
for (const auto& [start, end] : add) {
|
||||
const size_t take = std::min<size_t>(end - start, remaining);
|
||||
limited.SetRange(start, start + take);
|
||||
remaining -= static_cast<u32>(take);
|
||||
if (remaining == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
add = limited;
|
||||
num_new = remaining_budget - remaining;
|
||||
}
|
||||
sticky |= add;
|
||||
cpu |= add;
|
||||
g_sticky_fault_pages.fetch_add(num_new, std::memory_order_relaxed);
|
||||
BbStats::sticky_pages.fetch_add(num_new, std::memory_order_relaxed);
|
||||
UpdateProtection<false, false>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loop over each page in the given range, turn off those bits and notify the tracker if
|
||||
* needed. Call the given function on each turned off range.
|
||||
@@ -262,6 +331,12 @@ private:
|
||||
}
|
||||
|
||||
void KeepHotPagesModified(size_t start_page, size_t end_page) {
|
||||
// bbport: a pinned page must stay CPU modified; UpdateProtection (called right after this)
|
||||
// re-protects every page whose CPU bit was cleared, and the next write from the red-zone
|
||||
// generator would fault again on it.
|
||||
if (!sticky.None()) {
|
||||
cpu |= RegionBits(sticky, start_page, end_page);
|
||||
}
|
||||
if (num_hot == 0) {
|
||||
return;
|
||||
}
|
||||
@@ -282,6 +357,9 @@ private:
|
||||
u32 num_hot = 0;
|
||||
std::chrono::steady_clock::time_point hot_since{};
|
||||
|
||||
/// Pages the red-zone generator workaround keeps writable for the rest of the session.
|
||||
RegionBits sticky{};
|
||||
|
||||
PageManager* tracker;
|
||||
VAddr cpu_addr = 0;
|
||||
RegionBits cpu;
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <miniz.h>
|
||||
|
||||
#include <condition_variable>
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <future>
|
||||
#include <mutex>
|
||||
@@ -29,7 +30,7 @@
|
||||
namespace {
|
||||
|
||||
std::mutex submit_mutex{};
|
||||
u32 num_requests{};
|
||||
std::atomic<u32> num_requests{};
|
||||
std::condition_variable_any request_cv{};
|
||||
std::queue<std::packaged_task<void()>> req_queue{};
|
||||
std::mutex m_request{};
|
||||
@@ -44,13 +45,14 @@ namespace Storage {
|
||||
void ProcessIO(const std::stop_token& stoken) {
|
||||
Common::SetCurrentThreadName("shadPS4:PipelineCacheIO");
|
||||
|
||||
while (!stoken.stop_requested()) {
|
||||
for (;;) {
|
||||
{
|
||||
std::unique_lock lk{submit_mutex};
|
||||
Common::CondvarWait(request_cv, lk, stoken, [&] { return num_requests; });
|
||||
Common::CondvarWait(request_cv, lk, stoken, [&] { return num_requests.load() != 0; });
|
||||
}
|
||||
|
||||
if (stoken.stop_requested()) {
|
||||
// bbport: a stop request must not drop queued writes (Close() flushes through this queue).
|
||||
if (stoken.stop_requested() && num_requests == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -92,6 +94,9 @@ constexpr std::string GetBlobFileExtension(BlobType type) {
|
||||
case BlobType::PipelineBinary: {
|
||||
return "vkp";
|
||||
}
|
||||
case BlobType::ShaderInput: {
|
||||
return "in";
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
@@ -112,7 +117,7 @@ void DataBase::Open() {
|
||||
std::filesystem::path{game_info.GameSerial()}.replace_extension(".zip");
|
||||
|
||||
if (!mz_zip_reader_init_file(&zip_ar, cache_path.string().c_str(),
|
||||
MZ_ZIP_FLAG_READ_ALLOW_WRITING) ||
|
||||
MZ_ZIP_FLAG_WRITE_ALLOW_READING) ||
|
||||
!mz_zip_validate_archive(&zip_ar, 0)) {
|
||||
LOG_INFO(Render, "Cache archive {} is not found or archive is corrupted",
|
||||
cache_path.string().c_str());
|
||||
@@ -135,6 +140,10 @@ void DataBase::Close() {
|
||||
return;
|
||||
}
|
||||
|
||||
// bbport: process everything that was queued (the driver pipeline cache in particular)
|
||||
// before the worker is stopped; stopping first would drop those writes.
|
||||
Flush();
|
||||
|
||||
io_worker.request_stop();
|
||||
io_worker.join();
|
||||
|
||||
@@ -147,6 +156,27 @@ void DataBase::Close() {
|
||||
LOG_INFO(Render, "Cache dumped");
|
||||
}
|
||||
|
||||
void DataBase::Flush() {
|
||||
if (!IsOpened()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The queue is FIFO, so this marker completing means every earlier write is on disk. A
|
||||
// promise is used because the worker itself calls get_future() on each packaged task.
|
||||
std::promise<void> marker;
|
||||
auto done = marker.get_future();
|
||||
{
|
||||
std::scoped_lock lock{m_request};
|
||||
req_queue.emplace([&marker] { marker.set_value(); });
|
||||
}
|
||||
{
|
||||
std::scoped_lock lk{submit_mutex};
|
||||
++num_requests;
|
||||
}
|
||||
request_cv.notify_one();
|
||||
done.wait();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool WriteVector(const BlobType type, std::filesystem::path&& path_, std::vector<T>&& v) {
|
||||
{
|
||||
|
||||
@@ -19,6 +19,7 @@ enum class BlobType : u32 {
|
||||
PipelineKey,
|
||||
ShaderProfile,
|
||||
PipelineBinary,
|
||||
ShaderInput,
|
||||
};
|
||||
|
||||
class DataBase {
|
||||
@@ -29,9 +30,16 @@ public:
|
||||
|
||||
void Open();
|
||||
void Close();
|
||||
/// bbport: blocks until every queued blob write has reached the disk. Close() uses it before
|
||||
/// stopping the IO worker, which otherwise could exit with writes still queued (the process
|
||||
/// leaves through _Exit, so nothing else flushes them either).
|
||||
void Flush();
|
||||
[[nodiscard]] bool IsOpened() const {
|
||||
return opened;
|
||||
}
|
||||
[[nodiscard]] const std::filesystem::path& Directory() const {
|
||||
return cache_path;
|
||||
}
|
||||
void FinishPreload();
|
||||
/// bbport: removes every cached blob (an incompatible cache is rebuilt, not ignored).
|
||||
void Clear();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
// bbport: nearest resample of a depth/stencil image between native and reduced scene
|
||||
// targets. Used where the format has no blit support (D32S8 on RADV).
|
||||
// targets. Used where the format has no blit support (D32S8 on RADV), and for conservative
|
||||
// 2x2 min-filter downsampling of forward-Z depth proxies (Audit U3).
|
||||
|
||||
#version 450 core
|
||||
#extension GL_EXT_samplerless_texture_functions : require
|
||||
@@ -12,6 +13,8 @@ layout (binding = 1, set = 0) uniform utexture2D src_stencil;
|
||||
#endif
|
||||
#if defined(STENCIL_BITS)
|
||||
layout (push_constant) uniform StencilBit { uint bit; } pc;
|
||||
#else
|
||||
layout (push_constant) uniform ResampleMode { uint downscale; } pc;
|
||||
#endif
|
||||
|
||||
layout (binding = 0, set = 0) uniform texture2D src_depth;
|
||||
@@ -26,7 +29,21 @@ void main() {
|
||||
// (bit=0, writeMask=0) copies depth everywhere, including zero-stencil pixels.
|
||||
if (pc.bit != 0u && (texelFetch(src_stencil, coord, 0).r & pc.bit) == 0u) discard;
|
||||
#endif
|
||||
#if !defined(HAS_STENCIL) && !defined(STENCIL_BITS)
|
||||
if (pc.downscale != 0u) {
|
||||
// 2x2 conservative min-filter for forward-Z downsampling (Audit U3)
|
||||
const ivec2 base = clamp(ivec2(floor(uv * vec2(size) - 0.5)), ivec2(0), size - 1);
|
||||
const float d0 = texelFetch(src_depth, base, 0).r;
|
||||
const float d1 = texelFetch(src_depth, min(base + ivec2(1, 0), size - 1), 0).r;
|
||||
const float d2 = texelFetch(src_depth, min(base + ivec2(0, 1), size - 1), 0).r;
|
||||
const float d3 = texelFetch(src_depth, min(base + ivec2(1, 1), size - 1), 0).r;
|
||||
gl_FragDepth = min(min(d0, d1), min(d2, d3));
|
||||
} else {
|
||||
gl_FragDepth = texelFetch(src_depth, coord, 0).r;
|
||||
}
|
||||
#else
|
||||
gl_FragDepth = texelFetch(src_depth, coord, 0).r;
|
||||
#endif
|
||||
#if defined(HAS_STENCIL)
|
||||
gl_FragStencilRefARB = int(texelFetch(src_stencil, coord, 0).r);
|
||||
#endif
|
||||
|
||||
@@ -201,7 +201,9 @@ void main() {
|
||||
}
|
||||
diagnostic_history = clipped;
|
||||
// Reliable history suppresses subpixel shimmer even on distant geometry.
|
||||
float weight = mix(0.98, 0.85, moving) * coverage;
|
||||
const float max_weight = (variant & 32u) != 0u ? 0.98 : 0.88;
|
||||
const float min_weight = (variant & 32u) != 0u ? 0.85 : 0.75;
|
||||
float weight = mix(max_weight, min_weight, moving) * coverage;
|
||||
history_weight = weight;
|
||||
// Tonemapped blending: a few very bright HDR samples otherwise dominate.
|
||||
result = (variant & 1u) != 0u
|
||||
|
||||
@@ -622,8 +622,13 @@ struct Upscaler::Impl {
|
||||
mlsr.inv_scale[1] = 1.0f / mlsr.scale[1];
|
||||
mlsr.jitter[0] = f.jitter[0];
|
||||
mlsr.jitter[1] = f.jitter[1];
|
||||
mlsr.mv_scale[0] = f.motion_scale[0] / float(rw);
|
||||
mlsr.mv_scale[1] = f.motion_scale[1] / float(rh);
|
||||
static const bool mv_uv = [] {
|
||||
const char* env = std::getenv("BB_FSR411_MV_UV");
|
||||
return !env || env[0] != '0';
|
||||
}();
|
||||
mlsr.mv_scale[0] = mv_uv ? f.motion_scale[0] / float(rw) : f.motion_scale[0];
|
||||
mlsr.mv_scale[1] = mv_uv ? f.motion_scale[1] / float(rh) : f.motion_scale[1];
|
||||
|
||||
mlsr.tex_size[0] = mlsr.max_render_size[0] = float(ow);
|
||||
mlsr.tex_size[1] = mlsr.max_render_size[1] = float(oh);
|
||||
mlsr.width = ow;
|
||||
|
||||
@@ -0,0 +1,310 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#include "video_core/renderer_vulkan/vk_button_prompts.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
|
||||
#include "bbport_button_prompts.h"
|
||||
#include "video_core/buffer_cache/buffer_cache.h"
|
||||
#include "video_core/renderer_vulkan/vk_instance.h"
|
||||
#include "video_core/renderer_vulkan/vk_runtime.h"
|
||||
#include "video_core/renderer_vulkan/vk_scheduler.h"
|
||||
#include "video_core/texture_cache/image_view.h"
|
||||
|
||||
namespace Vulkan {
|
||||
namespace {
|
||||
|
||||
bool IsSrgb(vk::Format format) {
|
||||
switch (format) {
|
||||
case vk::Format::eBc1RgbaSrgbBlock:
|
||||
case vk::Format::eBc1RgbSrgbBlock:
|
||||
case vk::Format::eBc2SrgbBlock:
|
||||
case vk::Format::eBc3SrgbBlock:
|
||||
case vk::Format::eBc7SrgbBlock:
|
||||
case vk::Format::eR8G8B8A8Srgb:
|
||||
case vk::Format::eB8G8R8A8Srgb:
|
||||
case vk::Format::eA8B8G8R8SrgbPack32:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ButtonPrompts::ButtonPrompts(const Instance& instance_, Scheduler& scheduler_,
|
||||
VideoCore::BufferCache& buffer_cache_)
|
||||
: instance{instance_}, scheduler{scheduler_}, buffer_cache{buffer_cache_},
|
||||
image{instance_.GetDevice(), instance_.GetAllocator()} {
|
||||
BbPrompts::Start();
|
||||
}
|
||||
|
||||
ButtonPrompts::~ButtonPrompts() = default;
|
||||
|
||||
void ButtonPrompts::Update() {
|
||||
BbPrompts::Set set;
|
||||
if (!BbPrompts::Update(generation, table_generation, set)) {
|
||||
return;
|
||||
}
|
||||
generation = set.generation;
|
||||
table_generation = BbPrompts::TableGeneration();
|
||||
drawn = set.drawn;
|
||||
active.store(std::find(drawn.begin(), drawn.end(), true) != drawn.end(),
|
||||
std::memory_order_release);
|
||||
if (!active.load(std::memory_order_relaxed)) {
|
||||
return; // the game's icons: nothing to upload
|
||||
}
|
||||
if (!image) {
|
||||
layers = set.count;
|
||||
image.Create(vk::ImageCreateInfo{
|
||||
.flags = vk::ImageCreateFlagBits::eMutableFormat,
|
||||
.imageType = vk::ImageType::e2D,
|
||||
.format = vk::Format::eR8G8B8A8Unorm,
|
||||
.extent = {BbPrompts::IconSize, BbPrompts::IconSize, 1},
|
||||
.mipLevels = 1,
|
||||
.arrayLayers = layers,
|
||||
.samples = vk::SampleCountFlagBits::e1,
|
||||
.tiling = vk::ImageTiling::eOptimal,
|
||||
.usage = vk::ImageUsageFlagBits::eSampled | vk::ImageUsageFlagBits::eTransferDst,
|
||||
.sharingMode = vk::SharingMode::eExclusive,
|
||||
.initialLayout = vk::ImageLayout::eUndefined,
|
||||
});
|
||||
}
|
||||
if (set.count != layers) {
|
||||
active.store(false, std::memory_order_release);
|
||||
return;
|
||||
}
|
||||
// The icons at the game's size for the atlases' cells: means of premultiplied texels.
|
||||
constexpr u32 Small = BbPrompts::GameIconSize, Factor = BbPrompts::IconSize / Small;
|
||||
small.assign(std::size_t(layers) * Small * Small, 0);
|
||||
for (u32 layer = 0; layer < layers; ++layer) {
|
||||
const u32* icon = set.pixels.data() + std::size_t(layer) * BbPrompts::IconSize * BbPrompts::IconSize;
|
||||
for (u32 y = 0; y < Small; ++y) {
|
||||
for (u32 x = 0; x < Small; ++x) {
|
||||
u32 sum[4]{};
|
||||
for (u32 dy = 0; dy < Factor; ++dy) {
|
||||
for (u32 dx = 0; dx < Factor; ++dx) {
|
||||
const u32 texel = icon[(y * Factor + dy) * BbPrompts::IconSize + x * Factor + dx];
|
||||
for (u32 c = 0; c < 4; ++c) {
|
||||
sum[c] += (texel >> (8 * c)) & 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
u32 out = 0;
|
||||
for (u32 c = 0; c < 4; ++c) {
|
||||
out |= (sum[c] + Factor * Factor / 2) / (Factor * Factor) << (8 * c);
|
||||
}
|
||||
small[(std::size_t(layer) * Small + y) * Small + x] = out;
|
||||
}
|
||||
}
|
||||
}
|
||||
const u64 bytes = u64(set.pixels.size()) * sizeof(u32);
|
||||
auto& stream = buffer_cache.GetStreamBuffer();
|
||||
const u64 offset = stream.Copy(set.pixels.data(), bytes, 16);
|
||||
// In stream order, ahead of the draws that sample it; the draws before it are done reading it
|
||||
// (the barrier's source stages).
|
||||
scheduler.EndRendering();
|
||||
scheduler.Record([image = vk::Image{image.image}, buffer = stream.Handle(), offset,
|
||||
layers = layers](vk::CommandBuffer cmdbuf) {
|
||||
const vk::ImageSubresourceRange range{vk::ImageAspectFlagBits::eColor, 0, 1, 0, layers};
|
||||
const vk::ImageMemoryBarrier2 to_copy{
|
||||
.srcStageMask = vk::PipelineStageFlagBits2::eAllCommands,
|
||||
.srcAccessMask = vk::AccessFlagBits2::eShaderRead,
|
||||
.dstStageMask = vk::PipelineStageFlagBits2::eCopy,
|
||||
.dstAccessMask = vk::AccessFlagBits2::eTransferWrite,
|
||||
.oldLayout = vk::ImageLayout::eUndefined,
|
||||
.newLayout = vk::ImageLayout::eTransferDstOptimal,
|
||||
.image = image,
|
||||
.subresourceRange = range,
|
||||
};
|
||||
cmdbuf.pipelineBarrier2(vk::DependencyInfo{.imageMemoryBarrierCount = 1,
|
||||
.pImageMemoryBarriers = &to_copy});
|
||||
const vk::BufferImageCopy copy{
|
||||
.bufferOffset = offset,
|
||||
.bufferRowLength = 0,
|
||||
.bufferImageHeight = 0,
|
||||
.imageSubresource = {vk::ImageAspectFlagBits::eColor, 0, 0, layers},
|
||||
.imageOffset = {0, 0, 0},
|
||||
.imageExtent = {BbPrompts::IconSize, BbPrompts::IconSize, 1},
|
||||
};
|
||||
cmdbuf.copyBufferToImage(buffer, image, vk::ImageLayout::eTransferDstOptimal, copy);
|
||||
const vk::ImageMemoryBarrier2 to_sample{
|
||||
.srcStageMask = vk::PipelineStageFlagBits2::eCopy,
|
||||
.srcAccessMask = vk::AccessFlagBits2::eTransferWrite,
|
||||
.dstStageMask = vk::PipelineStageFlagBits2::eAllCommands,
|
||||
.dstAccessMask = vk::AccessFlagBits2::eShaderRead,
|
||||
.oldLayout = vk::ImageLayout::eTransferDstOptimal,
|
||||
.newLayout = vk::ImageLayout::eShaderReadOnlyOptimal,
|
||||
.image = image,
|
||||
.subresourceRange = range,
|
||||
};
|
||||
cmdbuf.pipelineBarrier2(vk::DependencyInfo{.imageMemoryBarrierCount = 1,
|
||||
.pImageMemoryBarriers = &to_sample});
|
||||
});
|
||||
}
|
||||
|
||||
vk::ImageView ButtonPrompts::View(u32 icon, const VideoCore::ImageViewInfo& info) {
|
||||
if (!Active() || icon == 0 || icon > drawn.size() || !drawn[icon - 1]) {
|
||||
return {};
|
||||
}
|
||||
const bool array = info.type == AmdGpu::ImageType::Color2DArray;
|
||||
if (!array && info.type != AmdGpu::ImageType::Color2D) {
|
||||
return {};
|
||||
}
|
||||
const bool srgb = IsSrgb(info.format);
|
||||
const u32 mapping = u32(info.mapping.r) | u32(info.mapping.g) << 8 | u32(info.mapping.b) << 16 |
|
||||
u32(info.mapping.a) << 24;
|
||||
auto& view = views[{icon, srgb, array, mapping}];
|
||||
if (!view) {
|
||||
auto result = instance.GetDevice().createImageViewUnique(vk::ImageViewCreateInfo{
|
||||
.image = image.image,
|
||||
.viewType = array ? vk::ImageViewType::e2DArray : vk::ImageViewType::e2D,
|
||||
.format = srgb ? vk::Format::eR8G8B8A8Srgb : vk::Format::eR8G8B8A8Unorm,
|
||||
.components = info.mapping,
|
||||
.subresourceRange = {vk::ImageAspectFlagBits::eColor, 0, 1, icon - 1, 1},
|
||||
});
|
||||
if (result.result != vk::Result::eSuccess) {
|
||||
std::printf("Button prompts: no image view (%s)\n", vk::to_string(result.result).c_str());
|
||||
return {};
|
||||
}
|
||||
view = std::move(result.value);
|
||||
}
|
||||
return *view;
|
||||
}
|
||||
|
||||
vk::ImageView ButtonPrompts::AtlasView(Runtime& runtime, VideoCore::Image& image,
|
||||
const VideoCore::ImageViewInfo& info) {
|
||||
if (!Active() || image.prompt_atlas == 0 || info.type != AmdGpu::ImageType::Color2D) {
|
||||
return {};
|
||||
}
|
||||
const auto cells = BbPrompts::AtlasCells(image.prompt_atlas);
|
||||
const auto is_drawn = [&](const BbPrompts::AtlasCell& cell) {
|
||||
return cell.icon <= drawn.size() && drawn[cell.icon - 1] && cell.icon <= layers;
|
||||
};
|
||||
if (std::none_of(cells.begin(), cells.end(), is_drawn)) {
|
||||
return {};
|
||||
}
|
||||
// A blit decodes the game's (BC7: a blit source on every device with BC textures).
|
||||
const vk::Format source_format = image.backing->image.image_ci.format;
|
||||
if (source_format != vk::Format::eBc7UnormBlock && source_format != vk::Format::eBc7SrgbBlock) {
|
||||
return {};
|
||||
}
|
||||
const u32 width = image.info.size.width, height = image.info.size.height;
|
||||
Atlas& atlas = atlases[image.image_uid];
|
||||
if (!atlas.image) {
|
||||
atlas.image = VideoCore::UniqueImage{instance.GetDevice(), instance.GetAllocator()};
|
||||
atlas.image.Create(vk::ImageCreateInfo{
|
||||
.flags = vk::ImageCreateFlagBits::eMutableFormat,
|
||||
.imageType = vk::ImageType::e2D,
|
||||
.format = vk::Format::eR8G8B8A8Unorm,
|
||||
.extent = {width, height, 1},
|
||||
.mipLevels = 1,
|
||||
.arrayLayers = 1,
|
||||
.samples = vk::SampleCountFlagBits::e1,
|
||||
.tiling = vk::ImageTiling::eOptimal,
|
||||
.usage = vk::ImageUsageFlagBits::eSampled | vk::ImageUsageFlagBits::eTransferDst,
|
||||
.sharingMode = vk::SharingMode::eExclusive,
|
||||
.initialLayout = vk::ImageLayout::eUndefined,
|
||||
});
|
||||
}
|
||||
if (atlas.upload != image.prompt_upload || atlas.generation != generation) {
|
||||
atlas.upload = image.prompt_upload;
|
||||
atlas.generation = generation;
|
||||
constexpr u32 Small = BbPrompts::GameIconSize;
|
||||
std::vector<vk::BufferImageCopy> copies;
|
||||
std::vector<u32> pixels;
|
||||
for (const auto& cell : cells) {
|
||||
if (!is_drawn(cell) || cell.x + Small > width || cell.y + Small > height) {
|
||||
continue;
|
||||
}
|
||||
copies.push_back(vk::BufferImageCopy{
|
||||
.bufferOffset = pixels.size() * sizeof(u32),
|
||||
.imageSubresource = {vk::ImageAspectFlagBits::eColor, 0, 0, 1},
|
||||
.imageOffset = {s32(cell.x), s32(cell.y), 0},
|
||||
.imageExtent = {Small, Small, 1},
|
||||
});
|
||||
const u32* icon = small.data() + std::size_t(cell.icon - 1) * Small * Small;
|
||||
pixels.insert(pixels.end(), icon, icon + Small * Small);
|
||||
}
|
||||
auto& stream = buffer_cache.GetStreamBuffer();
|
||||
const u64 offset = stream.Copy(pixels.data(), pixels.size() * sizeof(u32), 16);
|
||||
for (auto& copy : copies) {
|
||||
copy.bufferOffset += offset;
|
||||
}
|
||||
scheduler.EndRendering();
|
||||
runtime.Transit(&image, vk::ImageLayout::eTransferSrcOptimal, vk::PipelineStageFlagBits2::eBlit,
|
||||
vk::AccessFlagBits2::eTransferRead);
|
||||
runtime.FlushBarriers();
|
||||
scheduler.Record([source = image.GetImage(), target = vk::Image{atlas.image.image},
|
||||
buffer = stream.Handle(), copies = std::move(copies), width,
|
||||
height](vk::CommandBuffer cmdbuf) {
|
||||
const vk::ImageSubresourceRange range{vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1};
|
||||
const vk::ImageMemoryBarrier2 to_blit{
|
||||
.srcStageMask = vk::PipelineStageFlagBits2::eAllCommands,
|
||||
.srcAccessMask = vk::AccessFlagBits2::eShaderRead,
|
||||
.dstStageMask = vk::PipelineStageFlagBits2::eBlit,
|
||||
.dstAccessMask = vk::AccessFlagBits2::eTransferWrite,
|
||||
.oldLayout = vk::ImageLayout::eUndefined,
|
||||
.newLayout = vk::ImageLayout::eTransferDstOptimal,
|
||||
.image = target,
|
||||
.subresourceRange = range,
|
||||
};
|
||||
cmdbuf.pipelineBarrier2(vk::DependencyInfo{.imageMemoryBarrierCount = 1,
|
||||
.pImageMemoryBarriers = &to_blit});
|
||||
const vk::ImageBlit blit{
|
||||
.srcSubresource = {vk::ImageAspectFlagBits::eColor, 0, 0, 1},
|
||||
.srcOffsets = std::array{vk::Offset3D{0, 0, 0}, vk::Offset3D{s32(width), s32(height), 1}},
|
||||
.dstSubresource = {vk::ImageAspectFlagBits::eColor, 0, 0, 1},
|
||||
.dstOffsets = std::array{vk::Offset3D{0, 0, 0}, vk::Offset3D{s32(width), s32(height), 1}},
|
||||
};
|
||||
cmdbuf.blitImage(source, vk::ImageLayout::eTransferSrcOptimal, target,
|
||||
vk::ImageLayout::eTransferDstOptimal, blit, vk::Filter::eNearest);
|
||||
const vk::ImageMemoryBarrier2 to_copy{
|
||||
.srcStageMask = vk::PipelineStageFlagBits2::eBlit,
|
||||
.srcAccessMask = vk::AccessFlagBits2::eTransferWrite,
|
||||
.dstStageMask = vk::PipelineStageFlagBits2::eCopy,
|
||||
.dstAccessMask = vk::AccessFlagBits2::eTransferWrite,
|
||||
.oldLayout = vk::ImageLayout::eTransferDstOptimal,
|
||||
.newLayout = vk::ImageLayout::eTransferDstOptimal,
|
||||
.image = target,
|
||||
.subresourceRange = range,
|
||||
};
|
||||
cmdbuf.pipelineBarrier2(vk::DependencyInfo{.imageMemoryBarrierCount = 1,
|
||||
.pImageMemoryBarriers = &to_copy});
|
||||
cmdbuf.copyBufferToImage(buffer, target, vk::ImageLayout::eTransferDstOptimal, copies);
|
||||
const vk::ImageMemoryBarrier2 to_sample{
|
||||
.srcStageMask = vk::PipelineStageFlagBits2::eCopy,
|
||||
.srcAccessMask = vk::AccessFlagBits2::eTransferWrite,
|
||||
.dstStageMask = vk::PipelineStageFlagBits2::eAllCommands,
|
||||
.dstAccessMask = vk::AccessFlagBits2::eShaderRead,
|
||||
.oldLayout = vk::ImageLayout::eTransferDstOptimal,
|
||||
.newLayout = vk::ImageLayout::eShaderReadOnlyOptimal,
|
||||
.image = target,
|
||||
.subresourceRange = range,
|
||||
};
|
||||
cmdbuf.pipelineBarrier2(vk::DependencyInfo{.imageMemoryBarrierCount = 1,
|
||||
.pImageMemoryBarriers = &to_sample});
|
||||
});
|
||||
}
|
||||
const bool srgb = IsSrgb(info.format);
|
||||
const u32 mapping = u32(info.mapping.r) | u32(info.mapping.g) << 8 | u32(info.mapping.b) << 16 |
|
||||
u32(info.mapping.a) << 24;
|
||||
auto& view = atlas.views[{srgb, false, mapping}];
|
||||
if (!view) {
|
||||
auto result = instance.GetDevice().createImageViewUnique(vk::ImageViewCreateInfo{
|
||||
.image = atlas.image.image,
|
||||
.viewType = vk::ImageViewType::e2D,
|
||||
.format = srgb ? vk::Format::eR8G8B8A8Srgb : vk::Format::eR8G8B8A8Unorm,
|
||||
.components = info.mapping,
|
||||
.subresourceRange = {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1},
|
||||
});
|
||||
if (result.result != vk::Result::eSuccess) {
|
||||
std::printf("Button prompts: no atlas view (%s)\n", vk::to_string(result.result).c_str());
|
||||
return {};
|
||||
}
|
||||
view = std::move(result.value);
|
||||
}
|
||||
return *view;
|
||||
}
|
||||
|
||||
} // namespace Vulkan
|
||||
@@ -0,0 +1,76 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
// bbport: the port's button prompt icons on the GPU (gpu/shim/bbport_button_prompts.h). One image
|
||||
// array, a layer per game icon; a binding of one of the game's key guide icons samples its layer
|
||||
// instead while it is drawn for the device in use (Rasterizer::BindTextures). An atlas of the HUD
|
||||
// with icons packed in (BbPrompts::AtlasOf) samples an uncompressed copy with the port's icons in
|
||||
// its cells.
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <map>
|
||||
#include <tuple>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "common/types.h"
|
||||
#include "video_core/renderer_vulkan/vk_common.h"
|
||||
#include "video_core/texture_cache/image.h"
|
||||
|
||||
namespace VideoCore {
|
||||
class BufferCache;
|
||||
struct ImageViewInfo;
|
||||
} // namespace VideoCore
|
||||
|
||||
namespace Vulkan {
|
||||
|
||||
class Instance;
|
||||
class Runtime;
|
||||
class Scheduler;
|
||||
|
||||
class ButtonPrompts {
|
||||
public:
|
||||
ButtonPrompts(const Instance& instance, Scheduler& scheduler, VideoCore::BufferCache& buffer_cache);
|
||||
~ButtonPrompts();
|
||||
|
||||
/// The icons for the device in use, uploaded when they changed (the draw recording thread;
|
||||
/// ends the render pass then, once per change of device or bindings).
|
||||
void Update();
|
||||
|
||||
/// Whether any icon is the port's now.
|
||||
bool Active() const noexcept {
|
||||
return active.load(std::memory_order_acquire);
|
||||
}
|
||||
|
||||
/// The port's icon for the game's icon `icon` (Image::prompt_icon), viewed as `info` views
|
||||
/// the game's; null: the game's own.
|
||||
vk::ImageView View(u32 icon, const VideoCore::ImageViewInfo& info);
|
||||
|
||||
/// The copy of the HUD atlas `image` (Image::prompt_atlas) with the port's icons in its
|
||||
/// cells, viewed as `info` views the game's; null: the game's own. Made (in stream order, out
|
||||
/// of a render pass) when the icons or the atlas's bytes changed.
|
||||
vk::ImageView AtlasView(Runtime& runtime, VideoCore::Image& image,
|
||||
const VideoCore::ImageViewInfo& info);
|
||||
|
||||
private:
|
||||
struct Atlas {
|
||||
VideoCore::UniqueImage image;
|
||||
u32 upload = 0;
|
||||
u32 generation = 0;
|
||||
std::map<std::tuple<bool, bool, u32>, vk::UniqueImageView> views;
|
||||
};
|
||||
|
||||
const Instance& instance;
|
||||
Scheduler& scheduler;
|
||||
VideoCore::BufferCache& buffer_cache;
|
||||
VideoCore::UniqueImage image;
|
||||
u32 layers = 0;
|
||||
u32 generation = 0;
|
||||
u32 table_generation = 0;
|
||||
std::atomic<bool> active{false};
|
||||
std::vector<bool> drawn;
|
||||
std::vector<u32> small; ///< the icons at the game's size (atlas cells), a layer after another
|
||||
std::unordered_map<u64, Atlas> atlases; ///< by Image::image_uid
|
||||
std::map<std::tuple<u32, bool, bool, u32>, vk::UniqueImageView> views;
|
||||
};
|
||||
|
||||
} // namespace Vulkan
|
||||
@@ -1,11 +1,15 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <mutex>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <boost/container/small_vector.hpp>
|
||||
|
||||
#include "shader_recompiler/info.h"
|
||||
#include "video_core/renderer_vulkan/vk_compute_pipeline.h"
|
||||
#include "video_core/renderer_vulkan/vk_instance.h"
|
||||
#include "video_core/renderer_vulkan/vk_pipeline_cache.h"
|
||||
#include "video_core/renderer_vulkan/vk_scheduler.h"
|
||||
|
||||
namespace Vulkan {
|
||||
@@ -84,9 +88,10 @@ ComputePipeline::ComputePipeline(const Instance& instance, Scheduler& scheduler,
|
||||
const auto device = instance.GetDevice();
|
||||
auto [descriptor_set_result, descriptor_set] =
|
||||
device.createDescriptorSetLayoutUnique(desc_layout_ci);
|
||||
ASSERT_MSG(descriptor_set_result == vk::Result::eSuccess,
|
||||
"Failed to create compute descriptor set layout: {}",
|
||||
vk::to_string(descriptor_set_result));
|
||||
if (descriptor_set_result != vk::Result::eSuccess) {
|
||||
throw std::runtime_error("Failed to create compute descriptor set layout: " +
|
||||
vk::to_string(descriptor_set_result));
|
||||
}
|
||||
desc_layout = std::move(descriptor_set);
|
||||
|
||||
const vk::DescriptorSetLayout set_layout = *desc_layout;
|
||||
@@ -97,8 +102,10 @@ ComputePipeline::ComputePipeline(const Instance& instance, Scheduler& scheduler,
|
||||
.pPushConstantRanges = &push_constants,
|
||||
};
|
||||
auto [layout_result, layout] = instance.GetDevice().createPipelineLayoutUnique(layout_info);
|
||||
ASSERT_MSG(layout_result == vk::Result::eSuccess,
|
||||
"Failed to create compute pipeline layout: {}", vk::to_string(layout_result));
|
||||
if (layout_result != vk::Result::eSuccess) {
|
||||
throw std::runtime_error("Failed to create compute pipeline layout: " +
|
||||
vk::to_string(layout_result));
|
||||
}
|
||||
pipeline_layout = std::move(layout);
|
||||
SetObjectName(device, *pipeline_layout, "Compute PipelineLayout {}", debug_str);
|
||||
|
||||
@@ -106,10 +113,22 @@ ComputePipeline::ComputePipeline(const Instance& instance, Scheduler& scheduler,
|
||||
.stage = shader_ci,
|
||||
.layout = *pipeline_layout,
|
||||
};
|
||||
auto [pipeline_result, pipe] =
|
||||
instance.GetDevice().createComputePipelineUnique(pipeline_cache, compute_pipeline_ci);
|
||||
ASSERT_MSG(pipeline_result == vk::Result::eSuccess, "Failed to create compute pipeline: {}",
|
||||
vk::to_string(pipeline_result));
|
||||
/* bbport: a VkPipelineCache needs external synchronization; the async workers share this one
|
||||
* with the GPU thread. Failure is raised to PipelineCache (which skips the pipeline) instead
|
||||
* of aborting the process. */
|
||||
vk::Result pipeline_result = vk::Result::eSuccess;
|
||||
vk::UniquePipeline pipe;
|
||||
{
|
||||
std::scoped_lock lock{PipelineCreationMutex()};
|
||||
auto created =
|
||||
instance.GetDevice().createComputePipelineUnique(pipeline_cache, compute_pipeline_ci);
|
||||
pipeline_result = created.result;
|
||||
pipe = std::move(created.value);
|
||||
}
|
||||
if (pipeline_result != vk::Result::eSuccess) {
|
||||
throw std::runtime_error("Failed to create compute pipeline: " +
|
||||
vk::to_string(pipeline_result));
|
||||
}
|
||||
pipeline = std::move(pipe);
|
||||
SetObjectName(device, *pipeline, "Compute Pipeline {}", debug_str);
|
||||
}
|
||||
|
||||
@@ -9,20 +9,29 @@
|
||||
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <map>
|
||||
#include "shim/bb_env.h"
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/types.h"
|
||||
#include "video_core/buffer_cache/buffer.h"
|
||||
#include "video_core/renderer_vulkan/vk_scheduler.h"
|
||||
#include "video_core/renderer_vulkan/vk_instance.h"
|
||||
|
||||
namespace Vulkan {
|
||||
|
||||
class ConstantRing {
|
||||
public:
|
||||
static constexpr u64 Capacity = 32ull << 20;
|
||||
static u64 CapacityFor(const Instance& instance) {
|
||||
const char* env = bb_env("BB_CONSTANT_RING_MB");
|
||||
const u64 mb = env ? std::strtoull(env, nullptr, 10) : 0;
|
||||
const bool small = !instance.IsIntegrated() && instance.GetTotalMemoryBudget() <= (3ull << 30);
|
||||
return (mb ? mb : small ? 16ull : 32ull) << 20;
|
||||
}
|
||||
const u64 Capacity;
|
||||
|
||||
ConstantRing(const Instance& instance, Scheduler& scheduler_)
|
||||
: scheduler{scheduler_},
|
||||
: Capacity{CapacityFor(instance)}, scheduler{scheduler_},
|
||||
buffer{instance, 0, Capacity, VideoCore::MemoryType::Stream, "bbport constant ring"} {
|
||||
ASSERT(!buffer.mapped_data.empty());
|
||||
}
|
||||
@@ -45,7 +54,30 @@ public:
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
while (!holds.empty() && (holds.begin()->first << 16) + Capacity < at + size) {
|
||||
if (retired < holds.begin()->second) {
|
||||
Retire();
|
||||
if (retired < holds.begin()->second) {
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
holds.erase(holds.begin());
|
||||
}
|
||||
position = at + size;
|
||||
last_at = at;
|
||||
return at % Capacity;
|
||||
}
|
||||
|
||||
[[nodiscard]] u64 LastAllocated() const noexcept {
|
||||
return last_at;
|
||||
}
|
||||
|
||||
std::optional<u64> Reuse(u64 at, u64 size) {
|
||||
if (at + size > position || at + Capacity / 4 < position) {
|
||||
return std::nullopt;
|
||||
}
|
||||
u64& until = holds[at >> 16];
|
||||
until = std::max(until, position + 1);
|
||||
return at % Capacity;
|
||||
}
|
||||
|
||||
@@ -108,6 +140,8 @@ private:
|
||||
VideoCore::Buffer buffer;
|
||||
u64 position = 0; ///< stage A
|
||||
u64 retired = 0; ///< stage A: the GPU is done with everything before this
|
||||
u64 last_at = 0;
|
||||
std::map<u64, u64> holds;
|
||||
u64 pending_end = 0, pending_tick = 0, last_published = 0; ///< stage B
|
||||
std::array<StampEntry, 1024> stamps{};
|
||||
alignas(64) std::atomic<u64> stamps_head{0}; ///< stage B writes
|
||||
|
||||
@@ -0,0 +1,420 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 IFreemz, bbport contributors
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <filesystem>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include "video_core/renderer_vulkan/vk_dlss.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <winver.h>
|
||||
#include "../../../dlss_bridge/bbport_dlss_bridge.h"
|
||||
#elif defined(__linux__)
|
||||
#include <dlfcn.h>
|
||||
#include "../../../dlss_bridge/bbport_dlss_bridge.h"
|
||||
#endif
|
||||
|
||||
namespace Vulkan {
|
||||
|
||||
int Dlss::QualityForScale(float scale) {
|
||||
// DLAA only for equal sizes: any real upscale needs at least the Quality mode.
|
||||
return scale >= 2.9f ? 4 : scale >= 1.95f ? 3 : scale >= 1.65f ? 2 : scale > 1.01f ? 1 : 0;
|
||||
}
|
||||
|
||||
#if defined(_WIN32) || defined(__linux__)
|
||||
|
||||
namespace {
|
||||
#ifdef _WIN32
|
||||
constexpr wchar_t BridgeName[] = L"bbport_dlss.dll";
|
||||
constexpr wchar_t NgxName[] = L"nvngx_dlss.dll";
|
||||
using Module = HMODULE;
|
||||
|
||||
std::filesystem::path ExecutableDirectory() {
|
||||
std::wstring path(MAX_PATH, L'\0');
|
||||
const DWORD length = GetModuleFileNameW(nullptr, path.data(), DWORD(path.size()));
|
||||
path.resize(length);
|
||||
return std::filesystem::path{path}.parent_path();
|
||||
}
|
||||
|
||||
bool HasNgx(const std::filesystem::path& directory) {
|
||||
return std::filesystem::is_regular_file(directory / NgxName);
|
||||
}
|
||||
|
||||
Module LoadModule(const std::filesystem::path& path) {
|
||||
return LoadLibraryW(path.c_str());
|
||||
}
|
||||
|
||||
void* FindSymbol(Module module, const char* name) {
|
||||
return reinterpret_cast<void*>(GetProcAddress(module, name));
|
||||
}
|
||||
|
||||
/// "a.b.c.d" from the DLL's version resource (version.dll is loaded on demand, so the port
|
||||
/// keeps no extra import), or empty when the file has none.
|
||||
std::string FileVersion(const std::filesystem::path& path) {
|
||||
const HMODULE version = LoadLibraryW(L"version.dll");
|
||||
if (!version) {
|
||||
return {};
|
||||
}
|
||||
using SizeFn = DWORD(WINAPI*)(LPCWSTR, LPDWORD);
|
||||
using InfoFn = BOOL(WINAPI*)(LPCWSTR, DWORD, DWORD, LPVOID);
|
||||
using QueryFn = BOOL(WINAPI*)(LPCVOID, LPCWSTR, LPVOID*, PUINT);
|
||||
const auto size_fn = reinterpret_cast<SizeFn>(GetProcAddress(version, "GetFileVersionInfoSizeW"));
|
||||
const auto info_fn = reinterpret_cast<InfoFn>(GetProcAddress(version, "GetFileVersionInfoW"));
|
||||
const auto query_fn = reinterpret_cast<QueryFn>(GetProcAddress(version, "VerQueryValueW"));
|
||||
std::string text;
|
||||
if (size_fn && info_fn && query_fn) {
|
||||
DWORD handle{};
|
||||
const DWORD size = size_fn(path.c_str(), &handle);
|
||||
std::vector<BYTE> data(size);
|
||||
if (size && info_fn(path.c_str(), 0, size, data.data())) {
|
||||
LPVOID value{};
|
||||
UINT length{};
|
||||
if (query_fn(data.data(), L"\\", &value, &length) && value &&
|
||||
length >= sizeof(VS_FIXEDFILEINFO)) {
|
||||
const auto* info = static_cast<const VS_FIXEDFILEINFO*>(value);
|
||||
if (info->dwSignature == 0xFEEF04BDu) {
|
||||
char buffer[64];
|
||||
std::snprintf(buffer, sizeof(buffer), "%u.%u.%u.%u",
|
||||
unsigned(HIWORD(info->dwFileVersionMS)),
|
||||
unsigned(LOWORD(info->dwFileVersionMS)),
|
||||
unsigned(HIWORD(info->dwFileVersionLS)),
|
||||
unsigned(LOWORD(info->dwFileVersionLS)));
|
||||
text = buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
FreeLibrary(version);
|
||||
return text;
|
||||
}
|
||||
#else
|
||||
// bbport (Linux): libbbport_dlss.so (gpu/dlss_bridge) and NVIDIA's libnvidia-ngx-dlss.so.<version>
|
||||
// next to bb-probe; NGX finds the latter through the bridge's path list.
|
||||
constexpr char BridgeName[] = "libbbport_dlss.so";
|
||||
using Module = void*;
|
||||
|
||||
std::filesystem::path ExecutableDirectory() {
|
||||
std::error_code error;
|
||||
return std::filesystem::read_symlink("/proc/self/exe", error).parent_path();
|
||||
}
|
||||
|
||||
bool HasNgx(const std::filesystem::path& directory) {
|
||||
std::error_code error;
|
||||
for (const auto& entry : std::filesystem::directory_iterator(directory, error)) {
|
||||
if (entry.path().filename().string().starts_with("libnvidia-ngx-dlss.so.")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Module LoadModule(const std::filesystem::path& path) {
|
||||
Module module = dlopen(path.c_str(), RTLD_NOW | RTLD_LOCAL);
|
||||
if (!module) {
|
||||
std::printf("DLSS: %s\n", dlerror());
|
||||
}
|
||||
return module;
|
||||
}
|
||||
|
||||
void* FindSymbol(Module module, const char* name) {
|
||||
return dlsym(module, name);
|
||||
}
|
||||
#endif
|
||||
|
||||
/// The player's DLSS folder (<user>/dlss, BB_GPU_USER_DIR; beside bb-probe without it): NGX's
|
||||
/// logs, and NVIDIA's library when the player placed one there.
|
||||
std::filesystem::path UserDlssDirectory() {
|
||||
if (const char* user = std::getenv("BB_GPU_USER_DIR"); user && user[0]) {
|
||||
std::error_code error;
|
||||
const auto absolute = std::filesystem::absolute(std::filesystem::path{user} / "dlss", error);
|
||||
return error ? std::filesystem::path{user} / "dlss" : absolute;
|
||||
}
|
||||
return ExecutableDirectory() / "dlss";
|
||||
}
|
||||
|
||||
/// Where NVIDIA's DLSS library is: the player's own first, then beside bb-probe; empty: nowhere.
|
||||
std::filesystem::path NgxDirectory() {
|
||||
for (const auto& directory : {UserDlssDirectory(), ExecutableDirectory()}) {
|
||||
if (HasNgx(directory)) {
|
||||
return directory;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
/// Where the bridge is: beside bb-probe (the package, a build with DLSS_SDK_ROOT), else the
|
||||
/// player's DLSS folder; empty: nowhere.
|
||||
std::filesystem::path BridgeDirectory() {
|
||||
for (const auto& directory : {ExecutableDirectory(), UserDlssDirectory()}) {
|
||||
std::error_code error;
|
||||
if (std::filesystem::is_regular_file(directory / BridgeName, error)) {
|
||||
return directory;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void BridgeLog(int warning, const char* message) {
|
||||
std::printf("DLSS: %s%s\n", warning ? "warning: " : "", message);
|
||||
}
|
||||
|
||||
bool CollectExtensions(const VkExtensionProperties* required, u32 count,
|
||||
const std::vector<vk::ExtensionProperties>& available,
|
||||
std::vector<std::string>& storage, std::vector<const char*>& enabled) {
|
||||
storage.clear();
|
||||
for (u32 i = 0; i < count; ++i) {
|
||||
const auto& request = required[i];
|
||||
const auto match = std::ranges::find_if(available, [&](const auto& extension) {
|
||||
return std::strcmp(extension.extensionName.data(), request.extensionName) == 0 &&
|
||||
extension.specVersion >= request.specVersion;
|
||||
});
|
||||
if (match == available.end()) {
|
||||
std::printf("DLSS: missing Vulkan extension %s\n", request.extensionName);
|
||||
return false;
|
||||
}
|
||||
storage.emplace_back(request.extensionName);
|
||||
}
|
||||
for (const auto& name : storage) {
|
||||
if (std::ranges::none_of(enabled, [&](const char* current) { return name == current; })) {
|
||||
enabled.push_back(name.c_str());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
struct Dlss::Impl {
|
||||
Module module{};
|
||||
const BbDlssApi* api{};
|
||||
std::vector<std::string> instance_extensions, device_extensions;
|
||||
std::optional<FeatureDesc> feature;
|
||||
std::string problem;
|
||||
bool eligible{true}, instance_ready{}, device_ready{}, initialized{}, available{};
|
||||
|
||||
void Disable(std::string_view reason) {
|
||||
eligible = available = false;
|
||||
problem = reason;
|
||||
std::printf("DLSS: unavailable (%.*s)\n", int(reason.size()), reason.data());
|
||||
}
|
||||
};
|
||||
|
||||
Dlss* Dlss::Get() {
|
||||
static Dlss* const dlss = []() -> Dlss* {
|
||||
const char* setting = std::getenv("BB_DLSS");
|
||||
if (setting && setting[0] == '0') {
|
||||
return nullptr;
|
||||
}
|
||||
if (BridgeDirectory().empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
auto* created = new Dlss;
|
||||
// The process may end through quick_exit/_exit paths: release NGX first when it can.
|
||||
std::atexit([] {
|
||||
if (Dlss* live = Get()) {
|
||||
live->Shutdown();
|
||||
}
|
||||
});
|
||||
return created;
|
||||
}();
|
||||
return dlss;
|
||||
}
|
||||
|
||||
Dlss::Dlss() : impl{std::make_unique<Impl>()} {
|
||||
impl->module = LoadModule(BridgeDirectory() / BridgeName);
|
||||
const auto get_api =
|
||||
impl->module ? reinterpret_cast<BbDlssGetApiFn>(FindSymbol(impl->module, "BbDlssGetApi"))
|
||||
: nullptr;
|
||||
impl->api = get_api ? get_api() : nullptr;
|
||||
if (!impl->api || impl->api->abi != BBPORT_DLSS_BRIDGE_ABI) {
|
||||
impl->Disable("the DLSS bridge library is missing or from another version");
|
||||
return;
|
||||
}
|
||||
const auto ngx = NgxDirectory();
|
||||
if (ngx.empty()) {
|
||||
impl->Disable("NVIDIA's DLSS library is missing (nvngx_dlss.dll next to the game or in dlss/)");
|
||||
return;
|
||||
}
|
||||
// NGX writes its logs and model updates here: beside the saves and shader caches.
|
||||
const auto data = UserDlssDirectory();
|
||||
std::error_code error;
|
||||
std::filesystem::create_directories(data, error);
|
||||
const auto version = FileVersion(ngx / NgxName);
|
||||
if (version.empty()) {
|
||||
std::printf("DLSS: NVIDIA's library from %s\n", ngx.string().c_str());
|
||||
} else {
|
||||
std::printf("DLSS: NVIDIA's library from %s (version %s)\n", ngx.string().c_str(),
|
||||
version.c_str());
|
||||
}
|
||||
if (!impl->api->Configure(ngx.wstring().c_str(), data.wstring().c_str(), BridgeLog)) {
|
||||
impl->Disable("bridge configuration failed");
|
||||
}
|
||||
}
|
||||
|
||||
Dlss::~Dlss() {
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
void Dlss::AppendInstanceExtensions(std::vector<const char*>& enabled) {
|
||||
if (!impl->eligible) {
|
||||
return;
|
||||
}
|
||||
u32 count{};
|
||||
const VkExtensionProperties* required{};
|
||||
if (!impl->api->InstanceExtensions(&count, &required)) {
|
||||
return impl->Disable("instance extension query failed");
|
||||
}
|
||||
const auto [result, extensions] = vk::enumerateInstanceExtensionProperties();
|
||||
if (result != vk::Result::eSuccess ||
|
||||
!CollectExtensions(required, count, extensions, impl->instance_extensions, enabled)) {
|
||||
return impl->Disable("required Vulkan instance extensions are missing");
|
||||
}
|
||||
impl->instance_ready = true;
|
||||
}
|
||||
|
||||
void Dlss::AppendDeviceExtensions(vk::Instance instance, vk::PhysicalDevice physical,
|
||||
std::vector<const char*>& enabled) {
|
||||
if (!impl->eligible || !impl->instance_ready) {
|
||||
return;
|
||||
}
|
||||
const auto properties = physical.getProperties();
|
||||
if (properties.vendorID != 0x10de) {
|
||||
return impl->Disable("not an NVIDIA GPU");
|
||||
}
|
||||
u32 count{};
|
||||
const VkExtensionProperties* required{};
|
||||
if (!impl->api->DeviceExtensions(instance, physical, &count, &required)) {
|
||||
return impl->Disable("this GPU or driver does not support DLSS (GeForce RTX needed)");
|
||||
}
|
||||
const auto [result, extensions] = physical.enumerateDeviceExtensionProperties();
|
||||
if (result != vk::Result::eSuccess ||
|
||||
!CollectExtensions(required, count, extensions, impl->device_extensions, enabled)) {
|
||||
return impl->Disable("required Vulkan device extensions are missing");
|
||||
}
|
||||
impl->device_ready = true;
|
||||
}
|
||||
|
||||
void Dlss::Disable(std::string_view reason) {
|
||||
impl->Disable(reason);
|
||||
}
|
||||
|
||||
void Dlss::Initialize(vk::Instance instance, vk::PhysicalDevice physical, vk::Device device) {
|
||||
if (!impl->eligible || !impl->device_ready || impl->initialized) {
|
||||
return;
|
||||
}
|
||||
impl->initialized = true;
|
||||
if (!impl->api->Initialize(instance, physical, device,
|
||||
VULKAN_HPP_DEFAULT_DISPATCHER.vkGetInstanceProcAddr,
|
||||
VULKAN_HPP_DEFAULT_DISPATCHER.vkGetDeviceProcAddr)) {
|
||||
return impl->Disable("NVIDIA NGX initialization failed (update the GPU driver)");
|
||||
}
|
||||
impl->available = true;
|
||||
std::printf("DLSS: ready\n");
|
||||
}
|
||||
|
||||
bool Dlss::Available() const {
|
||||
return impl->available;
|
||||
}
|
||||
|
||||
std::string Dlss::Problem() const {
|
||||
return impl->problem;
|
||||
}
|
||||
|
||||
bool Dlss::HasFeature(const FeatureDesc& desc) const {
|
||||
return impl->feature && *impl->feature == desc;
|
||||
}
|
||||
|
||||
bool Dlss::CreateFeature(vk::CommandBuffer command, const FeatureDesc& desc) {
|
||||
if (!impl->available) {
|
||||
return false;
|
||||
}
|
||||
impl->feature.reset();
|
||||
const BbDlssFeature feature{desc.input_width, desc.input_height, desc.output_width,
|
||||
desc.output_height, desc.quality, 0,
|
||||
desc.preset, desc.hdr ? 1 : 0};
|
||||
if (!impl->api->CreateFeature(command, &feature)) {
|
||||
return false;
|
||||
}
|
||||
impl->feature = desc;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Dlss::Evaluate(vk::CommandBuffer command, const Frame& frame) {
|
||||
if (!impl->available || !impl->feature) {
|
||||
return false;
|
||||
}
|
||||
const auto image = [](const Resource& r) {
|
||||
const vk::ImageSubresourceRange range{r.aspect, 0, 1, 0, 1};
|
||||
return BbDlssImage{r.image,
|
||||
r.view,
|
||||
static_cast<VkImageSubresourceRange>(range),
|
||||
static_cast<VkFormat>(r.format),
|
||||
r.width,
|
||||
r.height};
|
||||
};
|
||||
const BbDlssEvaluate parameters{image(frame.color), image(frame.depth), image(frame.motion),
|
||||
image(frame.output), frame.jitter_x, frame.jitter_y,
|
||||
frame.reset ? 1 : 0, frame.frame_ms, frame.sharpness};
|
||||
return impl->api->Evaluate(command, ¶meters) != 0;
|
||||
}
|
||||
|
||||
void Dlss::ReleaseFeature() {
|
||||
impl->feature.reset();
|
||||
if (impl->api) {
|
||||
impl->api->ReleaseFeature();
|
||||
}
|
||||
}
|
||||
|
||||
void Dlss::Shutdown() {
|
||||
impl->available = false;
|
||||
impl->feature.reset();
|
||||
if (impl->api && impl->initialized) {
|
||||
impl->api->Shutdown();
|
||||
impl->initialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
struct Dlss::Impl {};
|
||||
Dlss::Dlss() = default;
|
||||
Dlss::~Dlss() = default;
|
||||
Dlss* Dlss::Get() {
|
||||
return nullptr;
|
||||
}
|
||||
void Dlss::AppendInstanceExtensions(std::vector<const char*>&) {}
|
||||
void Dlss::AppendDeviceExtensions(vk::Instance, vk::PhysicalDevice, std::vector<const char*>&) {}
|
||||
void Dlss::Initialize(vk::Instance, vk::PhysicalDevice, vk::Device) {}
|
||||
void Dlss::Disable(std::string_view) {}
|
||||
void Dlss::Shutdown() {}
|
||||
bool Dlss::Available() const {
|
||||
return false;
|
||||
}
|
||||
std::string Dlss::Problem() const {
|
||||
return {};
|
||||
}
|
||||
bool Dlss::HasFeature(const FeatureDesc&) const {
|
||||
return false;
|
||||
}
|
||||
bool Dlss::CreateFeature(vk::CommandBuffer, const FeatureDesc&) {
|
||||
return false;
|
||||
}
|
||||
bool Dlss::Evaluate(vk::CommandBuffer, const Frame&) {
|
||||
return false;
|
||||
}
|
||||
void Dlss::ReleaseFeature() {}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace Vulkan
|
||||
@@ -0,0 +1,79 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 IFreemz, bbport contributors
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
//
|
||||
// bbport: NVIDIA DLSS Super Resolution through the optional bridge (gpu/dlss_bridge, MIT;
|
||||
// bbport_dlss.dll), loaded at run time from next to bb-probe together with NVIDIA's
|
||||
// nvngx_dlss.dll. The port itself contains no NVIDIA code; without the libraries, on other GPUs
|
||||
// or with BB_DLSS=0 nothing changes. Adapted from IFreemz/shadPS4-Bloodborne-DLSS-FSR
|
||||
// (vk_dlss_ngx).
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include "common/types.h"
|
||||
#include "video_core/renderer_vulkan/vk_common.h"
|
||||
|
||||
namespace Vulkan {
|
||||
|
||||
class Dlss {
|
||||
public:
|
||||
/// The process-wide instance, or null when the DLLs are absent or BB_DLSS=0.
|
||||
static Dlss* Get();
|
||||
~Dlss();
|
||||
|
||||
/// Instance and device creation: adds what NGX needs (or disables DLSS when it is missing).
|
||||
void AppendInstanceExtensions(std::vector<const char*>& enabled);
|
||||
void AppendDeviceExtensions(vk::Instance instance, vk::PhysicalDevice physical,
|
||||
std::vector<const char*>& enabled);
|
||||
/// After the device exists.
|
||||
void Initialize(vk::Instance instance, vk::PhysicalDevice physical, vk::Device device);
|
||||
/// The device could not be created with NGX's extensions (the driver advertises them, but
|
||||
/// what they load is missing): DLSS off, FSR 3.1 instead.
|
||||
void Disable(std::string_view reason);
|
||||
void Shutdown();
|
||||
|
||||
[[nodiscard]] bool Available() const;
|
||||
/// Why DLSS cannot run on this system (empty when it can, or before device creation).
|
||||
[[nodiscard]] std::string Problem() const;
|
||||
|
||||
struct Resource {
|
||||
vk::Image image;
|
||||
vk::ImageView view;
|
||||
vk::Format format;
|
||||
vk::ImageAspectFlags aspect;
|
||||
u32 width, height;
|
||||
};
|
||||
struct FeatureDesc {
|
||||
u32 input_width, input_height, output_width, output_height;
|
||||
int quality;
|
||||
u32 preset; ///< NVSDK_NGX_DLSS_Hint_Render_Preset (0 default, 10 J, 11 K)
|
||||
bool hdr;
|
||||
bool operator==(const FeatureDesc&) const = default;
|
||||
};
|
||||
struct Frame {
|
||||
Resource color, depth, motion, output;
|
||||
float jitter_x, jitter_y;
|
||||
bool reset;
|
||||
float frame_ms;
|
||||
float sharpness;
|
||||
};
|
||||
|
||||
/// DLSS quality mode for an output/render size ratio (0 DLAA .. 4 Ultra Performance).
|
||||
static int QualityForScale(float scale);
|
||||
[[nodiscard]] bool HasFeature(const FeatureDesc& desc) const;
|
||||
/// Records the feature creation. The GPU must be done with the previous one.
|
||||
bool CreateFeature(vk::CommandBuffer command, const FeatureDesc& desc);
|
||||
bool Evaluate(vk::CommandBuffer command, const Frame& frame);
|
||||
void ReleaseFeature();
|
||||
|
||||
private:
|
||||
Dlss();
|
||||
struct Impl;
|
||||
std::unique_ptr<Impl> impl;
|
||||
};
|
||||
|
||||
} // namespace Vulkan
|
||||
@@ -194,8 +194,8 @@ void PrepareVertexInputs(const Shader::Info& vs, const Shader::Gcn::FetchShaderD
|
||||
out.ranges = arena.AppendArray(merged.data(), merged.size());
|
||||
out.count = static_cast<u32>(attributes.size());
|
||||
out.num_ranges = static_cast<u32>(merged.size());
|
||||
out.buffers_hash =
|
||||
buffers.empty() ? 0 : XXH3_64bits(buffers.data(), buffers.size() * sizeof(AmdGpu::Buffer));
|
||||
out.buffers_hash = HashBufferDescriptors(buffers.data(), buffers.size());
|
||||
|
||||
out.valid = true;
|
||||
}
|
||||
|
||||
@@ -270,7 +270,10 @@ void DrawPreparation::BeginSubmission(u64 seq, const AmdGpu::Regs& regs, u64 reg
|
||||
}
|
||||
// Idle helpers can starve on a busy CPU. Rather than queueing without bound, restart
|
||||
// them from the GPU thread's own state (one register copy) once the scanner lags.
|
||||
constexpr u64 MaxScanLag = 64;
|
||||
static const u64 MaxScanLag = [] {
|
||||
const char* env = std::getenv("BB_PREP_SCAN_LAG");
|
||||
return env && *env ? static_cast<u64>(std::strtoull(env, nullptr, 10)) : 16ull;
|
||||
}();
|
||||
if (!submissions.empty() && seq > tail_seq + MaxScanLag &&
|
||||
submissions.front()->seq < seq && !submissions.front()->scanned.load()) {
|
||||
*tail_regs = regs;
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include "common/types.h"
|
||||
#include "video_core/amdgpu/regs.h"
|
||||
#include "video_core/renderer_vulkan/vk_pipeline_cache.h"
|
||||
#include "bbport_toggles.h"
|
||||
#include <xxhash.h>
|
||||
|
||||
namespace Vulkan {
|
||||
|
||||
@@ -62,6 +64,28 @@ inline u64 ImageDescHash(const AmdGpu::Image& sharp, const Shader::ImageResource
|
||||
|
||||
/// Vertex inputs of a draw (the dynamic vertex input path): the attribute and binding
|
||||
/// descriptions, the V# of each stream, and the stream memory merged into ranges.
|
||||
inline u64 HashBufferDescriptors(const AmdGpu::Buffer* buffers, size_t count) {
|
||||
if (count == 0) return 0;
|
||||
if (BbToggle::Disabled2(BbToggle::StableMotionHash)) {
|
||||
return XXH3_64bits(buffers, count * sizeof(AmdGpu::Buffer));
|
||||
}
|
||||
constexpr size_t StackLimit = 32;
|
||||
std::array<AmdGpu::Buffer, StackLimit> stack_buffers;
|
||||
if (count <= StackLimit) {
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
stack_buffers[i] = buffers[i];
|
||||
stack_buffers[i].base_address = 0;
|
||||
}
|
||||
return XXH3_64bits(stack_buffers.data(), count * sizeof(AmdGpu::Buffer));
|
||||
} else {
|
||||
std::vector<AmdGpu::Buffer> copy(buffers, buffers + count);
|
||||
for (auto& b : copy) {
|
||||
b.base_address = 0;
|
||||
}
|
||||
return XXH3_64bits(copy.data(), count * sizeof(AmdGpu::Buffer));
|
||||
}
|
||||
}
|
||||
|
||||
struct PreparedVertexInputs {
|
||||
struct Range {
|
||||
VAddr base, end;
|
||||
|
||||
@@ -2,8 +2,13 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <boost/container/small_vector.hpp>
|
||||
#include <mutex>
|
||||
#include <tsl/robin_map.h>
|
||||
#include "bbport_toggles.h"
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "shader_recompiler/backend/spirv/emit_spirv_discard_frag.h"
|
||||
@@ -11,6 +16,7 @@
|
||||
#include "video_core/renderer_vulkan/liverpool_to_vk.h"
|
||||
#include "video_core/renderer_vulkan/vk_graphics_pipeline.h"
|
||||
#include "video_core/renderer_vulkan/vk_instance.h"
|
||||
#include "video_core/renderer_vulkan/vk_pipeline_cache.h"
|
||||
#include "video_core/renderer_vulkan/vk_scheduler.h"
|
||||
#include "video_core/renderer_vulkan/vk_shader_util.h"
|
||||
|
||||
@@ -18,6 +24,18 @@ namespace Vulkan {
|
||||
|
||||
using Shader::Backend::SPIRV::AuxShaderType;
|
||||
|
||||
static std::mutex aux_modules_mutex;
|
||||
static tsl::robin_map<u64, vk::UniqueShaderModule> aux_tcs_cache;
|
||||
static tsl::robin_map<u64, vk::UniqueShaderModule> aux_tes_cache;
|
||||
static tsl::robin_map<u64, vk::UniqueShaderModule> aux_frag_cache;
|
||||
|
||||
void ClearAuxShaderCaches() {
|
||||
std::scoped_lock lock{aux_modules_mutex};
|
||||
aux_tcs_cache.clear();
|
||||
aux_tes_cache.clear();
|
||||
aux_frag_cache.clear();
|
||||
}
|
||||
|
||||
static constexpr std::array LogicalStageToStageBit = {
|
||||
vk::ShaderStageFlagBits::eFragment,
|
||||
vk::ShaderStageFlagBits::eTessellationControl,
|
||||
@@ -55,8 +73,10 @@ GraphicsPipeline::GraphicsPipeline(
|
||||
.pPushConstantRanges = &push_constants,
|
||||
};
|
||||
auto [layout_result, layout] = instance.GetDevice().createPipelineLayoutUnique(layout_info);
|
||||
ASSERT_MSG(layout_result == vk::Result::eSuccess,
|
||||
"Failed to create graphics pipeline layout: {}", vk::to_string(layout_result));
|
||||
if (layout_result != vk::Result::eSuccess) {
|
||||
throw std::runtime_error("Failed to create graphics pipeline layout: " +
|
||||
vk::to_string(layout_result));
|
||||
}
|
||||
pipeline_layout = std::move(layout);
|
||||
SetObjectName(device, *pipeline_layout, "Graphics PipelineLayout {}", debug_str);
|
||||
|
||||
@@ -199,7 +219,31 @@ GraphicsPipeline::GraphicsPipeline(
|
||||
}
|
||||
shader_stages.emplace_back(vk::PipelineShaderStageCreateInfo{
|
||||
.stage = vk::ShaderStageFlagBits::eTessellationControl,
|
||||
.module = CompileSPV(sdata.tcs, instance.GetDevice()),
|
||||
.module = [&]() {
|
||||
if (BbToggle::Disabled(BbToggle::AuxTessCache)) {
|
||||
return CompileSPV(sdata.tcs, instance.GetDevice());
|
||||
}
|
||||
const auto& fs_info = runtime_infos[u32(Shader::SwStage::Fragment)].hw.fs;
|
||||
u64 key = static_cast<u64>(type) |
|
||||
(static_cast<u64>(fs_info.clip_distance_emulation) << 8) |
|
||||
(static_cast<u64>(fs_info.num_inputs) << 16);
|
||||
key ^= XXH3_64bits(fs_info.inputs.data(), fs_info.num_inputs * sizeof(fs_info.inputs[0]));
|
||||
std::scoped_lock lock{aux_modules_mutex};
|
||||
auto it = aux_tcs_cache.find(key);
|
||||
if (it == aux_tcs_cache.end()) {
|
||||
const vk::ShaderModuleCreateInfo shader_info = {
|
||||
.codeSize = sdata.tcs.size() * sizeof(u32),
|
||||
.pCode = sdata.tcs.data(),
|
||||
};
|
||||
auto [res, mod] = instance.GetDevice().createShaderModuleUnique(shader_info);
|
||||
if (res != vk::Result::eSuccess) {
|
||||
throw std::runtime_error("Failed to compile SPIR-V shader: " +
|
||||
vk::to_string(res));
|
||||
}
|
||||
it = aux_tcs_cache.emplace(key, std::move(mod)).first;
|
||||
}
|
||||
return *it->second;
|
||||
}(),
|
||||
.pName = "main",
|
||||
});
|
||||
}
|
||||
@@ -218,7 +262,31 @@ GraphicsPipeline::GraphicsPipeline(
|
||||
}
|
||||
shader_stages.emplace_back(vk::PipelineShaderStageCreateInfo{
|
||||
.stage = vk::ShaderStageFlagBits::eTessellationEvaluation,
|
||||
.module = CompileSPV(sdata.tes, instance.GetDevice()),
|
||||
.module = [&]() {
|
||||
if (BbToggle::Disabled(BbToggle::AuxTessCache)) {
|
||||
return CompileSPV(sdata.tes, instance.GetDevice());
|
||||
}
|
||||
const auto& fs_info = runtime_infos[u32(Shader::SwStage::Fragment)].hw.fs;
|
||||
u64 key = static_cast<u64>(AuxShaderType::PassthroughTES) |
|
||||
(static_cast<u64>(fs_info.clip_distance_emulation) << 8) |
|
||||
(static_cast<u64>(fs_info.num_inputs) << 16);
|
||||
key ^= XXH3_64bits(fs_info.inputs.data(), fs_info.num_inputs * sizeof(fs_info.inputs[0]));
|
||||
std::scoped_lock lock{aux_modules_mutex};
|
||||
auto it = aux_tes_cache.find(key);
|
||||
if (it == aux_tes_cache.end()) {
|
||||
const vk::ShaderModuleCreateInfo shader_info = {
|
||||
.codeSize = sdata.tes.size() * sizeof(u32),
|
||||
.pCode = sdata.tes.data(),
|
||||
};
|
||||
auto [res, mod] = instance.GetDevice().createShaderModuleUnique(shader_info);
|
||||
if (res != vk::Result::eSuccess) {
|
||||
throw std::runtime_error("Failed to compile SPIR-V shader: " +
|
||||
vk::to_string(res));
|
||||
}
|
||||
it = aux_tes_cache.emplace(key, std::move(mod)).first;
|
||||
}
|
||||
return *it->second;
|
||||
}(),
|
||||
.pName = "main",
|
||||
});
|
||||
}
|
||||
@@ -237,7 +305,28 @@ GraphicsPipeline::GraphicsPipeline(
|
||||
}
|
||||
shader_stages.emplace_back(vk::PipelineShaderStageCreateInfo{
|
||||
.stage = vk::ShaderStageFlagBits::eFragment,
|
||||
.module = CompileSPV(sdata.fragment, instance.GetDevice()),
|
||||
.module = [&]() {
|
||||
if (BbToggle::Disabled(BbToggle::AuxTessCache)) {
|
||||
return CompileSPV(sdata.fragment, instance.GetDevice());
|
||||
}
|
||||
const auto& vs = runtime_infos[static_cast<u32>(Shader::SwStage::Vertex)].hw.vs;
|
||||
const u64 key = XXH3_64bits(vs.outputs.data(), vs.outputs.size() * sizeof(vs.outputs[0]));
|
||||
std::scoped_lock lock{aux_modules_mutex};
|
||||
auto it = aux_frag_cache.find(key);
|
||||
if (it == aux_frag_cache.end()) {
|
||||
const vk::ShaderModuleCreateInfo shader_info = {
|
||||
.codeSize = sdata.fragment.size() * sizeof(u32),
|
||||
.pCode = sdata.fragment.data(),
|
||||
};
|
||||
auto [res, mod] = instance.GetDevice().createShaderModuleUnique(shader_info);
|
||||
if (res != vk::Result::eSuccess) {
|
||||
throw std::runtime_error("Failed to compile SPIR-V shader: " +
|
||||
vk::to_string(res));
|
||||
}
|
||||
it = aux_frag_cache.emplace(key, std::move(mod)).first;
|
||||
}
|
||||
return *it->second;
|
||||
}(),
|
||||
.pName = "main",
|
||||
});
|
||||
}
|
||||
@@ -411,10 +500,22 @@ GraphicsPipeline::GraphicsPipeline(
|
||||
.layout = *pipeline_layout,
|
||||
};
|
||||
|
||||
auto [pipeline_result, pipe] =
|
||||
device.createGraphicsPipelineUnique(pipeline_cache, pipeline_info);
|
||||
ASSERT_MSG(pipeline_result == vk::Result::eSuccess, "Failed to create graphics pipeline: {}",
|
||||
vk::to_string(pipeline_result));
|
||||
/* bbport: Vulkan requires external synchronization on VkPipelineCache. The async pipeline
|
||||
* workers and the GPU thread create pipelines at the same time otherwise, which RADV answers
|
||||
* with ErrorUnknown; the old ASSERT_MSG then exited the process (exit code 23). Serializing
|
||||
* the call fixes the cause, and a failure is reported to PipelineCache instead of aborting. */
|
||||
vk::Result pipeline_result = vk::Result::eSuccess;
|
||||
vk::UniquePipeline pipe;
|
||||
{
|
||||
std::scoped_lock lock{PipelineCreationMutex()};
|
||||
auto created = device.createGraphicsPipelineUnique(pipeline_cache, pipeline_info);
|
||||
pipeline_result = created.result;
|
||||
pipe = std::move(created.value);
|
||||
}
|
||||
if (pipeline_result != vk::Result::eSuccess) {
|
||||
throw std::runtime_error("Failed to create graphics pipeline: " +
|
||||
vk::to_string(pipeline_result));
|
||||
}
|
||||
pipeline = std::move(pipe);
|
||||
SetObjectName(device, *pipeline, "Graphics Pipeline {}", debug_str);
|
||||
}
|
||||
@@ -524,8 +625,10 @@ void GraphicsPipeline::BuildDescSetLayout(bool preloading) {
|
||||
};
|
||||
auto [layout_result, layout] =
|
||||
instance.GetDevice().createDescriptorSetLayoutUnique(desc_layout_ci);
|
||||
ASSERT_MSG(layout_result == vk::Result::eSuccess,
|
||||
"Failed to create graphics descriptor set layout: {}", vk::to_string(layout_result));
|
||||
if (layout_result != vk::Result::eSuccess) {
|
||||
throw std::runtime_error("Failed to create graphics descriptor set layout: " +
|
||||
vk::to_string(layout_result));
|
||||
}
|
||||
desc_layout = std::move(layout);
|
||||
}
|
||||
|
||||
|
||||
@@ -125,6 +125,8 @@ struct ClipDistanceShaderKey {
|
||||
}
|
||||
};
|
||||
|
||||
void ClearAuxShaderCaches();
|
||||
|
||||
} // namespace Vulkan
|
||||
|
||||
template <>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <tuple>
|
||||
|
||||
#include <boost/container/static_vector.hpp>
|
||||
#include <fmt/format.h>
|
||||
#include <fmt/ranges.h>
|
||||
@@ -11,6 +13,7 @@
|
||||
#include "imgui/renderer/imgui_core.h"
|
||||
#include "sdl_window.h"
|
||||
#include "video_core/renderer_vulkan/liverpool_to_vk.h"
|
||||
#include "video_core/renderer_vulkan/vk_dlss.h"
|
||||
#include "video_core/renderer_vulkan/vk_instance.h"
|
||||
#include "video_core/renderer_vulkan/vk_platform.h"
|
||||
#include "bbport_settings.h"
|
||||
@@ -199,7 +202,11 @@ Instance::Instance(const Frontend::WindowSystemInfo& window_info, s32 physical_d
|
||||
VK_VERSION_MAJOR(TargetVulkanApiVersion), VK_VERSION_MINOR(TargetVulkanApiVersion),
|
||||
VK_VERSION_MAJOR(properties.apiVersion), VK_VERSION_MINOR(properties.apiVersion));
|
||||
|
||||
CreateDevice();
|
||||
if (!CreateDevice()) {
|
||||
if (Dlss* dlss = Dlss::Get()) {
|
||||
dlss->Disable("device creation failed");
|
||||
}
|
||||
}
|
||||
BbSettings::ConfigureUpscalerSupport(IsFsr4Int8Supported(), IsFsr411Supported());
|
||||
CollectPhysicalMemoryInfo();
|
||||
CollectImageFormatInfo();
|
||||
@@ -207,6 +214,9 @@ Instance::Instance(const Frontend::WindowSystemInfo& window_info, s32 physical_d
|
||||
}
|
||||
|
||||
Instance::~Instance() {
|
||||
if (Dlss* dlss = Dlss::Get()) {
|
||||
dlss->Shutdown(); // NGX before the VkDevice and its images go away
|
||||
}
|
||||
ImGui::Core::Shutdown(GetDevice());
|
||||
vmaDestroyAllocator(allocator);
|
||||
}
|
||||
@@ -259,7 +269,7 @@ bool Instance::CreateDevice() {
|
||||
return false;
|
||||
}
|
||||
|
||||
boost::container::static_vector<const char*, 32> enabled_extensions;
|
||||
std::vector<const char*> enabled_extensions;
|
||||
const auto add_extension = [&](std::string_view extension) -> bool {
|
||||
const auto result =
|
||||
std::find_if(available_extensions.begin(), available_extensions.end(),
|
||||
@@ -644,7 +654,33 @@ bool Instance::CreateDevice() {
|
||||
device_chain.unlink<vk::PhysicalDeviceShaderMixedFloatDotProductFeaturesVALVE>();
|
||||
}
|
||||
|
||||
auto [device_result, dev] = physical_device.createDeviceUnique(device_chain.get());
|
||||
// DLSS (optional bridge library) needs its own device extensions on NVIDIA GPUs.
|
||||
const std::size_t own_extensions = enabled_extensions.size();
|
||||
Dlss* dlss = Dlss::Get();
|
||||
if (dlss) {
|
||||
dlss->AppendDeviceExtensions(*instance, physical_device, enabled_extensions);
|
||||
}
|
||||
const auto create = [&] {
|
||||
device_chain.get<vk::DeviceCreateInfo>().enabledExtensionCount =
|
||||
static_cast<u32>(enabled_extensions.size());
|
||||
device_chain.get<vk::DeviceCreateInfo>().ppEnabledExtensionNames =
|
||||
enabled_extensions.data();
|
||||
return physical_device.createDeviceUnique(device_chain.get());
|
||||
};
|
||||
auto [device_result, dev] = create();
|
||||
if (device_result != vk::Result::eSuccess && enabled_extensions.size() > own_extensions) {
|
||||
// The driver advertises NGX's extensions but the device does not start with them:
|
||||
// DLSS is optional, so retry without them and fall back to FSR 3.1.
|
||||
LOG_WARNING(Render_Vulkan, "Device creation with the DLSS extensions failed ({}): "
|
||||
"again without them", vk::to_string(device_result));
|
||||
if (dlss) {
|
||||
dlss->Disable("the Vulkan device does not start with NGX's extensions");
|
||||
}
|
||||
enabled_extensions.resize(own_extensions);
|
||||
auto retried = create();
|
||||
device_result = retried.result;
|
||||
dev = std::move(retried.value);
|
||||
}
|
||||
if (device_result != vk::Result::eSuccess) {
|
||||
LOG_CRITICAL(Render_Vulkan, "Failed to create device: {}", vk::to_string(device_result));
|
||||
return false;
|
||||
@@ -653,6 +689,10 @@ bool Instance::CreateDevice() {
|
||||
|
||||
VULKAN_HPP_DEFAULT_DISPATCHER.init(*device);
|
||||
|
||||
if (dlss) {
|
||||
dlss->Initialize(*instance, physical_device, *device);
|
||||
}
|
||||
|
||||
graphics_queue = device->getQueue(queue_family_index, 0);
|
||||
present_queue = device->getQueue(queue_family_index, 0);
|
||||
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "bbport_settings.h"
|
||||
#include "bbport_threads.h"
|
||||
#include "bbport_toggles.h"
|
||||
|
||||
#include "common/hash.h"
|
||||
#include "common/io_file.h"
|
||||
@@ -30,6 +32,7 @@
|
||||
#include "video_core/renderer_vulkan/vk_pipeline_serialization.h"
|
||||
#include "video_core/renderer_vulkan/vk_scheduler.h"
|
||||
#include "video_core/renderer_vulkan/vk_shader_util.h"
|
||||
#include "video_core/renderer_vulkan/vk_shader_capture.h"
|
||||
|
||||
namespace Vulkan {
|
||||
|
||||
@@ -37,6 +40,11 @@ using Shader::HwStage;
|
||||
using Shader::Output;
|
||||
using Shader::SwStage;
|
||||
|
||||
std::mutex& PipelineCreationMutex() {
|
||||
static std::mutex mutex;
|
||||
return mutex;
|
||||
}
|
||||
|
||||
constexpr static auto SpirvVersion1_6 = 0x00010600U;
|
||||
|
||||
constexpr static std::array DescriptorHeapSizes = {
|
||||
@@ -347,6 +355,7 @@ PipelineCache::PipelineCache(const Instance& instance_, Scheduler& scheduler_,
|
||||
.needs_unorm_fixup = instance.GetDriverID() == vk::DriverId::eMesaKosmickrisp,
|
||||
.needs_clip_distance_emulation = instance.GetDriverID() == vk::DriverId::eNvidiaProprietary,
|
||||
.supports_shader_stencil_export = instance_.IsShaderStencilExportSupported(),
|
||||
.fast_shader_math = EmulatorSettings.IsFastShaderMath(),
|
||||
};
|
||||
std::vector<u8> driver_cache_data{};
|
||||
if (EmulatorSettings.IsPipelineCacheEnabled()) {
|
||||
@@ -368,77 +377,65 @@ PipelineCache::PipelineCache(const Instance& instance_, Scheduler& scheduler_,
|
||||
LOG_WARNING(Render, "Failed to create pipeline cache from stored driver data ({}): recreating empty",
|
||||
vk::to_string(cache_result));
|
||||
auto [empty_res, empty_cache] = instance.GetDevice().createPipelineCacheUnique({});
|
||||
ASSERT_MSG(empty_res == vk::Result::eSuccess, "Failed to create empty pipeline cache: {}",
|
||||
vk::to_string(empty_res));
|
||||
cache = std::move(empty_cache);
|
||||
if (empty_res != vk::Result::eSuccess) {
|
||||
/* bbport: VK_NULL_HANDLE is a legal pipeline cache, so pipeline creation can go on
|
||||
* without one (no driver-side caching) instead of exiting the process. */
|
||||
LOG_CRITICAL(Render,
|
||||
"Failed to create empty pipeline cache ({}); continuing without a "
|
||||
"driver pipeline cache",
|
||||
vk::to_string(empty_res));
|
||||
} else {
|
||||
cache = std::move(empty_cache);
|
||||
}
|
||||
}
|
||||
pipeline_cache = std::move(cache);
|
||||
|
||||
WarmUp();
|
||||
StartShaderImport();
|
||||
}
|
||||
|
||||
class PipelineCompiler {
|
||||
public:
|
||||
explicit PipelineCompiler(u32 threads) {
|
||||
for (u32 i = 0; i < threads; ++i) {
|
||||
workers.emplace_back([this] { Run(); });
|
||||
}
|
||||
}
|
||||
~PipelineCompiler() {
|
||||
{
|
||||
std::scoped_lock lk{mutex};
|
||||
stop = true;
|
||||
}
|
||||
cv.notify_all();
|
||||
for (auto& worker : workers) {
|
||||
worker.join();
|
||||
}
|
||||
}
|
||||
void Submit(std::function<void()> job) {
|
||||
{
|
||||
std::scoped_lock lk{mutex};
|
||||
jobs.push_back(std::move(job));
|
||||
}
|
||||
cv.notify_one();
|
||||
}
|
||||
|
||||
private:
|
||||
void Run() {
|
||||
for (;;) {
|
||||
std::function<void()> job;
|
||||
{
|
||||
std::unique_lock lk{mutex};
|
||||
cv.wait(lk, [&] { return stop || !jobs.empty(); });
|
||||
if (jobs.empty()) {
|
||||
return; // stopping, every job done
|
||||
}
|
||||
job = std::move(jobs.front());
|
||||
jobs.pop_front();
|
||||
PipelineCompiler& PipelineCache::GetCompiler() {
|
||||
if (!compiler) {
|
||||
const char* env_threads = std::getenv("BB_ASYNC_PIPELINE_THREADS");
|
||||
const char* env_async = std::getenv("BB_ASYNC_PIPELINES");
|
||||
const int cfg_val = BbSettings::Get().async_pipelines.load();
|
||||
const u32 concurrency = std::thread::hardware_concurrency();
|
||||
const u32 default_threads = concurrency <= 8 ? std::max(1u, concurrency / 4) : std::clamp(concurrency / 2, 2u, 8u);
|
||||
u32 threads = default_threads;
|
||||
if (env_threads && *env_threads) {
|
||||
threads = u32(std::strtoul(env_threads, nullptr, 10));
|
||||
} else if (env_async && *env_async && env_async[0] != '0') {
|
||||
const u32 parsed = u32(std::strtoul(env_async, nullptr, 10));
|
||||
if (parsed > 1) {
|
||||
threads = parsed;
|
||||
}
|
||||
job();
|
||||
} else if (cfg_val > 0) {
|
||||
threads = u32(cfg_val);
|
||||
}
|
||||
compiler = std::make_unique<PipelineCompiler>(std::max(threads, 1u));
|
||||
std::printf("GPU: async pipeline compiler active on %u worker threads (BB_ASYNC_PIPELINES=0: disable)\n",
|
||||
std::max(threads, 1u));
|
||||
}
|
||||
std::mutex mutex;
|
||||
std::condition_variable cv;
|
||||
std::deque<std::function<void()>> jobs;
|
||||
std::vector<std::thread> workers;
|
||||
bool stop = false;
|
||||
};
|
||||
return *compiler;
|
||||
}
|
||||
|
||||
struct PipelineCache::PendingPipeline {
|
||||
std::mutex mutex;
|
||||
std::condition_variable cv;
|
||||
bool done = false;
|
||||
std::unique_ptr<GraphicsPipeline> pipeline;
|
||||
GraphicsPipeline::SerializationSupport sdata{};
|
||||
std::array<vk::ShaderModule, MaxShaderStages> modules{};
|
||||
};
|
||||
|
||||
PipelineCache::~PipelineCache() = default;
|
||||
|
||||
PipelineCache::~PipelineCache() {
|
||||
// bbport: the saver thread touches the device and the cache storage; it must be joined while
|
||||
// both are still alive. Sync() normally does this already; this covers teardown paths that
|
||||
// skip it.
|
||||
StopDriverCacheSaver();
|
||||
ClearAuxShaderCaches();
|
||||
}
|
||||
|
||||
// bbport: shader/pipeline compile time on the GPU thread, reported by BB_FRAME_STATS.
|
||||
std::atomic<u64> g_bb_compile_ns;
|
||||
std::atomic<u32> g_bb_compiles;
|
||||
std::atomic<u32> g_bb_background_pipelines_total{0};
|
||||
std::atomic<u32> g_bb_background_pipelines_done{0};
|
||||
std::atomic<bool> g_bb_shader_import_active{false};
|
||||
std::atomic<u32> g_bb_compiles_total{0};
|
||||
namespace {
|
||||
struct CompileTimer {
|
||||
std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
|
||||
@@ -447,6 +444,7 @@ struct CompileTimer {
|
||||
std::chrono::steady_clock::now() - start)
|
||||
.count());
|
||||
++g_bb_compiles;
|
||||
g_bb_compiles_total.fetch_add(1, std::memory_order_relaxed);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -456,7 +454,11 @@ struct TargetStreak {
|
||||
u32 last_frame = ~0u;
|
||||
u32 frames = 0;
|
||||
};
|
||||
std::unordered_map<u64, TargetStreak> target_streaks;
|
||||
tsl::robin_map<u64, TargetStreak> target_streaks = [] {
|
||||
tsl::robin_map<u64, TargetStreak> map;
|
||||
map.reserve(128);
|
||||
return map;
|
||||
}();
|
||||
|
||||
/// The draw's render target: its first color buffer written, else its depth buffer, else 0.
|
||||
u64 DrawTarget(const AmdGpu::Regs& regs) {
|
||||
@@ -520,7 +522,32 @@ const GraphicsPipeline* PipelineCache::TryPreparedPipeline(const PreparedDraw& p
|
||||
info.pgm_base = params.Base();
|
||||
info.user_data = params.user_data;
|
||||
info.RefreshFlatBuf();
|
||||
if (info.pgm_base != stage.pgm_base || info.flattened_ud_buf.size() != stage.flat_size ||
|
||||
if (info.pgm_base != stage.pgm_base || info.flattened_ud_buf.size() != stage.flat_size) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!BbToggle::Disabled(BbToggle::FlatHashValidation)) {
|
||||
const u64 computed_hash = XXH3_64bits(info.flattened_ud_buf.data(),
|
||||
info.flattened_ud_buf.size() * sizeof(u32));
|
||||
const auto& modules = stage.program->modules;
|
||||
size_t mod_idx = stage.program->last_used;
|
||||
if (mod_idx >= modules.size() ||
|
||||
prepared.key.stage_hashes[static_cast<u32>(stage.hw_stage)] != HashCombine(stage.hash, mod_idx)) {
|
||||
for (size_t p = 0; p < modules.size(); ++p) {
|
||||
for (size_t s = 0; s < MaxShaderStages; ++s) {
|
||||
if (prepared.key.stage_hashes[s] == HashCombine(stage.hash, p)) {
|
||||
mod_idx = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mod_idx < modules.size() && modules[mod_idx].flat_hash != 0) {
|
||||
if (computed_hash != modules[mod_idx].flat_hash) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (
|
||||
std::memcmp(info.flattened_ud_buf.data(), stage.flat,
|
||||
stage.flat_size * sizeof(u32)) != 0) {
|
||||
return nullptr;
|
||||
@@ -533,6 +560,8 @@ const GraphicsPipeline* PipelineCache::TryPreparedPipeline(const PreparedDraw& p
|
||||
const GraphicsPipeline* PipelineCache::GetGraphicsPipeline(const DrawIndirectParams params,
|
||||
const PreparedDraw* prepared,
|
||||
bool indirect) {
|
||||
PollShaderImport();
|
||||
MaybeSaveDriverPipelineCache();
|
||||
used_prepared = nullptr;
|
||||
NoteDrawTarget(liverpool->regs);
|
||||
if (prepared) {
|
||||
@@ -541,59 +570,102 @@ const GraphicsPipeline* PipelineCache::GetGraphicsPipeline(const DrawIndirectPar
|
||||
return pipeline;
|
||||
}
|
||||
}
|
||||
sel.draw_indirect_params = params;
|
||||
if (!RefreshGraphicsKey(sel)) {
|
||||
return nullptr;
|
||||
bool hit = false;
|
||||
if (!BbToggle::Disabled(BbToggle::SelectionCache) && selection_cache.valid &&
|
||||
selection_cache.reg_checksum == liverpool->gfx_reg_checksum &&
|
||||
selection_cache.indirect_params.vertex_sgpr_offset == params.vertex_sgpr_offset &&
|
||||
selection_cache.indirect_params.instance_sgpr_offset == params.instance_sgpr_offset) {
|
||||
sel.graphics_key = selection_cache.key;
|
||||
sel.infos = selection_cache.infos;
|
||||
sel.modules = selection_cache.modules;
|
||||
sel.fetch_shader = selection_cache.fetch_shader;
|
||||
sel.motion = selection_cache.motion;
|
||||
sel.draw_indirect_params = params;
|
||||
hit = true;
|
||||
}
|
||||
|
||||
if (!hit) {
|
||||
sel.draw_indirect_params = params;
|
||||
if (!RefreshGraphicsKey(sel)) {
|
||||
selection_cache.valid = false;
|
||||
return nullptr;
|
||||
}
|
||||
if (!BbToggle::Disabled(BbToggle::SelectionCache)) {
|
||||
selection_cache.valid = true;
|
||||
selection_cache.reg_checksum = liverpool->gfx_reg_checksum;
|
||||
selection_cache.indirect_params = params;
|
||||
selection_cache.key = sel.graphics_key;
|
||||
selection_cache.infos = sel.infos;
|
||||
selection_cache.modules = sel.modules;
|
||||
selection_cache.fetch_shader = sel.fetch_shader;
|
||||
selection_cache.motion = sel.motion;
|
||||
}
|
||||
}
|
||||
|
||||
if (const auto found = graphics_pipelines.find(sel.graphics_key); found != graphics_pipelines.end()) {
|
||||
return found->second.get();
|
||||
}
|
||||
// bbport BB_ASYNC_PIPELINES: being compiled on a worker, or to be.
|
||||
const bool skippable = AsyncSkippable(sel, indirect);
|
||||
/* bbport: a pipeline the driver refused `MaxPipelineFailures` times is not attempted again
|
||||
* (the failure was logged then). Its draws are dropped, as they already were while it was
|
||||
* pending; the rest of the frame keeps rendering. */
|
||||
if (const auto failed = graphics_failures.find(sel.graphics_key);
|
||||
failed != graphics_failures.end() && failed->second >= MaxPipelineFailures) {
|
||||
return nullptr;
|
||||
}
|
||||
if (const auto pending = pending_graphics.find(sel.graphics_key); pending != pending_graphics.end()) {
|
||||
const std::shared_ptr<PendingPipeline> job = pending->second;
|
||||
{
|
||||
std::unique_lock lk{job->mutex};
|
||||
if (!job->done) {
|
||||
if (skippable) {
|
||||
++async_skipped;
|
||||
return nullptr; // drawn from the frame its pipeline is ready
|
||||
if (job->make && !job->started.exchange(true)) {
|
||||
try {
|
||||
job->pipeline = job->make();
|
||||
} catch (const std::exception&) {}
|
||||
job->done = true;
|
||||
} else {
|
||||
if (skippable) {
|
||||
++async_skipped;
|
||||
return nullptr; // drawn from the frame its pipeline is ready
|
||||
}
|
||||
// A pass that is not drawn every frame needs it now: the wait is compile time.
|
||||
const auto start = std::chrono::steady_clock::now();
|
||||
job->cv.wait(lk, [&] { return job->done; });
|
||||
g_bb_compile_ns += u64(std::chrono::duration_cast<std::chrono::nanoseconds>(
|
||||
std::chrono::steady_clock::now() - start)
|
||||
.count());
|
||||
++async_waited;
|
||||
}
|
||||
// A pass that is not drawn every frame needs it now: the wait is compile time.
|
||||
const auto start = std::chrono::steady_clock::now();
|
||||
job->cv.wait(lk, [&] { return job->done; });
|
||||
g_bb_compile_ns += u64(std::chrono::duration_cast<std::chrono::nanoseconds>(
|
||||
std::chrono::steady_clock::now() - start)
|
||||
.count());
|
||||
++async_waited;
|
||||
}
|
||||
}
|
||||
pending_graphics.erase(sel.graphics_key);
|
||||
return FinishPipeline(sel.graphics_key, *job);
|
||||
}
|
||||
if (skippable) {
|
||||
if (!compiler) {
|
||||
const char* env = std::getenv("BB_ASYNC_PIPELINE_THREADS");
|
||||
const u32 concurrency = std::thread::hardware_concurrency();
|
||||
const u32 default_threads = concurrency > 2 ? std::clamp(concurrency / 2, 2u, 8u) : 1u;
|
||||
const u32 threads = env && *env ? u32(std::strtoul(env, nullptr, 10)) : default_threads;
|
||||
compiler = std::make_unique<PipelineCompiler>(std::max(threads, 1u));
|
||||
std::printf("GPU: new pipelines of passes drawn every frame compile on %u threads "
|
||||
"(BB_ASYNC_PIPELINES=0: on the GPU thread, the game waits)\n",
|
||||
std::max(threads, 1u));
|
||||
}
|
||||
auto& comp = GetCompiler();
|
||||
auto job = std::make_shared<PendingPipeline>();
|
||||
job->modules = sel.modules;
|
||||
pending_graphics.emplace(sel.graphics_key, job);
|
||||
++async_started;
|
||||
++g_bb_compiles;
|
||||
compiler->Submit([this, job, key = sel.graphics_key, infos = sel.infos,
|
||||
g_bb_compiles_total.fetch_add(1, std::memory_order_relaxed);
|
||||
comp.Submit([this, job, key = sel.graphics_key, infos = sel.infos,
|
||||
runtime_infos = sel.runtime_infos, fetch = sel.fetch_shader,
|
||||
modules = sel.modules]() mutable {
|
||||
GraphicsPipeline::SerializationSupport sdata{};
|
||||
auto pipeline = std::make_unique<GraphicsPipeline>(
|
||||
instance, scheduler, desc_heap, profile, key, *pipeline_cache, infos,
|
||||
runtime_infos, fetch, modules, sdata, false);
|
||||
std::unique_ptr<GraphicsPipeline> pipeline;
|
||||
try {
|
||||
pipeline = std::make_unique<GraphicsPipeline>(
|
||||
instance, scheduler, desc_heap, profile, key, *pipeline_cache, infos,
|
||||
runtime_infos, fetch, modules, sdata, false);
|
||||
} catch (const std::exception& e) {
|
||||
/* bbport: the driver refused this pipeline. The job completes without one and
|
||||
* FinishPipeline() accounts and skips it; an exception must never escape a
|
||||
* worker thread (std::terminate). */
|
||||
LOG_WARNING(Render_Vulkan, "Async graphics pipeline {:#x} failed: {}",
|
||||
std::hash<GraphicsPipelineKey>{}(key), e.what());
|
||||
}
|
||||
std::scoped_lock lk{job->mutex};
|
||||
job->pipeline = std::move(pipeline);
|
||||
job->sdata = std::move(sdata);
|
||||
@@ -610,9 +682,24 @@ const GraphicsPipeline* PipelineCache::GetGraphicsPipeline(const DrawIndirectPar
|
||||
CompileTimer timer;
|
||||
|
||||
GraphicsPipeline::SerializationSupport sdata{};
|
||||
it.value() = std::make_unique<GraphicsPipeline>(
|
||||
instance, scheduler, desc_heap, profile, sel.graphics_key, *pipeline_cache, sel.infos,
|
||||
sel.runtime_infos, sel.fetch_shader, sel.modules, sdata, false);
|
||||
try {
|
||||
it.value() = std::make_unique<GraphicsPipeline>(
|
||||
instance, scheduler, desc_heap, profile, sel.graphics_key, *pipeline_cache,
|
||||
sel.infos, sel.runtime_infos, sel.fetch_shader, sel.modules, sdata, false);
|
||||
} catch (const std::exception& e) {
|
||||
/* bbport: the driver refused the pipeline (see PipelineCreationMutex). The empty map
|
||||
* entry is removed and the draw skipped; the key is retried a bounded number of
|
||||
* times by the next draws, then left out. Previously this aborted the process. */
|
||||
graphics_pipelines.erase(sel.graphics_key);
|
||||
const u32 failures = ++graphics_failures[sel.graphics_key];
|
||||
if (failures <= MaxPipelineFailures) {
|
||||
LOG_WARNING(Render_Vulkan,
|
||||
"Graphics pipeline {:#x} failed to create (attempt {} of {}): {}; "
|
||||
"the draw is skipped",
|
||||
pipeline_hash, failures, u32{MaxPipelineFailures}, e.what());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RegisterPipelineData(sel.graphics_key, pipeline_hash, sdata);
|
||||
++num_new_pipelines;
|
||||
@@ -632,9 +719,24 @@ const GraphicsPipeline* PipelineCache::GetGraphicsPipeline(const DrawIndirectPar
|
||||
|
||||
const GraphicsPipeline* PipelineCache::FinishPipeline(const GraphicsPipelineKey& key,
|
||||
PendingPipeline& job) {
|
||||
if (!job.pipeline) {
|
||||
/* bbport: the pipeline could not be created (the creator already logged the driver
|
||||
* error). Account it and let the next draws retry up to the cap; a null pipeline is
|
||||
* never stored, so a later attempt is possible and no draw dereferences it. */
|
||||
const u32 failures = ++graphics_failures[key];
|
||||
if (failures <= MaxPipelineFailures) {
|
||||
LOG_WARNING(Render_Vulkan,
|
||||
"Graphics pipeline {:#x} is unavailable (attempt {} of {}): the draw is "
|
||||
"skipped",
|
||||
std::hash<GraphicsPipelineKey>{}(key), failures, u32{MaxPipelineFailures});
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
const auto pipeline_hash = std::hash<GraphicsPipelineKey>{}(key);
|
||||
RegisterPipelineData(key, pipeline_hash, job.sdata);
|
||||
++num_new_pipelines;
|
||||
if (!job.saved) {
|
||||
RegisterPipelineData(key, pipeline_hash, job.sdata);
|
||||
++num_new_pipelines;
|
||||
}
|
||||
if (EmulatorSettings.IsShaderCollect()) {
|
||||
for (const vk::ShaderModule module : job.modules) {
|
||||
if (module) {
|
||||
@@ -642,6 +744,7 @@ const GraphicsPipeline* PipelineCache::FinishPipeline(const GraphicsPipelineKey&
|
||||
}
|
||||
}
|
||||
}
|
||||
graphics_failures.erase(key);
|
||||
auto& slot = graphics_pipelines[key];
|
||||
slot = std::move(job.pipeline);
|
||||
return slot.get();
|
||||
@@ -655,7 +758,14 @@ bool PipelineCache::AsyncSkippable(const PipelineSelection& selection, bool indi
|
||||
// scene's, the output's) missed most passes: many set a 16384 scissor.
|
||||
static const bool enabled = [] {
|
||||
const char* env = std::getenv("BB_ASYNC_PIPELINES");
|
||||
return !(env && env[0] == '0');
|
||||
if (env) {
|
||||
return env[0] != '0';
|
||||
}
|
||||
const int cfg_val = BbSettings::Get().async_pipelines.load();
|
||||
if (cfg_val == 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}();
|
||||
if (!enabled || !instance.IsVertexInputDynamicState() || !selection.regs) {
|
||||
return false;
|
||||
@@ -685,7 +795,11 @@ bool PipelineCache::AsyncSkippable(const PipelineSelection& selection, bool indi
|
||||
// A full-screen pass (one triangle or quad: lighting, fog, post-processing) waits for its
|
||||
// pipeline: going without one for a frame left whole frames grey. So does an indirect draw
|
||||
// (its size unknown here). What may go without is geometry, which shows a frame later.
|
||||
constexpr u32 FullScreenIndices = 12;
|
||||
static const bool env_async_full_screen = [] {
|
||||
const char* env = std::getenv("BB_ASYNC_FULL_SCREEN");
|
||||
return env && env[0] == '1';
|
||||
}();
|
||||
const u32 FullScreenIndices = env_async_full_screen ? 3u : (!BbToggle::Disabled(BbToggle::AsyncFullScreenTuning) ? 6u : 12u);
|
||||
if (indirect || selection.regs->num_indices <= FullScreenIndices) {
|
||||
return false;
|
||||
}
|
||||
@@ -703,9 +817,15 @@ bool PipelineCache::AsyncSkippable(const PipelineSelection& selection, bool indi
|
||||
}
|
||||
|
||||
const ComputePipeline* PipelineCache::GetComputePipeline() {
|
||||
MaybeSaveDriverPipelineCache();
|
||||
if (!RefreshComputeKey()) {
|
||||
return nullptr;
|
||||
}
|
||||
/// bbport: a compute pipeline the driver refused repeatedly is not attempted again.
|
||||
if (const auto failed = compute_failures.find(compute_key);
|
||||
failed != compute_failures.end() && failed->second >= MaxPipelineFailures) {
|
||||
return nullptr;
|
||||
}
|
||||
const auto [it, is_new] = compute_pipelines.try_emplace(compute_key);
|
||||
if (is_new) {
|
||||
const auto pipeline_hash = std::hash<ComputePipelineKey>{}(compute_key);
|
||||
@@ -713,9 +833,23 @@ const ComputePipeline* PipelineCache::GetComputePipeline() {
|
||||
CompileTimer timer;
|
||||
|
||||
ComputePipeline::SerializationSupport sdata{};
|
||||
it.value() = std::make_unique<ComputePipeline>(instance, scheduler, desc_heap, profile,
|
||||
*pipeline_cache, compute_key, *sel.infos[0],
|
||||
sel.modules[0], sdata, false);
|
||||
try {
|
||||
it.value() = std::make_unique<ComputePipeline>(
|
||||
instance, scheduler, desc_heap, profile, *pipeline_cache, compute_key,
|
||||
*sel.infos[0], sel.modules[0], sdata, false);
|
||||
} catch (const std::exception& e) {
|
||||
/* bbport: the driver refused the pipeline. Remove the empty entry, account it and
|
||||
* skip the dispatch; a bounded number of later dispatches retries it. */
|
||||
compute_pipelines.erase(compute_key);
|
||||
const u32 failures = ++compute_failures[compute_key];
|
||||
if (failures <= MaxPipelineFailures) {
|
||||
LOG_WARNING(Render_Vulkan,
|
||||
"Compute pipeline {:#x} failed to create (attempt {} of {}): {}; "
|
||||
"the dispatch is skipped",
|
||||
pipeline_hash, failures, u32{MaxPipelineFailures}, e.what());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
RegisterPipelineData(compute_key, sdata);
|
||||
++num_new_pipelines;
|
||||
|
||||
@@ -1049,8 +1183,28 @@ vk::ShaderModule PipelineCache::CompileModule(Shader::Info& info, Shader::Runtim
|
||||
DumpShader(code, info.pgm_hash, info.hw_stage, perm_idx, "bin");
|
||||
CompileTimer timer;
|
||||
|
||||
const bool capture = BbShaderCapture::Enabled();
|
||||
std::optional<Shader::Info> in_info;
|
||||
const auto in_runtime_info = runtime_info;
|
||||
const auto in_binding = binding;
|
||||
const bool keep_input = EmulatorSettings.IsPipelineCacheEnabled();
|
||||
if (capture || keep_input) {
|
||||
in_info.emplace(info);
|
||||
BbShaderCapture::BeginInput();
|
||||
}
|
||||
|
||||
const auto ir_program = Shader::TranslateProgram(code, pools, info, runtime_info, profile);
|
||||
auto spv = Shader::Backend::SPIRV::EmitSPIRV(profile, runtime_info, ir_program, binding);
|
||||
if (keep_input) {
|
||||
RegisterShaderInput(
|
||||
BbShaderCapture::TakeInput(*in_info, in_runtime_info, in_binding, code, perm_idx,
|
||||
info.flattened_ud_buf),
|
||||
info.pgm_hash, perm_idx);
|
||||
}
|
||||
if (capture) {
|
||||
BbShaderCapture::Write(*in_info, in_runtime_info, profile, in_binding, code, perm_idx, spv,
|
||||
info, binding);
|
||||
}
|
||||
DumpShader(spv, info.pgm_hash, info.hw_stage, perm_idx, "spv");
|
||||
|
||||
vk::ShaderModule module;
|
||||
@@ -1130,7 +1284,9 @@ PipelineCache::Result PipelineCache::GetProgram(PipelineSelection& sel, HwStage
|
||||
const auto perm_hash = HashCombine(params.hash, 0);
|
||||
|
||||
RegisterShaderMeta(new_program->info, spec.fetch_shader_data, spec, perm_hash, 0);
|
||||
new_program->AddPermut(module, std::move(spec));
|
||||
const u64 flat_hash = XXH3_64bits(new_program->info.flattened_ud_buf.data(),
|
||||
new_program->info.flattened_ud_buf.size() * sizeof(u32));
|
||||
new_program->AddPermut(module, std::move(spec), flat_hash);
|
||||
new_program->info_template = std::make_unique<Shader::Info>(new_program->info);
|
||||
Program* program = new_program.get();
|
||||
{
|
||||
@@ -1172,7 +1328,9 @@ PipelineCache::Result PipelineCache::GetProgram(PipelineSelection& sel, HwStage
|
||||
|
||||
RegisterShaderMeta(info, spec.fetch_shader_data, spec, perm_hash, perm_idx);
|
||||
std::unique_lock lk{programs_mutex};
|
||||
program->AddPermut(module, std::move(spec));
|
||||
const u64 flat_hash = XXH3_64bits(info.flattened_ud_buf.data(),
|
||||
info.flattened_ud_buf.size() * sizeof(u32));
|
||||
program->AddPermut(module, std::move(spec), flat_hash);
|
||||
} else {
|
||||
info.AddBindings(binding);
|
||||
module = it->module;
|
||||
|
||||
@@ -3,11 +3,30 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <condition_variable>
|
||||
#include <chrono>
|
||||
#include <deque>
|
||||
#include <functional>
|
||||
#include <future>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <unordered_map>
|
||||
#include <shared_mutex>
|
||||
#include <variant>
|
||||
#include <boost/container/static_vector.hpp>
|
||||
#include <tsl/robin_map.h>
|
||||
#include <filesystem>
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
namespace Vulkan {
|
||||
extern std::atomic<u64> g_bb_compile_ns;
|
||||
extern std::atomic<u32> g_bb_compiles;
|
||||
extern std::atomic<u32> g_bb_background_pipelines_total;
|
||||
extern std::atomic<u32> g_bb_background_pipelines_done;
|
||||
extern std::atomic<bool> g_bb_shader_import_active;
|
||||
} // namespace Vulkan
|
||||
#include "shader_recompiler/profile.h"
|
||||
#include "shader_recompiler/recompiler.h"
|
||||
#include "shader_recompiler/specialization.h"
|
||||
@@ -40,10 +59,16 @@ class Instance;
|
||||
class Scheduler;
|
||||
class ShaderCache;
|
||||
|
||||
/// bbport: Vulkan requires external synchronization on VkPipelineCache. The BB_ASYNC_PIPELINES
|
||||
/// workers and the GPU thread create pipelines at the same time otherwise, which RADV answers
|
||||
/// with ErrorUnknown ("constant crashes 23"). One mutex: a pipeline creation is ~18 ms anyway.
|
||||
std::mutex& PipelineCreationMutex();
|
||||
|
||||
struct Program {
|
||||
struct Module {
|
||||
vk::ShaderModule module;
|
||||
Shader::StageSpecialization spec;
|
||||
u64 flat_hash = 0;
|
||||
};
|
||||
static constexpr size_t MaxPermutations = 8;
|
||||
using ModuleList = boost::container::small_vector<Module, MaxPermutations>;
|
||||
@@ -59,14 +84,14 @@ struct Program {
|
||||
Program(Shader::HwStage stage, Shader::SwStage l_stage, Shader::ShaderParams params)
|
||||
: info{stage, l_stage, params} {}
|
||||
|
||||
void AddPermut(vk::ShaderModule module, Shader::StageSpecialization&& spec) {
|
||||
modules.emplace_back(module, std::move(spec));
|
||||
void AddPermut(vk::ShaderModule module, Shader::StageSpecialization&& spec, u64 flat_hash = 0) {
|
||||
modules.emplace_back(module, std::move(spec), flat_hash);
|
||||
}
|
||||
|
||||
void InsertPermut(vk::ShaderModule module, Shader::StageSpecialization&& spec,
|
||||
size_t perm_idx) {
|
||||
size_t perm_idx, u64 flat_hash = 0) {
|
||||
modules.resize(std::max(modules.size(), perm_idx + 1)); // <-- beware of realloc
|
||||
modules[perm_idx] = {module, std::move(spec)};
|
||||
modules[perm_idx] = {module, std::move(spec), flat_hash};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -114,7 +139,53 @@ struct PrepWorker {
|
||||
|
||||
struct PreparedDraw;
|
||||
|
||||
class PipelineCompiler;
|
||||
class PipelineCompiler {
|
||||
public:
|
||||
explicit PipelineCompiler(u32 threads) {
|
||||
for (u32 i = 0; i < threads; ++i) {
|
||||
workers.emplace_back([this] { Run(); });
|
||||
}
|
||||
}
|
||||
~PipelineCompiler() {
|
||||
{
|
||||
std::scoped_lock lk{mutex};
|
||||
stop = true;
|
||||
}
|
||||
cv.notify_all();
|
||||
for (auto& worker : workers) {
|
||||
worker.join();
|
||||
}
|
||||
}
|
||||
void Submit(std::function<void()> job) {
|
||||
{
|
||||
std::scoped_lock lk{mutex};
|
||||
jobs.push_back(std::move(job));
|
||||
}
|
||||
cv.notify_one();
|
||||
}
|
||||
|
||||
private:
|
||||
void Run() {
|
||||
for (;;) {
|
||||
std::function<void()> job;
|
||||
{
|
||||
std::unique_lock lk{mutex};
|
||||
cv.wait(lk, [&] { return stop || !jobs.empty(); });
|
||||
if (jobs.empty()) {
|
||||
return; // stopping, every job done
|
||||
}
|
||||
job = std::move(jobs.front());
|
||||
jobs.pop_front();
|
||||
}
|
||||
job();
|
||||
}
|
||||
}
|
||||
std::mutex mutex;
|
||||
std::condition_variable cv;
|
||||
std::deque<std::function<void()>> jobs;
|
||||
std::vector<std::thread> workers;
|
||||
bool stop = false;
|
||||
};
|
||||
|
||||
class PipelineCache {
|
||||
public:
|
||||
@@ -127,6 +198,11 @@ public:
|
||||
|
||||
bool LoadComputePipeline(Serialization::Archive& ar);
|
||||
bool LoadGraphicsPipeline(Serialization::Archive& ar);
|
||||
struct PreloadJob {
|
||||
GraphicsPipelineKey key;
|
||||
std::function<std::unique_ptr<GraphicsPipeline>()> make;
|
||||
};
|
||||
bool LoadGraphicsPipeline(Serialization::Archive& ar, std::vector<PreloadJob>& jobs);
|
||||
bool LoadPipelineStage(Serialization::Archive& ar, size_t stage);
|
||||
|
||||
/// `indirect`: the draw's arguments are in memory (bbport: never skipped while compiling).
|
||||
@@ -185,6 +261,14 @@ private:
|
||||
|
||||
std::string GetDriverCacheKey() const;
|
||||
void SaveDriverPipelineCache();
|
||||
/// bbport: asks the driver-cache saver thread to write the native driver cache about once a
|
||||
/// minute when new pipelines exist. The window thread ends the process with std::_Exit(0), so
|
||||
/// the presenter destructor (the only other SaveDriverPipelineCache caller) never runs and the
|
||||
/// .vkp would never be written. No-op when nothing new was compiled. The dump (10+ MB) and the
|
||||
/// disk flush run on the saver thread, never on the GPU thread.
|
||||
void MaybeSaveDriverPipelineCache();
|
||||
void DriverCacheSaveLoop();
|
||||
void StopDriverCacheSaver();
|
||||
|
||||
private:
|
||||
const Instance& instance;
|
||||
@@ -202,9 +286,29 @@ private:
|
||||
const PreparedDraw* used_prepared = nullptr;
|
||||
tsl::robin_map<ComputePipelineKey, std::unique_ptr<ComputePipeline>> compute_pipelines;
|
||||
tsl::robin_map<GraphicsPipelineKey, std::unique_ptr<GraphicsPipeline>> graphics_pipelines;
|
||||
struct SelectionCache {
|
||||
bool valid = false;
|
||||
u64 reg_checksum = ~0ull;
|
||||
DrawIndirectParams indirect_params{};
|
||||
GraphicsPipelineKey key;
|
||||
std::array<const Shader::Info*, MaxShaderStages> infos{};
|
||||
std::array<vk::ShaderModule, MaxShaderStages> modules{};
|
||||
std::optional<Shader::Gcn::FetchShaderData> fetch_shader{};
|
||||
bool motion = false;
|
||||
};
|
||||
SelectionCache selection_cache{};
|
||||
PipelineCompiler& GetCompiler();
|
||||
PipelineSelection sel{}; ///< GPU thread selection state
|
||||
ComputePipelineKey compute_key{};
|
||||
u32 num_new_pipelines{}; // new pipelines added to the cache since the game start
|
||||
std::chrono::steady_clock::time_point last_driver_cache_save{};
|
||||
u32 num_new_pipelines_at_last_save{};
|
||||
/// bbport: the periodic .vkp dump runs here, off the GPU thread (see MaybeSaveDriverPipelineCache).
|
||||
std::mutex driver_save_mutex;
|
||||
std::condition_variable driver_save_cv;
|
||||
std::thread driver_save_thread;
|
||||
bool driver_save_pending = false;
|
||||
bool driver_save_stop = false;
|
||||
|
||||
// Only if Config::collectShadersForDebug()
|
||||
tsl::robin_map<vk::ShaderModule,
|
||||
@@ -215,12 +319,89 @@ private:
|
||||
/// on worker threads (PipelineCompiler) while its draws go without it for a frame or two,
|
||||
/// instead of the game standing still for the driver (18 ms a pipeline on a GTX 1060, 1-4 s
|
||||
/// hitches on a first session). Other passes (one-time renders) compile at once, as before.
|
||||
struct PendingPipeline;
|
||||
struct PendingPipeline {
|
||||
std::mutex mutex;
|
||||
std::condition_variable cv;
|
||||
bool done = false;
|
||||
std::unique_ptr<GraphicsPipeline> pipeline;
|
||||
GraphicsPipeline::SerializationSupport sdata{};
|
||||
std::array<vk::ShaderModule, MaxShaderStages> modules{};
|
||||
bool saved = false;
|
||||
std::function<std::unique_ptr<GraphicsPipeline>()> make;
|
||||
std::atomic<bool> started{false};
|
||||
};
|
||||
bool AsyncSkippable(const PipelineSelection& sel, bool indirect);
|
||||
const GraphicsPipeline* FinishPipeline(const GraphicsPipelineKey& key, PendingPipeline& job);
|
||||
tsl::robin_map<GraphicsPipelineKey, std::shared_ptr<PendingPipeline>> pending_graphics;
|
||||
u64 async_started = 0, async_skipped = 0, async_waited = 0; ///< statistics
|
||||
/// bbport: pipelines the driver refused to create. A key is attempted a bounded number of
|
||||
/// times and afterwards its draws are skipped: one bad shader/permutation must not exit the
|
||||
/// process and must not be retried every frame either. GPU thread only.
|
||||
static constexpr u32 MaxPipelineFailures = 32;
|
||||
tsl::robin_map<GraphicsPipelineKey, u32> graphics_failures;
|
||||
tsl::robin_map<ComputePipelineKey, u32> compute_failures;
|
||||
std::unique_ptr<PipelineCompiler> compiler; ///< last: its threads are joined first
|
||||
|
||||
struct ShaderImport;
|
||||
void SaveProfile();
|
||||
void StartShaderImport();
|
||||
#ifdef _WIN32
|
||||
static bool LaunchShaderImport(ShaderImport& state);
|
||||
#endif
|
||||
void PollShaderImport() {
|
||||
if (import_ready.load(std::memory_order_relaxed)) [[unlikely]] {
|
||||
MergeShaderImport(false);
|
||||
}
|
||||
}
|
||||
void MergeShaderImport(bool at_start);
|
||||
void MergeImportedProgram(ShaderImport& state, size_t index);
|
||||
void AdoptImportedProgram(ShaderImport& state, u64 hash, u64 perms);
|
||||
void MergeImportedKey(ShaderImport& state, std::vector<u8>&& bytes);
|
||||
void QueueImportedCompute(ShaderImport& state, Serialization::Archive& ar);
|
||||
void QueueImportedGraphics(ShaderImport& state, Serialization::Archive& ar);
|
||||
std::optional<size_t> AdoptImportedPermutation(std::vector<u8>&& meta, std::vector<u32>&& spv,
|
||||
std::vector<u8>&& input);
|
||||
std::atomic<bool> import_ready{false};
|
||||
std::unique_ptr<ShaderImport> import;
|
||||
};
|
||||
|
||||
struct PipelineCache::ShaderImport {
|
||||
#ifdef _WIN32
|
||||
std::atomic<void*> process{nullptr};
|
||||
std::wstring exe, command;
|
||||
std::atomic<bool> stopping{false};
|
||||
#else
|
||||
pid_t pid = -1;
|
||||
#endif
|
||||
std::atomic<bool> running{false};
|
||||
std::thread watcher;
|
||||
bool listed = false, done = false;
|
||||
std::vector<std::pair<u64, std::vector<std::filesystem::path>>> programs;
|
||||
std::vector<std::filesystem::path> keys;
|
||||
size_t next_program = 0, next_key = 0;
|
||||
u32 frame = ~0u;
|
||||
u32 merged = 0, skipped = 0, queued = 0, compute = 0, adopted = 0;
|
||||
std::unordered_map<u64, u64> remap;
|
||||
std::chrono::steady_clock::time_point start;
|
||||
std::mutex compute_mutex;
|
||||
std::vector<std::pair<ComputePipelineKey, std::unique_ptr<ComputePipeline>>> compute_made;
|
||||
std::atomic<u32> compute_queued{0};
|
||||
|
||||
~ShaderImport() {
|
||||
#ifdef _WIN32
|
||||
stopping = true;
|
||||
if (void* handle = process.load(); running.load() && handle) {
|
||||
TerminateProcess(static_cast<HANDLE>(handle), 1);
|
||||
}
|
||||
#else
|
||||
if (running.load()) {
|
||||
kill(pid, SIGTERM);
|
||||
}
|
||||
#endif
|
||||
if (watcher.joinable()) {
|
||||
watcher.join();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Vulkan
|
||||
@@ -0,0 +1,576 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 bbport contributors
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
// bbport render: shader recipes imported while the game runs (a bb-probe --import-shaders
|
||||
// process translating them) and merged into the cache as they come. Split out of
|
||||
// pipeline_cache.cpp (2026-10-26).
|
||||
|
||||
#include <algorithm>
|
||||
#include "shim/bb_env.h"
|
||||
#include <atomic>
|
||||
#include <bit>
|
||||
#include <chrono>
|
||||
#include <condition_variable>
|
||||
#include <csetjmp>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <deque>
|
||||
#include <filesystem>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <fstream>
|
||||
#include <thread>
|
||||
#include <unordered_set>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <signal.h>
|
||||
#include <spawn.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
extern char** environ;
|
||||
#endif
|
||||
|
||||
#include "bbport_toggles.h"
|
||||
#include "common/hash.h"
|
||||
#include "common/scope_exit.h"
|
||||
#include "common/io_file.h"
|
||||
#include "common/path_util.h"
|
||||
#include "common/serdes.h"
|
||||
#include "common/thread.h"
|
||||
#include "core/emulator_settings.h"
|
||||
#include "video_core/cache_storage.h"
|
||||
#include "video_core/renderer_vulkan/vk_pipeline_cache.h"
|
||||
#include "video_core/renderer_vulkan/vk_pipeline_serialization.h"
|
||||
#include "video_core/renderer_vulkan/vk_scheduler.h"
|
||||
#include "video_core/renderer_vulkan/vk_shader_capture.h"
|
||||
#include "video_core/renderer_vulkan/vk_shader_util.h"
|
||||
#include "shader_recompiler/backend/spirv/emit_spirv.h"
|
||||
#include "shader_recompiler/info.h"
|
||||
#include "shader_recompiler/runtime_info.h"
|
||||
#include "video_core/renderer_vulkan/vk_instance.h"
|
||||
|
||||
namespace Vulkan {
|
||||
|
||||
#ifdef _WIN32
|
||||
bool PipelineCache::LaunchShaderImport(ShaderImport& state) {
|
||||
STARTUPINFOW startup{};
|
||||
startup.cb = sizeof(startup);
|
||||
startup.dwFlags = STARTF_USESTDHANDLES;
|
||||
startup.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
|
||||
startup.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
startup.hStdError = GetStdHandle(STD_ERROR_HANDLE);
|
||||
PROCESS_INFORMATION created{};
|
||||
std::wstring command = state.command;
|
||||
if (!CreateProcessW(state.exe.c_str(), command.data(), nullptr, nullptr, TRUE,
|
||||
BELOW_NORMAL_PRIORITY_CLASS, nullptr, nullptr, &startup, &created)) {
|
||||
return false;
|
||||
}
|
||||
CloseHandle(created.hThread);
|
||||
state.process = created.hProcess;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
void PipelineCache::StartShaderImport() {
|
||||
auto& store = Storage::DataBase::Instance();
|
||||
if (!store.IsOpened()) {
|
||||
return;
|
||||
}
|
||||
std::error_code ec;
|
||||
if (std::filesystem::exists(store.Directory() / "import", ec)) {
|
||||
MergeShaderImport(true);
|
||||
import_ready.store(true, std::memory_order_relaxed);
|
||||
}
|
||||
SaveProfile();
|
||||
// bbport: the import child validates <cache>/profile.bin before it imports any recipe, so the
|
||||
// profile has to be on disk (not just queued) before CreateProcess runs.
|
||||
store.Flush();
|
||||
std::string pack_str;
|
||||
const char* pack = bb_env("BB_SHADER_RECIPES");
|
||||
if (!pack || !*pack || !std::filesystem::exists(pack, ec)) {
|
||||
if (std::filesystem::exists("shader_recipes.bin", ec)) {
|
||||
pack_str = "shader_recipes.bin";
|
||||
pack = pack_str.c_str();
|
||||
} else {
|
||||
#ifdef _WIN32
|
||||
wchar_t exe_buf[MAX_PATH];
|
||||
if (GetModuleFileNameW(nullptr, exe_buf, MAX_PATH)) {
|
||||
auto p1 = std::filesystem::path(exe_buf).parent_path() / "shader_recipes.bin";
|
||||
auto p2 = std::filesystem::path(exe_buf).parent_path().parent_path() / "shader_recipes.bin";
|
||||
if (std::filesystem::exists(p1, ec)) {
|
||||
pack_str = p1.string();
|
||||
pack = pack_str.c_str();
|
||||
} else if (std::filesystem::exists(p2, ec)) {
|
||||
pack_str = p2.string();
|
||||
pack = pack_str.c_str();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
std::string game_str;
|
||||
const char* game = bb_env("BB_SHADER_GAME_DIR");
|
||||
if (!game || !*game || !std::filesystem::exists(game, ec)) {
|
||||
if (std::filesystem::exists("../CUSA03173", ec)) {
|
||||
game_str = "../CUSA03173";
|
||||
game = game_str.c_str();
|
||||
} else if (std::filesystem::exists("CUSA03173", ec)) {
|
||||
game_str = "CUSA03173";
|
||||
game = game_str.c_str();
|
||||
}
|
||||
}
|
||||
if (!pack || !*pack || !game || !*game || !std::filesystem::exists(pack, ec) || !std::filesystem::exists(game, ec)) {
|
||||
return;
|
||||
}
|
||||
const std::string dir = store.Directory().string();
|
||||
const std::string params = fmt::format("{:x}", Shader::MotionVectors::params_address);
|
||||
const std::string positions = fmt::format("{:x}", Shader::MotionVectors::positions_address);
|
||||
|
||||
if (!import) {
|
||||
import = std::make_unique<ShaderImport>();
|
||||
} else {
|
||||
import->listed = import->done = false;
|
||||
import->programs.clear();
|
||||
import->keys.clear();
|
||||
import->next_program = import->next_key = 0;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
{
|
||||
wchar_t exe[MAX_PATH];
|
||||
std::wstring command;
|
||||
if (GetModuleFileNameW(nullptr, exe, MAX_PATH)) {
|
||||
command = L"\"" + std::wstring{exe} + L"\" --import-shaders";
|
||||
for (const std::string& arg : {dir, std::string{pack}, std::string{game}, params, positions}) {
|
||||
command += L" \"" + std::filesystem::path{arg}.wstring() + L"\"";
|
||||
}
|
||||
}
|
||||
import->exe = exe;
|
||||
import->command = command;
|
||||
if (command.empty() || !LaunchShaderImport(*import)) {
|
||||
import->done = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#else
|
||||
const char* argv[] = {"bb-probe", "--import-shaders", dir.c_str(), pack, game,
|
||||
params.c_str(), positions.c_str(), nullptr};
|
||||
std::vector<char*> env;
|
||||
for (char** e = environ; *e; ++e) {
|
||||
if (std::strncmp(*e, "LD_PRELOAD=", 11) != 0) {
|
||||
env.push_back(*e);
|
||||
}
|
||||
}
|
||||
env.push_back(nullptr);
|
||||
if (posix_spawn(&import->pid, "/proc/self/exe", nullptr, nullptr, const_cast<char**>(argv),
|
||||
env.data()) != 0) {
|
||||
import->done = true;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
import->running = true;
|
||||
g_bb_shader_import_active.store(true, std::memory_order_relaxed);
|
||||
import->watcher = std::thread([this, state = import.get()] {
|
||||
Common::SetCurrentThreadName("bb:ShaderImport");
|
||||
#ifdef _WIN32
|
||||
for (int restarts = 0;; ++restarts) {
|
||||
void* handle = state->process.load();
|
||||
WaitForSingleObject(handle, INFINITE);
|
||||
DWORD code = 0;
|
||||
GetExitCodeProcess(handle, &code);
|
||||
CloseHandle(handle);
|
||||
state->process = nullptr;
|
||||
if (code == 0 || state->stopping || restarts == 16) {
|
||||
break;
|
||||
}
|
||||
std::printf("Shader recipes: the import process ended (code %lu), started again\n",
|
||||
static_cast<unsigned long>(code));
|
||||
if (!LaunchShaderImport(*state)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
int status = 0;
|
||||
while (waitpid(state->pid, &status, 0) < 0 && errno == EINTR) {
|
||||
}
|
||||
#endif
|
||||
state->running = false;
|
||||
std::error_code ec;
|
||||
if (std::filesystem::exists(Storage::DataBase::Instance().Directory() / "import", ec)) {
|
||||
import_ready.store(true, std::memory_order_relaxed);
|
||||
} else {
|
||||
g_bb_shader_import_active.store(false, std::memory_order_relaxed);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
std::string Hex(u64 value) {
|
||||
return fmt::format("{:#018x}", value);
|
||||
}
|
||||
|
||||
std::vector<u8> ReadImportFile(const fs::path& path) {
|
||||
std::vector<u8> bytes;
|
||||
const Common::FS::IOFile file{path, Common::FS::FileAccessMode::Read};
|
||||
if (file.IsOpen()) {
|
||||
bytes.resize(file.GetSize());
|
||||
file.Read(bytes);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
void RemoveImportedProgram(const fs::path& from, const std::vector<fs::path>& files, u64 hash,
|
||||
u64 perms) {
|
||||
std::error_code ec;
|
||||
for (const auto& file : files) {
|
||||
fs::remove(file, ec);
|
||||
}
|
||||
for (u64 perm = 0; perm < perms; ++perm) {
|
||||
fs::remove(from / (Hex(HashCombine(hash, perm)) + ".meta"), ec);
|
||||
}
|
||||
}
|
||||
|
||||
bool RemapImportedKey(const std::unordered_map<u64, u64>& remap, std::vector<u8>& bytes,
|
||||
const fs::path& path) {
|
||||
bool drop = false, changed = false;
|
||||
try {
|
||||
Serialization::Archive in{std::vector<u8>{bytes}};
|
||||
Serialization::Reader reader{in};
|
||||
u32 version{}, is_compute{};
|
||||
reader.Read(version);
|
||||
reader.Read(is_compute);
|
||||
const auto map = [&](auto& value) {
|
||||
if (const auto it = remap.find(u64(value)); it != remap.end()) {
|
||||
drop |= it->second == 0;
|
||||
changed |= it->second != u64(value);
|
||||
value = static_cast<std::remove_reference_t<decltype(value)>>(it->second);
|
||||
}
|
||||
};
|
||||
Serialization::Archive out{};
|
||||
Serialization::Writer writer{out};
|
||||
writer.Write(version);
|
||||
writer.Write(is_compute);
|
||||
if (version != Vulkan::PipelineStore::PipelineKeyVersion) {
|
||||
// another build's
|
||||
} else if (is_compute) {
|
||||
ComputePipelineKey key{};
|
||||
key.Deserialize(in);
|
||||
ComputePipeline::SerializationSupport sdata{};
|
||||
sdata.Deserialize(in);
|
||||
map(key.value);
|
||||
key.Serialize(out);
|
||||
sdata.Serialize(out);
|
||||
} else {
|
||||
GraphicsPipelineKey key{};
|
||||
key.Deserialize(in);
|
||||
GraphicsPipeline::SerializationSupport sdata{};
|
||||
sdata.Deserialize(in);
|
||||
for (auto& stage : key.stage_hashes) {
|
||||
map(stage);
|
||||
}
|
||||
key.Serialize(out);
|
||||
sdata.Serialize(out);
|
||||
}
|
||||
if (changed && !drop) {
|
||||
bytes = std::move(out.TakeOff());
|
||||
const Common::FS::IOFile file{path, Common::FS::FileAccessMode::Write};
|
||||
if (file.IsOpen()) {
|
||||
file.Write(bytes);
|
||||
}
|
||||
}
|
||||
} catch (const std::exception&) {
|
||||
drop = true;
|
||||
}
|
||||
return !drop;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void PipelineCache::MergeShaderImport(bool at_start) {
|
||||
auto& store = Storage::DataBase::Instance();
|
||||
if (!import) {
|
||||
import = std::make_unique<ShaderImport>();
|
||||
}
|
||||
auto& state = *import;
|
||||
if (state.compute_queued.load(std::memory_order_relaxed) != 0) {
|
||||
std::scoped_lock lk{state.compute_mutex};
|
||||
for (auto& [key, pipeline] : state.compute_made) {
|
||||
compute_pipelines.try_emplace(key, std::move(pipeline));
|
||||
state.compute_queued.fetch_sub(1, std::memory_order_relaxed);
|
||||
}
|
||||
state.compute_made.clear();
|
||||
}
|
||||
if (!at_start && state.running.load(std::memory_order_relaxed)) {
|
||||
return;
|
||||
}
|
||||
if (state.done || !store.IsOpened()) {
|
||||
if (state.compute_queued.load(std::memory_order_relaxed) == 0) {
|
||||
import_ready.store(false, std::memory_order_relaxed);
|
||||
}
|
||||
return;
|
||||
}
|
||||
const fs::path dir = store.Directory(), from = dir / "import";
|
||||
std::error_code ec;
|
||||
if (!state.listed) {
|
||||
state.listed = true;
|
||||
state.start = std::chrono::steady_clock::now();
|
||||
std::map<u64, std::vector<fs::path>> by_program;
|
||||
for (const auto& entry : fs::directory_iterator{from, ec}) {
|
||||
const auto ext = entry.path().extension();
|
||||
if (ext == ".spv" || ext == ".in") {
|
||||
const u64 hash = std::strtoull(entry.path().stem().string().c_str(), nullptr, 16);
|
||||
by_program[hash].push_back(entry.path());
|
||||
} else if (ext == ".key") {
|
||||
state.keys.push_back(entry.path());
|
||||
}
|
||||
}
|
||||
state.programs.assign(by_program.begin(), by_program.end());
|
||||
}
|
||||
const u32 frame = BbStats::frame_number.load(std::memory_order_relaxed);
|
||||
if (!at_start && frame == state.frame) {
|
||||
return;
|
||||
}
|
||||
state.frame = frame;
|
||||
const auto deadline = std::chrono::steady_clock::now() + std::chrono::milliseconds(at_start ? 5 : 2);
|
||||
const auto in_budget = [&] {
|
||||
return std::chrono::steady_clock::now() < deadline;
|
||||
};
|
||||
while (state.next_program < state.programs.size() && in_budget()) {
|
||||
MergeImportedProgram(state, state.next_program++);
|
||||
}
|
||||
while (state.next_program == state.programs.size() && state.next_key < state.keys.size() &&
|
||||
in_budget()) {
|
||||
const fs::path& path = state.keys[state.next_key++];
|
||||
std::vector<u8> bytes;
|
||||
{
|
||||
const Common::FS::IOFile file{path, Common::FS::FileAccessMode::Read};
|
||||
if (!file.IsOpen()) {
|
||||
continue;
|
||||
}
|
||||
bytes.resize(file.GetSize());
|
||||
file.Read(bytes);
|
||||
}
|
||||
if (!state.remap.empty() && !RemapImportedKey(state.remap, bytes, path)) {
|
||||
fs::remove(path, ec);
|
||||
continue;
|
||||
}
|
||||
fs::rename(path, dir / path.filename(), ec);
|
||||
MergeImportedKey(state, std::move(bytes));
|
||||
}
|
||||
if (state.next_program == state.programs.size() && state.next_key == state.keys.size()) {
|
||||
fs::remove_all(from, ec);
|
||||
state.done = true;
|
||||
g_bb_shader_import_active.store(false, std::memory_order_relaxed);
|
||||
std::printf("Shader recipes: %u programs merged into the pipeline cache (%u translated by "
|
||||
"the game meanwhile, %u of their permutations joined theirs), %u graphics and "
|
||||
"%u compute pipelines compiling in the background (%.0f ms)\n",
|
||||
state.merged, state.skipped, state.adopted, state.queued, state.compute,
|
||||
std::chrono::duration<double, std::milli>(std::chrono::steady_clock::now() -
|
||||
state.start)
|
||||
.count());
|
||||
}
|
||||
}
|
||||
|
||||
void PipelineCache::MergeImportedProgram(ShaderImport& state, size_t index) {
|
||||
auto& store = Storage::DataBase::Instance();
|
||||
const fs::path dir = store.Directory(), from = dir / "import";
|
||||
std::error_code ec;
|
||||
const auto& [hash, files] = state.programs[index];
|
||||
u64 perms = 0;
|
||||
for (const auto& file : files) {
|
||||
perms += file.extension() == ".spv" ? 1 : 0;
|
||||
}
|
||||
if (program_cache.find(hash) != program_cache.end()) {
|
||||
AdoptImportedProgram(state, hash, perms);
|
||||
RemoveImportedProgram(from, files, hash, perms);
|
||||
++state.skipped;
|
||||
return;
|
||||
}
|
||||
if (fs::exists(dir / (Hex(hash) + "_0.spv"), ec)) {
|
||||
RemoveImportedProgram(from, files, hash, perms);
|
||||
++state.skipped;
|
||||
return;
|
||||
}
|
||||
for (const auto& file : files) {
|
||||
fs::rename(file, dir / file.filename(), ec);
|
||||
}
|
||||
const PipelineSelection saved = sel;
|
||||
for (u64 perm = 0; perm < perms; ++perm) {
|
||||
const std::string meta_name = Hex(HashCombine(hash, perm));
|
||||
fs::rename(from / (meta_name + ".meta"), dir / (meta_name + ".meta"), ec);
|
||||
std::vector<u8> meta;
|
||||
store.Load(Storage::BlobType::ShaderMeta, meta_name, meta);
|
||||
try {
|
||||
Serialization::Archive ar{std::move(meta)};
|
||||
std::unique_lock lk{programs_mutex};
|
||||
LoadPipelineStage(ar, 0);
|
||||
} catch (const std::exception&) {
|
||||
}
|
||||
}
|
||||
sel = saved;
|
||||
++state.merged;
|
||||
}
|
||||
|
||||
void PipelineCache::AdoptImportedProgram(ShaderImport& state, u64 hash, u64 perms) {
|
||||
const fs::path from = Storage::DataBase::Instance().Directory() / "import";
|
||||
std::unique_lock lk{programs_mutex};
|
||||
for (u64 perm = 0; perm < perms; ++perm) {
|
||||
const u64 perm_hash = HashCombine(hash, perm);
|
||||
const std::string name = fmt::format("{}_{}", Hex(hash), perm);
|
||||
auto meta = ReadImportFile(from / (Hex(perm_hash) + ".meta"));
|
||||
const auto bytes = ReadImportFile(from / (name + ".spv"));
|
||||
std::vector<u32> spv(bytes.size() / 4);
|
||||
std::memcpy(spv.data(), bytes.data(), spv.size() * 4);
|
||||
if (const auto idx = AdoptImportedPermutation(std::move(meta), std::move(spv),
|
||||
ReadImportFile(from / (name + ".in")))) {
|
||||
state.remap[perm_hash] = HashCombine(hash, u64(*idx));
|
||||
++state.adopted;
|
||||
} else {
|
||||
state.remap[perm_hash] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PipelineCache::MergeImportedKey(ShaderImport& state, std::vector<u8>&& bytes) {
|
||||
const PipelineSelection saved = sel;
|
||||
try {
|
||||
Serialization::Archive ar{std::move(bytes)};
|
||||
Serialization::Reader reader{ar};
|
||||
u32 version{}, is_compute{};
|
||||
reader.Read(version);
|
||||
reader.Read(is_compute);
|
||||
if (version != Vulkan::PipelineStore::PipelineKeyVersion) {
|
||||
// another build's
|
||||
} else if (is_compute) {
|
||||
QueueImportedCompute(state, ar);
|
||||
} else {
|
||||
QueueImportedGraphics(state, ar);
|
||||
}
|
||||
} catch (const std::exception&) {
|
||||
}
|
||||
sel = saved;
|
||||
}
|
||||
|
||||
void PipelineCache::QueueImportedCompute(ShaderImport& state, Serialization::Archive& ar) {
|
||||
ComputePipelineKey key{};
|
||||
key.Deserialize(ar);
|
||||
ComputePipeline::SerializationSupport sdata{};
|
||||
sdata.Deserialize(ar);
|
||||
std::vector<u8> meta;
|
||||
Storage::DataBase::Instance().Load(Storage::BlobType::ShaderMeta, Hex(key.value), meta);
|
||||
bool loaded = false;
|
||||
if (!meta.empty() && compute_pipelines.find(key) == compute_pipelines.end()) {
|
||||
Serialization::Archive meta_ar{std::move(meta)};
|
||||
std::unique_lock lk{programs_mutex};
|
||||
loaded = LoadPipelineStage(meta_ar, 0);
|
||||
}
|
||||
if (!loaded) {
|
||||
return;
|
||||
}
|
||||
const Shader::Info* info = sel.infos[0];
|
||||
const vk::ShaderModule module = sel.modules[0];
|
||||
++state.compute;
|
||||
state.compute_queued.fetch_add(1, std::memory_order_relaxed);
|
||||
GetCompiler().Submit([this, &state, key, info, module, sdata]() mutable {
|
||||
std::unique_ptr<ComputePipeline> pipeline;
|
||||
try {
|
||||
pipeline = std::make_unique<ComputePipeline>(instance, scheduler, desc_heap, profile,
|
||||
*pipeline_cache, key, *info, module,
|
||||
sdata, true);
|
||||
} catch (const std::exception&) {
|
||||
}
|
||||
std::scoped_lock lk{state.compute_mutex};
|
||||
if (pipeline) {
|
||||
state.compute_made.emplace_back(key, std::move(pipeline));
|
||||
} else {
|
||||
state.compute_queued.fetch_sub(1, std::memory_order_relaxed);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void PipelineCache::QueueImportedGraphics(ShaderImport& state, Serialization::Archive& ar) {
|
||||
std::vector<PreloadJob> jobs;
|
||||
{
|
||||
std::unique_lock lk{programs_mutex};
|
||||
LoadGraphicsPipeline(ar, jobs);
|
||||
}
|
||||
for (auto& [key, make] : jobs) {
|
||||
if (graphics_pipelines.find(key) != graphics_pipelines.end() ||
|
||||
pending_graphics.find(key) != pending_graphics.end()) {
|
||||
continue;
|
||||
}
|
||||
auto job = std::make_shared<PendingPipeline>();
|
||||
job->saved = true;
|
||||
job->make = std::move(make);
|
||||
pending_graphics.emplace(key, job);
|
||||
++state.queued;
|
||||
g_bb_background_pipelines_total.fetch_add(1, std::memory_order_relaxed);
|
||||
GetCompiler().Submit([job] {
|
||||
SCOPE_EXIT {
|
||||
g_bb_background_pipelines_done.fetch_add(1, std::memory_order_relaxed);
|
||||
};
|
||||
if (job->started.exchange(true)) {
|
||||
return;
|
||||
}
|
||||
std::unique_ptr<GraphicsPipeline> pipeline;
|
||||
try {
|
||||
pipeline = job->make();
|
||||
} catch (const std::exception&) {
|
||||
}
|
||||
std::scoped_lock lk{job->mutex};
|
||||
job->pipeline = std::move(pipeline);
|
||||
job->done = true;
|
||||
job->cv.notify_all();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<size_t> PipelineCache::AdoptImportedPermutation(std::vector<u8>&& meta,
|
||||
std::vector<u32>&& spv,
|
||||
std::vector<u8>&& input) {
|
||||
Shader::Info info{};
|
||||
Shader::StageSpecialization spec{};
|
||||
spec.info = &info;
|
||||
size_t import_idx{};
|
||||
try {
|
||||
Serialization::Archive ar{std::move(meta)};
|
||||
if (!LoadShaderMeta(ar, info, spec, import_idx)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
} catch (const std::exception&) {
|
||||
return std::nullopt;
|
||||
}
|
||||
const auto it = program_cache.find(info.pgm_hash);
|
||||
if (it == program_cache.end()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
Program& program = *it.value();
|
||||
auto& modules = program.modules;
|
||||
if (const auto found = std::ranges::find(modules, spec, &Program::Module::spec);
|
||||
found != modules.end()) {
|
||||
return size_t(std::distance(modules.begin(), found));
|
||||
}
|
||||
if (spv.size() < 5 || spv[0] != 0x07230203u) {
|
||||
return std::nullopt;
|
||||
}
|
||||
vk::ShaderModule module = CompileSPV(spv, instance.GetDevice());
|
||||
if (!module) {
|
||||
return std::nullopt;
|
||||
}
|
||||
const size_t idx = modules.size();
|
||||
RegisterShaderMeta(info, spec, HashCombine(info.pgm_hash, idx), idx);
|
||||
RegisterShaderBinary(std::move(spv), info.pgm_hash, idx);
|
||||
if (!input.empty()) {
|
||||
RegisterShaderInput(std::move(input), info.pgm_hash, idx);
|
||||
}
|
||||
spec.info = &program.info;
|
||||
program.InsertPermut(module, std::move(spec), idx);
|
||||
return idx;
|
||||
}
|
||||
|
||||
} // namespace Vulkan
|
||||
@@ -2,19 +2,36 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "common/serdes.h"
|
||||
#include "common/scope_exit.h"
|
||||
#include "common/thread.h"
|
||||
#include "core/emulator_settings.h"
|
||||
#include "shader_recompiler/frontend/fetch_shader.h"
|
||||
#include "shader_recompiler/info.h"
|
||||
#include "video_core/cache_storage.h"
|
||||
#include "video_core/renderer_vulkan/vk_instance.h"
|
||||
#include "video_core/renderer_vulkan/vk_pipeline_cache.h"
|
||||
#include "video_core/renderer_vulkan/vk_shader_util.h"
|
||||
#include <chrono>
|
||||
#include <filesystem>
|
||||
#include <future>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
#include "common/hash.h"
|
||||
#include "video_core/renderer_vulkan/vk_shader_util.h"
|
||||
#include "video_core/renderer_vulkan/vk_pipeline_serialization.h"
|
||||
|
||||
namespace Serialization {
|
||||
/* You should increment versions below once corresponding serialization scheme is changed. */
|
||||
static constexpr u32 ShaderBinaryVersion = 7u; // bbport: interpolated integer fix (Pascal)
|
||||
static constexpr u32 ShaderMetaVersion = 7u; // bbport: ImageResource::needs_native
|
||||
static constexpr u32 PipelineKeyVersion = 5u; // bbport: Info layout (ImageResource::needs_native)
|
||||
/* bbport: the versions live in vk_pipeline_serialization.h (PipelineStore) so the runtime, the
|
||||
* shader-rebuild tool and the recipe importer cannot drift apart. When they did, the rebuild tool
|
||||
* rewrote profile.bin to its own version after every start and WarmUp wiped the cache next time. */
|
||||
static_assert(Vulkan::PipelineStore::ShaderBinaryVersion == 25u,
|
||||
"modernized recompiler & fast shader math (Phase 2)");
|
||||
static_assert(Vulkan::PipelineStore::ShaderMetaVersion == 8u,
|
||||
"the object motion buffer addresses");
|
||||
static_assert(Vulkan::PipelineStore::PipelineKeyVersion == 5u,
|
||||
"Info layout (ImageResource::needs_native)");
|
||||
static constexpr u32 ShaderBinaryVersion = Vulkan::PipelineStore::ShaderBinaryVersion;
|
||||
static constexpr u32 ShaderMetaVersion = Vulkan::PipelineStore::ShaderMetaVersion;
|
||||
static constexpr u32 PipelineKeyVersion = Vulkan::PipelineStore::PipelineKeyVersion;
|
||||
} // namespace Serialization
|
||||
|
||||
namespace Vulkan {
|
||||
@@ -93,6 +110,15 @@ void RegisterShaderBinary(std::vector<u32>&& spv, u64 pgm_hash, size_t perm_idx)
|
||||
std::move(spv));
|
||||
}
|
||||
|
||||
void RegisterShaderInput(std::vector<u8>&& input, u64 pgm_hash, size_t perm_idx) {
|
||||
if (!Storage::DataBase::Instance().IsOpened()) {
|
||||
return;
|
||||
}
|
||||
Storage::DataBase::Instance().Save(Storage::BlobType::ShaderInput,
|
||||
fmt::format("{:#018x}_{}", pgm_hash, perm_idx),
|
||||
std::move(input));
|
||||
}
|
||||
|
||||
bool LoadShaderMeta(Serialization::Archive& ar, Shader::Info& info,
|
||||
std::optional<Shader::Gcn::FetchShaderData>& fetch_shader_data,
|
||||
Shader::StageSpecialization& spec, size_t& perm_idx) {
|
||||
@@ -127,6 +153,12 @@ bool LoadShaderMeta(Serialization::Archive& ar, Shader::Info& info,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LoadShaderMeta(Serialization::Archive& ar, Shader::Info& info,
|
||||
Shader::StageSpecialization& spec, size_t& perm_idx) {
|
||||
std::optional<Shader::Gcn::FetchShaderData> unused_fetch{};
|
||||
return LoadShaderMeta(ar, info, unused_fetch, spec, perm_idx);
|
||||
}
|
||||
|
||||
void ComputePipelineKey::Serialize(Serialization::Archive& ar) const {
|
||||
Serialization::Writer key{ar};
|
||||
key.Write(value);
|
||||
@@ -168,11 +200,22 @@ bool PipelineCache::LoadComputePipeline(Serialization::Archive& ar) {
|
||||
}
|
||||
|
||||
const auto [it, is_new] = compute_pipelines.try_emplace(compute_key);
|
||||
ASSERT(is_new);
|
||||
if (!is_new) {
|
||||
return false;
|
||||
}
|
||||
|
||||
it.value() =
|
||||
std::make_unique<ComputePipeline>(instance, scheduler, desc_heap, profile, *pipeline_cache,
|
||||
compute_key, *sel.infos[0], sel.modules[0], sdata, true);
|
||||
try {
|
||||
it.value() = std::make_unique<ComputePipeline>(
|
||||
instance, scheduler, desc_heap, profile, *pipeline_cache, compute_key, *sel.infos[0],
|
||||
sel.modules[0], sdata, true);
|
||||
} catch (const std::exception& e) {
|
||||
/* bbport: a cached pipeline the driver refuses must not abort startup (the constructor
|
||||
* now throws instead of asserting). Drop the entry; the shader compiles on demand. */
|
||||
compute_pipelines.erase(compute_key);
|
||||
LOG_WARNING(Render_Vulkan, "Cached compute pipeline {:#x} failed to create: {}",
|
||||
compute_key.value, e.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
sel.infos.fill(nullptr);
|
||||
sel.modules.fill(nullptr);
|
||||
@@ -216,6 +259,51 @@ bool GraphicsPipeline::SerializationSupport::Deserialize(Serialization::Archive&
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PipelineCache::LoadGraphicsPipeline(Serialization::Archive& ar, std::vector<PreloadJob>& jobs) {
|
||||
sel.infos.fill(nullptr);
|
||||
sel.modules.fill(nullptr);
|
||||
sel.fetch_shader.reset();
|
||||
sel.graphics_key.Deserialize(ar);
|
||||
|
||||
GraphicsPipeline::SerializationSupport sdata{};
|
||||
sdata.Deserialize(ar);
|
||||
|
||||
for (int stage_idx = 0; stage_idx < MaxShaderStages; ++stage_idx) {
|
||||
const auto& hash = sel.graphics_key.stage_hashes[stage_idx];
|
||||
if (!hash) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::vector<u8> meta_blob;
|
||||
Storage::DataBase::Instance().Load(Storage::BlobType::ShaderMeta,
|
||||
fmt::format("{:#018x}", hash), meta_blob);
|
||||
if (meta_blob.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Serialization::Archive meta_ar{std::move(meta_blob)};
|
||||
|
||||
if (!LoadPipelineStage(meta_ar, stage_idx)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
jobs.emplace_back(sel.graphics_key,
|
||||
[this, key = sel.graphics_key, infos = sel.infos,
|
||||
runtime_infos = sel.runtime_infos, fetch = sel.fetch_shader,
|
||||
modules = sel.modules, sdata = std::move(sdata)]() mutable {
|
||||
return std::make_unique<GraphicsPipeline>(
|
||||
instance, scheduler, desc_heap, profile, key, *pipeline_cache,
|
||||
infos, runtime_infos, fetch, modules, sdata, true);
|
||||
});
|
||||
|
||||
sel.infos.fill(nullptr);
|
||||
sel.modules.fill(nullptr);
|
||||
sel.fetch_shader.reset();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PipelineCache::LoadGraphicsPipeline(Serialization::Archive& ar) {
|
||||
sel.graphics_key.Deserialize(ar);
|
||||
|
||||
@@ -243,11 +331,21 @@ bool PipelineCache::LoadGraphicsPipeline(Serialization::Archive& ar) {
|
||||
}
|
||||
|
||||
const auto [it, is_new] = graphics_pipelines.try_emplace(sel.graphics_key);
|
||||
ASSERT(is_new);
|
||||
if (!is_new) {
|
||||
return false;
|
||||
}
|
||||
|
||||
it.value() = std::make_unique<GraphicsPipeline>(
|
||||
instance, scheduler, desc_heap, profile, sel.graphics_key, *pipeline_cache, sel.infos,
|
||||
sel.runtime_infos, sel.fetch_shader, sel.modules, sdata, true);
|
||||
try {
|
||||
it.value() = std::make_unique<GraphicsPipeline>(
|
||||
instance, scheduler, desc_heap, profile, sel.graphics_key, *pipeline_cache, sel.infos,
|
||||
sel.runtime_infos, sel.fetch_shader, sel.modules, sdata, true);
|
||||
} catch (const std::exception& e) {
|
||||
/* bbport: a cached pipeline the driver refuses must not abort startup (the constructor
|
||||
* now throws instead of asserting). Drop the entry; the shader compiles on demand. */
|
||||
graphics_pipelines.erase(sel.graphics_key);
|
||||
LOG_WARNING(Render_Vulkan, "Cached graphics pipeline failed to create: {}", e.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
sel.infos.fill(nullptr);
|
||||
sel.modules.fill(nullptr);
|
||||
@@ -265,6 +363,22 @@ bool PipelineCache::LoadPipelineStage(Serialization::Archive& ar, size_t stage)
|
||||
return false;
|
||||
}
|
||||
|
||||
// bbport: the permutation index is only the name of the module in the store, not the
|
||||
// shader's identity. Different sessions appended permutations in the order the game first
|
||||
// used them, so the same specialization can be stored under another index. An equal
|
||||
// specialization is the same SPIR-V, so reuse the module already in memory and keep the
|
||||
// pipeline; refusing it dropped hundreds of otherwise valid preloads every launch.
|
||||
auto it_pgm = program_cache.find(program->info.pgm_hash);
|
||||
if (it_pgm != program_cache.end()) {
|
||||
Program* live = it_pgm.value().get();
|
||||
const auto it = std::ranges::find(live->modules, spec, &Program::Module::spec);
|
||||
if (it != live->modules.end()) {
|
||||
sel.infos[stage] = &live->info;
|
||||
sel.modules[stage] = it->module;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<u32> spv{};
|
||||
Storage::DataBase::Instance().Load(Storage::BlobType::ShaderBinary,
|
||||
fmt::format("{:#018x}_{}", program->info.pgm_hash, perm_idx),
|
||||
@@ -275,145 +389,593 @@ bool PipelineCache::LoadPipelineStage(Serialization::Archive& ar, size_t stage)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Permutation hash depends on shader variation index. To prevent collisions, we need insert it
|
||||
// at the exact position rather than append
|
||||
|
||||
vk::ShaderModule module{};
|
||||
|
||||
auto [it_pgm, new_program] = program_cache.try_emplace(program->info.pgm_hash);
|
||||
if (new_program) {
|
||||
module = CompileSPV(spv, instance.GetDevice());
|
||||
if (!module) {
|
||||
return false;
|
||||
}
|
||||
it_pgm.value() = std::move(program);
|
||||
} else {
|
||||
const auto& it = std::ranges::find(it_pgm.value()->modules, spec, &Program::Module::spec);
|
||||
if (it != it_pgm.value()->modules.end()) {
|
||||
// A matching permutation is valid only at its original index. A different index means
|
||||
// the store holds entries from more than one cache generation, so this pipeline is
|
||||
// left to compile at runtime.
|
||||
const auto idx = std::distance(it_pgm.value()->modules.begin(), it);
|
||||
if (perm_idx != idx) {
|
||||
LOG_WARNING(Render_Vulkan,
|
||||
"Cached permutation {} of {}_{:x} conflicts with index {}, skipping "
|
||||
"preload",
|
||||
perm_idx, program->info.hw_stage, program->info.pgm_hash, idx);
|
||||
return false;
|
||||
}
|
||||
module = it->module;
|
||||
} else {
|
||||
module = CompileSPV(spv, instance.GetDevice());
|
||||
if (!module) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
vk::ShaderModule module = CompileSPV(spv, instance.GetDevice());
|
||||
if (!module) {
|
||||
return false;
|
||||
}
|
||||
it_pgm.value()->InsertPermut(module, std::move(spec), perm_idx);
|
||||
|
||||
sel.infos[stage] = &it_pgm.value()->info;
|
||||
if (it_pgm == program_cache.end()) {
|
||||
Program* live = program.get();
|
||||
live->InsertPermut(module, std::move(spec), perm_idx);
|
||||
program_cache.emplace(live->info.pgm_hash, std::move(program));
|
||||
sel.infos[stage] = &live->info;
|
||||
} else {
|
||||
Program* live = it_pgm.value().get();
|
||||
// `spec` was built against the temporary program; point it at the live one before it is
|
||||
// stored (the previous code left a dangling Shader::Info in the module list).
|
||||
spec.info = &live->info;
|
||||
if (perm_idx < live->modules.size() && live->modules[perm_idx].spec.Valid()) {
|
||||
// The stored index is occupied by a different specialization. Appending keeps the
|
||||
// modules referenced by pipelines loaded earlier in this warm-up valid.
|
||||
live->AddPermut(module, std::move(spec));
|
||||
} else {
|
||||
live->InsertPermut(module, std::move(spec), perm_idx);
|
||||
}
|
||||
sel.infos[stage] = &live->info;
|
||||
}
|
||||
sel.modules[stage] = module;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PipelineCache::SaveProfile() {
|
||||
constexpr u32 CacheMagic = 0x42425043u;
|
||||
u32 hdr[4] = {CacheMagic, Serialization::ShaderBinaryVersion, Serialization::ShaderMetaVersion, Serialization::PipelineKeyVersion};
|
||||
std::vector<u8> data(sizeof(hdr) + sizeof(profile));
|
||||
std::memcpy(data.data(), hdr, sizeof(hdr));
|
||||
std::memcpy(data.data() + sizeof(hdr), &profile, sizeof(profile));
|
||||
Storage::DataBase::Instance().Save(Storage::BlobType::ShaderProfile, "profile", std::move(data));
|
||||
}
|
||||
|
||||
namespace {
|
||||
/* bbport: metas stamped with a version this build cannot load (LoadShaderMeta rejects both a
|
||||
* different meta and binary version) are dead weight. They are left behind by builds/tools that
|
||||
* wrote an older constant; the keys that referenced them are dropped on the first warm-up that
|
||||
* sees them. Delete the metas and their companion .spv/.in blobs so the cache converges instead
|
||||
* of keeping dead copies and making "N stale metas" look like an active writer. A companion is
|
||||
* named <pgm_hash>_<perm_idx>, and its meta's file name is exactly HashCombine(pgm_hash,
|
||||
* perm_idx), so it is orphaned precisely when that hash is not one of the live metas. */
|
||||
void PurgeStaleShaderMetas() {
|
||||
auto& db = Storage::DataBase::Instance();
|
||||
if (!db.IsOpened() || EmulatorSettings.IsPipelineCacheArchived()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::unordered_set<u64> live_metas;
|
||||
const u32 removed = db.ForEachBlob(
|
||||
Storage::BlobType::ShaderMeta, [&](std::vector<u8>&& data) {
|
||||
if (data.size() < 16) {
|
||||
return false;
|
||||
}
|
||||
u32 meta_version{};
|
||||
u32 binary_version{};
|
||||
u64 name{};
|
||||
std::memcpy(&meta_version, data.data() + 0, sizeof(meta_version));
|
||||
std::memcpy(&binary_version, data.data() + 4, sizeof(binary_version));
|
||||
std::memcpy(&name, data.data() + 8, sizeof(name));
|
||||
if (meta_version != Serialization::ShaderMetaVersion ||
|
||||
binary_version != Serialization::ShaderBinaryVersion) {
|
||||
return false;
|
||||
}
|
||||
live_metas.insert(name);
|
||||
return true;
|
||||
});
|
||||
if (removed == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
u32 companions{};
|
||||
std::error_code ec;
|
||||
for (const auto& entry : std::filesystem::directory_iterator{db.Directory(), ec}) {
|
||||
if (!entry.is_regular_file(ec)) {
|
||||
continue;
|
||||
}
|
||||
const auto& path = entry.path();
|
||||
const auto ext = path.extension().string();
|
||||
if (ext != ".spv" && ext != ".in") {
|
||||
continue;
|
||||
}
|
||||
const auto stem = path.stem().string();
|
||||
const auto sep = stem.rfind('_');
|
||||
if (sep == std::string::npos) {
|
||||
continue;
|
||||
}
|
||||
u64 pgm_hash{};
|
||||
u64 perm_idx{};
|
||||
try {
|
||||
pgm_hash = std::stoull(stem.substr(0, sep), nullptr, 16);
|
||||
perm_idx = std::stoull(stem.substr(sep + 1), nullptr, 10);
|
||||
} catch (const std::exception&) {
|
||||
continue;
|
||||
}
|
||||
if (!live_metas.contains(HashCombine(pgm_hash, perm_idx))) {
|
||||
companions += std::filesystem::remove(path, ec) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
LOG_WARNING(Render,
|
||||
"Removed {} shader metas stamped with an unsupported version and {} orphaned "
|
||||
"shader blobs; every meta left is version {}/{}",
|
||||
removed, companions, Serialization::ShaderMetaVersion,
|
||||
Serialization::ShaderBinaryVersion);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void PipelineCache::WarmUp() {
|
||||
if (!EmulatorSettings.IsPipelineCacheEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto warmup_start = std::chrono::steady_clock::now();
|
||||
|
||||
Storage::DataBase::Instance().Open();
|
||||
|
||||
// Check if cache is compatible
|
||||
std::vector<u8> profile_data{};
|
||||
Storage::DataBase::Instance().Load(Storage::BlobType::ShaderProfile, "profile", profile_data);
|
||||
constexpr u32 CacheMagic = 0x42425043u;
|
||||
const auto save_profile = [&]() {
|
||||
u32 hdr[4] = {CacheMagic, Serialization::ShaderBinaryVersion, Serialization::ShaderMetaVersion, Serialization::PipelineKeyVersion};
|
||||
std::vector<u8> data(sizeof(hdr) + sizeof(profile));
|
||||
std::memcpy(data.data(), hdr, sizeof(hdr));
|
||||
std::memcpy(data.data() + sizeof(hdr), &profile, sizeof(profile));
|
||||
Storage::DataBase::Instance().Save(Storage::BlobType::ShaderProfile, "profile", std::move(data));
|
||||
};
|
||||
if (profile_data.empty()) {
|
||||
Storage::DataBase::Instance().FinishPreload();
|
||||
|
||||
profile_data.resize(sizeof(profile));
|
||||
std::memcpy(profile_data.data(), &profile, sizeof(profile));
|
||||
Storage::DataBase::Instance().Save(Storage::BlobType::ShaderProfile, "profile",
|
||||
std::move(profile_data));
|
||||
SaveProfile();
|
||||
return;
|
||||
}
|
||||
if (profile_data.size() != sizeof(Shader::Profile)) {
|
||||
LOG_WARNING(Render, "Pipeline cache profile has unexpected size ({} != {})",
|
||||
profile_data.size(), sizeof(Shader::Profile));
|
||||
}
|
||||
Shader::Profile cached_profile{};
|
||||
if (profile_data.size() == sizeof(Shader::Profile)) {
|
||||
bool valid = false;
|
||||
bool have_cached = false;
|
||||
bool stale_version_header = false;
|
||||
/* bbport: older builds of the shader-rebuild tool stamped profile.bin with their own copy of
|
||||
* the binary version (24) while the runtime wrote 25. The profile contents and the meta/key
|
||||
* versions are still current in that case, and every individual .meta is version-checked by
|
||||
* LoadShaderMeta, so the header can be updated in place instead of deleting a valid cache.
|
||||
* This stops the launcher<->WarmUp version flip from wiping all shaders on every launch. */
|
||||
constexpr u32 StaleToolBinaryVersion = 24u;
|
||||
if (profile_data.size() == 16 + sizeof(Shader::Profile)) {
|
||||
u32 hdr[4];
|
||||
std::memcpy(hdr, profile_data.data(), sizeof(hdr));
|
||||
if (hdr[0] == CacheMagic &&
|
||||
(hdr[1] == Serialization::ShaderBinaryVersion ||
|
||||
hdr[1] == StaleToolBinaryVersion) &&
|
||||
hdr[2] == Serialization::ShaderMetaVersion &&
|
||||
hdr[3] == Serialization::PipelineKeyVersion) {
|
||||
std::memcpy(&cached_profile, profile_data.data() + 16, sizeof(cached_profile));
|
||||
have_cached = true;
|
||||
valid = (cached_profile == profile);
|
||||
stale_version_header = valid && hdr[1] != Serialization::ShaderBinaryVersion;
|
||||
}
|
||||
} else if (profile_data.size() == sizeof(Shader::Profile)) {
|
||||
std::memcpy(&cached_profile, profile_data.data(), sizeof(cached_profile));
|
||||
have_cached = true;
|
||||
valid = (cached_profile == profile);
|
||||
}
|
||||
if (profile_data.size() != sizeof(Shader::Profile) || cached_profile != profile) {
|
||||
// bbport: upstream closed the cache for the session here, so it was never rewritten
|
||||
// and every later session compiled every shader again (stutters on each new area).
|
||||
// Start a fresh cache for this build and GPU instead.
|
||||
if (!valid) {
|
||||
/* bbport: name the fields that differ. A wipe leaves no trace otherwise, so a cache that
|
||||
* is rebuilt on every launch cannot be told apart from one that is merely cold. */
|
||||
if (have_cached) {
|
||||
const auto* cached = reinterpret_cast<const u8*>(&cached_profile);
|
||||
const auto* current = reinterpret_cast<const u8*>(&profile);
|
||||
std::string diff;
|
||||
for (size_t i = 0; i < sizeof(Shader::Profile); ++i) {
|
||||
if (cached[i] != current[i]) {
|
||||
if (!diff.empty()) {
|
||||
diff += ", ";
|
||||
}
|
||||
diff += fmt::format("[{}] {:#04x} -> {:#04x}", i, cached[i], current[i]);
|
||||
}
|
||||
}
|
||||
LOG_WARNING(Render, "Cached shader profile differs from this system: {}", diff);
|
||||
} else {
|
||||
LOG_WARNING(Render,
|
||||
"Cached shader profile is unreadable ({} bytes, versions or magic differ)",
|
||||
profile_data.size());
|
||||
}
|
||||
LOG_WARNING(Render, "Pipeline cache isn't compatible with current system: rebuilding it");
|
||||
Storage::DataBase::Instance().Clear();
|
||||
Storage::DataBase::Instance().FinishPreload();
|
||||
profile_data.resize(sizeof(profile));
|
||||
std::memcpy(profile_data.data(), &profile, sizeof(profile));
|
||||
Storage::DataBase::Instance().Save(Storage::BlobType::ShaderProfile, "profile",
|
||||
std::move(profile_data));
|
||||
SaveProfile();
|
||||
return;
|
||||
}
|
||||
if (stale_version_header) {
|
||||
LOG_INFO(Render,
|
||||
"Cached shader profile matches this system; updating its version header to {} "
|
||||
"without rebuilding the cache",
|
||||
Serialization::ShaderBinaryVersion);
|
||||
save_profile();
|
||||
}
|
||||
|
||||
const char* env_warmup = std::getenv("BB_WARMUP_ASYNC");
|
||||
const bool warmup_async = !env_warmup || (std::strcmp(env_warmup, "0") != 0);
|
||||
|
||||
u32 num_pipelines{};
|
||||
u32 num_total_pipelines{};
|
||||
|
||||
u32 num_removed{};
|
||||
u32 num_reused_permutations{};
|
||||
|
||||
try {
|
||||
num_removed = Storage::DataBase::Instance().ForEachBlob(
|
||||
Storage::BlobType::PipelineKey, [&](std::vector<u8>&& data) {
|
||||
++num_total_pipelines;
|
||||
if (!warmup_async) {
|
||||
try {
|
||||
num_removed = Storage::DataBase::Instance().ForEachBlob(
|
||||
Storage::BlobType::PipelineKey, [&](std::vector<u8>&& data) {
|
||||
++num_total_pipelines;
|
||||
|
||||
Serialization::Archive ar{std::move(data)};
|
||||
Serialization::Reader pldata{ar};
|
||||
Serialization::Archive ar{std::move(data)};
|
||||
Serialization::Reader pldata{ar};
|
||||
|
||||
u32 version{};
|
||||
pldata.Read(version);
|
||||
if (version != Serialization::PipelineKeyVersion) {
|
||||
return false;
|
||||
u32 version{};
|
||||
pldata.Read(version);
|
||||
if (version != Serialization::PipelineKeyVersion) {
|
||||
return false;
|
||||
}
|
||||
|
||||
u32 is_compute{};
|
||||
pldata.Read(is_compute);
|
||||
|
||||
bool result{};
|
||||
if (is_compute) {
|
||||
result = LoadComputePipeline(ar);
|
||||
} else {
|
||||
result = LoadGraphicsPipeline(ar);
|
||||
}
|
||||
|
||||
if (result) {
|
||||
++num_pipelines;
|
||||
}
|
||||
return result;
|
||||
});
|
||||
} catch (const Serialization::CorruptData& e) {
|
||||
LOG_ERROR(Render, "Corrupted pipeline cache detected during WarmUp: {}. Clearing cache.",
|
||||
e.what());
|
||||
Storage::DataBase::Instance().Clear();
|
||||
Storage::DataBase::Instance().FinishPreload();
|
||||
profile_data.resize(sizeof(profile));
|
||||
std::memcpy(profile_data.data(), &profile, sizeof(profile));
|
||||
Storage::DataBase::Instance().Save(Storage::BlobType::ShaderProfile, "profile",
|
||||
std::move(profile_data));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
struct StagedPermut {
|
||||
Program* program = nullptr;
|
||||
size_t perm_idx = 0;
|
||||
Shader::StageSpecialization spec;
|
||||
std::shared_future<vk::ShaderModule> future;
|
||||
};
|
||||
|
||||
struct WarmUpGraphicsEntry {
|
||||
GraphicsPipelineKey key;
|
||||
GraphicsPipeline::SerializationSupport sdata;
|
||||
std::array<const Shader::Info*, MaxShaderStages> infos{};
|
||||
std::array<std::shared_future<vk::ShaderModule>, MaxShaderStages> futures{};
|
||||
std::optional<Shader::Gcn::FetchShaderData> fetch_shader;
|
||||
};
|
||||
|
||||
struct WarmUpComputeEntry {
|
||||
ComputePipelineKey key;
|
||||
ComputePipeline::SerializationSupport sdata;
|
||||
const Shader::Info* info = nullptr;
|
||||
std::shared_future<vk::ShaderModule> future;
|
||||
};
|
||||
|
||||
std::vector<WarmUpGraphicsEntry> staged_graphics;
|
||||
std::vector<WarmUpComputeEntry> staged_compute;
|
||||
std::vector<StagedPermut> staged_permutations;
|
||||
tsl::robin_map<u64, std::shared_future<vk::ShaderModule>> spv_futures;
|
||||
|
||||
auto stage_shader = [&](Serialization::Archive& ar,
|
||||
std::optional<Shader::Gcn::FetchShaderData>& out_fetch_shader,
|
||||
const Shader::Info*& out_info,
|
||||
std::shared_future<vk::ShaderModule>& out_future) -> bool {
|
||||
auto program = std::make_unique<Program>();
|
||||
Shader::StageSpecialization spec{};
|
||||
spec.info = &program->info;
|
||||
size_t perm_idx{};
|
||||
if (!LoadShaderMeta(ar, program->info, out_fetch_shader, spec, perm_idx)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<u32> spv{};
|
||||
Storage::DataBase::Instance().Load(
|
||||
Storage::BlobType::ShaderBinary,
|
||||
fmt::format("{:#018x}_{}", program->info.pgm_hash, perm_idx), spv);
|
||||
if (spv.empty() || spv[0] != 0x07230203u) {
|
||||
LOG_WARNING(Render_Vulkan, "Cached shader binary {}_{:x}_{} is missing or invalid SPIR-V",
|
||||
program->info.hw_stage, program->info.pgm_hash, perm_idx);
|
||||
return false;
|
||||
}
|
||||
|
||||
const u64 perm_hash = HashCombine(program->info.pgm_hash, perm_idx);
|
||||
Program* program_ptr = nullptr;
|
||||
{
|
||||
std::unique_lock lk{programs_mutex};
|
||||
auto [it_pgm, new_program] = program_cache.try_emplace(program->info.pgm_hash);
|
||||
if (new_program) {
|
||||
it_pgm.value() = std::move(program);
|
||||
}
|
||||
program_ptr = it_pgm.value().get();
|
||||
}
|
||||
|
||||
u32 is_compute{};
|
||||
pldata.Read(is_compute);
|
||||
out_info = &program_ptr->info;
|
||||
spec.info = &program_ptr->info;
|
||||
|
||||
bool result{};
|
||||
if (is_compute) {
|
||||
result = LoadComputePipeline(ar);
|
||||
} else {
|
||||
result = LoadGraphicsPipeline(ar);
|
||||
// A permutation index is only the name of the module in the store; the specialization
|
||||
// is the shader's identity. Earlier sessions appended permutations in a different
|
||||
// order, so an equal specialization can be staged under another index. Reuse it and
|
||||
// keep the pipeline; this used to discard several hundred preloads per launch.
|
||||
auto it = std::ranges::find_if(staged_permutations, [&](const StagedPermut& p) {
|
||||
return p.program == program_ptr && p.spec == spec;
|
||||
});
|
||||
if (it != staged_permutations.end()) {
|
||||
if (it->perm_idx != perm_idx) {
|
||||
++num_reused_permutations;
|
||||
}
|
||||
out_future = it->future;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (result) {
|
||||
auto conflict_it = std::ranges::find_if(staged_permutations, [&](const StagedPermut& p) {
|
||||
return p.program == program_ptr && p.perm_idx == perm_idx;
|
||||
});
|
||||
if (conflict_it != staged_permutations.end()) {
|
||||
LOG_WARNING(Render_Vulkan,
|
||||
"Cached permutation index {} of {}_{:x} already used with different spec, skipping preload",
|
||||
perm_idx, program_ptr->info.hw_stage, program_ptr->info.pgm_hash);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto task = std::make_shared<std::packaged_task<vk::ShaderModule()>>(
|
||||
[device = instance.GetDevice(), spv_data = std::move(spv)]() {
|
||||
return CompileSPV(spv_data, device);
|
||||
});
|
||||
out_future = task->get_future().share();
|
||||
spv_futures.emplace(perm_hash, out_future);
|
||||
GetCompiler().Submit([task]() { (*task)(); });
|
||||
staged_permutations.push_back(StagedPermut{
|
||||
.program = program_ptr,
|
||||
.perm_idx = perm_idx,
|
||||
.spec = std::move(spec),
|
||||
.future = out_future,
|
||||
});
|
||||
return true;
|
||||
};
|
||||
|
||||
try {
|
||||
num_removed = Storage::DataBase::Instance().ForEachBlob(
|
||||
Storage::BlobType::PipelineKey, [&](std::vector<u8>&& data) {
|
||||
++num_total_pipelines;
|
||||
|
||||
Serialization::Archive ar{std::move(data)};
|
||||
Serialization::Reader pldata{ar};
|
||||
|
||||
u32 version{};
|
||||
pldata.Read(version);
|
||||
if (version != Serialization::PipelineKeyVersion) {
|
||||
return false;
|
||||
}
|
||||
|
||||
u32 is_compute{};
|
||||
pldata.Read(is_compute);
|
||||
|
||||
if (is_compute) {
|
||||
ComputePipelineKey key{};
|
||||
key.Deserialize(ar);
|
||||
ComputePipeline::SerializationSupport sdata{};
|
||||
sdata.Deserialize(ar);
|
||||
|
||||
std::vector<u8> meta_blob;
|
||||
Storage::DataBase::Instance().Load(
|
||||
Storage::BlobType::ShaderMeta,
|
||||
fmt::format("{:#018x}", key.value), meta_blob);
|
||||
if (meta_blob.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Serialization::Archive meta_ar{std::move(meta_blob)};
|
||||
std::optional<Shader::Gcn::FetchShaderData> fetch_dummy;
|
||||
const Shader::Info* c_info = nullptr;
|
||||
std::shared_future<vk::ShaderModule> c_future;
|
||||
if (!stage_shader(meta_ar, fetch_dummy, c_info, c_future)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
staged_compute.push_back(WarmUpComputeEntry{
|
||||
.key = key,
|
||||
.sdata = sdata,
|
||||
.info = c_info,
|
||||
.future = c_future,
|
||||
});
|
||||
return true;
|
||||
} else {
|
||||
GraphicsPipelineKey key{};
|
||||
key.Deserialize(ar);
|
||||
GraphicsPipeline::SerializationSupport sdata{};
|
||||
sdata.Deserialize(ar);
|
||||
|
||||
WarmUpGraphicsEntry entry{};
|
||||
entry.key = key;
|
||||
entry.sdata = sdata;
|
||||
|
||||
for (int stage_idx = 0; stage_idx < MaxShaderStages; ++stage_idx) {
|
||||
const auto& hash = key.stage_hashes[stage_idx];
|
||||
if (!hash) {
|
||||
continue;
|
||||
}
|
||||
std::vector<u8> meta_blob;
|
||||
Storage::DataBase::Instance().Load(
|
||||
Storage::BlobType::ShaderMeta,
|
||||
fmt::format("{:#018x}", hash), meta_blob);
|
||||
if (meta_blob.empty()) {
|
||||
return false;
|
||||
}
|
||||
Serialization::Archive meta_ar{std::move(meta_blob)};
|
||||
if (!stage_shader(meta_ar, entry.fetch_shader, entry.infos[stage_idx],
|
||||
entry.futures[stage_idx])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
staged_graphics.push_back(std::move(entry));
|
||||
return true;
|
||||
}
|
||||
});
|
||||
} catch (const Serialization::CorruptData& e) {
|
||||
LOG_ERROR(Render, "Corrupted pipeline cache detected during WarmUp: {}. Clearing cache.",
|
||||
e.what());
|
||||
Storage::DataBase::Instance().Clear();
|
||||
Storage::DataBase::Instance().FinishPreload();
|
||||
profile_data.resize(sizeof(profile));
|
||||
std::memcpy(profile_data.data(), &profile, sizeof(profile));
|
||||
Storage::DataBase::Instance().Save(Storage::BlobType::ShaderProfile, "profile",
|
||||
std::move(profile_data));
|
||||
return;
|
||||
}
|
||||
|
||||
// Between passes: wait for all compilation futures to complete and populate program permutations
|
||||
for (auto& item : staged_permutations) {
|
||||
vk::ShaderModule mod = item.future.get();
|
||||
if (mod) {
|
||||
std::unique_lock lk{programs_mutex};
|
||||
item.program->InsertPermut(mod, std::move(item.spec), item.perm_idx);
|
||||
}
|
||||
}
|
||||
|
||||
// Pass 2: synchronous pipeline instantiation on startup thread
|
||||
for (auto& entry : staged_compute) {
|
||||
vk::ShaderModule mod = entry.future.get();
|
||||
if (!mod) {
|
||||
continue;
|
||||
}
|
||||
const auto [it, is_new] = compute_pipelines.try_emplace(entry.key);
|
||||
if (is_new) {
|
||||
try {
|
||||
it.value() = std::make_unique<ComputePipeline>(
|
||||
instance, scheduler, desc_heap, profile, *pipeline_cache, entry.key,
|
||||
*entry.info, mod, entry.sdata, true);
|
||||
} catch (const std::exception& e) {
|
||||
/* bbport: one driver-refused cached pipeline is skipped, not fatal. */
|
||||
compute_pipelines.erase(entry.key);
|
||||
LOG_WARNING(Render_Vulkan, "Cached compute pipeline failed to create: {}",
|
||||
e.what());
|
||||
continue;
|
||||
}
|
||||
++num_pipelines;
|
||||
}
|
||||
}
|
||||
|
||||
const std::array<Shader::RuntimeInfo, MaxShaderStages> empty_runtime_infos{};
|
||||
if (warmup_async) {
|
||||
for (auto& entry : staged_graphics) {
|
||||
if (graphics_pipelines.find(entry.key) != graphics_pipelines.end() ||
|
||||
pending_graphics.find(entry.key) != pending_graphics.end()) {
|
||||
continue;
|
||||
}
|
||||
auto job = std::make_shared<PendingPipeline>();
|
||||
job->saved = true;
|
||||
job->sdata = entry.sdata;
|
||||
job->make = [this, key = entry.key, infos = entry.infos,
|
||||
fetch = entry.fetch_shader, futures = entry.futures,
|
||||
sdata = entry.sdata]() mutable -> std::unique_ptr<GraphicsPipeline> {
|
||||
std::array<vk::ShaderModule, MaxShaderStages> modules{};
|
||||
for (size_t s = 0; s < MaxShaderStages; ++s) {
|
||||
if (futures[s].valid()) {
|
||||
modules[s] = futures[s].get();
|
||||
if (!modules[s]) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
const std::array<Shader::RuntimeInfo, MaxShaderStages> empty_runtime_infos{};
|
||||
return std::make_unique<GraphicsPipeline>(
|
||||
instance, scheduler, desc_heap, profile, key, *pipeline_cache,
|
||||
infos, empty_runtime_infos, fetch, modules, sdata, true);
|
||||
};
|
||||
pending_graphics.emplace(entry.key, job);
|
||||
++num_pipelines;
|
||||
g_bb_background_pipelines_total.fetch_add(1, std::memory_order_relaxed);
|
||||
GetCompiler().Submit([job] {
|
||||
SCOPE_EXIT {
|
||||
g_bb_background_pipelines_done.fetch_add(1, std::memory_order_relaxed);
|
||||
};
|
||||
if (job->started.exchange(true)) {
|
||||
return;
|
||||
}
|
||||
std::unique_ptr<GraphicsPipeline> pipeline;
|
||||
try {
|
||||
pipeline = job->make();
|
||||
} catch (const std::exception&) {
|
||||
}
|
||||
std::unique_lock lk{job->mutex};
|
||||
job->pipeline = std::move(pipeline);
|
||||
job->done = true;
|
||||
job->cv.notify_all();
|
||||
});
|
||||
}
|
||||
} else {
|
||||
for (auto& entry : staged_graphics) {
|
||||
bool all_stages_ok = true;
|
||||
std::array<vk::ShaderModule, MaxShaderStages> modules{};
|
||||
for (size_t s = 0; s < MaxShaderStages; ++s) {
|
||||
if (entry.futures[s].valid()) {
|
||||
modules[s] = entry.futures[s].get();
|
||||
if (!modules[s]) {
|
||||
all_stages_ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!all_stages_ok) {
|
||||
continue;
|
||||
}
|
||||
const auto [it, is_new] = graphics_pipelines.try_emplace(entry.key);
|
||||
if (is_new) {
|
||||
try {
|
||||
it.value() = std::make_unique<GraphicsPipeline>(
|
||||
instance, scheduler, desc_heap, profile, entry.key, *pipeline_cache,
|
||||
entry.infos, empty_runtime_infos, entry.fetch_shader, modules,
|
||||
entry.sdata, true);
|
||||
} catch (const std::exception& e) {
|
||||
/* bbport: one driver-refused cached pipeline is skipped, not fatal. */
|
||||
graphics_pipelines.erase(entry.key);
|
||||
LOG_WARNING(Render_Vulkan,
|
||||
"Cached graphics pipeline failed to create: {}", e.what());
|
||||
continue;
|
||||
}
|
||||
++num_pipelines;
|
||||
}
|
||||
return result;
|
||||
});
|
||||
} catch (const Serialization::CorruptData& e) {
|
||||
LOG_ERROR(Render, "Corrupted pipeline cache detected during WarmUp: {}. Clearing cache.",
|
||||
e.what());
|
||||
Storage::DataBase::Instance().Clear();
|
||||
Storage::DataBase::Instance().FinishPreload();
|
||||
// Without its profile the next start would skip the warm-up altogether.
|
||||
profile_data.resize(sizeof(profile));
|
||||
std::memcpy(profile_data.data(), &profile, sizeof(profile));
|
||||
Storage::DataBase::Instance().Save(Storage::BlobType::ShaderProfile, "profile",
|
||||
std::move(profile_data));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LOG_INFO(Render, "Preloaded {} pipelines", num_pipelines);
|
||||
/* bbport: drop metas left by builds/tools that wrote an older binary version. This runs after
|
||||
* the preload pass on purpose: LoadShaderMeta rejects an unsupported version silently, so the
|
||||
* keys that referenced those metas are dropped and their metas can then be deleted in one go.
|
||||
* Purging first would make the preload hit deleted files and log an io_file error per key.
|
||||
* Runs only when the profile above is compatible. */
|
||||
PurgeStaleShaderMetas();
|
||||
|
||||
sel.infos.fill(nullptr);
|
||||
sel.modules.fill(nullptr);
|
||||
sel.fetch_shader.reset();
|
||||
|
||||
const auto warmup_end = std::chrono::steady_clock::now();
|
||||
const auto warmup_ms =
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(warmup_end - warmup_start).count();
|
||||
|
||||
LOG_INFO(Render, "Pipeline cache warmup completed in {} ms (preloaded {} pipelines, mode={})",
|
||||
warmup_ms, num_pipelines, warmup_async ? "async" : "sync");
|
||||
if (num_total_pipelines > num_pipelines) {
|
||||
// bbport: only the unusable keys go. Clearing the whole cache here also deleted the
|
||||
// profile (so the next start loaded nothing) and the shaders of the pipelines just
|
||||
// preloaded (whose later keys then referenced missing files): every other start
|
||||
// threw the cache away and the one in between started cold.
|
||||
LOG_WARNING(Render, "{} cached pipelines could not be loaded: removed {} keys, kept {}",
|
||||
num_total_pipelines - num_pipelines, num_removed, num_pipelines);
|
||||
}
|
||||
if (num_reused_permutations != 0) {
|
||||
LOG_INFO(Render,
|
||||
"{} cached shader stages reused a permutation already staged under a different "
|
||||
"index (same specialization, so the preload was kept)",
|
||||
num_reused_permutations);
|
||||
}
|
||||
|
||||
Storage::DataBase::Instance().FinishPreload();
|
||||
}
|
||||
@@ -430,7 +992,16 @@ void PipelineCache::SaveDriverPipelineCache() {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
auto [res, data] = instance.GetDevice().getPipelineCacheData(*pipeline_cache);
|
||||
vk::Result res{vk::Result::eSuccess};
|
||||
std::vector<u8> data;
|
||||
{
|
||||
/* Vulkan requires external synchronization on the VkPipelineCache handle, and the
|
||||
* async compiler workers create pipelines concurrently (see vk_graphics_pipeline.cpp). */
|
||||
std::scoped_lock lock{PipelineCreationMutex()};
|
||||
auto result = instance.GetDevice().getPipelineCacheData(*pipeline_cache);
|
||||
res = result.result;
|
||||
data = std::move(result.value);
|
||||
}
|
||||
if (res == vk::Result::eSuccess && !data.empty()) {
|
||||
LOG_INFO(Render, "Saving native Vulkan driver pipeline cache ({} bytes)", data.size());
|
||||
Storage::DataBase::Instance().Save(Storage::BlobType::PipelineBinary,
|
||||
@@ -441,7 +1012,64 @@ void PipelineCache::SaveDriverPipelineCache() {
|
||||
}
|
||||
}
|
||||
|
||||
void PipelineCache::MaybeSaveDriverPipelineCache() {
|
||||
if (num_new_pipelines == num_new_pipelines_at_last_save) {
|
||||
return;
|
||||
}
|
||||
const auto now = std::chrono::steady_clock::now();
|
||||
/* The first new pipeline is written out at once (a small, cheap dump) so even an early crash
|
||||
* leaves a cache behind; later dumps are spaced out so the .vkp loses at most a minute. */
|
||||
if (last_driver_cache_save.time_since_epoch().count() != 0 &&
|
||||
now - last_driver_cache_save < std::chrono::minutes(1)) {
|
||||
return;
|
||||
}
|
||||
last_driver_cache_save = now;
|
||||
num_new_pipelines_at_last_save = num_new_pipelines;
|
||||
/* bbport: this is called from the GPU thread for every draw. Hand the work to a saver thread:
|
||||
* getPipelineCacheData() copies the whole driver cache (10+ MB here) and the write/flush used
|
||||
* to block the GPU thread, producing a periodic hitch every minute. */
|
||||
std::scoped_lock lk{driver_save_mutex};
|
||||
if (driver_save_stop) {
|
||||
return;
|
||||
}
|
||||
if (!driver_save_thread.joinable()) {
|
||||
driver_save_thread = std::thread([this] { DriverCacheSaveLoop(); });
|
||||
}
|
||||
driver_save_pending = true;
|
||||
driver_save_cv.notify_one();
|
||||
}
|
||||
|
||||
void PipelineCache::DriverCacheSaveLoop() {
|
||||
Common::SetCurrentThreadName("bb:DriverCacheSave");
|
||||
std::unique_lock lk{driver_save_mutex};
|
||||
for (;;) {
|
||||
driver_save_cv.wait(lk, [&] { return driver_save_stop || driver_save_pending; });
|
||||
if (driver_save_stop) {
|
||||
return;
|
||||
}
|
||||
driver_save_pending = false;
|
||||
lk.unlock();
|
||||
SaveDriverPipelineCache();
|
||||
/* Make this dump durable here, off the GPU thread. The GPU thread only asked for it. */
|
||||
Storage::DataBase::Instance().Flush();
|
||||
lk.lock();
|
||||
}
|
||||
}
|
||||
|
||||
void PipelineCache::StopDriverCacheSaver() {
|
||||
{
|
||||
std::scoped_lock lk{driver_save_mutex};
|
||||
if (!driver_save_thread.joinable()) {
|
||||
return;
|
||||
}
|
||||
driver_save_stop = true;
|
||||
}
|
||||
driver_save_cv.notify_all();
|
||||
driver_save_thread.join();
|
||||
}
|
||||
|
||||
void PipelineCache::Sync() {
|
||||
StopDriverCacheSaver();
|
||||
SaveDriverPipelineCache();
|
||||
Storage::DataBase::Instance().Close();
|
||||
}
|
||||
|
||||
@@ -9,6 +9,23 @@
|
||||
|
||||
namespace Vulkan {
|
||||
|
||||
namespace PipelineStore {
|
||||
/* bbport: single source of truth for the cache version. The runtime constants in
|
||||
* vk_pipeline_serialization.cpp used to be a separate copy, and when only one of them was
|
||||
* bumped the launcher rewrote profile.bin to the other value on every start. WarmUp then saw
|
||||
* a mismatching profile and wiped the whole cache, which is why shaders recompiled forever. */
|
||||
static constexpr u32 ShaderBinaryVersion = 25u;
|
||||
static constexpr u32 ShaderMetaVersion = 8u;
|
||||
static constexpr u32 PipelineKeyVersion = 5u;
|
||||
}
|
||||
|
||||
void RegisterShaderInput(std::vector<u8>&& input, u64 pgm_hash, size_t perm_idx);
|
||||
bool LoadShaderMeta(Serialization::Archive& ar, Shader::Info& info,
|
||||
std::optional<Shader::Gcn::FetchShaderData>& fetch_shader_data,
|
||||
Shader::StageSpecialization& spec, size_t& perm_idx);
|
||||
bool LoadShaderMeta(Serialization::Archive& ar, Shader::Info& info,
|
||||
Shader::StageSpecialization& spec, size_t& perm_idx);
|
||||
|
||||
void RegisterPipelineData(const ComputePipelineKey& key,
|
||||
ComputePipeline::SerializationSupport& sdata);
|
||||
void RegisterPipelineData(const GraphicsPipelineKey& key, u64 hash,
|
||||
@@ -18,4 +35,10 @@ void RegisterShaderMeta(const Shader::Info& info,
|
||||
const Shader::StageSpecialization& spec, size_t perm_hash, size_t perm_idx);
|
||||
void RegisterShaderBinary(std::vector<u32>&& spv, u64 pgm_hash, size_t perm_idx);
|
||||
|
||||
inline void RegisterShaderMeta(const Shader::Info& info,
|
||||
const Shader::StageSpecialization& spec, size_t perm_hash, size_t perm_idx) {
|
||||
std::optional<Shader::Gcn::FetchShaderData> unused_fetch{};
|
||||
RegisterShaderMeta(info, unused_fetch, spec, perm_hash, perm_idx);
|
||||
}
|
||||
|
||||
} // namespace Vulkan
|
||||
@@ -3,15 +3,25 @@
|
||||
|
||||
// Include the vulkan platform specific header
|
||||
#if defined(ANDROID)
|
||||
#ifndef VK_USE_PLATFORM_ANDROID_KHR
|
||||
#define VK_USE_PLATFORM_ANDROID_KHR
|
||||
#endif
|
||||
#elif defined(_WIN64)
|
||||
#ifndef VK_USE_PLATFORM_WIN32_KHR
|
||||
#define VK_USE_PLATFORM_WIN32_KHR
|
||||
#endif
|
||||
#elif defined(__APPLE__)
|
||||
#ifndef VK_USE_PLATFORM_METAL_EXT
|
||||
#define VK_USE_PLATFORM_METAL_EXT
|
||||
#endif
|
||||
#else
|
||||
#ifndef VK_USE_PLATFORM_WAYLAND_KHR
|
||||
#define VK_USE_PLATFORM_WAYLAND_KHR
|
||||
#endif
|
||||
#ifndef VK_USE_PLATFORM_XLIB_KHR
|
||||
#define VK_USE_PLATFORM_XLIB_KHR
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include <fmt/ranges.h>
|
||||
@@ -21,7 +31,11 @@
|
||||
#include "common/path_util.h"
|
||||
#include "core/emulator_settings.h"
|
||||
#include "sdl_window.h"
|
||||
#include "video_core/renderer_vulkan/vk_dlss.h"
|
||||
#include "video_core/renderer_vulkan/vk_platform.h"
|
||||
#ifdef _WIN32
|
||||
#include "platform/win32/nvidia_profile.h"
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <mach-o/dyld.h>
|
||||
@@ -257,6 +271,9 @@ std::vector<const char*> GetInstanceLayers(bool enable_validation, bool enable_c
|
||||
vk::UniqueInstance CreateInstance(Frontend::WindowSystemType window_type, bool enable_validation,
|
||||
bool enable_crash_diagnostic) {
|
||||
LOG_INFO(Render_Vulkan, "Creating vulkan instance");
|
||||
#ifdef _WIN32
|
||||
BbNvidiaProfile::Apply();
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
// Initialize the environment with the path to the included ICD, so that the loader will
|
||||
@@ -286,7 +303,10 @@ vk::UniqueInstance CreateInstance(Frontend::WindowSystemType window_type, bool e
|
||||
VK_VERSION_MAJOR(available_version), VK_VERSION_MINOR(available_version));
|
||||
|
||||
const auto layers = GetInstanceLayers(enable_validation, enable_crash_diagnostic);
|
||||
const auto extensions = GetLayerExtensions(GetInstanceExtensions(window_type, true), layers);
|
||||
auto extensions = GetLayerExtensions(GetInstanceExtensions(window_type, true), layers);
|
||||
if (Dlss* dlss = Dlss::Get()) {
|
||||
dlss->AppendInstanceExtensions(extensions); // the optional DLSS bridge needs its own
|
||||
}
|
||||
|
||||
const vk::ApplicationInfo application_info = {
|
||||
.pApplicationName = "shadPS4",
|
||||
|
||||
@@ -18,8 +18,13 @@
|
||||
#include "video_core/renderer_vulkan/vk_instance.h"
|
||||
#include "video_core/renderer_vulkan/vk_pipeline_cache.h"
|
||||
#include "video_core/renderer_vulkan/vk_rasterizer.h"
|
||||
#include <xxhash.h>
|
||||
#include "shim/bb_env.h"
|
||||
#include "shim/bbgpu_fault_hint.h"
|
||||
#include "video_core/renderer_vulkan/vk_gpu_profiler.h"
|
||||
#include "bbport_threads.h"
|
||||
#include "bbport_button_prompts.h"
|
||||
#include "video_core/renderer_vulkan/vk_button_prompts.h"
|
||||
#include "video_core/renderer_vulkan/vk_runtime.h"
|
||||
#include "video_core/renderer_vulkan/vk_scheduler.h"
|
||||
#include "video_core/renderer_vulkan/vk_shader_hle.h"
|
||||
@@ -58,6 +63,8 @@ Rasterizer::Rasterizer(const Instance& instance_, Scheduler& scheduler_, Runtime
|
||||
camera_motion->SetObjectMotion(object_motion.get());
|
||||
upscaler = std::make_unique<TemporalUpscaler>(instance, scheduler, texture_cache, runtime,
|
||||
*camera_motion, *scene_targets);
|
||||
// bbport: the game's key guide icons drawn for the device in use (bbport_button_prompts.h).
|
||||
prompts = std::make_unique<ButtonPrompts>(instance, scheduler, buffer_cache);
|
||||
if (!EmulatorSettings.IsNullGPU()) {
|
||||
liverpool->BindRasterizer(this);
|
||||
}
|
||||
@@ -479,6 +486,57 @@ bool Rasterizer::PendingWriteOverlaps(VAddr address, u64 size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace {
|
||||
bool RingDedupOn() {
|
||||
static const bool on = !bb_env_off("BB_RING_DEDUP");
|
||||
return on;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
bool Rasterizer::CopyRingDeduplicated(
|
||||
u32 index, VAddr address, u64 size, u64 alignment,
|
||||
boost::container::static_vector<RingBinding, Shader::NUM_BUFFERS>& out) {
|
||||
struct Slot {
|
||||
VAddr address = 0;
|
||||
u64 size = 0;
|
||||
XXH128_hash_t hash{};
|
||||
u64 at = 0;
|
||||
};
|
||||
thread_local auto slots = std::make_unique<std::array<Slot, 8192>>();
|
||||
thread_local auto bytes = std::make_unique<std::array<u8, VideoCore::BufferCache::STREAM_THRESHOLD>>();
|
||||
thread_local auto by_content = std::make_unique<std::array<Slot, 8192>>();
|
||||
if (size > bytes->size()) {
|
||||
return false;
|
||||
}
|
||||
memory->CopySparseMemory(address, bytes->data(), size);
|
||||
const XXH128_hash_t hash = XXH3_128bits(bytes->data(), size);
|
||||
auto& slot = (*slots)[((address * 0x9E3779B97F4A7C15ull) ^ (size * 0xC2B2AE3D27D4EB4Full)) >> 51];
|
||||
auto& content_slot = (*by_content)[hash.low64 >> 51];
|
||||
std::optional<u64> offset;
|
||||
if (slot.address == address && slot.size == size && XXH128_isEqual(slot.hash, hash)) {
|
||||
offset = constant_ring->Reuse(slot.at, size);
|
||||
}
|
||||
if (!offset && content_slot.size == size && XXH128_isEqual(content_slot.hash, hash)) {
|
||||
offset = constant_ring->Reuse(content_slot.at, size);
|
||||
if (offset) {
|
||||
slot = content_slot;
|
||||
slot.address = address;
|
||||
}
|
||||
}
|
||||
if (!offset) {
|
||||
offset = constant_ring->Allocate(size, alignment);
|
||||
if (!offset) {
|
||||
return false;
|
||||
}
|
||||
std::memcpy(constant_ring->Data(*offset), bytes->data(), size);
|
||||
constant_ring->Flush(*offset, size);
|
||||
slot = {address, size, hash, constant_ring->LastAllocated()};
|
||||
content_slot = slot;
|
||||
}
|
||||
out.push_back({index, static_cast<u32>(size), *offset, address});
|
||||
return true;
|
||||
}
|
||||
|
||||
void Rasterizer::CollectRingBindings(const Shader::Info& stage, const PreparedDraw* prepared,
|
||||
boost::container::static_vector<RingBinding, Shader::NUM_BUFFERS>& out) {
|
||||
const PreparedStage* prepared_stage = nullptr;
|
||||
@@ -495,6 +553,11 @@ void Rasterizer::CollectRingBindings(const Shader::Info& stage, const PreparedDr
|
||||
const u64 alignment = std::max<u64>(instance.StorageMinAlignment(),
|
||||
instance.UniformMinAlignment());
|
||||
const auto copy = [&](u32 index, const void* source, VAddr address, u64 size) {
|
||||
if (!source && address != 0 && RingDedupOn()) {
|
||||
if (CopyRingDeduplicated(index, address, size, alignment, out)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
const auto offset = constant_ring->Allocate(size, alignment);
|
||||
if (!offset) {
|
||||
return;
|
||||
@@ -955,15 +1018,19 @@ void Rasterizer::DrawRecord(const GraphicsPipeline* pipeline, const PreparedDraw
|
||||
scene_debug_frame = scene_debug && std::remove(scene_debug) == 0;
|
||||
scene_targets->debug = scene_debug_frame;
|
||||
}
|
||||
// bbport: the key guide icons for the device in use (a change: uploaded before this draw).
|
||||
prompts->Update();
|
||||
bind_prepared = used_prepared;
|
||||
motion_draw = pipeline->GetGraphicsKey().motion_vectors;
|
||||
motion_geometry = 0;
|
||||
|
||||
PrepareRenderState(pipeline);
|
||||
if (upscaler->Enabled() && std::popcount(pipeline->GetGraphicsKey().mrt_mask) == 1) {
|
||||
const u32 draw_colors = std::popcount(pipeline->GetGraphicsKey().mrt_mask);
|
||||
// Stencil-only draws (UI masks) too: their depth must become the UI depth.
|
||||
if (upscaler->Enabled() && (draw_colors == 1 || (draw_colors == 0 && db_desc.first))) {
|
||||
const auto& viewport = Regs().viewports[0];
|
||||
upscaler->OnDraw(pipeline->GetStage(Shader::SwStage::Vertex).pgm_hash,
|
||||
cb_descs[0].first, db_desc.first,
|
||||
draw_colors ? cb_descs[0].first : VideoCore::ImageId{}, db_desc.first,
|
||||
UiComposition::NativeViewport(viewport.xscale * 2, viewport.yscale * 2));
|
||||
}
|
||||
const PreparedDraw* draw_prepared = bind_prepared;
|
||||
@@ -1175,10 +1242,11 @@ void Rasterizer::DrawIndirectRecord(const GraphicsPipeline* pipeline, bool is_in
|
||||
motion_draw = false;
|
||||
motion_geometry = 0;
|
||||
PrepareRenderState(pipeline);
|
||||
if (upscaler->Enabled() && std::popcount(pipeline->GetGraphicsKey().mrt_mask) == 1) {
|
||||
const u32 draw_colors = std::popcount(pipeline->GetGraphicsKey().mrt_mask);
|
||||
if (upscaler->Enabled() && (draw_colors == 1 || (draw_colors == 0 && db_desc.first))) {
|
||||
const auto& viewport = Regs().viewports[0];
|
||||
upscaler->OnDraw(pipeline->GetStage(Shader::SwStage::Vertex).pgm_hash,
|
||||
cb_descs[0].first, db_desc.first,
|
||||
draw_colors ? cb_descs[0].first : VideoCore::ImageId{}, db_desc.first,
|
||||
UiComposition::NativeViewport(viewport.xscale * 2, viewport.yscale * 2));
|
||||
}
|
||||
if (!BindResources(pipeline)) {
|
||||
@@ -1485,6 +1553,12 @@ bool Rasterizer::TexturesBindableOnHelper(const Shader::Info& stage,
|
||||
image_id = depth_image_id;
|
||||
image = &texture_cache.GetImage(image_id);
|
||||
}
|
||||
// bbport: prompt textures need the main thread (their views and the atlas's decode are
|
||||
// recorded there), so the helper leaves this stage to BindTextures.
|
||||
DetectPromptTextures(*image);
|
||||
if (prompts->Active() && (image->prompt_icon != 0 || image->prompt_atlas != 0)) {
|
||||
return false;
|
||||
}
|
||||
if (image->binding.needs_rebind || !texture_cache.IsUpToDate(image_id) ||
|
||||
scene_targets->Tracks(image->image_uid) ||
|
||||
(upscaler->Enabled() && upscaler->RedirectsSampled(image_id))) {
|
||||
@@ -1729,8 +1803,8 @@ void Rasterizer::ResolveVertexBuffers(const GraphicsPipeline* pipeline,
|
||||
// Include every stream: identical position buffers can be paired with different
|
||||
// skinning/instance data. Index topology and base offsets are matched separately.
|
||||
motion_geometry = ready ? ready->buffers_hash
|
||||
: XXH3_64bits(guest_buffers.data(),
|
||||
guest_buffers.size() * sizeof(AmdGpu::Buffer));
|
||||
: HashBufferDescriptors(guest_buffers.data(), guest_buffers.size());
|
||||
|
||||
}
|
||||
// Object motion research: vertex streams of G-buffer draws.
|
||||
if (FrameCapture::Active() && gbuffer_draw) {
|
||||
@@ -2216,6 +2290,25 @@ Rasterizer::ImageDescCacheEntry& Rasterizer::CachedImageDescEntry(const AmdGpu::
|
||||
return entry;
|
||||
}
|
||||
|
||||
void Rasterizer::DetectPromptTextures(VideoCore::Image& image) {
|
||||
if (!prompts->Active()) {
|
||||
return;
|
||||
}
|
||||
// A key guide icon the GPU copied in (never uploaded, so never recognised by RefreshImage).
|
||||
if (image.MaybePromptIcon()) {
|
||||
image.prompt_icon = u8(BbPrompts::IconOf(
|
||||
reinterpret_cast<const void*>(image.info.guest_address), 1024));
|
||||
}
|
||||
// An atlas uploaded before the prompts' table was read (RefreshImage deferred it).
|
||||
if (image.prompt_upload == ~0u) {
|
||||
const u32 atlas =
|
||||
BbPrompts::AtlasOf(reinterpret_cast<const void*>(image.info.guest_address),
|
||||
image.info.guest_size, image.info.size.width, image.info.size.height);
|
||||
image.prompt_atlas = u8(atlas);
|
||||
image.prompt_upload = atlas ? 1u : 0u;
|
||||
}
|
||||
}
|
||||
|
||||
void Rasterizer::BindTextures(const Shader::Info& stage, const PreparedStage* prepared,
|
||||
Shader::Backend::Bindings& binding, u32& write_index,
|
||||
bool& barrier, bool on_helper) {
|
||||
@@ -2402,6 +2495,29 @@ void Rasterizer::BindTextures(const Shader::Info& stage, const PreparedStage* pr
|
||||
image_id, desc, memo_entry ? &memo_entry->view_memo : nullptr, !on_helper);
|
||||
const auto binding = image.binding;
|
||||
|
||||
// bbport: one of the game's key guide icons, or an HUD atlas with them, samples the
|
||||
// port's own for the device in use (the atlas is decoded out of the render pass).
|
||||
if (!is_storage && prompts->Active()) {
|
||||
DetectPromptTextures(image);
|
||||
if (image.prompt_atlas != 0) {
|
||||
if (const vk::ImageView atlas =
|
||||
prompts->AtlasView(runtime, image, desc.view_info)) {
|
||||
image.usage.texture = 1u;
|
||||
image_infos.emplace_back(VK_NULL_HANDLE, atlas,
|
||||
vk::ImageLayout::eShaderReadOnlyOptimal);
|
||||
set_ok = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (const vk::ImageView icon = prompts->View(image.prompt_icon, desc.view_info)) {
|
||||
image.usage.texture = 1u;
|
||||
image_infos.emplace_back(VK_NULL_HANDLE, icon,
|
||||
vk::ImageLayout::eShaderReadOnlyOptimal);
|
||||
set_ok = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// bbport: a proxied scene image sampled with normalized coordinates reads the proxy:
|
||||
// no resample to the native size (the native image is not touched).
|
||||
if (binding_proxy_ok[binding_index] && !is_storage && !binding.force_general &&
|
||||
@@ -2632,7 +2748,16 @@ bool Rasterizer::BindTexturesFromSet(const Shader::Info& stage, const PreparedSt
|
||||
if (!entry.id) {
|
||||
continue;
|
||||
}
|
||||
const auto& image = texture_cache.GetImage(entry.id);
|
||||
auto& image = texture_cache.GetImage(entry.id);
|
||||
// bbport: a key guide icon or icon atlas never takes the memoized set: it samples the
|
||||
// port's own for the device in use (BindTextures).
|
||||
DetectPromptTextures(image);
|
||||
if (prompts->Active() && (image.prompt_icon != 0 || image.prompt_atlas != 0)) {
|
||||
++texture_set_why[2];
|
||||
++texture_set_misses;
|
||||
set.generation = ~0ull;
|
||||
return false;
|
||||
}
|
||||
// Proxy entries need a current proxy; native entries of a proxied image go through
|
||||
// BindTextures, which may sample the proxy instead.
|
||||
const bool proxies_on = !BbToggle::Disabled(BbToggle::SampleSceneProxies);
|
||||
@@ -2818,12 +2943,14 @@ RenderState Rasterizer::BeginRenderingFull(const GraphicsPipeline* pipeline) {
|
||||
state.height = instance.GetMaxFramebufferHeight();
|
||||
state.num_layers = std::numeric_limits<u16>::max();
|
||||
state.num_color_attachments = std::bit_width(key.mrt_mask);
|
||||
bool has_attachment = false;
|
||||
for (auto cb = 0u; cb < state.num_color_attachments; ++cb) {
|
||||
auto& [image_id, desc] = cb_descs[cb];
|
||||
if (!image_id) {
|
||||
state.color_attachments[cb] = {};
|
||||
continue;
|
||||
}
|
||||
has_attachment = true;
|
||||
auto* image = &texture_cache.GetImage(image_id);
|
||||
if (image->binding.needs_rebind) {
|
||||
last_targets[cb].generation = ~0ULL; // FindImage may rewrite the description
|
||||
@@ -2896,6 +3023,7 @@ RenderState Rasterizer::BeginRenderingFull(const GraphicsPipeline* pipeline) {
|
||||
}
|
||||
|
||||
if (auto image_id = db_desc.first; image_id) {
|
||||
has_attachment = true;
|
||||
auto& desc = db_desc.second;
|
||||
const auto htile_address = regs.depth_htile_data_base.GetAddress();
|
||||
const auto& image_view = texture_cache.FindDepthTarget(image_id, desc);
|
||||
@@ -3024,8 +3152,15 @@ RenderState Rasterizer::BeginRenderingFull(const GraphicsPipeline* pipeline) {
|
||||
}
|
||||
}
|
||||
|
||||
if (state.num_layers == std::numeric_limits<u16>::max()) {
|
||||
// Without attachments the area stays at the max framebuffer size. Draws cannot pass the
|
||||
// scissors, so bound it by them.
|
||||
if (!has_attachment) {
|
||||
state.num_layers = 1;
|
||||
const AmdGpu::Scissor scissor = regs.GetCombinedScissor();
|
||||
if (scissor.bottom_right_x > 0 && scissor.bottom_right_y > 0) {
|
||||
state.width = std::min<u32>(state.width, scissor.bottom_right_x);
|
||||
state.height = std::min<u32>(state.height, scissor.bottom_right_y);
|
||||
}
|
||||
}
|
||||
|
||||
if (reduced) {
|
||||
@@ -3175,6 +3310,12 @@ bool Rasterizer::OnWriteFault(VAddr addr, bool assume_locks) {
|
||||
return false;
|
||||
}
|
||||
buffer_cache.ExtendWriteFault(addr);
|
||||
if (BbFaultHint::redzone) {
|
||||
// A PS4 vertex generator keeps locals in the System V red zone, which the Windows
|
||||
// exception frame destroys on every handled fault. Keep this page writable so this
|
||||
// routine does not fault on it again.
|
||||
buffer_cache.MakeWriteFaultSticky(addr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3246,31 +3387,7 @@ void Rasterizer::UpdateDynamicState(const GraphicsPipeline* pipeline, const bool
|
||||
void Rasterizer::UpdateViewportScissorState() const {
|
||||
const auto& regs = Regs();
|
||||
|
||||
const auto combined_scissor_value_tl = [](s16 scr, s16 win, s16 gen, s16 win_offset) {
|
||||
return std::max({scr, s16(win + win_offset), s16(gen + win_offset)});
|
||||
};
|
||||
const auto combined_scissor_value_br = [](s16 scr, s16 win, s16 gen, s16 win_offset) {
|
||||
return std::min({scr, s16(win + win_offset), s16(gen + win_offset)});
|
||||
};
|
||||
const bool enable_offset = !regs.window_scissor.window_offset_disable;
|
||||
|
||||
AmdGpu::Scissor scsr{};
|
||||
scsr.top_left_x = combined_scissor_value_tl(
|
||||
regs.screen_scissor.top_left_x, s16(regs.window_scissor.top_left_x),
|
||||
s16(regs.generic_scissor.top_left_x),
|
||||
enable_offset ? regs.window_offset.window_x_offset : 0);
|
||||
scsr.top_left_y = combined_scissor_value_tl(
|
||||
regs.screen_scissor.top_left_y, s16(regs.window_scissor.top_left_y),
|
||||
s16(regs.generic_scissor.top_left_y),
|
||||
enable_offset ? regs.window_offset.window_y_offset : 0);
|
||||
scsr.bottom_right_x = combined_scissor_value_br(
|
||||
regs.screen_scissor.bottom_right_x, regs.window_scissor.bottom_right_x,
|
||||
regs.generic_scissor.bottom_right_x,
|
||||
enable_offset ? regs.window_offset.window_x_offset : 0);
|
||||
scsr.bottom_right_y = combined_scissor_value_br(
|
||||
regs.screen_scissor.bottom_right_y, regs.window_scissor.bottom_right_y,
|
||||
regs.generic_scissor.bottom_right_y,
|
||||
enable_offset ? regs.window_offset.window_y_offset : 0);
|
||||
const AmdGpu::Scissor scsr = regs.GetCombinedScissor();
|
||||
|
||||
boost::container::static_vector<vk::Viewport, AmdGpu::NUM_VIEWPORTS> viewports;
|
||||
boost::container::static_vector<vk::Rect2D, AmdGpu::NUM_VIEWPORTS> scissors;
|
||||
@@ -3342,10 +3459,10 @@ void Rasterizer::UpdateViewportScissorState() const {
|
||||
std::max(vp_scsr.top_left_x, s16(regs.viewport_scissors[i].top_left_x));
|
||||
vp_scsr.top_left_y =
|
||||
std::max(vp_scsr.top_left_y, s16(regs.viewport_scissors[i].top_left_y));
|
||||
vp_scsr.bottom_right_x = std::min(AmdGpu::Scissor::Clamp(vp_scsr.bottom_right_x),
|
||||
regs.viewport_scissors[i].bottom_right_x);
|
||||
vp_scsr.bottom_right_y = std::min(AmdGpu::Scissor::Clamp(vp_scsr.bottom_right_y),
|
||||
regs.viewport_scissors[i].bottom_right_y);
|
||||
vp_scsr.bottom_right_x =
|
||||
std::min(vp_scsr.bottom_right_x, s16(regs.viewport_scissors[i].bottom_right_x));
|
||||
vp_scsr.bottom_right_y =
|
||||
std::min(vp_scsr.bottom_right_y, s16(regs.viewport_scissors[i].bottom_right_y));
|
||||
}
|
||||
if (target_scale[0] != 1.0f || target_scale[1] != 1.0f) {
|
||||
const auto scale = [](s32 v, float f) { return s32(std::lround(float(v) * f)); };
|
||||
|
||||
@@ -31,6 +31,7 @@ namespace Vulkan {
|
||||
|
||||
class GraphicsPipeline;
|
||||
class Runtime;
|
||||
class ButtonPrompts;
|
||||
|
||||
class Rasterizer {
|
||||
public:
|
||||
@@ -254,6 +255,9 @@ private:
|
||||
const AmdGpu::ComputeProgram& CsRegs() const;
|
||||
static void RunDrawPacket(void* rasterizer, const u8* packet, u32 size);
|
||||
struct RingBinding;
|
||||
bool CopyRingDeduplicated(
|
||||
u32 index, VAddr address, u64 size, u64 alignment,
|
||||
boost::container::static_vector<RingBinding, Shader::NUM_BUFFERS>& out);
|
||||
void CollectRingBindings(const Shader::Info& stage, const PreparedDraw* prepared,
|
||||
boost::container::static_vector<RingBinding, Shader::NUM_BUFFERS>& out);
|
||||
void PrintPipeStats();
|
||||
@@ -309,6 +313,10 @@ private:
|
||||
static void RunTextureTask(void* rasterizer);
|
||||
static void JoinBindHelper(void* rasterizer);
|
||||
|
||||
/// bbport: checks `image` for one of the game's key guide icons or icon atlases once the
|
||||
/// prompts' table is ready (a GPU copy is never uploaded, so the bind path checks too).
|
||||
void DetectPromptTextures(VideoCore::Image& image);
|
||||
|
||||
/// Display pass: counts the frame (BbStats::gpu_frames) and, with BB_BUFFER_STATS, the lag.
|
||||
void NoteFrameStart();
|
||||
/// BB_GPU_PROFILE: a timestamp where a render pass starts (vk_gpu_profiler.h).
|
||||
@@ -352,6 +360,7 @@ private:
|
||||
u64 motion_geometry{}; ///< vertex-stream identity of the current direct draw
|
||||
bool gbuffer_draw = false;
|
||||
std::unique_ptr<TemporalUpscaler> upscaler; // bbport: FSR (docs/upscaler.md)
|
||||
std::unique_ptr<ButtonPrompts> prompts; // bbport: button prompts (gpu/shim/bbport_button_prompts.h)
|
||||
std::array<float, 2> draw_jitter{}; ///< viewport offset of the current draw, pixels
|
||||
std::array<float, 2> target_scale{1.0f, 1.0f}; ///< pass drawn into the upscaler's output-size images
|
||||
const bool host_markers_enabled;
|
||||
|
||||
@@ -57,15 +57,28 @@ bool SceneTargets::Blittable(vk::Format format) const {
|
||||
}
|
||||
bool SceneTargets::ShaderResampled(const VideoCore::Image& image) const {
|
||||
const auto format = image.backing->image.image_ci.format;
|
||||
if (!image.info.props.is_depth || (Blittable(format) && !force_stencil_bits)) return false;
|
||||
if (!image.info.props.is_depth) return false;
|
||||
const bool stencil = bool(image.aspect_mask & vk::ImageAspectFlagBits::eStencil);
|
||||
if (stencil) {
|
||||
if (Blittable(format) && !force_stencil_bits) return false;
|
||||
const auto features = Features(format);
|
||||
const auto required = vk::FormatFeatureFlagBits::eSampledImage |
|
||||
vk::FormatFeatureFlagBits::eDepthStencilAttachment;
|
||||
return (features & required) == required &&
|
||||
(instance.IsShaderStencilExportSupported() || force_stencil_bits);
|
||||
}
|
||||
// bbport: conservative 2x2 min-filter for forward-Z depth proxies (Audit U3).
|
||||
if (BbToggle::Disabled(BbToggle::DepthMinFilter)) {
|
||||
if (Blittable(format)) return false;
|
||||
}
|
||||
const auto features = Features(format);
|
||||
const auto required = vk::FormatFeatureFlagBits::eSampledImage |
|
||||
vk::FormatFeatureFlagBits::eDepthStencilAttachment;
|
||||
// Without shader stencil export (e.g. Pascal) depth/stencil stays native: the eight-draw
|
||||
// stencil resampler costs too much on such GPUs. BB_SCENE_STENCIL_BITS=1 forces it (tests).
|
||||
return (features & required) == required &&
|
||||
(!(image.aspect_mask & vk::ImageAspectFlagBits::eStencil) ||
|
||||
instance.IsShaderStencilExportSupported() || force_stencil_bits);
|
||||
return (features & required) == required;
|
||||
|
||||
|
||||
}
|
||||
// 1 for the scene size, 2 for half resolution (the game's post-processing chain), else 0.
|
||||
// Half resolution needs a scene size that halves exactly: the proxy keeps the scene's factor,
|
||||
@@ -178,7 +191,7 @@ void SceneTargets::Copy(Entry& e, VideoCore::Image& original, bool to_native) {
|
||||
const auto& proxy = e.image.image_ci.extent;
|
||||
Resample(src, dst, original,
|
||||
to_native ? vk::Extent2D{original.info.size.width, original.info.size.height}
|
||||
: vk::Extent2D{proxy.width, proxy.height});
|
||||
: vk::Extent2D{proxy.width, proxy.height}, !to_native);
|
||||
// (Depth proxies are single-level: Eligible.)
|
||||
if (to_native) e.state.Resolved(); else e.state.CopiedToProxy();
|
||||
copying = false;
|
||||
@@ -219,7 +232,7 @@ void SceneTargets::Copy(Entry& e, VideoCore::Image& original, bool to_native) {
|
||||
copying = false;
|
||||
}
|
||||
void SceneTargets::Resample(vk::Image src, vk::Image dst, const VideoCore::Image& original,
|
||||
vk::Extent2D dst_size) {
|
||||
vk::Extent2D dst_size, bool downscale) {
|
||||
const auto device = instance.GetDevice();
|
||||
const auto format = original.backing->image.image_ci.format;
|
||||
const bool stencil = bool(original.aspect_mask & vk::ImageAspectFlagBits::eStencil);
|
||||
@@ -289,9 +302,11 @@ void SceneTargets::Resample(vk::Image src, vk::Image dst, const VideoCore::Image
|
||||
cmd.pushConstants(layout, vk::ShaderStageFlagBits::eFragment, 0, sizeof(bit), &bit);
|
||||
cmd.setStencilWriteMask(vk::StencilFaceFlagBits::eFrontAndBack, bit);
|
||||
cmd.setStencilReference(vk::StencilFaceFlagBits::eFrontAndBack, bit);
|
||||
cmd.draw(3, 1, 0, 0);
|
||||
cmd.draw(3, 1, 0, 0);
|
||||
}
|
||||
} else {
|
||||
const u32 mode = downscale ? 1u : 0u;
|
||||
cmd.pushConstants(layout, vk::ShaderStageFlagBits::eFragment, 0, sizeof(mode), &mode);
|
||||
cmd.draw(3, 1, 0, 0);
|
||||
}
|
||||
cmd.endRendering();
|
||||
|
||||
@@ -87,7 +87,7 @@ private:
|
||||
bool Blittable(vk::Format) const;
|
||||
bool ShaderResampled(const VideoCore::Image&) const;
|
||||
void Resample(vk::Image src, vk::Image dst, const VideoCore::Image& original,
|
||||
vk::Extent2D dst_size);
|
||||
vk::Extent2D dst_size, bool downscale = false);
|
||||
vk::Pipeline ResamplePipeline(vk::Format, bool stencil);
|
||||
void CreateResampleResources();
|
||||
void Transition(Entry&, vk::ImageAspectFlags, vk::ImageLayout,
|
||||
|
||||
@@ -26,6 +26,35 @@ namespace Vulkan {
|
||||
|
||||
std::mutex Scheduler::submit_mutex;
|
||||
|
||||
void ReportCommandOutsideChunk(const void* chunk, size_t chunk_used, const void* command,
|
||||
const char* reason) noexcept {
|
||||
/* Rate limited rather than once per session: a single overwritten chunk abandons the rest of
|
||||
* its list on every Execute, and the next ones carry the same defect. */
|
||||
static std::atomic<u32> reported{0};
|
||||
if (reported.fetch_add(1, std::memory_order_relaxed) >= 32) {
|
||||
return;
|
||||
}
|
||||
const auto base = reinterpret_cast<std::uintptr_t>(chunk);
|
||||
const auto addr = reinterpret_cast<std::uintptr_t>(command);
|
||||
LOG_CRITICAL(Render_Vulkan,
|
||||
"RecordChunk::Execute: {} for command {:#x} (slot {}, used {}, capacity {}): "
|
||||
"dropped the rest of the chunk",
|
||||
reason, static_cast<unsigned long long>(addr),
|
||||
static_cast<unsigned long long>(addr - base),
|
||||
static_cast<unsigned long long>(chunk_used),
|
||||
static_cast<unsigned long long>(RecordChunk::Capacity));
|
||||
}
|
||||
|
||||
void ReportRecordOutOfMemory() noexcept {
|
||||
static std::atomic<u32> reported{0};
|
||||
if (reported.fetch_add(1, std::memory_order_relaxed) >= 8) {
|
||||
return;
|
||||
}
|
||||
LOG_CRITICAL(Render_Vulkan,
|
||||
"Recording chunk is out of host memory: the affected draw is skipped instead of "
|
||||
"being recorded with data that was not copied");
|
||||
}
|
||||
|
||||
Scheduler::Scheduler(const Instance& instance, bool threaded_recording)
|
||||
: instance{instance}, work_semaphore{instance}, command_pool{instance, &work_semaphore} {
|
||||
// bbport: BB_VK_RECORD_THREAD=0 records on the calling thread.
|
||||
@@ -296,28 +325,34 @@ void Scheduler::WaitHostCopies() {
|
||||
}
|
||||
|
||||
void Scheduler::KickRecording(bool force) {
|
||||
if (!recorder_thread.joinable()) {
|
||||
if (!recorder_running) {
|
||||
return;
|
||||
}
|
||||
// Callers kick where nobody holds the raw command buffer: deferral resumes.
|
||||
direct_mode = false;
|
||||
// Batches of tens of KiB keep the queue handoff cheap relative to the work it carries.
|
||||
if (!force && full_chunks.empty() && CurrentChunk().Size() < 32 * 1024) {
|
||||
return;
|
||||
}
|
||||
if (full_chunks.empty() && CurrentChunk().Empty()) {
|
||||
return;
|
||||
}
|
||||
// The chunk that takes the current one's place, taken first (AcquireChunk locks
|
||||
// recorder_mutex) and swapped in below: record_chunk is never null, not even for a fault
|
||||
// handler recording on this thread meanwhile (issue #100).
|
||||
std::unique_ptr<RecordChunk> next_record = record_chunk->Empty() ? nullptr : AcquireChunk();
|
||||
bool wake;
|
||||
bool wake = false;
|
||||
{
|
||||
std::scoped_lock lk{recorder_mutex};
|
||||
/* bbport: the same lock the recording path takes. Handing the current chunk to the
|
||||
* recorder while another thread is still pushing into it let the recorder reset `used`
|
||||
* and recycle the storage under that thread (#185, "randomly closes after 10-60 min"). */
|
||||
std::scoped_lock lk{record_mutex};
|
||||
// Batches of tens of KiB keep the queue handoff cheap relative to the work it carries.
|
||||
if (!force && full_chunks.empty() && CurrentChunk().Size() < 32 * 1024) {
|
||||
return;
|
||||
}
|
||||
if (full_chunks.empty() && CurrentChunk().Empty()) {
|
||||
return;
|
||||
}
|
||||
// The chunk that takes the current one's place, taken first (AcquireChunk locks
|
||||
// recorder_mutex) and swapped in below: record_chunk is never null, not even for a fault
|
||||
// handler recording on this thread meanwhile (issue #100).
|
||||
std::unique_ptr<RecordChunk> next_record =
|
||||
CurrentChunk().Empty() ? nullptr : AcquireChunk();
|
||||
std::scoped_lock recorder_lk{recorder_mutex};
|
||||
for (auto& chunk : full_chunks) {
|
||||
recorder_queue.push_back(std::move(chunk));
|
||||
}
|
||||
full_chunks.clear();
|
||||
if (next_record) {
|
||||
record_chunk.swap(next_record); // next_record: the chunk handed over
|
||||
recorder_queue.push_back(std::move(next_record));
|
||||
@@ -325,7 +360,6 @@ void Scheduler::KickRecording(bool force) {
|
||||
wake = recorder_sleeping;
|
||||
queued_chunks.store(recorder_queue.size(), std::memory_order_release);
|
||||
}
|
||||
full_chunks.clear();
|
||||
// A busy recorder picks the new chunks up by itself: waking it is a syscall per draw.
|
||||
if (wake) {
|
||||
recorder_cv.notify_one();
|
||||
@@ -333,7 +367,7 @@ void Scheduler::KickRecording(bool force) {
|
||||
}
|
||||
|
||||
void Scheduler::SyncRecording() {
|
||||
if (!recorder_thread.joinable()) {
|
||||
if (!recorder_running) {
|
||||
return;
|
||||
}
|
||||
KickRecording(true);
|
||||
|
||||
@@ -5,11 +5,13 @@
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <condition_variable>
|
||||
#include <deque>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <new>
|
||||
#include <span>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -576,46 +578,83 @@ struct DynamicState {
|
||||
|
||||
using SubmitFunc = Common::UniqueFunction<void, SubmitInfo&>;
|
||||
|
||||
/// bbport: a block of deferred Vulkan commands. Commands are closures placed in
|
||||
/// a recorded command that is not inside its chunk's storage (the intrusive list was
|
||||
/// overwritten). Logs once per session; `chunk` is the chunk storage, `chunk_used` its high
|
||||
/// water mark (chunk slot index = command - chunk).
|
||||
void ReportCommandOutsideChunk(const void* chunk, size_t chunk_used, const void* command,
|
||||
const char* reason) noexcept;
|
||||
|
||||
/// A recorded command could not be stored (host out of memory). The command is dropped, never
|
||||
/// run with data that was not copied: a dropped draw leaves a frame wrong, a freed span crashes
|
||||
/// the driver.
|
||||
void ReportRecordOutOfMemory() noexcept;
|
||||
|
||||
/// a block of deferred Vulkan commands. Commands are closures placed in
|
||||
/// fixed storage (no allocation per command) and run in order on the recording thread.
|
||||
class RecordChunk {
|
||||
public:
|
||||
static constexpr size_t Capacity = 128 * 1024;
|
||||
|
||||
/// Returns false (and leaves `func` untouched) when the chunk has no room.
|
||||
/// Stamp of a live command slot. Command storage is bump-allocated, so a slot is only ever
|
||||
/// written once; a stamp that no longer matches means the chunk memory was reused under a
|
||||
/// live command list. Checking it costs one load and catches what the address check cannot
|
||||
/// (#185: the "vtable" read was 0x756ad00, i.e. buffer-handle data in the slot).
|
||||
static constexpr std::uint32_t CommandMagic = 0x4242434Du; // "BBCM"
|
||||
|
||||
/// Records `func`. Only false when the host is out of memory; the command storage spills to
|
||||
/// the heap instead of failing, so a full chunk can never split data from its command.
|
||||
template <typename Func>
|
||||
bool Push(Func&& func) {
|
||||
using Command = TypedCommand<std::decay_t<Func>>;
|
||||
static_assert(sizeof(Command) <= Capacity, "recorded command is too large");
|
||||
const size_t offset = (used + alignof(Command) - 1) & ~(alignof(Command) - 1);
|
||||
if (offset + sizeof(Command) > Capacity) {
|
||||
auto* slot = static_cast<void*>(Allocate(sizeof(Command), alignof(Command)));
|
||||
if (!slot) [[unlikely]] {
|
||||
return false;
|
||||
}
|
||||
auto* command = new (storage + offset) Command(std::forward<Func>(func));
|
||||
auto* command = new (slot) Command(std::forward<Func>(func));
|
||||
if (last) {
|
||||
last->next = command;
|
||||
} else {
|
||||
first = command;
|
||||
}
|
||||
last = command;
|
||||
used = offset + sizeof(Command);
|
||||
PrefetchAhead();
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Raw storage in the chunk for a command's variable-length data; null when full.
|
||||
/// Raw storage in the chunk for a command's variable-length data. Bump-allocated from the
|
||||
/// fixed block; the heap spill keeps it in the same chunk when the block is full, so the
|
||||
/// data can never be split from the command that reads it. Null only on host OOM.
|
||||
void* Allocate(size_t bytes, size_t align) {
|
||||
const size_t offset = (used + align - 1) & ~(align - 1);
|
||||
if (offset + bytes > Capacity) {
|
||||
return nullptr;
|
||||
if (bytes == 0) {
|
||||
return storage + used;
|
||||
}
|
||||
used = offset + bytes;
|
||||
PrefetchAhead();
|
||||
return storage + offset;
|
||||
if (align < alignof(std::max_align_t)) {
|
||||
align = alignof(std::max_align_t);
|
||||
}
|
||||
const size_t offset = (used + align - 1) & ~(align - 1);
|
||||
if (offset + bytes <= Capacity) {
|
||||
used = offset + bytes;
|
||||
PrefetchAhead();
|
||||
return storage + offset;
|
||||
}
|
||||
return AllocateSpill(bytes, align);
|
||||
}
|
||||
|
||||
void Execute(vk::CommandBuffer cmdbuf) {
|
||||
for (CommandBase* command = first; command;) {
|
||||
/* bbport: a command outside this chunk's storage means the list was overwritten
|
||||
* (phase-2 C8: the loop read command 0 at +0x1d7378 and 0x4803b9f9492 at +0x1d2c38,
|
||||
* both faulting on [command+0x10]). The stamp check below additionally rejects a
|
||||
* slot whose memory was reused for data; both are integer comparisons on validated
|
||||
* memory, so they run unconditionally. */
|
||||
if (!InChunk(command)) {
|
||||
ReportCommandOutsideChunk(storage, used, command, "outside the chunk storage");
|
||||
break;
|
||||
}
|
||||
if (command->magic != CommandMagic) {
|
||||
ReportCommandOutsideChunk(storage, used, command, "command stamp overwritten");
|
||||
break;
|
||||
}
|
||||
CommandBase* const next = command->next;
|
||||
command->Execute(cmdbuf);
|
||||
command->~CommandBase();
|
||||
@@ -623,6 +662,7 @@ public:
|
||||
}
|
||||
first = last = nullptr;
|
||||
used = 0;
|
||||
spill.clear();
|
||||
}
|
||||
|
||||
[[nodiscard]] bool Empty() const noexcept {
|
||||
@@ -644,9 +684,36 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
/// A block owned by this chunk for data/commands that did not fit in `storage`. Freed once
|
||||
/// the chunk has been executed, so anything it holds outlives every command recorded with
|
||||
/// it and never outlives the chunk.
|
||||
struct Spill {
|
||||
std::unique_ptr<std::byte[]> memory;
|
||||
std::byte* data = nullptr;
|
||||
size_t size = 0;
|
||||
};
|
||||
|
||||
void* AllocateSpill(size_t bytes, size_t align) {
|
||||
if (align > 64) {
|
||||
align = 64;
|
||||
}
|
||||
// One extra alignment unit so the returned pointer can be aligned by hand.
|
||||
auto memory = std::unique_ptr<std::byte[]>(new (std::nothrow) std::byte[bytes + align]);
|
||||
if (!memory) [[unlikely]] {
|
||||
return nullptr;
|
||||
}
|
||||
const auto base = reinterpret_cast<std::uintptr_t>(memory.get());
|
||||
const auto aligned = (base + (align - 1)) & ~static_cast<std::uintptr_t>(align - 1);
|
||||
spill.push_back(Spill{std::move(memory), reinterpret_cast<std::byte*>(aligned), bytes});
|
||||
return reinterpret_cast<void*>(aligned);
|
||||
}
|
||||
|
||||
struct CommandBase {
|
||||
virtual ~CommandBase() = default;
|
||||
virtual void Execute(vk::CommandBuffer cmdbuf) = 0;
|
||||
/// Checked before the virtual call; see CommandMagic.
|
||||
std::uint32_t magic = CommandMagic;
|
||||
std::uint32_t reserved = 0;
|
||||
CommandBase* next{};
|
||||
};
|
||||
template <typename Func>
|
||||
@@ -659,12 +726,30 @@ private:
|
||||
Func func;
|
||||
};
|
||||
|
||||
/// Whether `command` points at a command slot inside this chunk: the loop in Execute() is
|
||||
/// about to read its vtable, so the check is integer comparisons and no dereference.
|
||||
[[nodiscard]] bool InChunk(const CommandBase* command) const noexcept {
|
||||
const auto base = reinterpret_cast<std::uintptr_t>(storage);
|
||||
const auto addr = reinterpret_cast<std::uintptr_t>(command);
|
||||
if (addr >= base && addr + sizeof(CommandBase) <= base + used) {
|
||||
return true;
|
||||
}
|
||||
for (const auto& block : spill) {
|
||||
const auto start = reinterpret_cast<std::uintptr_t>(block.data);
|
||||
if (addr >= start && addr + sizeof(CommandBase) <= start + block.size) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
alignas(64) std::byte storage[Capacity];
|
||||
size_t used = 0;
|
||||
CommandBase* first{};
|
||||
CommandBase* last{};
|
||||
/// Rare: only a batch that crosses the end of `storage` uses it. Cleared by Execute().
|
||||
std::vector<Spill> spill;
|
||||
};
|
||||
|
||||
class Scheduler {
|
||||
public:
|
||||
/// `threaded_recording`: Vulkan commands passed to Record() are recorded by a worker thread.
|
||||
@@ -740,10 +825,20 @@ public:
|
||||
func(current_cmdbuf);
|
||||
return;
|
||||
}
|
||||
if (!CurrentChunk().Push(std::forward<Func>(func))) {
|
||||
RetireChunk();
|
||||
const bool pushed = CurrentChunk().Push(std::forward<Func>(func));
|
||||
ASSERT(pushed);
|
||||
/* bbport: the chunk is bookkeeping shared by the threads allowed to record (the GPU
|
||||
* command thread and the draw recording thread). Without this lock a RecordData() copy
|
||||
* or a RetireChunk() on one thread can land on a command another thread just pushed -
|
||||
* #185 read a buffer handle where the vtable of its command was. */
|
||||
std::scoped_lock lk{record_mutex};
|
||||
if (record_data_failed.load(std::memory_order_relaxed)) [[unlikely]] {
|
||||
// A RecordData() of this batch could not be copied: the command would read a span
|
||||
// that was never filled (or a null one). Skipping it leaves a frame wrong; running
|
||||
// it crashes the driver.
|
||||
return;
|
||||
}
|
||||
if (!CurrentChunk().Push(std::forward<Func>(func))) [[unlikely]] {
|
||||
ReportRecordOutOfMemory(); // host OOM only: Push() spills instead of failing
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -753,30 +848,53 @@ public:
|
||||
!BbToggle::Disabled(BbToggle::ThreadedRecording);
|
||||
}
|
||||
|
||||
/// Makes room for `bytes` of RecordData() plus the command that uses them in the current
|
||||
/// chunk: data and command must share a chunk, which is recycled once executed.
|
||||
/// True when the caller holds the raw command buffer (after CommandBuffer(), until the next
|
||||
/// KickRecording()/Finish()): Finish() would submit it and replace it under the caller.
|
||||
[[nodiscard]] bool IsDirectRecording() const noexcept {
|
||||
return direct_mode;
|
||||
}
|
||||
|
||||
/// Makes room for a batch of RecordData() plus the commands that read it, in one chunk.
|
||||
/// Must be called before the batch's first RecordData(): retirement is only safe at batch
|
||||
/// boundaries. Data and commands are never separated afterwards - RecordData() spills
|
||||
/// instead of retiring, and Print/Push() spills instead of failing.
|
||||
void ReserveRecordData(size_t bytes) {
|
||||
if (!IsRecordingDeferred()) {
|
||||
return;
|
||||
}
|
||||
ASSERT(bytes + 1024 <= RecordChunk::Capacity);
|
||||
if (RecordChunk::Capacity - CurrentChunk().Size() < bytes + 1024) {
|
||||
std::scoped_lock lk{record_mutex};
|
||||
record_data_failed.store(false, std::memory_order_relaxed);
|
||||
if (bytes + RecordCommandHeadroom > RecordChunk::Capacity) {
|
||||
// A batch larger than a chunk: retiring cannot make room, the spill carries it.
|
||||
return;
|
||||
}
|
||||
if (RecordChunk::Capacity - CurrentChunk().Size() < bytes + RecordCommandHeadroom) {
|
||||
RetireChunk();
|
||||
}
|
||||
}
|
||||
|
||||
/// Copies `data` into recording storage that lives until the command that uses it has
|
||||
/// been recorded (the same chunk). With threaded recording off, returns `data` itself.
|
||||
/// Copies data into recording storage that lives until the command that uses it has been
|
||||
/// recorded (the same chunk). With threaded recording off, returns data itself.
|
||||
template <typename T>
|
||||
std::span<const T> RecordData(std::span<const T> data) {
|
||||
if (!IsRecordingDeferred() || data.empty()) {
|
||||
return data;
|
||||
}
|
||||
// Room for the data and the command that follows it, so both stay in one chunk.
|
||||
const size_t bytes = data.size_bytes();
|
||||
ReserveRecordData(bytes + alignof(T));
|
||||
auto* dst = static_cast<T*>(CurrentChunk().Allocate(bytes, alignof(T)));
|
||||
std::memcpy(dst, data.data(), bytes);
|
||||
std::scoped_lock lk{record_mutex};
|
||||
/* bbport: this used to retire the chunk when the copy was close to the end. That split
|
||||
* the batch: the data stayed in the retired chunk (executed and recycled first) while
|
||||
* its command went to the next one, so the driver read freed memory (#185, "randomly
|
||||
* closes after 10-60 min": nvoglv64 [rcx+0x130] with rcx=0). The chunk now keeps the
|
||||
* copy - in its fixed block or in the spill that it frees only after Execute(). */
|
||||
auto* dst = static_cast<T*>(CurrentChunk().Allocate(data.size_bytes(), alignof(T)));
|
||||
if (!dst) [[unlikely]] {
|
||||
/* Host OOM: there is no safe span to hand the command, so this batch's commands
|
||||
* are dropped rather than run against a null/param pointer. */
|
||||
record_data_failed.store(true, std::memory_order_relaxed);
|
||||
ReportRecordOutOfMemory();
|
||||
return {};
|
||||
}
|
||||
std::memcpy(dst, data.data(), data.size_bytes());
|
||||
return {dst, data.size()};
|
||||
}
|
||||
|
||||
@@ -877,11 +995,18 @@ public:
|
||||
static std::mutex submit_mutex;
|
||||
|
||||
private:
|
||||
/// Data bytes a batch may need plus room for the Record() calls that read them. The old
|
||||
/// value (256) did not cover the two or three commands EmitVertexBuffers pushes after its
|
||||
/// data, so the last one could be pushed into a new chunk (#185).
|
||||
static constexpr size_t RecordCommandHeadroom = 4096;
|
||||
|
||||
void AllocateWorkerCommandBuffers();
|
||||
|
||||
std::unique_ptr<RecordChunk> AcquireChunk();
|
||||
|
||||
/// Moves the full current chunk aside; a new one takes its place (swapped in: never null).
|
||||
/// Callers must hold `record_mutex`: a chunk retired while another thread still records into
|
||||
/// it is executed (and recycled) under that thread's writes.
|
||||
void RetireChunk() {
|
||||
auto full = AcquireChunk();
|
||||
record_chunk.swap(full);
|
||||
@@ -931,6 +1056,12 @@ private:
|
||||
// bbport: threaded recording
|
||||
std::unique_ptr<RecordChunk> record_chunk;
|
||||
std::vector<std::unique_ptr<RecordChunk>> full_chunks;
|
||||
/// Serializes the chunk bump allocator and its hand-off to the recorder (see Record()).
|
||||
/// Order: record_mutex before recorder_mutex, never the other way round.
|
||||
std::mutex record_mutex;
|
||||
/// A RecordData() of the current batch could not be copied (host OOM); the batch's commands
|
||||
/// are dropped until the next ReserveRecordData().
|
||||
std::atomic<bool> record_data_failed{false};
|
||||
std::mutex recorder_mutex;
|
||||
std::condition_variable_any recorder_cv;
|
||||
std::condition_variable_any recorder_idle_cv;
|
||||
|
||||
@@ -0,0 +1,322 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 bbport contributors
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#include "video_core/renderer_vulkan/vk_shader_capture.h"
|
||||
#include "shim/bb_env.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "common/serdes.h"
|
||||
#include "shader_recompiler/backend/bindings.h"
|
||||
#include "shader_recompiler/frontend/decode.h"
|
||||
#include "shader_recompiler/frontend/opcodes.h"
|
||||
#include "shader_recompiler/info.h"
|
||||
#include "shader_recompiler/profile.h"
|
||||
#include "shader_recompiler/runtime_info.h"
|
||||
|
||||
namespace BbShaderCapture {
|
||||
|
||||
namespace {
|
||||
|
||||
/// Guest memory read while compiling: a size of 0 is a program (its length found by decoding).
|
||||
struct Read {
|
||||
const u8* address;
|
||||
size_t size;
|
||||
};
|
||||
thread_local std::vector<Read> reads;
|
||||
|
||||
void RecordRead(const void* address, size_t size) {
|
||||
reads.push_back({static_cast<const u8*>(address), size});
|
||||
}
|
||||
|
||||
const char* Directory() {
|
||||
static const char* dir = bb_env("BB_SHADER_CAPTURE");
|
||||
return dir && *dir ? dir : nullptr;
|
||||
}
|
||||
|
||||
/// Bytes of a program at `code` up to and including its s_setpc_b64 (fetch shaders return so).
|
||||
size_t ProgramBytes(const u8* code) {
|
||||
const auto* start = reinterpret_cast<const u32*>(code);
|
||||
Shader::Gcn::GcnCodeSlice code_slice(start, start + 1024);
|
||||
Shader::Gcn::GcnDecodeContext decoder;
|
||||
while (!code_slice.atEnd()) {
|
||||
const auto inst = decoder.decodeInstruction(code_slice);
|
||||
if (inst.opcode == Shader::Gcn::Opcode::S_SETPC_B64) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return size_t(code_slice.position() - start) * sizeof(u32);
|
||||
}
|
||||
|
||||
struct Out {
|
||||
std::vector<u8> bytes;
|
||||
void Raw(const void* data, size_t size) {
|
||||
const auto* p = static_cast<const u8*>(data);
|
||||
bytes.insert(bytes.end(), p, p + size);
|
||||
}
|
||||
template <typename T>
|
||||
void Value(const T& value) {
|
||||
Raw(&value, sizeof(T));
|
||||
}
|
||||
void Words(std::span<const u32> words) {
|
||||
Value(u32(words.size()));
|
||||
Raw(words.data(), words.size_bytes());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
bool Enabled() {
|
||||
return Directory() != nullptr;
|
||||
}
|
||||
|
||||
void Begin() {
|
||||
reads.clear();
|
||||
Shader::guest_read_hook = RecordRead;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/// The guest memory read since Begin(), merged into ranges.
|
||||
std::vector<std::pair<const u8*, size_t>> MergedReads() {
|
||||
std::vector<std::pair<const u8*, size_t>> ranges;
|
||||
for (const auto& read : reads) {
|
||||
ranges.emplace_back(read.address, read.size ? read.size : ProgramBytes(read.address));
|
||||
}
|
||||
std::ranges::sort(ranges);
|
||||
std::vector<std::pair<const u8*, size_t>> merged;
|
||||
for (const auto& [address, size] : ranges) {
|
||||
if (!merged.empty() && address <= merged.back().first + merged.back().second) {
|
||||
auto& last = merged.back();
|
||||
last.second = std::max<size_t>(last.second, size_t(address + size - last.first));
|
||||
} else {
|
||||
merged.emplace_back(address, size);
|
||||
}
|
||||
}
|
||||
return merged;
|
||||
}
|
||||
|
||||
/// Layout of the structures an input record stores as bytes: another layout cannot be read.
|
||||
u32 InputLayout() {
|
||||
return u32(sizeof(Shader::RuntimeInfo) * 31 + sizeof(Shader::Backend::Bindings) * 7 +
|
||||
Shader::ShaderParams::NumShaderUserData);
|
||||
}
|
||||
|
||||
struct In {
|
||||
std::span<const u8> bytes;
|
||||
size_t at = 0;
|
||||
bool ok = true;
|
||||
void Raw(void* out, size_t size) {
|
||||
if (at + size > bytes.size()) {
|
||||
ok = false;
|
||||
return;
|
||||
}
|
||||
std::memcpy(out, bytes.data() + at, size);
|
||||
at += size;
|
||||
}
|
||||
template <typename T>
|
||||
T Value() {
|
||||
T value{};
|
||||
Raw(&value, sizeof(T));
|
||||
return value;
|
||||
}
|
||||
std::vector<u32> Words() {
|
||||
const u32 count = Value<u32>();
|
||||
if (!ok || size_t(count) * 4 > bytes.size() - at) {
|
||||
ok = false;
|
||||
return {};
|
||||
}
|
||||
std::vector<u32> words(count);
|
||||
Raw(words.data(), words.size() * sizeof(u32));
|
||||
return words;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
u32 InputLayoutId() {
|
||||
return InputLayout();
|
||||
}
|
||||
|
||||
void BeginInput() {
|
||||
reads.clear();
|
||||
Shader::guest_read_hook = RecordRead;
|
||||
}
|
||||
|
||||
std::vector<u8> TakeInput(const Shader::Info& in_info, const Shader::RuntimeInfo& runtime_info,
|
||||
const Shader::Backend::Bindings& in_bindings, std::span<const u32> code,
|
||||
size_t perm_idx, std::span<const u32> flat) {
|
||||
Shader::guest_read_hook = nullptr;
|
||||
Out out;
|
||||
out.Raw("BBSI", 4);
|
||||
out.Value(InputVersion);
|
||||
out.Value(InputLayout());
|
||||
out.Value(Shader::MotionVectors::params_address);
|
||||
out.Value(Shader::MotionVectors::positions_address);
|
||||
out.Value(u32(in_info.hw_stage));
|
||||
out.Value(u32(in_info.sw_stage));
|
||||
out.Value(in_info.pgm_hash);
|
||||
out.Value(u64(perm_idx));
|
||||
out.Value(u64(in_info.pgm_base));
|
||||
std::array<u32, Shader::ShaderParams::NumShaderUserData> user_data{};
|
||||
std::copy_n(in_info.user_data.begin(),
|
||||
std::min(in_info.user_data.size(), user_data.size()), user_data.begin());
|
||||
out.Value(user_data);
|
||||
out.Words(code);
|
||||
auto stored_rt = runtime_info;
|
||||
std::span<const u32> vs_copy{};
|
||||
if (runtime_info.hw_stage == Shader::HwStage::Geometry) {
|
||||
vs_copy = runtime_info.hw.gs.vs_copy;
|
||||
stored_rt.hw.gs.vs_copy = {};
|
||||
}
|
||||
out.Value(stored_rt);
|
||||
out.Words(vs_copy);
|
||||
out.Value(in_bindings);
|
||||
out.Words(flat);
|
||||
const auto merged = MergedReads();
|
||||
out.Value(u32(merged.size()));
|
||||
for (const auto& [address, size] : merged) {
|
||||
out.Value(u64(reinterpret_cast<uintptr_t>(address)));
|
||||
out.Value(u32(size));
|
||||
out.Raw(address, size);
|
||||
}
|
||||
return std::move(out.bytes);
|
||||
}
|
||||
|
||||
bool ReadInput(std::span<const u8> bytes, Input& input, bool without_code) {
|
||||
In in{bytes};
|
||||
char magic[4];
|
||||
in.Raw(magic, 4);
|
||||
if (!in.ok || std::memcmp(magic, "BBSI", 4) != 0 || in.Value<u32>() != InputVersion ||
|
||||
in.Value<u32>() != InputLayout()) {
|
||||
return false;
|
||||
}
|
||||
input.params_address = in.Value<u64>();
|
||||
input.positions_address = in.Value<u64>();
|
||||
input.hw_stage = Shader::HwStage(in.Value<u32>());
|
||||
input.sw_stage = Shader::SwStage(in.Value<u32>());
|
||||
input.pgm_hash = in.Value<u64>();
|
||||
input.perm_idx = in.Value<u64>();
|
||||
input.pgm_base = in.Value<u64>();
|
||||
input.user_data = in.Value<std::array<u32, Shader::ShaderParams::NumShaderUserData>>();
|
||||
input.code = in.Words();
|
||||
input.runtime_info = in.Value<Shader::RuntimeInfo>();
|
||||
input.vs_copy = in.Words();
|
||||
input.bindings = in.Value<Shader::Backend::Bindings>();
|
||||
input.flat = in.Words();
|
||||
const u32 regions = in.Value<u32>();
|
||||
input.regions.clear();
|
||||
for (u32 i = 0; i < regions && in.ok; ++i) {
|
||||
auto& region = input.regions.emplace_back();
|
||||
region.address = in.Value<u64>();
|
||||
const u32 size = in.Value<u32>();
|
||||
if (!in.ok || size > bytes.size() - in.at) {
|
||||
return false;
|
||||
}
|
||||
region.bytes.resize(size);
|
||||
in.Raw(region.bytes.data(), size);
|
||||
}
|
||||
return in.ok && in.at == bytes.size() && (without_code || !input.code.empty());
|
||||
}
|
||||
|
||||
std::vector<u8> WriteInput(const Input& input) {
|
||||
Out out;
|
||||
out.Raw("BBSI", 4);
|
||||
out.Value(InputVersion);
|
||||
out.Value(InputLayout());
|
||||
out.Value(input.params_address);
|
||||
out.Value(input.positions_address);
|
||||
out.Value(u32(input.hw_stage));
|
||||
out.Value(u32(input.sw_stage));
|
||||
out.Value(input.pgm_hash);
|
||||
out.Value(input.perm_idx);
|
||||
out.Value(input.pgm_base);
|
||||
out.Value(input.user_data);
|
||||
out.Words(input.code);
|
||||
out.Value(input.runtime_info);
|
||||
out.Words(input.vs_copy);
|
||||
out.Value(input.bindings);
|
||||
out.Words(input.flat);
|
||||
out.Value(u32(input.regions.size()));
|
||||
for (const auto& region : input.regions) {
|
||||
out.Value(region.address);
|
||||
out.Value(u32(region.bytes.size()));
|
||||
out.Raw(region.bytes.data(), region.bytes.size());
|
||||
}
|
||||
return std::move(out.bytes);
|
||||
}
|
||||
|
||||
void Write(const Shader::Info& in_info, const Shader::RuntimeInfo& runtime_info,
|
||||
const Shader::Profile& profile, const Shader::Backend::Bindings& in_bindings,
|
||||
std::span<const u32> code, size_t perm_idx, std::span<const u32> spv,
|
||||
const Shader::Info& out_info, const Shader::Backend::Bindings& out_bindings) {
|
||||
Shader::guest_read_hook = nullptr;
|
||||
Out out;
|
||||
out.Raw("BBSC", 4);
|
||||
out.Value(u32{2}); // format version
|
||||
// Globals the backend reads (object motion vectors).
|
||||
out.Value(Shader::MotionVectors::params_address);
|
||||
out.Value(Shader::MotionVectors::positions_address);
|
||||
out.Value(u32(in_info.hw_stage));
|
||||
out.Value(u32(in_info.sw_stage));
|
||||
out.Value(in_info.pgm_hash);
|
||||
out.Value(u64(perm_idx));
|
||||
out.Value(u64(in_info.pgm_base));
|
||||
std::array<u32, Shader::ShaderParams::NumShaderUserData> user_data{};
|
||||
std::copy_n(in_info.user_data.begin(),
|
||||
std::min(in_info.user_data.size(), user_data.size()), user_data.begin());
|
||||
out.Value(user_data);
|
||||
out.Words(code);
|
||||
out.Value(runtime_info);
|
||||
out.Words(runtime_info.hw_stage == Shader::HwStage::Geometry ? runtime_info.hw.gs.vs_copy
|
||||
: std::span<const u32>{});
|
||||
out.Value(profile);
|
||||
out.Value(in_bindings);
|
||||
|
||||
// The memory read, merged into ranges.
|
||||
std::vector<std::pair<const u8*, size_t>> ranges;
|
||||
for (const auto& read : reads) {
|
||||
ranges.emplace_back(read.address, read.size ? read.size : ProgramBytes(read.address));
|
||||
}
|
||||
std::ranges::sort(ranges);
|
||||
std::vector<std::pair<const u8*, size_t>> merged;
|
||||
for (const auto& [address, size] : ranges) {
|
||||
if (!merged.empty() && address <= merged.back().first + merged.back().second) {
|
||||
auto& last = merged.back();
|
||||
last.second = std::max<size_t>(last.second, size_t(address + size - last.first));
|
||||
} else {
|
||||
merged.emplace_back(address, size);
|
||||
}
|
||||
}
|
||||
out.Value(u32(merged.size()));
|
||||
for (const auto& [address, size] : merged) {
|
||||
out.Value(u64(reinterpret_cast<uintptr_t>(address)));
|
||||
out.Value(u32(size));
|
||||
out.Raw(address, size);
|
||||
}
|
||||
|
||||
out.Words(spv);
|
||||
Serialization::Archive archive;
|
||||
out_info.Serialize(archive);
|
||||
const auto info_bytes = archive.TakeOff();
|
||||
out.Value(u64(info_bytes.size()));
|
||||
out.Raw(info_bytes.data(), info_bytes.size());
|
||||
out.Value(out_bindings);
|
||||
|
||||
static std::atomic<u32> sequence{0};
|
||||
char name[512];
|
||||
std::snprintf(name, sizeof(name), "%s/%016llx_%u_%zu_%u.bbsc", Directory(),
|
||||
(unsigned long long)in_info.pgm_hash, u32(in_info.hw_stage), perm_idx,
|
||||
sequence.fetch_add(1));
|
||||
if (FILE* file = std::fopen(name, "wb")) {
|
||||
std::fwrite(out.bytes.data(), 1, out.bytes.size(), file);
|
||||
std::fclose(file);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace BbShaderCapture
|
||||
@@ -0,0 +1,72 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 bbport contributors
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <span>
|
||||
#include <vector>
|
||||
|
||||
#include "common/types.h"
|
||||
#include "shader_recompiler/backend/bindings.h"
|
||||
#include "shader_recompiler/info.h"
|
||||
#include "shader_recompiler/runtime_info.h"
|
||||
|
||||
namespace Shader {
|
||||
struct Info;
|
||||
struct RuntimeInfo;
|
||||
struct Profile;
|
||||
namespace Backend {
|
||||
struct Bindings;
|
||||
}
|
||||
} // namespace Shader
|
||||
|
||||
namespace BbShaderCapture {
|
||||
|
||||
/// Whether compilations are recorded (BB_SHADER_CAPTURE set).
|
||||
bool Enabled();
|
||||
|
||||
/// Starts recording the guest memory the compiler reads on this thread.
|
||||
void Begin();
|
||||
|
||||
/// Writes the record of a compilation (`in_info`: the info as it was before compiling).
|
||||
void Write(const Shader::Info& in_info, const Shader::RuntimeInfo& runtime_info,
|
||||
const Shader::Profile& profile, const Shader::Backend::Bindings& in_bindings,
|
||||
std::span<const u32> code, size_t perm_idx, std::span<const u32> spv,
|
||||
const Shader::Info& out_info, const Shader::Backend::Bindings& out_bindings);
|
||||
|
||||
/// The pipeline cache's own record of a compilation's inputs (BBSI): what translating the
|
||||
/// permutation again needs when a later build changes the compiler's output (shader_rebuild.h).
|
||||
/// Its layout changes only with InputVersion or the stored structures' sizes.
|
||||
constexpr u32 InputVersion = 1;
|
||||
/// The sizes of the structures a record stores as bytes (ReadInput rejects another).
|
||||
u32 InputLayoutId();
|
||||
|
||||
struct Input {
|
||||
struct Region {
|
||||
u64 address;
|
||||
std::vector<u8> bytes;
|
||||
};
|
||||
u64 params_address = 0, positions_address = 0;
|
||||
Shader::HwStage hw_stage{};
|
||||
Shader::SwStage sw_stage{};
|
||||
u64 pgm_hash = 0, perm_idx = 0, pgm_base = 0;
|
||||
std::array<u32, Shader::ShaderParams::NumShaderUserData> user_data{};
|
||||
std::vector<u32> code, vs_copy, flat;
|
||||
Shader::RuntimeInfo runtime_info{};
|
||||
Shader::Backend::Bindings bindings{};
|
||||
std::vector<Region> regions;
|
||||
};
|
||||
|
||||
/// Starts recording the guest memory the compiler reads on this thread (for TakeInput).
|
||||
void BeginInput();
|
||||
/// The input record of the compilation since BeginInput (`flat`: the info's flat user data).
|
||||
std::vector<u8> TakeInput(const Shader::Info& in_info, const Shader::RuntimeInfo& runtime_info,
|
||||
const Shader::Backend::Bindings& in_bindings, std::span<const u32> code,
|
||||
size_t perm_idx, std::span<const u32> flat);
|
||||
/// Parses an input record; false for another version or layout, or damaged bytes.
|
||||
/// `without_code`: a record whose program code was left out (shader recipes) is valid too.
|
||||
bool ReadInput(std::span<const u8> bytes, Input& input, bool without_code = false);
|
||||
/// The record of `input` (ReadInput's layout).
|
||||
std::vector<u8> WriteInput(const Input& input);
|
||||
|
||||
} // namespace BbShaderCapture
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "video_core/host_shaders/buffer_multi_copy_comp.h"
|
||||
#include "bbport_toggles.h"
|
||||
#include "video_core/renderer_vulkan/vk_gpu_profiler.h"
|
||||
#include "shim/bb_env.h"
|
||||
|
||||
extern std::unique_ptr<AmdGpu::Liverpool> liverpool;
|
||||
|
||||
@@ -18,6 +19,11 @@ namespace Vulkan {
|
||||
|
||||
static constexpr u64 COPY_SHADER_HASH = 0xfefebf9f;
|
||||
|
||||
bool CopySkipSameOn() {
|
||||
static const bool on = !bb_env_off("BB_COPY_SKIP_SAME");
|
||||
return on;
|
||||
}
|
||||
|
||||
// bbport: the copy shader runs ~57 times per frame with ~1024 small ranges each. As one
|
||||
// vkCmdCopyBuffer with that many regions it cost ~37 ns of GPU time per range (~2.1 ms per
|
||||
// frame) plus the recording; buffer_multi_copy.comp copies all ranges in one dispatch.
|
||||
@@ -160,13 +166,28 @@ static bool ExecuteCopyShaderHLE(const Shader::Info& info, const AmdGpu::Compute
|
||||
copies.clear();
|
||||
copies.reserve(cs_program.dim_x);
|
||||
|
||||
const bool skip_same = CopySkipSameOn();
|
||||
const u8* src_base_ptr = reinterpret_cast<const u8*>(src_buf_sharp.base_address);
|
||||
const u8* dst_base_ptr = reinterpret_cast<const u8*>(dst_buf_sharp.base_address);
|
||||
|
||||
for (u32 i = 0; i < cs_program.dim_x; i++) {
|
||||
const auto& [dst_idx, src_idx, end] = ctl_buf[i];
|
||||
const u32 local_dst_offset = dst_idx * buf_stride;
|
||||
const u32 local_src_offset = src_idx * buf_stride;
|
||||
const u32 local_size = (end + 1) * buf_stride;
|
||||
if (local_size == 0) {
|
||||
continue;
|
||||
}
|
||||
if (skip_same && src_base_ptr && dst_base_ptr) {
|
||||
if (std::memcmp(dst_base_ptr + local_dst_offset, src_base_ptr + local_src_offset, local_size) == 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
copies.emplace_back(local_src_offset, local_dst_offset, local_size);
|
||||
}
|
||||
if (copies.empty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// bbport: 64 KiB instead of 64 MiB. The copies are a few KiB spread over up to 57 MiB, and
|
||||
// each batch synchronizes (uploads, marks GPU-modified) its whole range: GPU time of the copy
|
||||
|
||||
Loaded 100 of 170 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user