Compare commits

...
97 Commits
Author SHA1 Message Date
Mrsuss60 b3350bb4f5 Launcher: UI polish, global cursor handler, and lazy tab loading to fix freezes
- Implemented a global `CursorGuard` to automatically apply the pointing-hand cursor to all interactive widgets.
- Fixed clipped Save Manager button text by enforcing stylesheet `min-height` and removing stray padding spaces.
- Eliminated tab-switching stutters by background-loading the M&K, Advanced, and Saves tabs via `QTimer` and deferring I/O scans.
- Added a yellow warning label to patches disabled by the Live FPS conflict check.
- Resolved tab routing logic bugs, removed duplicate `QTimer` calls, and fixed an `IndentationError`.
2026-11-07 00:16:07 +00:00
Mrsuss60 019939a5e5 fix(launcher): resolve inverted AZERTY and QWERTY keybind presets and scancode mappings 2026-11-06 23:03:33 +00:00
Mrsuss60 17bfa1e4b7 style(launcher): add Lvl and Playtime labels to save slot cards 2026-11-06 19:10:47 +00:00
Mrsuss60 1cc0678c21 fix(launcher): embed universal save slot portrait and fix Windows PE/taskbar icons
- Replace player-specific slot crops and distorted icon0.png title banners with a universal 512x512 Bloodborne cover portrait for all save cards
- Update find_character_portrait to resolve assets from PyInstaller's runtime bundle (sys._MEIPASS) and embed resources via build_bblauncher.bat
- Fix batch variable expansion conflict in build_bblauncher.bat that dropped the --icon parameter during PyInstaller builds
- Re-encode icon.ico into standard Windows DIB/BMP format across 7 resolutions (16 to 256) to ensure native Windows Explorer shell support
- Call SetCurrentProcessExplicitAppUserModelID and bind app.setWindowIcon on startup to display the launcher icon on the Windows taskbar
2026-11-06 19:02:37 +00:00
Mrsuss60 432d2ddbf1 gpu, probe: fix permutation conflicts, stale metas, and red-zone faults
- Reuse an equal-spec permutation module found at a different index instead of dropping the preload, recovering the permutation-conflict preloads
- Purge stale-version metas after the preload pass along with their orphaned .spv/.in companions, eliminating missing-file errors and silent key drops
- Migrate the stale profile header in place by accepting binary version 24 and updating it to 25, unifying cache versioning on 25
- Add bounded "sticky writable pages" for known generator RIP ranges to survive Windows KiUserExceptionDispatch clobbering the System V red zone
- Expose the StickyFaultPages toggle and BbStats::sticky_pages counter, with BB_STICKY_FAULT_PAGES env and A/B toggle bit 1<<2
- Set the red-zone fault hint around bbgpu_handle_fault and merge bbgpu.h/bbgpu.cpp with the save-manager changes
2026-11-06 13:22:49 +00:00
Mrsuss60 ce83b806b9 gpu, probe: stop shader cache wipes and recurring pipeline recompilation
- Unifies the cache version constants under PipelineStore so the runtime, the rebuild tool and the recipe importer can no longer stamp different binary versions into profile.bin and wipe the cache on the next launch.
- Accepts a stale 24 version header in both WarmUp and the rebuild tool and rewrites it in place instead of clearing valid shaders, and names the differing profile bytes when a real mismatch forces a rebuild.
- Fixes the imported meta layout to the four fields RegisterShaderMeta actually writes, removing two stray motion addresses that shifted the specialization by 16 bytes and made every imported recipe unreadable.
- Moves the periodic driver pipeline cache dump to a saver thread and flushes it there, taking the creation mutex so the async compiler workers cannot race the VkPipelineCache handle.
- Drains the cache IO queue in Close() before stopping the worker and flushes profile.bin before the import child starts, so queued writes are not lost at exit or race the child's profile validation.
- Records only recipes whose program or reference code is missing in the running game build, keeping transient failures retryable, and switches the launch environment to _putenv_s so the import child receives the game directory.
2026-11-06 02:23:13 +00:00
Mrsuss60 8d76278ccc feat(save): add save game manager, slot parser, and ng+ safepoints (closes #188)
Implement a complete Save Game Manager spanning the PySide6 launcher and the C runtime.

- Launcher UI: Added "SAVE MANAGER" sidebar tab with in-game styled character slot cards (portrait, level, playtime clock, blood echoes, and area/map location name) and backup controls.
- Save Data Parser: Decoded unencrypted userdata0010 slot tables (base 0x1080, stride 0x192), extracting character names (UTF-16LE), levels (+0x38), playtime (+0x3C), blood echoes (+0x40), and map IDs (+0x48) mapped via FromSoftware location tables.
- Save Path Resolution: Implemented param.sfo binary parser reading INSTALL_DIR_SAVEDATA to dynamically route save files to canonical title ID CUSA00207 across all regional and GOTY editions, with automatic legacy directory migration.
- Backup & Safeguard System: Added manual backups, pre-launch rolling snapshots with auto-pruning, pre-restore safety backups, and zip archive import/export bundling companion SPRJ0005.sce_sys metadata.
- C Runtime Safepoint: Hooked save_umount in src/runtime_savedata.c to throttle and auto-snapshot save data to user/savedata_backups/auto_safepoint across all character slots before NG+ transitions. Controlled via bbport.ini setting save_auto_backup and BB_SAVE_AUTO_BACKUP environment override.
2026-11-06 01:52:37 +00:00
Mrsuss60 3e60038643 gpu, probe: fix random exit 139, 140 and 23 crashes in long sessions
- Keeps the data a deferred command reads in the same recording chunk until that chunk has executed, and serializes chunk allocation and hand-off between the GPU and recording threads so a recycled chunk is never read under a live command.
- Compiles graphics and compute pipelines one at a time on the shared VkPipelineCache, and turns creation failures and rejected shaders into logged and skipped draws instead of process aborts.
- Recovers from malformed or desynced PM4 streams by abandoning the submission or skipping the packet, with rate-limited diagnostics in place of the fatal asserts.
- Records the guest allocator assertion (DLFixedAllocator, id 0x61) with its first argument next to the allocation failure counters in the crash dump.

closes #177
closes #178
closes #181
closes #185
and addresses similar issues reported on discord server
2026-11-04 14:16:05 +00:00
Mrsuss60 8ea9aa3744 input: add last-input priority and straight-line reversals to keyboard movement
-Implements last-input priority for opposing directional keys so pressing a new direction while holding the previous one immediately takes precedence instead of stopping to neutral.
-Resumes movement in the original direction automatically when the newer opposing key is released while the first key remains held.
-Ramps direct 180-degree reversals through center magnitude along the target axis rather than sweeping around the outer perimeter to prevent perpendicular drift during quick strafe switches.
-Adds automated unit test coverage in the pad test suite to verify opposing key overrides, release resumptions, and center decays.
2026-11-03 20:12:19 +00:00
MrSuS60 34e567b9e4 Merge pull request #190 from HatsyRei/fix/ui-composition-memo-scale
renderer_vulkan: redirect stencil-only UI mask draws into the UI depth
2026-11-03 10:43:56 +00:00
Mrsuss60 94388d5921 Fix(input): Fix keyboard movement drift and add analog stick simulation
* Eliminates sideways drift during keyboard movement by having movement keys drive both stick axes simultaneously while adding a deadzone to prevent resting gamepad drift from bleeding through.
* Simulates smooth analog stick ramping with 70 ms rise and 45 ms fall times so the character accelerates and decelerates naturally.
* Normalizes diagonal movement vectors along the unit circle to prevent speed overextension and smoothly sweeps direction changes at 1100 degrees per second.
* Automatically cancels opposing directional key combinations to neutral.
2026-11-03 00:15:50 +00:00
Mrsuss60 d9b1bc6e07 launcher: add texture quality setting, reorganize display settings, and fix keyboard layout bindings
* Add a texture quality selector with auto, full, half, and quarter modes to the Display & Graphics tab, persisting choices to bbport.ini and passing them via BB_TEXTURE_QUALITY at launch.
* Reorganize the Display & Graphics tab by grouping upscaler controls into a dedicated Upscaler Settings card and replacing the redundant enable checkbox with direct dropdown selection.
* Fix keybind assignment discrepancies on AZERTY and QWERTY layouts by storing printed letter characters directly so button labels and configuration entries stay synchronized.
* Increments launcher version to 0.8.1 and records the active texture quality mode in the startup log banner.
2026-11-02 22:02:42 +00:00
Mrsuss60 8841db5b24 gpu: port upstream mip-skipping texture quality setting
Implement mip-skipping texture quality setting based on upstream bloodborne_pc

* Adapts the mip-skipping texture quality feature from deadinside's upstream implementation (https://github.com/deadinside28/bloodborne_pc).
* Adds a configurable texture quality setting with auto, full, half, and quarter modes to reduce memory usage on graphics cards with limited VRAM.
* Evaluates the Vulkan device memory budget on startup to automatically select half quality on GPUs with 3 GB of VRAM or less when auto mode is selected.
* Restricts mip reduction strictly to 2D block-compressed surfaces of at least 512x512 with three or more mips, leaving render targets, depth buffers, storage images, and GPU-modified surfaces at full resolution.
* Adjusts staging upload copies, detiling compute dispatches, and descriptor view ranges to ensure shader sampling seamlessly aligns with reduced textures.
* Retains complete guest metadata across image lookups to prevent cache invalidation loops and ensure stable frame pacing.
2026-11-02 21:56:29 +00:00
Mrsuss60 ed73550c85 gpu, scripts: resolve startup stalls via async pipeline warmup and cached pre-launch
Eliminate multi-minute boot delays across pre-window launch and initial black screen presentation:

- Vulkan (vk_pipeline_serialization): Dispatch cached graphics pipelines asynchronously to worker threads via pending_graphics during WarmUp, removing the synchronous driver compilation stall on the render thread before the first frame.
- Vulkan (vk_shader_rebuild): Protect RebuildDirectory on Windows with Vectored Exception Handling to safely bypass incompatible shaders, and persist ShaderBinaryVersion in profile.bin on failure to stop repeating broken rebuilds every launch.
- Vulkan (vk_pipeline_import): Cap startup shader recipe merges to a 5 ms budget, deferring remaining imports to per-frame polls.
- Host Runtime (probe.c): Defer bbgpu_rebuild_shader_caches() until after bbgpu_init() so the SDL window and presenter open immediately.
- Pre-launch Scripts (prepare, link_libc, link_modules): Add mtime checks against source binaries to reuse existing boot images, and remove the redundant 28,000-file traversal in prepare.py.
- Platform (nvidia_profile): Add a single-run guard to BbNvidiaProfile::Apply() to prevent redundant NVAPI driver queries.
2026-11-02 17:47:31 +00:00
Mrsuss60 2054129fae launcher, scripts: support eboot.elf alongside eboot.bin across all launch paths (#189)
Extend executable discovery and validation across the launcher, run.bat, and
preparation scripts to accept both eboot.bin and eboot.elf interchangeably,
following the raw ELF parsing support merged in PR #189.

Changes:
- bblauncherAPP/bblauncher_Utils.py:
  - Added find_eboot_file() to probe for eboot.bin first, falling back to eboot.elf.
  - Updated resolve_game_dir() to accept direct file paths or directories containing
    either eboot.bin or eboot.elf.
  - Updated check_live_clock_signature() and verify_prelaunch() to identify and
    validate whichever executable variant is present.
- bblauncherAPP/bblauncher_UI.py & bblauncher_app.py:
  - Updated Browse file dialog filter to "PS4 Executables (*.bin *.elf);;All Files (*)".
  - Updated path field placeholders, drop-area hints, and error diagnostics to
    reference both eboot.bin and eboot.elf.
- run.bat:
  - Added argument checks and game directory existence verification for eboot.elf.
- scripts (prepare.py, game_check.py, link_libc.py, link_modules.py, mods.py):
  - Added find_eboot() helper to resolve eboot.bin or eboot.elf across preparation,
    image hash validation, and module linking.
  - Protected eboot.elf alongside eboot.bin from being overwritten by mod asset links.

Resolves #189 follow-up where Itemzflow and raw ELF dumps named eboot.elf were
rejected during launcher path resolution.
2026-11-02 15:07:28 +00:00
MrSuS60 d0f2a891b5 Merge pull request #189 from facundo1701/facundo1701-patch-accept-raw-elf
Update prepary.py to accept raw elf
2026-11-02 15:46:53 +01:00
HatsyRei 574f133635 renderer_vulkan: redirect stencil-only UI mask draws into the UI depth
At outputs other than 1080p, the UI-only composition path (no upscaled scene: upscaler off, loading screens, quit to menu) took the UI depth from the trigger draw, often none. Mask draws with color writes off never reached TemporalUpscaler::OnDraw, so they went into the guest depth, and the next icon draw switched the UI depth and cleared its stencil. Icons clipped by those masks (HUD quick item, loading screen item) failed the stencil test and were missing. Stencil-only draws now adopt a UI-sized depth as the UI depth, so the mask is drawn where the icons test against it.
2026-11-02 18:46:50 +08:00
facundo1701 d7b2db1122 Update prepary.py to accept raw elf
Accept an already-unwrapped ELF as eboot.bin

Problem:
Some dumpers (e.g. Itemzflow) write eboot.bin as a plain ELF (7F 45 4C 46)
instead of a plaintext PS4 SELF. prepare.py then exits with:
prepare failed: eboot.bin: expected PS4 SELF header (magic bytes O\x15=\x1d)
and the game cannot start.

Cause:
parse_self() only accepts the SELF magic. It rebuilds an ELF from the SELF's
embedded ELF header, program headers and segment data. A raw ELF already is that result.

Change:
In parse_self():
accept 7F 45 4C 46 as well as the SELF magic;
for a raw ELF, read the ELF header and program headers from offset 0 with the
same validation as before (x86-64, 56-byte program headers, size limit);
check every segment lies inside the file, then return the data as the ELF with
no missing metadata headers.
The SELF path is unchanged.

Test:
Manual: a clean 1.09 Itemzflow dump (raw ELF, 89.3 MiB) failed at prepare.py before and launches now. 
Player is able to make a character, start a new save, and play normally with a clean 1.09 Itemzflow dump.
2026-11-02 01:54:21 -03:00
Mrsuss60 85d9bc98da Merge branch 'master' of https://github.com/Mrsuss60/bloodborne_pc_windows_port 2026-11-01 21:42:11 +00:00
Mrsuss60 7889ca068a launcher: update launcher version to v0.8.0 2026-11-01 21:41:59 +00:00
MrSuS60 0176a88b3f Update README.md 2026-11-01 19:06:27 +01:00
MrSuS60 2cc3764f59 Use MZ_ZIP_FLAG_WRITE_ALLOW_READING to build with miniz < 3.1
Use MZ_ZIP_FLAG_WRITE_ALLOW_READING to build with miniz < 3.1
2026-11-01 16:11:54 +01:00
HatsyRei ac726e6313 cache_storage: use MZ_ZIP_FLAG_WRITE_ALLOW_READING to build with miniz < 3.1
MZ_ZIP_FLAG_READ_ALLOW_WRITING only exists in miniz >= 3.1.0. The reader ignores the writer flag, and FinishPreload() reopens the archive as r+b via mz_zip_writer_init_from_reader(), so the cache stays writable.
2026-11-01 22:51:26 +08:00
Mrsuss60 d81d63be3c gpu, launcher: PM4 buffer chaining, CE FIFO, GC part 2 (issue #184), async pipelines & skip network choice
Port PM4 packet improvements, constant engine task scheduling, and garbage
collector verification from shadps4, along with launcher async pipeline controls
and automated title screen offline dialog bypass.

Upstream shadps4 reference commits and features:
- b6f0c58d & 9d3524f5 (Liverpool/AMDGPU): Implement IT_STRMOUT_BUFFER_UPDATE
  for streamout buffer offset tracking and handle IT_GET_LOD_STATS in both
  graphics and compute command queues.
- 1b9d1591 (Liverpool/AMDGPU): Follow chained indirect buffers (INDIRECT_BUFFER
  with chain bit set) by directly replacing the active command span rather than
  nesting tasks, preventing call-depth recursion and stack overhead.
- 626f3ace (AMDGPU / Texture Cache): Support stencil-only depth targets and
  decouple stencil slice sizing from color/depth aspect sizing logic.
- f9d07487 (Liverpool/AMDGPU): Implement global Constant Engine (CE) task FIFO
  scheduling across graphics submissions with scheduler-yielding waits.
- e6faa2e3, 0918faa0, eedf851a (Video Core / Memory - shadps4 Issue #184):
  - Integrate Garbage Collector Part 2 download verification (HasGpuValidData()
    and CanBeDownloaded()) to safely reclaim GPU memory without guest desync.
  - Implement deferred verification queue (maybe_download) using native Win32
    pointer hashing (XXH3_64bits) instead of emulator address-space lookups.
  - Add edge-page protection (ReadEdgeImagePages) and modification invalidation
    (MarkDirtyIfEdgesModified) to prevent edge page corruption.
  - Preserve fork-specific optimizations: custom idle threshold
    (BB_GC_IDLE_SECONDS), depth target fast-free paths, and submission rate
    limiters.

Launcher & Game Patch additions:
- Async Pipelines: Exposed the BB_ASYNC_PIPELINES setting in the launcher UI
  under GPU Adapter (Auto, Off, 1, 2, 4, 8 threads) for background Vulkan
  pipeline compilation. Realigned dropdown dimensions and layout.
- Skip Online/Offline Screen: Integrated the "Skip Online/Offline Choice"
  patch in patches/Bloodborne.xml (detouring 0x01f39030 to 0x1b49cd0) to bypass
  the PSN network choice prompt directly to the main menu. Enabled by default
  in scripts/patches.py (SKIP_NETWORK_CHOICE_DEFAULT = True) with support for
  BB_SKIP_NETWORK_CHOICE=0 and bbport.ini overrides.
2026-11-01 11:43:24 +00:00
Mrsuss60 b62051dba1 shader_recompiler: modernize CFG reconstruction, Phi optimization, and math lowering
Port essential compiler correctness, instruction lowering, and control-flow fixes
from upstream shadPS4 to eliminate shader translation aborts, prevent uniform
register corruption, and ensure deterministic SPIR-V code generation.

Changes & upstream shadPS4 commits incorporated:
- 524be7c1: Exclude GetUserData from Phi folding to prevent corrupting push constant/buffer table inputs.
- 603cff43: Stabilize Phi deduplication order to guarantee deterministic SPIR-V output and pipeline cache consistency.
- ab1dd384: Lower undefined 64-bit integer values to OpUndef in the SPIR-V emitter.
- a808e762: Accept S_SLEEP as a scheduling hint (no-op with warning) instead of aborting shader translation.
- 6752d8b1: Correct operand metadata for BUFFER_WBINVL1 / BUFFER_WBINVL1_SC and lower them to device memory barriers.
- 08225c2b: Account for singleton workgroup dimensions in LDS barrier analysis for compute shaders.
- 78bedfac: Preserve CFG fallthrough edges and halt lookahead on terminators to fix structured control flow reconstruction.
- f0ea8eb7: Handle HW_ID.SE_ID hardware register reads in S_GETREG_B32 as virtual engine zero.
- de278985: Support GsOp::EmitCut in S_SENDMSG and add missing stream field to SendMsgSimm.
- b61f6c57: Add fast_shader_math option to relax float rules in fragment/compute stages, and bump shader cache binary version.
2026-10-31 21:38:26 +00:00
Mrsuss60 6b2cc0e07c video_core: modernize command processor sync, packet pacing, and texture cache
Port critical stability and synchronization fixes from upstream shadPS4 to improve
command ring buffer pacing, eliminate CE/DE counter desyncs, and prevent texture
cache thrashing.

Changes & upstream shadPS4 commits incorporated:
- e6c79a5f: Validate ce_task.handle before .done() and prevent underflow in WaitOnDeCounterDiff.
- 7ea677e5: Pre-read packet size before execution in graphics/CE loops to prevent ring reuse races.
- c64a1e0a: Handle PM4 Type 2 padding packets and use atomic acquire on PM4CmdRewind::Valid().
- e0845a12: Fix string format name for NumberFormat::Ubscaled in pixel format enum.
- ca36c7e3: Implement SubresourceExtent::Contains() for per-dimension mip/layer matching.
- 699009c9: Guard ExpandImage copies with HasGpuValidData() to avoid overwriting CPU-dirty data.
- d3ff0e0c: Immediately register and track parent images in ResolveOverlap to preserve subresource slices.
- 0cd6e4f2: Bound attachment-less render pass areas by GetCombinedScissor() to prevent oversized framebuffers.
- b3d46e96: Verified full mip-chain transfer handling in CopyImageWithBuffer.
2026-10-31 20:56:30 +00:00
Mrsuss60 c3f55890c2 audio: resolve crackling, stuttering, and clipping on low-spec CPUs
- Remove aggressive thread priority overrides to prevent CPU starvation on low core-count processors.
- Strip synthetic gain boosting and limiter saturation in favor of direct, uncolored volume calculation.
- Increase audio queue cushion threshold to comfortably cover WASAPI device periods.
- Streamline output pacing pipeline and remove obsolete Win32 timer resolution calls.
2026-10-31 19:02:27 +00:00
Mrsuss60 da42893471 Revert 624ac74921 2026-10-31 17:42:18 +00:00
Mrsuss60 624ac74921 vulkan: remove legacy sparse arena and implement dense VRAM buffer mirrors
- Completely eliminated legacy sparse memory binding (vkQueueBindSparse),
  preventing multi-second queue driver stalls and freezes on NVIDIA/Intel GPUs.
- Replaced the sparse arena with dense, device-local VRAM mirrors using 16 KiB
  block granularity and dynamic growth/merging up to 64 MB.
- Integrated mirror allocations directly with the Vulkan Buffer Device Address
  (BDA) in-shader page table mapping.
- Added foundational layer memory and buffer memory model modules in preparation
  for direct host-memory imports and residency management.
2026-10-31 12:22:14 +00:00
Mrsuss60 dcdb834f99 vulkan: import upstream shader caching & memory optimizations, fix live FPS camera tracking
Ported performance and pipeline optimizations from upstream bbport(https://github.com/deadinside28/bloodborne_pc/commit/0fc2921c45f8ff3900f6bfa43a299e9a4f532af4):
- Optimized virtual memory mappings in win32_memory: replaced repetitive
  VirtualQuery syscalls with direct internal view range lookups.
- Implemented constant ring buffer deduplication in the Vulkan rasterizer
  using XXH3 hashing and dynamic VRAM-budgeted ring sizing.
- Added shader recipe import and background pre-compilation support,
  enabling seamless warmup from shader_recipes.bin without hitching.
- Added compute copy shader HLE bypass to skip identical memory blocks.
- Integrated NVAPI profile initialization to enforce high-performance
  power management states on NVIDIA GPUs under Windows.
- Polished the in-game shader compilation indicator with subtle styling,
  animated spinner, and clean synchronization with the F11 HUD toggle.
Live FPS & Camera tracking fixes:
- Fixed delayed third-person camera follow and excessive camera pull-back
  distance when sprinting under the dynamic clock / deltatime patch.
- Cleaned out 41 artificial camera damping overrides in Bloodborne.xml,
  restoring authentic 1:1 camera response and physics across uncapped
  and variable framerates.
2026-10-29 23:34:46 +00:00
Mrsuss60 83a168eee2 fix(core): fix live FPS 60 cap and restore static XML presets
- Uncapped guest frame pacer ceiling to 240 FPS so 90/120/Uncapped targets can exceed 60 FPS.
- Fixed launcher setting BB_FPS_PATCH=0 when live mode is disabled, which previously locked static presets back to 30 FPS.
2026-10-29 14:54:05 +00:00
Mrsuss60 f8f450b19f renderer & runtime: fix crashes 139/140, BC6H format rejections, and texture stalls
- Runtime: Expand Bloodborne v1.09 signature detection to recognize EU (CUSA00207),
  Asian (CUSA03023), and Japanese (CUSA00900) regional SKUs, as well as 01.00
  base disc SFOs. Fixes VEH recovery guards being skipped on non-US dumps,
  preventing exit code 140 crashes (#175).
- Vulkan Scheduler: Fix premature chunk retirement in RecordData that caused
  mid-batch chunk splitting. Pointers passed into pushDescriptorSetKHR and
  bindVertexBuffers now reliably stay alive within the same chunk as their
  commands, eliminating host driver NULL dereferences (crash code 139).
- Texture Cache: Fallback to non-storage usage flags when drivers reject
  STORAGE_IMAGE on compressed image formats like BC6H (#174).
- Texture Cache: Batch ProcessDownloadImages into a single GPU flush and barrier
  wait rather than synchronizing per texture, eliminating multi-second stalls
  and watchdog freezes when opening menus or loading item icons (#176).
- Texture Cache: Add allocation checks prior to accessing slot_images in lookup
  and overlap resolution to protect against UAF.
2026-10-28 01:11:54 +00:00
Mrsuss60 a7cbfae63e core: implement dynamic live FPS patching and high-framerate physics stabilization
Replaces static framerate caps with a dynamic in-engine clock and deltatime
patching system, allowing arbitrary framerate targets (60, 90, 120, Uncap)
and on-the-fly switching without requiring game restarts.

Physics & Animation:
- Fixed collision clipping, player jitter, and character desync on
  moving platforms when running above 30 FPS.
- Added a cloth simulation frametime stabilizer to eliminate Havok cloth
  flutter and vertex spikes during framerate fluctuations.
- Clamped physics deltatime scaling to maintain consistent gravity, jump arcs,
  and attack animations at high refresh rates.

Launcher & Safety:
Launcher & Safety:
- Added real-time conflict filtering: enabling Live FPS automatically disables
  and locks out conflicting legacy patches (FPS++, Sprint Fix, Performance Patch)
  in both UI and backend to prevent memory write collisions.
- Added eboot validation on launch with graceful fallback to XML patches if an
  unsupported executable layout is detected.
- Updated launcher dropdown labels to indicate active patch mode (Live vs XML).
2026-10-27 23:16:19 +00:00
Mrsuss60 7b4bb9576c launcher: update launcher version to v0.7.1 2026-10-26 18:08:48 +00:00
Mrsuss60 6efb5ac1e8 runtime: harden allocator faults, chunk execution, and diagnostics
Implement defensive recovery guards for guest allocator exhaustion,
validate deferred Vulkan record chunks before execution, introduce a
secondary runtime toggle word, and improve build tracking in crash dumps.
- Crash recovery guards (probe.c):
  - Handle null allocations at 0x2199310 (16-byte block) and 0x4370b6
    (40-byte block) by substituting a zeroed host-aligned allocation and
    replaying the faulting instruction, preventing hard access violations.
  - Add PE header metadata (TimeDateStamp, SizeOfImage, CheckSum) and
    compilation timestamps into crash logs to correlate dumps with exact builds.
- Vulkan scheduler (vk_scheduler):
  - Add RecordChunk::InChunk bounds checking during deferred command
    execution to detect corrupted intrusive list pointers, dropping the
    malformed remainder instead of crashing on invalid vtables.
- Optimization toggles (bbport_toggles, runtime_memory):
  - Introduce a second 64-bit toggle mask (BB_TOGGLE_FILE2) polled by a
    dedicated watcher thread.
  - Relocate StableMotionHash to word 2 bit 0 (unsharing bit 41 with
    RecorderFences) and add DefensiveGuards (bit 1) as a fallback switch.
- Launcher (bblauncher_app):
  - Automatically configure BB_INTEL_TONEMAP_FIX for Intel processors
    while preserving explicit environment variable overrides.
Addresses reported crash logs from Discord.
Closes #158, closes #168, closes #171, closes #172
2026-10-26 17:04:38 +00:00
Mrsuss60 f8597057ed ui: consolidate visual settings and tweaks into the F4 menu
Streamline in-game configuration by eliminating duplicate settings
between the INSERT setup menu and the F4 tweak overlay. All visual
toggles, camera tools, and engine-level post-processing options are now
centralized under F4 > Visual & Graphic Tweaks.
- INSERT menu: remove duplicate effect toggles (Chromatic Aberration,
  DoF, Motion Blur, SSAO, Skip Intro) and clean up layout spacing
  between Output Resolution and Performance & CPU.
- F4 overlay: integrate Model Detail selector, Dynamic Light Shadows,
  SSR Reflections, Free Camera, and Debug Menu (with dual hint markers).
- Renaming: update built-in anti-aliasing label to "Native Game AA".
- Categorization: move Skip Intro from Combat to Visual & Graphic Tweaks.
- Search & state: hook newly moved options into the F4 cheat search
  filter and include relevant entries in the restart-required check.
2026-10-26 13:59:54 +00:00
Mrsuss60 92c1461054 overlay: make in-game overlay permanently active
Hardcode the in-game overlay to always initialize rather than allowing
it to be toggled off. Toggling the overlay off breaks character creation
because the game relies on ImGui input dialogs to enter player names.

- Launcher UI: remove the overlay configuration checkbox from the
  Display & Graphics tab and re-align remaining layout controls.
- Launcher backend: force feat_overlay to True and strip BB_OVERLAY
  from the child process environment on launch.
- Engine runtime: remove the BB_OVERLAY=0 bypass from BbOverlay::Init()
  so the presentation and dialog layer cannot be accidentally disabled.
2026-10-26 13:58:21 +00:00
Mrsuss60 466e8e7dd4 renderer_vulkan: improve temporal upscaler clarity and depth downsampling
Address severe blur, smearing, and ghosting across the temporal upscaling
and anti-aliasing pipelines (FSR 3.1, FSR 4/4.1.1, DLSS, and TAA):
- Conservative depth downsampling: route pure depth buffers through shader
  resampling with a 2x2 min-filter (forward-Z) when downscaling, eliminating
  bilinear depth edge bleeding and silhouette disocclusion halos.
- TAA responsiveness: update default accumulation history weights from
  0.98/0.85 to 0.88/0.75 to mitigate ghosting trails, and enable YCoCg
  bounding box clipping, variance clipping, tonemap blend, and 3x3 filtering
  by default.
- Motion vector stability: mask out transient buffer base addresses when
  hashing buffer descriptors for motion geometry tracking, preventing
  dynamic ring-buffer pointer drift across frames from invalidating motion data.
- Tuning & diagnostics: add environment overrides for FSR 4.1.1 motion vector
  scale mode (BB_FSR411_MV_UV), TAA camera jitter negation (BB_TAA_JITTER_INVERT),
  and global sharpness default (BB_SHARPNESS_DEFAULT).
2026-10-25 23:15:45 +00:00
Mrsuss60 2083ff8be9 perf(vulkan): parallelize pipeline cache warmup and memoize draw key selection
Optimize startup load times and GPU command thread throughput by parallelizing shader module preloading and eliminating redundant per-draw pipeline key rebuilds:
- vk_pipeline_serialization: restructure PipelineCache::WarmUp into a two-pass parallel flow. Pass 1 deserializes metadata and stages SPIR-V bytecodes; background workers compile VkShaderModule handles concurrently via PipelineCompiler with stage deduplication; Pass 2 creates pipeline objects synchronously on the startup thread. Add boot-time duration logging, with BB_WARMUP_ASYNC=0 available as a sequential fallback.
- vk_pipeline_cache: add a single-entry SelectionCache on the GPU command thread. When a draw misses TryPreparedPipeline but shares the previous draw's gfx_reg_checksum and indirect SGPR offsets, reuse cached selection state directly and skip RefreshGraphicsKey (memset, register decoding, color buffer loops, and stage re-specialization). Gated on BbToggle::SelectionCache (bit 60).
- vk_pipeline_cache: expose PipelineCompiler in the header and centralize worker instantiation through PipelineCache::GetCompiler(), ensuring CPU thread clamping applies consistently to both warmup and runtime async compilation.
2026-10-25 19:55:04 +00:00
Mrsuss60 bb91ba0537 perf(vulkan): cache auxiliary tess/clip shaders, tune async compilation, and optimize prepared-draw validation
Implement targeted performance optimizations and compilation hitch reductions across the Vulkan pipeline cache, draw preparation, and shader lifecycle:
- vk_graphics_pipeline: cache unique auxiliary VkShaderModule instances (rect-list TCS, quad-list TCS, passthrough TES, and discard fragment shaders) across pipeline creation to eliminate redundant SPIR-V recompilation; clear safely during PipelineCache teardown (gated on BbToggle::AuxTessCache)
- vk_pipeline_cache: lower default full-screen async compilation index cutoff from 12 to 6, and expose BB_ASYNC_FULL_SCREEN=1 override to lower the cutoff to <= 3 without dropping single-triangle post passes (gated on BbToggle::AsyncFullScreenTuning)
- vk_pipeline_cache: embed a 64-bit flat-buffer hash (XXH3) into Program::Module upon specialization, performing an early-reject filter in TryPreparedPipeline prior to calling std::memcmp (gated on BbToggle::FlatHashValidation)
- vk_pipeline_cache: clamp background PipelineCompiler worker threads to max(1, concurrency / 4) on <=8 hardware threads to prevent CPU starvation and Stage A GPU thread preemption on low-core systems
- vk_pipeline_cache: replace node-based std::unordered_map for target_streaks with an open-addressing tsl::robin_map and reserve 128 buckets to eliminate dynamic heap allocations on the GPU thread
- vk_draw_prep: make MaxScanLag rebase threshold configurable via BB_PREP_SCAN_LAG and reduce the default from 64 to 16, decreasing scanner catch-up latency on weak CPUs
2026-10-25 18:25:59 +00:00
Mrsuss60 45e4500328 fix(cheats): eliminate error 487 by dynamically allocating and retargeting JSON scratch page
When opening the F4 Cheats & Tweaks menu, some systems threw "Could not commit the JSON scratch page (Win32 error 487)" (ERROR_INVALID_ADDRESS). This occurred because the derived scratch address (image_base - 0x3FC000) was already reserved by a VirtualAlloc2 placeholder or third-party module reservation, which cannot be committed via standard VirtualAlloc(MEM_COMMIT).
- AllocateJsonScratchNearImage: scan for genuine MEM_FREE 64 KiB granules within +/-2 GiB signed RIP reach of the 1 Hit Kill code cave (image + 0x50DB869) when the primary scratch address is occupied.
- AllocateJsonScratchInGuestSpace: as a fallback, carve out and replace a single 64 KiB placeholder granule in the guest low-map range ([0x0800000000, 0x1000000000)) using VirtualAlloc2 with MEM_REPLACE_PLACEHOLDER.
- PatchOneHitKillScratch: recalculate and update the signed 32-bit RIP displacement for the cmp rbx, [rip+disp32] instruction in the 1 Hit Kill code cave (0x50DB862) to match the allocated scratch address.
- EnsureJsonScratchLocked: only commit genuinely free pages; gracefully fall back to the dynamic allocator and retarget both references without failing or losing the JSON master state.
2026-10-25 15:23:39 +00:00
Hatsy Rei 4ad13c6ee5 Merge pull request #170 from HatsyRei/fix/pointer-scroll
fix(input): menu pointer hover refresh item details, no longer fight scrolling
2026-10-25 19:56:38 +08:00
HatsyRei cd4ca77e06 fix(input): stop the menu pointer fighting the mouse wheel
Moving the mouse while scrolling a menu with the wheel made hover and the
wheel take turns at the cursor. Each notch is a pad Up/Down pulse (50 ms
held, 50 ms gap, up to 8 queued) and hover was only refused while a
direction was held, so any movement in a gap snapped the cursor back under
the pointer and the next notch stepped from there.

- A wheel notch now gives the wheel the cursor: hover is refused
  (host_wheel_holds_cursor) and the window hides the OS cursor.
- While pulses are pending and for 400 ms after the last notch, movement
  is ignored. After that, moving 10 stage pixels, or a click, hands the
  cursor back to the pointer and drops any queued pulses. Leaving the menu
  resets it.
- BBHOST_POINTER_LOG=1 logs when the wheel takes and releases the cursor.
2026-10-25 14:55:09 +08:00
HatsyRei c0611c89e7 fix(input): refresh item details when the menu pointer hovers a row
Hovering a row in the Inventory or Item Storage moved the highlight but
left the item name and description on the previous item; the wheel and
the pad updated them.

The pointer sets the cursor itself (sub_1ecf6b0) and then calls the list's
cursor listener, as sub_1ecff30 does after a pad move. It only called
functions opening with push rbp; mov rbp,rsp, and the item list's
listener (vtable 0x57393b0, slot 0x1f128f0) is a frameless thunk
(mov rax,[rdi+8]) forwarding to the dialog's refresh (0x1faa350:
sub_1f9d3a0, sub_1f9c010, sub_1f9d840). It was skipped silently.

The listener is now called when its vtable lies in the eboot image and the
slot points into the eboot's code, prologue or not. BBHOST-PORTS.md notes
the deviation from bbhost.
2026-10-25 14:54:59 +08:00
Mrsuss60 7c0e5f0d20 fix(crash): root-cause Dantelion2 heap init, asset copy cascade, texture cache UAF and swapchain recovery
Recent 0.6.5 crash reports (#159, #160, #165, #166, #167 and Discord reports) surfaced recurring crashes across the guest heap allocator, asset structure copy cascade, texture cache slot lookups, Vulkan swapchain presentation, and out-of-bounds patch addresses.
- probe: allocate a dedicated 128 KiB thread-local bump arena for Dantelion2 DLTemporaryHeap when RCX is NULL; gate recovery behind CUSA03173 v1.09 runtime verification (image extent, static TLS offset -1840, and param.sfo title/version)
- probe: restore asset structure copy destination R13 with an aligned low-alloc buffer and replay the 920-byte copy at 0x21d5b45 instead of skipping to the epilogue; remove the ineffective Rip+=5 fallback at 0x2199310
- texture_cache: validate slot_images.is_allocated() before accessing cached image descriptors in FindImage(); invalidate memoized find_image_cache entries when an image is unregistered or deleted to eliminate SlotVector use-after-free crashes
- vk_swapchain: handle VK_ERROR_OUT_OF_DATE_KHR, VK_ERROR_SUBOPTIMAL_KHR, and VK_ERROR_SURFACE_LOST_KHR gracefully via swapchain recreation instead of asserting
- patches: remove duplicate out-of-bounds 0x0603AC8D and 0x0603AD1A entries from the performance patch in Bloodborne.xml that targeted unmapped memory beyond the ELF data segment
Addresses #159, #160, #165, #166, #167 and reported issues on discord server.
2026-10-24 19:18:58 +00:00
Mrsuss60 26198d6a44 launcher, input: add system hotkeys column, AZERTY/QWERTY presets and reliable process termination
Enhance keybinding management with layout awareness, expose dedicated
system hotkeys in the launcher, and ensure clean game process termination.

- System Hotkeys:
  - Add a dedicated, keyboard-only right column for In-Game Overlay (Insert),
    Performance HUD (F11), Cheat Menu (F4), and Mouse Capture/Release (F1).
  - Prevent accidental menu triggers during mouse combat by enforcing
    keyboard-only assignments for system actions.
  - Mouse capture hotkey now toggles both release and recapture.
- Keyboard Layouts & Presets:
  - Store bindings as physical SDL scancode names while dynamically displaying
    the active Windows layout character (e.g. physical W displays as Z on AZERTY).
  - Add one-click AZERTY (ZQSD) and QWERTY (WASD) movement preset buttons
    to the keybind header.
  - Separate in-game display names from persistent ini storage keys to avoid
    config corruption across different locales.
  - Support automatic keybind conflict swapping.
- Process Termination:
  - Re-architect game process termination to asynchronously kill the full
    process tree in the background without freezing the UI.
  - Sweep orphaned bbport.exe processes on exit and handle premature STOP requests.
- Stubs & Tests:
  - Add bbgpu_menu_pointer_mouse_buttons link stubs to test_pad.c.
2026-10-24 10:10:54 +00:00
MrSuS60 5831879a2e Merge pull request #164 from HatsyRei/fix/storage-right-click
fix(input): handle RMB for item Storage page
2026-10-24 00:01:09 +01:00
Mrsuss60 b84dcb359c gpu, input: add F4 in-game cheats & tweaks menu
Add an independent in-game ImGui Cheat & Debug Menu window toggled via F4
or gamepad chord (L1 + R1 + Back/View), providing 17 live, reversible
memory patches across 4 categories.

- Data sources:
  - patches/CUSA03173_01.09.json: sourced from shadps4-emu/ps4_cheats
    (https://github.com/shadps4-emu/ps4_cheats/blob/main/CHEATS/CUSA03173_01.09.json)
    by Shiningami + bloo, providing explicit on/off byte sequences.
  - patches/Bloodborne.xml: community tweaks, QoL, and visual effect toggles.
- Patch categories: Player/God Mode (Infinite Health/Stamina, No Dead,
  Stealth, Silent), Items & Echoes (Infinite Echoes, Insight, Items),
  Combat & World (1 Hit Kill, Enemy Control, Disable Rally, Sensitive Analog,
  Skip Intro), and Visuals (Disable Motion Blur, DoF, SSAO, Chromatic Aberration).
- Live engine: gpu/shim/bbport_cheats safely writes and restores memory in
  guest image bounds using VirtualProtect with automatic rollback on error.
- Crash prevention & safety:
  - Relocates JSON master hook storage to an allocated read/write scratch page
    (image_base - 0x3FC000) so 1 Hit Kill can verify player pointer without
    crashing on unmapped memory.
  - Zydis instruction validation verifies target memory operands are committed
    and valid before patches apply.
  - Patching gates on runtime_guest_image_ready() (src/probe.c) to ensure
    startup relocations and module initializers have completed.
- UI & persistence: independent ImGui window with search filter, active count,
  and Enable/Disable All; choices persist under [Cheats] in bbport.ini
  protected by save_mutex.
2026-10-23 21:47:11 +00:00
Mrsuss60 466e30ebc4 input, gpu: dynamic keyboard, mouse and gamepad HUD button prompts
Replace the game's native PlayStation button prompt icons in key guides,
tutorials, and HUD prompt atlases with icons matching the active input device.

- Device tracking: runtime_pad detects active device (PlayStation pad,
  non-PS gamepad, keyboard/mouse) and bumps an atomic generation counter on
  device, gamepad model, or binding changes.
- Async icon loader: parses menu/common.tpf.dcx via vendored miniz without
  blocking the render loop; matches 32x32 BC7 icons and HUD atlas cells by
  XXH3 content hash rather than filenames.
- Icon rasterizer: renders 128x128 RGBA key caps, mouse glyphs, chords,
  and controller labels using the embedded font.
- Vulkan redirection: vk_button_prompts manages an image array layer per icon
  and uncompressed patched atlas copies; vk_rasterizer intercepts prompt
  texture bindings and bypasses memoized texture sets on active override.
- Immediate mouse response: window-level mouse activity timer ensures prompts
  switch to KBM immediately even when cursor capture is off or native camera
  owns the mouse delta.
- Fallback & safety: missing or unreadable common.tpf.dcx, unbound inputs,
  D-pad, and BB_BUTTON_PROMPTS=0 keep the game's original icons.
- Vendored miniz 3.0.2 under gpu/third_party/miniz/ (Unlicense) linked statically
  into bbgpu; notice added to licenses/third_party/SOURCE-NOTICES.txt.
2026-10-23 11:33:05 +00:00
HatsyRei e0a64d48c6 fix(input): handle RMB for item Storage page
When mouse pointer is enabled, RMB acts as Back everywhere. In Item Storage
it closed the screen instead of pressing its default binding (L2), to
switch between storing and retrieving.

Storage is recognised by the menu step the game names L"depository"
(sub_1fba4f0), found from the flow's open menu, while its item list has focus.
There, when right click is bound to L2 with M&K controls on, right click presses
L2; otherwise, in the item popup and in every other menu it still goes back.

The pad sampler now reads the mouse while the pointer owns it and skips only
the buttons the pointer uses, so middle/side buttons keep their bindings in
menus too. tests/test_pad.c gains stubs for the pointer's functions.
2026-10-23 12:57:43 +08:00
Mrsuss60 116e1c2951 Add optional DLSS Super Resolution to the Vulkan upscaler path, selectable as upscaler=dlss in bbport.ini, the in-game overlay, and launcher.
EXPERIMENTAL: real DLSS rendering and live preset switching.

- New MSVC-built bbport_dlss.dll bridge (gpu/dlss_bridge, MIT); the port
  loads it with a plain C ABI and carries no NVIDIA headers.
- NVIDIA NGX SDK headers and link library (nvsdk_ngx_s.lib, static CRT)
  vendored under the NVIDIA RTX SDK license; nvngx_dlss.dll is loaded from
  user/dlss/ or out/ and is not committed.
- Same temporal inputs as FSR 3.1 (colour, depth, motion, jitter, reset)
  plus frame time and sharpness; preset=0 maps to DLAA.
- dlss_preset=0|10|11 adds the J/K render-preset hint; overlay row shown
  only while DLSS is selected.
- Graceful fallback to FSR 3.1 for missing bridge/runtime, BB_DLSS=0,
  non-RTX GPUs, and NGX failures.
- Create the NGX feature before the pass is recorded and release it only
  after scheduler.Finish(); the previous path freed state that an
  unsubmitted command buffer still referenced and was the likely cause of
  the 0xC0000005 crashes on RTX cards when changing presets live.
  Removes Scheduler::WaitSubmittedWork().
- build.bat builds the bridge with MSVC via vswhere; all other targets
  stay MinGW-w64. BB_DLSS_BRIDGE=0 skips the step.
2026-10-22 22:47:26 +00:00
Hatsy Rei 8d9ee1a2aa Merge pull request #161 from HatsyRei/fix/monocular-mouse-look
fix(input): mouse look in the monocular
2026-10-22 23:27:21 +08:00
HatsyRei 87011f0943 fix(input): mouse look in the monocular (aim camera)
The camera manager (switch on mgr+0x84 at image+0x1436be6) only runs the
follow camera update (0x143ac60) in modes 0 and 3. Modes 1 and 2 run the
aim camera update (0x1433860) used by the monocular, which the native mouse
hook never reached, so the view stayed locked to the character's facing and
mouse motion piled up until the follow camera came back.

Hook the aim camera's two call sites with a small SysV->Win64 thunk. The aim
camera keeps its own pitch/yaw (+0x148/+0x14c) and adds stick * speed * dt,
so the mouse delta is added there directly: signed by the stick speeds to
match gamepad direction, scaled by the zoom ratio the game applies to the
stick, and only while the camera accepts stick input (+0x188).

The mouse delta processing (sensitivity, acceleration, smoothing) and the
stick offset cleanup are split out of host_native_mouse_inject unchanged so
both cameras share them.
2026-10-22 22:39:51 +08:00
Hatsy Rei d81863f1bd Merge pull request #157 from HatsyRei/fix/mouse-lock-on-switch
fix(input): restore mouse flick lock-on switching
2026-10-22 17:46:07 +08:00
HatsyRei 04dd406111 fix(input): restore mouse flick lock-on switching, drop stale delta on unlock
The native camera hook (6d59baa) skipped updates while locked on and the
pad no longer mapped the mouse to the right stick, so flicks never
switched targets. Deltas also piled up during lock-on and were applied
as a camera jump once it ended.

- Pad maps mouse movement to a decaying right-stick impulse whenever
  the hook doesn't own the mouse (locked on, or hook inactive).
- Hook reports lock-on state and discards leftover delta and smoothing
  state when lock-on ends.
2026-10-22 09:04:03 +08:00
Mrsuss60 4035ab4e13 fix(crash): root-cause allocation failures, assert diagnostics, non-BMI1 LZCNT and TLS
The 0.6.3 crash reports (#148, #149, #151, #155) all reached the same
generic exit 139, and "code 23" came from raise_exception's exit(23)
with no dump, so unrelated failures looked identical.

- runtime_memory: record and report every allocation failure
  (operation, size, params, host error); surface the last failure in
  runtime_report() and in every crash dump
- probe: hook the guest panic printer at 0x20b55b0 and capture the
  assert id and both strings; full dumps for the first 50 asserts,
  compact append to out/assert_repeat.log afterwards
- runtime_kernel: raise_exception now logs, dumps and continues like
  retail; BB_GAME_ASSERT_STOP=1 stops with exit 142 instead of 23
- probe: patch LZCNT via a Zydis linear sweep using the real
  instruction length (406 sites, incl. redundant prefixes); stop
  patching 135 in-instruction data patterns; handle 16/32/64-bit
  operands and flags in the emulator
- probe: keep enter_on_stack arg1 in %rbx, skip wrfsbase on NULL TCB;
  FS guard rebases once and diagnoses instead of looping
- probe: richer crash dumps (fault classification, Zydis decode at
  RIP, host unwind + validated guest RBP chain, memory accounting)
- probe: classify exit codes 140 (guest NULL), 141 (abort trap),
  142 (assert stop), 132 (illegal instruction); reaper publishes the
  classified code so a blocking dump cannot revert to 139

Addresses #148, #151, #155. Ref #149.
2026-10-21 22:31:06 +00:00
Mrsuss60 0f60f96d5d feat(launcher): overhaul launcher UI, diagnostics dashboard, and advanced settings
Overhaul the PySide6 launcher with a multi-tab interface, improved diagnostics,
deeper graphics/engine controls, and bidirectional INI synchronization.
Key improvements:
- Tab Architecture: Restructure into Home/Dashboard, Display, Mouse & Controls,
  Patches & Effects, and Advanced tabs with lazy tab construction for fast startup.
- Home Dashboard: Add pre-launch environment audit (Game, Vulkan, AVX), session
  runtime clock, one-click system diagnostics copy, and a filterable log viewer.
- Display & Effects: Add FSR 4.1.1, upscaler presets, live resolution switching,
  Model LOD scaling, and granular toggles for all engine post-processing passes.
- Advanced Tab: Support runtime environment overrides (vblank, frames ahead, dmem,
  custom mods/patches/user directories) and INI reload/edit shortcuts.
- UX & Controls: Add drag-and-drop path inputs, slider wheel scroll guards, and
  bidirectional sync between launcher controls and bbport.ini.
2026-10-21 17:47:28 +00:00
MrSuS60 7a9231bfe6 Merge pull request #154 from HatsyRei/fix/launcher-shift-bind
fix(launcher): allow binding Shift on its own
2026-10-21 10:48:31 +01:00
HatsyRei fde3de8497 fix(launcher): allow binding Shift on its own 2026-10-21 08:34:31 +08:00
Mrsuss60 bc19f6fad4 update README and CHANGES 2026-10-20 23:30:28 +00:00
Mrsuss60 a5de376171 Strip unneeded DWARF debug symbols and relocation sections from bbport.exe and bb-probe.exe using strip -s.
This reduces executable binary sizes from ~260 MB down to ~12.4 MB (~95%
reduction) for both local batch builds and GitHub Actions CI artifacts:
- build.bat: invoke strip -s when strip.exe is present prior to creating bb-probe.exe
- .github/workflows/build.yml: add strip -s step during binary finalization
2026-10-20 23:24:05 +00:00
MrSuS60 2e572eaf4f Merge pull request #152 from HatsyRei/chore/license-staging
License compliance for release builds
2026-10-20 23:15:40 +01:00
HatsyRei 5d8c71bd8e chore(licenses): add notices for the launcher
BloodborneLauncher.exe bundles Python and Qt for Python. Ship the
Python licence and a notice for PySide6 and Qt (LGPL-3.0, with source
links) under licenses/launcher/, which CI copies with the build.
2026-10-20 23:09:32 +08:00
HatsyRei 88781c1f68 chore(licenses): add notices for vendored files
A few files in the vendored shadPS4 code and the GCN register headers
are MIT, BSD-3-Clause or Zlib rather than GPL: bit_field.h (Dolphin),
the SSA rewrite pass, AMD's FSR 1 shaders and GCN headers, and DXVK's
barrier tracker. List their copyright lines and licence texts in
licenses/third_party/SOURCE-NOTICES.txt, which CI ships with builds.
2026-10-20 23:09:32 +08:00
HatsyRei 4667f9f672 ci: ship notices for libraries built into bbport
Dear ImGui, LibAtrac9, FSR-Vulkan with its FidelityFX SDK sources,
sirit, SPIRV-Headers, half, the DejaVu font, robin-map, Vulkan Memory
Allocator, Vulkan-Headers, magic_enum, miniz and xbyak are compiled
into bbport.exe, and their MIT/BSD-style licences require the notice
with binaries. Copy each licence file into out/licenses/third_party/.

miniz, xbyak and magic_enum are fetched outside pacman, so keep their
licence files under /mingw64/share/licenses when installing them.
2026-10-20 23:09:32 +08:00
HatsyRei 229e98d345 chore(licenses): add notices missing from MSYS2
libtheora, libvpx, p11-kit (BSD-3-Clause), libvorbis (BSD-style) and
opencore-amr (Apache-2.0) ship no licence file in their MSYS2
packages, yet their licences require the notice with binaries. Add
the upstream files for the packaged versions (libtheora 1.2.0, libvpx
1.17.0, p11-kit 0.26.5, libvorbis 1.3.7, opencore-amr 0.1.6, including
its NOTICE) under licenses/msys2/, which CI copies into the build.
2026-10-20 23:09:32 +08:00
HatsyRei 94b0f5fc80 fix(build): don't stage Windows system DLLs
The import scan copied bcryptprimitives.dll, gdiplus.dll and
WSOCK32.dll out of the Windows directory. They are on every Windows
system and not ours to redistribute, so skip DLLs found there.
2026-10-20 23:09:32 +08:00
HatsyRei c286c57291 ci: ship licence texts with the Windows build
Stage LICENSE and licenses/ into out/licenses, together with the
licence files of the MSYS2 packages that own the bundled DLLs, and
upload them with the artifact. msys2/PACKAGES.txt lists each package
with its version and declared licence, plus the MSYS2 sources link.
2026-10-20 21:42:35 +08:00
HatsyRei 1023d5b8c2 chore(licenses): add LGPL 2.1 and 3.0 texts
Several bundled MSYS2 libraries are LGPL and rely on the standard
licence texts instead of shipping their own.
2026-10-20 21:15:34 +08:00
MrSuS60 4f6181c3f5 Merge pull request #150 from HatsyRei/feat/menu-pointer
feat(input): port bbhost mouse pointer support for in-game menus
2026-10-20 14:04:59 +01:00
HatsyRei 5b9353b773 docs: credit bbhost for the menu pointer
Credit droogie and the bbhost contributors, and note that builds with
the menu pointer are distributed under GPL-3.0-or-later.
2026-10-20 20:07:38 +08:00
HatsyRei 6791014a06 feat(launcher): add mouse pointer menu option
A checkbox in the Mouse & Keyboard card for bbport.ini mouse_menu,
kept in sync with the in-game overlay toggle.
2026-10-20 20:07:38 +08:00
HatsyRei c367451e81 feat(window): keep the cursor in game menus
While a game menu has focus, a click no longer captures the mouse for
the camera: left click chooses, right click goes back and the wheel
scrolls. Capture is released when a menu opens and taken back when it
closes, unless the window lost focus in between.
2026-10-20 20:07:37 +08:00
HatsyRei b93fb28768 feat(input): hook the menu pointer into the game
bbport_menu_pointer implements bbhost's host interface for this port:
safe guest reads, the cursor on the game's 1920x1080 UI stage, pad and
settings state. probe.c installs bbhost's list-update hook before the
image is protected, and the glue confirms the hook took.

runtime_pad.c adds the presses the pointer makes. A click, right click
or wheel notch is held for 50 ms with a 50 ms gap, so the game sees
each one as a single press.
2026-10-20 20:07:37 +08:00
HatsyRei edea92789d feat(settings): add mouse_menu option
bbport.ini mouse_menu (on by default) switches the mouse pointer in
the game's menus; the in-game overlay shows it as a checkbox under the
mouse and keyboard controls.
2026-10-20 20:07:37 +08:00
HatsyRei 540fdd484f feat(input): add bbhost menu pointer sources
Import src/engine/menu_pointer.{cpp,h} from droogie/bbhost at db5457c
(unchanged at 566184a) into gpu/shim/bbhost/, following DarkIzuku's
bloodborne_pc port. Only an SPDX/attribution header and, in the .cpp,
the include block differ from upstream.

compat.h declares the parts of bbhost's host interface the file uses,
with bbhost's signatures; features this port lacks are stubs.

These files are GPL-3.0-or-later, and so are builds containing them:
add licenses/GPL-3.0.txt and licenses/BBHOST-PORTS.md.
2026-10-20 20:07:37 +08:00
Mrsuss60 17d5806669 fix(core): correct BMI1/LZCNT emulation, graphics worker fault recovery, and module validation
fix(core): correct BMI1/LZCNT emulation, graphics worker fault recovery, and module validation

- Fix flag calculations in emulate_lzcnt_site (ZF on zero result) and emulate_bmi1 (CF/ZF for BLSR, BLSMSK, BLSI per Intel specification).
- Remove allocator BSR rewrite in patch_non_bmi1 that left dest undefined on zero inputs; route all LZCNT sites on non-BMI1 CPUs through UD2 traps.
- Remove broken heap alloc guard returning NULL at 0x207de26 that induced Dantelion2 transaction assertion panics.
- Add graphics worker job dispatch guard in win_veh_handler (0x21b4b30..0x21b4b55) to restore callee-saved registers and cleanly unwind culled batches to caller.
- Guard native mouse camera thunk against corrupt or unmapped jump targets with boundary clamping and DEP exception recovery.
- Add explicit existence and size validation for sce_module/libc.prx with contextual file names in prepare.py.

Closes #27
Closes #96
Closes #124
Closes #138
Closes #140
Closes #141
Closes #145
2026-10-20 00:08:49 +00:00
Mrsuss60 8a7e29d830 feat: Add launcher GPU selection, 21 text languages, and blur kernel assertion clamp
Port upstream improvements from deadinside28/bloodborne_pc (commit 8185b88):
1. Launcher GPU Selection & Complete 21-Language Support (#249):
   - Added `--gpus` CLI argument to `tools/gpu_capabilities.c` to enumerate all available
     Vulkan physical devices with vendor ID, device type, name, and default ranking.
   - Added a "GPU Adapter" dropdown under "Draw Prep Workers" in the launcher UI
     to allow explicit device selection on multi-GPU systems and laptops.
   - Expanded the launcher's Game Text Language selector to include all 21 localized
     PS4 text languages supported by Bloodborne.
   - Choices persist in configuration and pass `BB_GPU_ID` and `BB_LANGUAGE` to the
     engine runtime.
2. Crash 0xa0020007 (Code 23) Blur Kernel Clamp:
   - Implemented `raise_exception` in `src/runtime_kernel.c` bound to NIDs
     `OMDRKKAZ8I4#p#J` and `zE-wXIZjLoM#p#J`.
   - Filtered out non-fatal blur-kernel assertions (`code == 0xa0020007u`) from Yebis
     at call ranges 0xbbc3e0..0xbbc700 and 0xc33000..0xc34200 unless explicitly stopped
     with `BB_GAME_ASSERT_STOP=1`.
   - Added entry hook at `image + 0xbbc3e0` (`GPUTexUtil_GetRecursiveSampleParameters`)
     in `src/probe.c` to clamp sample count `edi >= 3`, preventing black screens and
     assertion trips during recursive texture sampling.
Upstream credits:
- deadinside28/bloodborne_pc@8185b88
Closes #126
2026-10-19 21:21:09 +00:00
MrSuS60 d7db864959 Merge pull request #147 from HatsyRei/master
Fix native mouse look turning slower when the mouse moves faster
2026-10-19 16:57:38 +01:00
HatsyRei 4fd204afdf fix(input): make native mouse look linear instead of speed-inverted
The camera update rebuilds pitch/yaw from the camera position each frame,
so the direct angle writes had no lasting effect; the right-stick buffer
was the only input that moved the camera. Injecting delta*25 pushed the
stick past 0.998, where the engine turns at a fixed rate that ramps up
while held and resets on reversal: slow motion turned fast, quick
back-and-forth motion turned slowly.

Below full tilt the engine turns by stick * speed * dt. For each axis the
mouse moved, push the stick half-tilt toward the delta and set that axis's
turn speed to 2*|delta|/dt for one update, so the camera turns exactly by
the mouse delta at any speed. The original speeds are restored on the next
update.

- Pass the update's frame time (guest xmm0) from the thunk to the hook.
- Remove our previous stick offset if the pad left the buffer untouched
  (it does not refresh it while loading).
- Drop the direct angle writes.
2026-10-19 22:39:01 +08:00
MrSuS60 85fbd269d0 Update README.md 2026-10-19 14:29:17 +01:00
MrSuS60 b3abb8bfaf Update README.md 2026-10-19 00:31:09 +01:00
Mrsuss60 2c9ca0288b docs(readme): clarify native CPU execution, shadps4 GPU backend, and direct camera hook 2026-10-18 21:12:10 +00:00
Mrsuss60 6d59baaffb feat(input): implement native 360 mouse camera hook and responsiveness tuning
- Replace synthetic gamepad stick emulation with a direct guest camera update hook at image+0x1436c00 and image+0x1436e15 targeting 0x183ac60.
- Inject raw mouse deltas into engine camera angles and dynamic controller stick buffer (rsi_ctx->0x58->0x280/0x80 + 0x40) with active orientation flag, enabling full 360-degree rotation (yaw and pitch) and real-time view matrix recalculation.
- Add pointer validation and range guards across all camera offsets and context pointers to prevent access violations.
- Respect engine target lock-on state and cursor capture state.
- Restore physical gamepad right stick passthrough without interference.
- Introduce customizable settings in overlay, launcher UI, and bbport.ini for mouse smoothing (0.00-0.80), responsiveness (0.50-2.50), and acceleration (1.00-2.00).
2026-10-18 20:35:19 +00:00
MrSuS60 1534296063 Update Credits.md 2026-10-18 13:57:20 +01:00
Mrsuss60 bb3f67b36e fix: resolve multiple engine and GPU crashes across memory, tiling, and particle routines
Addresses multiple crash scenarios reported in issues #127, #129, #134, #135, #136, and Discord reports:
- Fix #134: Resolve startup read violation at 0x207de26 in DLTemporaryHeap::Allocate by handling NULL heap pointers with clean ABI register unwinding and diagnostic logging.
- Fix #135: Prevent mid-game crash in msvcrt.dll memcpy by adding NULL pointer guards and contextual logging to guest_memcpy, guest_memmove, guest_memset, and guest_memcmp; add epilogue recovery for 0x21d5b45 asset copies.
- Fix #136: Prevent launcher patch startup crash at 0x443025 by catching NULL bucket chunk allocations and safely terminating the refill link loop without memory corruption.
- Fix #129: Fix Vulkan VK_ERROR_DEVICE_LOST in Central Yharnam by enforcing workgroup bounds (dim_x > 0) in TileImage and DetileImage, adding barrier flushes to compute passes, and flushing barriers before synchronous queue finishes.
- Fix #127: Extend Red Zone exception unwinding in probe.c to include functions 0x28d0160 through 0x28d064d, preventing signal 11 crashes during Ebrietas particle generation at >60 FPS.
-  Add validation for missing, empty (0 bytes), or truncated eboot.bin files in scripts/prepare.py with actionable error reporting.
2026-10-18 11:54:03 +00:00
Mrsuss60 78d3a40e8b bblauncher: add Off upscaler option, lazy-load tabs, reposition save button, and fix settings sync
- Add "Off" option to Upscaler Technology combobox:
  * Update UPSCALER_CHOICES with ("Off", "off"), ("FSR 3.1", "fsr31"), and ("FSR 4", "fsr4").
  * Establish bidirectional synchronization between the upscaler dropdown and the "Enable Temporal Upscaler" checkbox.
  * Block signals during programmatic updates to prevent feedback loops.
  * Persist "off" state to bbport.ini and export BB_UPSCALER=off upon launch when disabled.

- Improve launcher launch performance:
  * Implement true lazy tab loading: instantiate only the Home tab synchronously on startup, reducing window presentation time to under 100 ms.
  * Defer construction of Patches and Settings tabs until clicked, accompanied by idle background warming via QTimer.singleShot.
  * Replace 21 inline setStyleSheet calls on keybind buttons with a dynamic CSS property ([listening="true"]) in the central stylesheet.
  * Exclude unused Qt framework binaries from PyInstaller bundling (QtVirtualKeyboard, QtPdf, QtSvg, QtOpenGL, QtDesigner, QtHelp, QtSql, QtTest, QtXml) to accelerate %TEMP% decompression.

- Keybind UI repositioning:
  * Move "Save Input Parameters to bbport.ini" button to the keybind card header beside "Reset Keybinds to Defaults".
  * Remove redundant full-width bottom bar button.

- Settings and lifecycle synchronization fixes:
  * Flush current launcher settings and bbport.ini configurations to disk immediately prior to launching the game process.
  * Expand sync_bbport_ini_to_ui to synchronize upscaler selection and output resolution changes made via the in-game overlay.
  * Replace hardcoded stack indices with dynamic indexOf lookups during tab substitution.
  * Replace unicode em dash glyph in the minimize button with the standard minus symbol.
2026-10-18 01:05:40 +00:00
Mrsuss60 b363586db1 upscaler: enhance FSR 3.1 quality and add FSR 4 ML reconstruction with fallback
- Eliminate double anti-aliasing blur by automatically applying 'Disable AA'
  patch when temporal upscalers (fsr31, fsr4, taa) are active.
- Enable jitter, per-pixel object motion, and 0.65 RCAS sharpening by default.
- Apply FidelityFX negative mip bias (log2(render/output) - 0.5f) to retain
  fine texture detail under subpixel jitter.
- Clamp frame time delta to 66.7 ms (15 fps floor) to eliminate smear artifacts
  during render hitches and engine stalls.
- Integrate FSR 4 INT8 compute upscaler provider (VK_KHR_shader_integer_dot_product).
- Implement dynamic capability detection and missing-shader check with seamless
  automatic fallback to FSR 3.1 and in-game HUD diagnostics.
- Add upscaler technology selector to BloodborneLauncher and in-game overlay menu.
- Add fetch_fsr4_shaders.py asset download utility.
2026-10-18 00:26:01 +00:00
Mrsuss60 0a71dd171f gpu: sync upstream shadps4 min/max blend factor normalization and audit buffer sync
Upstream shadPS4 sync:
- Normalize min/max blend factors (shadps4-emu/shadPS4@c5dd8b8b):
  rewrite zero/one min/max blend factor combinations on UNORM and sRGB
  render targets into equivalent VK_BLEND_OP_ADD operations in LiverpoolToVK.
  Apply separately to color and alpha blend attachments in GraphicsPipeline,
  superseding the earlier ad-hoc alpha rewrite and suppressing spurious
  unimplemented blend factor warnings.
- Remove duplicate SynchronizeMemoryFromImage (shadps4-emu/shadPS4@098292a2):
  audited BufferCache::ObtainBuffer and confirmed the duplicate outer call
  is already absent in our port tree, with texture memory synchronization
  cleanly handled by SynchronizeMemory.
2026-10-17 21:28:47 +00:00
Mrsuss60 9bb2fb633e gpu: sync upstream shadps4 fixes for compute fast path, mip copy, subgroup barriers, and null index buffer
Sync four upstream shadPS4 fixes covering compute copy/clear detection,
multi-mip image copies, LDS synchronization, and index buffer fallback.
Upstream shadPS4 sync:
- Compute image copy/clear fast path with flatbuf (shadps4-emu/shadPS4@dade3afd):
  allow a user-data flat buffer as the third bound buffer in IsComputeImageCopy
  and IsComputeImageClear, restoring native vkCmdCopyImage and
  vkCmdClearColorImage fast paths when flatbuf user data is present.
- Copy every mip level in CopyImageWithBuffer (shadps4-emu/shadPS4@b3d46e96):
  remove ASSERT(num_mips == 1) and iterate over all mip levels with 16-byte
  aligned buffer offsets, batching transfers into a single submission to fix
  missing texture mips and potential transfer assertions.
- Subgroup LDS memory barriers (shadps4-emu/shadPS4@945dbc3c):
  introduce Opcode::SubgroupBarrier and emit OpMemoryBarrier with Scope::Subgroup
  and AcquireRelease | WorkgroupMemory semantics in SharedMemoryBarrierPass when
  workgroup size does not match HW subgroup or profile.needs_lds_barriers is
  false, preventing host compiler instruction reordering on lockstep LDS accesses.
- Null index buffer fallback and maintenance6 support (shadps4-emu/shadPS4@e9f2c54c, shadps4-emu/shadPS4@23c41333):
  add optional VK_KHR_maintenance6 detection and allocate a 16-byte device-local
  null index buffer in BufferCache when unsupported. Bind the fallback buffer or
  null descriptor when index base address is null or mapped size is zero, and
  use bindIndexBuffer2KHR with size when VK_KHR_maintenance5 is active.
2026-10-17 20:47:38 +00:00
Mrsuss60 cff5008539 gpu, launcher: sync shadPS4 upstream fixes and add draw prep worker tuning
Sync four upstream shadPS4 fixes and expose draw preparation worker thread
configuration across settings files and launchers.
Upstream shadPS4 sync:
- Coroutine leak fix (shadps4-emu/shadPS4@12c5978f): explicitly destroy indirect buffer coroutine
  frames in Liverpool ProcessCeUpdate, ProcessGraphics, and ProcessCompute
  after task completion, eliminating host heap leaks (~600 B per indirect buffer).
- First-page texture lookup (shadps4-emu/shadPS4@145932bf): query only the first page bucket in
  TextureCache::FindImageFromRange via ForEachImageWithAddress instead of walking
  every page in large multi-page ranges.
- EarlyFragmentTests for depth_before_shader (shadps4-emu/shadPS4@7d28d279): pass depth_before_shader
  through pipeline runtime info and emit spv::ExecutionMode::EarlyFragmentTests
  when shaders do not write custom depth, enabling early-Z rejection.
- Tiled texture download & eviction (shadps4-emu/shadPS4@e6faa2e3): support downloading GPU-modified
  tiled textures via TileManager::TileImage during memory pressure GC. Added
  CanTileImage capability validation to safely retain unsupported configurations,
  AccessBuffer compute-read barriers in TileImage, and an optional round-trip
  detile verification pass (BB_TILED_DOWNLOAD_VERIFY=1).
Draw prep worker tuning:
- Add prep_workers setting in bbport.ini, bbport_settings, and vk_draw_prep,
  allowing manual worker count overrides (auto, 0, 1, 2, ...).
- Expose Draw Prep Workers dropdown in bblauncher (under Anisotropic Filtering)
  with CPU core/thread recommendations (e.g. 1 worker for 4-thread CPUs to
  prevent thread oversubscription and stutter).
- Expose Draw Prep Workers in the in-game overlay menu (Performance & CPU section)
  with restart prompt.
- Update .gitignore for launcher build artifacts.
2026-10-17 15:49:22 +00:00
MrSuS60 e8a2a81150 Merge pull request #123 from HatsyRei/master
input: stop Shift+LMB heavy attack from also sending light attack
2026-10-17 15:22:27 +01:00
HatsyRei 81675bea3f input: stop Shift+LMB heavy attack from also sending light attack
The default Heavy Attack binding (Shift + Mouse Left) overlaps Light
Attack (Mouse Left), so both matched and the game received R1 and R2 in
the same frame. Untransformed movesets acted on R2, but transformed
weapons acted on R1, so heavy attacks stopped working after Tab.
- A held, bound Shift + mouse chord now owns that button: bare
  Mouse Left / Right actions don't fire while it is held.
- Shift + click still sends the bare action when no chord is bound to
  that button.
2026-10-17 13:30:55 +08:00
Mrsuss60 980247d765 Merge branch 'master' of https://github.com/Mrsuss60/bloodborne_pc_windows_port 2026-10-16 23:40:57 +00:00
Mrsuss60 f57c375aec fix(cpu): resolve non-BMI1 startup crash & expand crash telemetry
- Fix startup crash (exit code 139 / SEGV) on legacy CPUs lacking BMI1:
  * Patch FromSoftware allocator '63 - lzcnt' sequences in-place to native BSR + NOPs to prevent empty bucket lookups and null dereferences.
  * Trap standalone LZCNT sites with UD2 for exact software emulation with proper ZF/CF flag semantics.
  * Add BEXTR (0xF7) emulation and decode memory operands (SIB, displacements, RIP-relative) for BMI1 instructions.
- Enhance crash dump and diagnostics:
  * Resolve host RIP, 16 stack walk frames, and RBP frame chain to module name and offset.
  * Classify access violation fault type (READ / WRITE / DEP EXECUTE).
  * Collect and display GPU model, driver version, and Vulkan API in stdout and crash logs.
  * Append loaded modules table with base ranges, module names, sizes, and file paths.

Fixes #114, #117
Ref #113
2026-10-16 23:40:48 +00:00
MrSuS60 7d00f23c52 Update README.md 2026-10-17 00:40:18 +01:00
Mrsuss60 a666b7153d fix(build): rebuild libatrac9.a when stale or missing Atrac9 symbols 2026-10-16 22:08:15 +00:00
205 changed files with 45703 additions and 6904 deletions

No files matched your search

+47
View File
@@ -63,6 +63,8 @@ jobs:
done
mkdir -p /mingw64/include/magic_enum
curl -sSL -o /mingw64/include/magic_enum/magic_enum.hpp https://raw.githubusercontent.com/Neargye/magic_enum/master/include/magic_enum/magic_enum.hpp
mkdir -p /mingw64/share/licenses/magic_enum
curl -sSfL -o /mingw64/share/licenses/magic_enum/LICENSE https://raw.githubusercontent.com/Neargye/magic_enum/master/LICENSE
# Fix VMA header location
if [ -f /mingw64/include/vma/vk_mem_alloc.h ]; then
@@ -74,11 +76,13 @@ jobs:
cmake -S /tmp/miniz_repo -B /tmp/miniz_build -G Ninja -DCMAKE_INSTALL_PREFIX=/mingw64 -DBUILD_EXAMPLES=OFF -DBUILD_TESTS=OFF
cmake --build /tmp/miniz_build --target install
cp -f /mingw64/include/miniz/*.h /mingw64/include/ || true
install -Dm644 /tmp/miniz_repo/LICENSE /mingw64/share/licenses/miniz/LICENSE
echo "Miniz successfully built and installed to /mingw64"
# Install xbyak headers
git clone --depth 1 https://github.com/herumi/xbyak /tmp/xbyak
cp -r /tmp/xbyak/xbyak /mingw64/include/
install -Dm644 /tmp/xbyak/COPYRIGHT /mingw64/share/licenses/xbyak/COPYRIGHT
echo "Xbyak headers installed to /mingw64/include/xbyak"
- name: Compile Bloodborne PC Port
@@ -110,6 +114,7 @@ jobs:
cmake --build out/gpu --target bbgpu bbport bb-gpu-capabilities -j $(nproc)
echo "=== 5. Finalizing binaries ==="
strip -s out/bbport.exe
cp -f out/bbport.exe out/bb-probe.exe
echo "=== 6. Staging DLLs ==="
@@ -117,6 +122,47 @@ jobs:
ls -la out/bbport.exe
echo "=== 7. Staging licences ==="
mkdir -p out/licenses/msys2
cp -f LICENSE out/licenses/LICENSE
cp -rf licenses/. out/licenses/
# The MSYS2 packages that own the staged DLLs, with their licence files and versions.
pkgs=$(for dll in out/*.dll; do pacman -Qqo "/mingw64/bin/$(basename "$dll")" 2>/dev/null || true; done | sort -u)
test -n "$pkgs" || { echo "No staged DLL belongs to an MSYS2 package"; exit 1; }
pacman -Qi $pkgs | awk -F ' *: ' '/^Name/{n=$2} /^Version/{v=$2} /^Licenses/{print n, v, "-", $2}' \
> out/licenses/msys2/PACKAGES.txt
echo "Sources: https://repo.msys2.org/mingw/sources/" >> out/licenses/msys2/PACKAGES.txt
for pkg in $pkgs; do
# Not every package ships files under share/licenses.
pacman -Qql "$pkg" | { grep '^/mingw64/share/licenses/.*[^/]$' || true; } | while read -r f; do
rel=${f#/mingw64/share/licenses/}
mkdir -p "out/licenses/msys2/$(dirname "$rel")"
cp -f "$f" "out/licenses/msys2/$rel"
done
done
# Libraries compiled into bbport.exe: name:licence file.
for spec in \
imgui:gpu/third_party/imgui/LICENSE.txt \
LibAtrac9:third_party/LibAtrac9/LICENSE \
fsr-vulkan:gpu/third_party/fsr-vulkan/LICENSE.txt \
fsr-vulkan:gpu/third_party/fsr-vulkan/NOTICE.md \
fsr-vulkan:gpu/third_party/fsr-vulkan/UPSTREAM.md \
fsr-vulkan/ffx-1.1.4:gpu/third_party/fsr-vulkan/upstream/ffx-1.1.4/sdk/LICENSE.txt \
sirit:gpu/third_party/sirit/LICENSE.txt \
SPIRV-Headers:gpu/third_party/sirit/externals/SPIRV-Headers/LICENSE \
half:gpu/third_party/half/LICENSE.txt \
DejaVu-fonts:gpu/third_party/fonts/LICENSE-DejaVu.txt \
robin-map:/mingw64/share/licenses/robin-map/LICENSE \
VulkanMemoryAllocator:/mingw64/share/licenses/VulkanMemoryAllocator/LICENSE \
vulkan-headers:/mingw64/share/licenses/vulkan-headers/LICENSE \
magic_enum:/mingw64/share/licenses/magic_enum/LICENSE \
miniz:/mingw64/share/licenses/miniz/LICENSE \
xbyak:/mingw64/share/licenses/xbyak/COPYRIGHT; do
mkdir -p "out/licenses/third_party/${spec%%:*}"
cp -f "${spec#*:}" "out/licenses/third_party/${spec%%:*}/"
done
ls -R out/licenses | head -n 50 || true
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
@@ -125,3 +171,4 @@ jobs:
out/bbport.exe
out/bb-probe.exe
out/*.dll
out/licenses/
+84
View File
@@ -264,3 +264,87 @@ This document details the optimizations, fixes, and refactoring applied to ensur
2. Packaged self-contained embedded Python runtime (`python-embed/`), enabling out-of-the-box patch generation and profile management without requiring host system Python installations.
3. Updated `run.bat` launcher launcher script to auto-detect and resolve local embedded Python environment transparently.
---
## 15. Linear Mouse Look & In-Game Menu Pointer (PR #147 & PR #150 by @HatsyRei)
- **Files**: `gpu/shim/window.cpp`, `src/probe.c`, `gpu/shim/bbhost/menu_pointer.cpp`, `gpu/shim/bbport_menu_pointer.cpp`, `bblauncherAPP/`.
- **Change**:
1. Replaced exponential acceleration curve with 1:1 linear mouse camera look, overriding dynamic speed registers (`2.0f * |delta| / dt`) and preserving user sensitivity.
2. Ported in-game mouse pointer support from bbhost (credit @droogie / @DarkIzuku) allowing mouse cursor navigation inside native game menus (hover selects, left-click confirms, right-click backs out, wheel scrolls).
3. Added `mouse_menu` toggle under `[Controls]` in `bbport.ini` and the launcher GUI.
---
## 16. Upstream Launcher GPU Selection, Languages & Assertion Clamps
- **Files**: `tools/gpu_capabilities.c`, `bblauncherAPP/`, `src/runtime_kernel.c`, `src/probe.c`.
- **Change**:
1. Added physical Vulkan GPU adapter selection in the launcher and persistent INI configuration.
2. Added support for all 21 PS4 native text languages via `BB_LANGUAGE`.
3. Implemented `sceKernelDebugRaiseException` / `raise_exception` service and added assertion bypass clamp for blur kernel code `0xa0020007` (Code 23) to prevent black screens.
---
## 17. CPU Emulation, Graphics Worker Fault Recovery & Module Validation (Closes #27, #96, #124, #138, #140, #141, #145)
- **Files**: `src/probe.c`, `src/runtime_alloc.c`, `scripts/prepare.py`, `gpu/shadps4/video_core/renderer_vulkan/vk_scheduler.cpp`.
- **Change**:
1. Fixed CPU flag calculations in `emulate_lzcnt_site` (ZF flag on 0) and `emulate_bmi1` (CF/ZF for BLSR, BLSMSK, BLSI) for non-BMI1 processors.
2. Removed allocator BSR rewrite in `patch_non_bmi1` that left destination registers undefined on zero inputs, routing all non-BMI1 LZCNT sites through UD2 exception traps.
3. Removed broken heap alloc guard returning NULL at `0x207de26` that induced Dantelion2 WorldChrMan transaction panics.
4. Added graphics worker batch fault recovery in VEH (`0x21b4b30..0x21b4b55`) with full callee-saved register restoration to safely unwind culled batches.
5. Guarded native mouse camera thunk against corrupt jump targets and DEP violations.
6. Added explicit validation for companion modules (`sce_module/libc.prx`) during preparation.
---
## 18. Build System Optimization & License Compliance (PR #152 & Release Binary Strip)
- **Files**: `build.bat`, `.github/workflows/build.yml`, `scripts/stage_dlls.py`, `licenses/`.
- **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.
---
## 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.
+35 -13
View File
@@ -1,32 +1,50 @@
# Native Windows Port of Bloodborne
![Platform](https://img.shields.io/badge/PLATFORM-WINDOWS-0078D6?style=for-the-badge&logo=windows&logoColor=white&labelColor=1a0f0f)
[![Latest release](https://img.shields.io/github/v/release/Mrsuss60/bloodborne_pc_windows_port?style=for-the-badge&logo=github&logoColor=white&labelColor=1a0f0f&color=8b0000&label=RELEASE)](https://github.com/Mrsuss60/bloodborne_pc_windows_port/releases)
[![Downloads](https://img.shields.io/github/downloads/Mrsuss60/bloodborne_pc_windows_port/total?style=for-the-badge&logo=github&logoColor=white&labelColor=1a0f0f&color=b22222&label=DOWNLOADS)](https://github.com/Mrsuss60/bloodborne_pc_windows_port/releases)
[![Stars](https://img.shields.io/github/stars/Mrsuss60/bloodborne_pc_windows_port?style=for-the-badge&logo=github&logoColor=white&labelColor=1a0f0f&color=c9a227&label=STARS)](https://github.com/Mrsuss60/bloodborne_pc_windows_port/stargazers)
[![Last commit](https://img.shields.io/github/last-commit/Mrsuss60/bloodborne_pc_windows_port?style=for-the-badge&logo=git&logoColor=white&labelColor=1a0f0f&color=6b6b6b&label=LAST%20COMMIT)](https://github.com/Mrsuss60/bloodborne_pc_windows_port/commits)
![Platform](https://flat.badgen.net/badge/PLATFORM/WINDOWS/0078D6?labelColor=1a0f0f&icon=windows)
[![Latest release](https://img.shields.io/github/v/release/Mrsuss60/bloodborne_pc_windows_port?display_name=tag&style=flat&logo=github&logoColor=white&labelColor=1a0f0f&color=8b0000&label=RELEASE)](https://github.com/Mrsuss60/bloodborne_pc_windows_port/releases)
[![Downloads](https://flat.badgen.net/github/assets-dl/Mrsuss60/bloodborne_pc_windows_port/total?label=DOWNLOADS&labelColor=1a0f0f&color=b22222)](https://github.com/Mrsuss60/bloodborne_pc_windows_port/releases)
[![Stars](https://flat.badgen.net/github/stars/Mrsuss60/bloodborne_pc_windows_port?label=STARS&labelColor=1a0f0f&color=c9a227&icon=github)](https://github.com/Mrsuss60/bloodborne_pc_windows_port/stargazers)
[![Last commit](https://flat.badgen.net/github/last-commit/Mrsuss60/bloodborne_pc_windows_port?label=LAST%20COMMIT&labelColor=1a0f0f&color=6b6b6b&icon=git)](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 native 64-bit Windows port of the PlayStation 4 executable of *Bloodborne* (CUSA03173, version 1.09).
`bloodborne_pc_windows_port` is a 64-bit Windows port of the PlayStation 4 executable of *Bloodborne* (CUSA03173, version 1.09).
This project is a Windows adaptation of the original Linux port ([bbport](https://github.com/deadinside28/bloodborne_pc) by [deadinside28](https://github.com/deadinside28)). It replaces the Linux-specific kernel, memory mapping, and POSIX threading implementation with a native Win32 runtime, allowing the game to run directly on Windows with Vulkan.
This project is a Windows adaptation of the original Linux port ([bbport](https://github.com/deadinside28/bloodborne_pc) by [deadinside28](https://github.com/deadinside28)). It replaces the Linux-specific kernel, memory mapping, and POSIX threading implementation with a native Win32 runtime, allowing the game to run on Windows with Vulkan.
The game's x86-64 code executes natively on your CPU without general emulation. System library calls are handled by a dedicated lightweight runtime, and GPU commands are translated directly to Vulkan with support for AMD FSR 3.1 and FSR 4 temporal upscaling.
> **No game files or copyrighted assets are included.** You must provide your own decrypted dump of Bloodborne (CUSA03173, version 1.09).
> This project is not affiliated with Sony Interactive Entertainment, FromSoftware, or AMD.
> **Important Architecture Clarifications:**
> - **Native CPU Execution (No CPU Emulation or JIT)**: Because the PlayStation 4 uses an x86-64 processor, the game's compiled CPU machine code runs natively and directly on your PC processor. There is no CPU emulator, virtual machine, or dynamic recompiler (JIT) translation layer.
> - **GPU Emulation Handled by shadPS4**: Desktop graphics cards cannot natively parse PS4 AMD GCN command packets or PS4 GPU hardware shaders. All GPU emulation, command stream translation, and shader recompilation into Vulkan SPIR-V pipelines are handled by the [shadPS4](https://github.com/shadps4-emu/shadPS4) Vulkan video core (`gpu/`, `libbbgpu`), customized with a multithreaded draw pipeline and FSR upscaling.
> - **Not a Source Decompilation or Source Port**: This project is not a PC port recompiled from leaked source code or a reverse-engineered C/C++ decompilation. It executes the retail PS4 binary directly by preparing an offline flat memory image and providing a specialized High-Level Emulation (HLE) runtime for PS4 system calls.
> - **No game files or copyrighted assets are included.** You must provide your own decrypted dump of Bloodborne (CUSA03173, version 1.09).
> - This project is not affiliated with Sony Interactive Entertainment, FromSoftware, or AMD.
**Status: Playable on Windows.** The game boots, loads saves, and runs with audio, gamepad support, and state persistence.
---
## Architecture: Native vs Emulated
| Component | Execution Model | Implementation Details |
|---|---|---|
| **CPU / Game Logic** | **100% Native** | Direct x86-64 execution on host CPU. No CPU emulation, no JIT, no instruction translation. |
| **System Calls / OS** | **Native HLE Runtime** | Custom lightweight C runtime (`src/`) implementing memory mapping, threading, file I/O, and PS4 libc/libSceFios2 calls. |
| **GPU / Graphics** | **Emulation / Translation (shadPS4)** | Handled by the [shadPS4](https://github.com/shadps4-emu/shadPS4) Vulkan core (`gpu/`). Translates PS4 PM4 command streams and GCN shaders into Vulkan SPIR-V pipelines with custom multithreaded command dispatch. |
| **Upscaling** | **Native Vulkan** | AMD FSR 3.1 and FSR 4 integration using custom synthetic motion vectors and subpixel jitter. |
| **Audio** | **Native Win32** | Decoded directly using bundled LibAtrac9 and output via SDL3 audio streams. |
| **Controls** | **Native Win32 / SDL3** | Raw mouse capture with a direct 360-degree camera rotation hook (`src/probe.c`) alongside native gamepad support. |
---
## Windows Port Changes
This repository adapts the original Linux codebase specifically for Windows systems:
- **Win32 Memory & Synchronization**: Replaced Linux `mmap`, `mprotect`, and POSIX primitives with Windows `VirtualAlloc`, `VirtualProtect`, and native Win32 synchronization events (`src/win32_compat.c`, `src/win32_memory.c`, `src/runtime_host.c`).
- **Direct 360-Degree Native Mouse Look**: Replaced legacy gamepad stick emulation with a direct camera hook into the engine's update routines (`src/probe.c`). Raw mouse deltas inject directly into camera orientation angles and dynamic motion buffers, enabling full 360-degree rotation (yaw and pitch), real-time view matrix recalculation, and customization sliders for responsiveness, acceleration, and smoothing.
- **Graphical Launcher**: Modular PySide6 launcher (`BloodborneLauncher.exe` / `bblauncherAPP/`), providing real-time configuration for target frame rates (30, 60, 90, uncap), render resolutions, FSR upscaling, community patches, and full interactive keybind remapping.
- **Command Line Launcher**: `run.bat` provides direct scripted startup, automatic patch compilation, and mod staging on Windows. Automatically prioritizes bundled portable Python runtimes (`python-embed/`).
- **Modern Mouse & Keyboard Support**: Relative cursor capture and mouse look adapted from the Linux port (`deadinside28`), engine deadzone jump compensation (~16/127), smoothing filters, and a modern press-to-rebind keybinding system with conflict auto-swapping.
- **Vulkan Frame Pacing**: Integrated presenter queue pacing (`BB_FRAMES_AHEAD=2`) to bound GPU run-ahead, stabilizing frametimes and smoothing 0.1% and 1.0% stutter lows.
- **Texture Barrier Fix**: Fixed dynamic texture streaming race conditions in `tile_manager.cpp`, ensuring item icons in the HUD and loading screens render correctly without static noise.
- **AT9 Audio Playback**: Bundles LibAtrac9 compilation to decode AT9 game audio natively on Windows with soft-clipping saturation curves to eliminate audio pops.
@@ -37,6 +55,7 @@ This repository adapts the original Linux codebase specifically for Windows syst
## Technical Highlights
- **Native Execution**: The game eboot is converted offline into a flat memory image; PS4 libc and libSceFios2 functions are linked directly into the binary. No CPU emulation or instruction translation occurs at run time.
- **shadPS4 Vulkan Core**: Graphics rendering and shader translation are handled through a dedicated integration of shadPS4's Vulkan backend, with hundreds of engine-specific performance fixes and synchronization enhancements.
- **High Framerate Support**: Community simulation patches allow running at 60 FPS, 90 FPS, or uncapped with accurate physics and movement speeds.
- **Synthetic Motion Vectors & Temporal Upscaling**: Because Bloodborne lacks an internal velocity buffer, the port computes camera motion from depth buffers and object motion from previous frame vertex positions. The scene can render at lower internal resolutions (e.g., 720p or 1080p) while FSR 3.1 / 4 upscales to your display resolution, leaving UI elements crisp at native resolution.
- **Persistent Pipeline Binary Caches**: Hardware-compiled Vulkan driver pipeline binaries (`.vkp`) are saved to disk and reloaded on startup, eliminating recurring shader compilation stutter.
@@ -146,7 +165,7 @@ Save files and shader caches are stored in `user/`. Settings are saved to `bbpor
## Controls and In-Game Features
- **Mouse & Keyboard**:
- **Mouse Look**: Relative cursor capture with seamless release when opening menus or alt-tabbing.
- **Mouse Look**: Direct 360-degree native camera rotation hook with 1:1 mouse input. Configurable sensitivity, smoothing, responsiveness, and acceleration sliders in the launcher and in-game overlay. Relative cursor capture releases automatically when menus open or when alt-tabbing.
- **Light Attack (R1)**: Mouse Left
- **Heavy / Charged Attack (R2)**: Shift + Mouse Left
- **Firearm / Gun (L2)**: Mouse Right
@@ -191,11 +210,13 @@ Save files and shader caches are stored in `user/`. Settings are saved to `bbpor
## Credits and Licenses
This project is licensed under the **GNU General Public License v2 or later** ([LICENSE](LICENSE)) due to its use of shadPS4 components.
The game menu mouse pointer is adapted from [bbhost](https://github.com/droogie/bbhost) (GPL-3.0-or-later), so builds that contain it are distributed under the **GNU GPL v3 or later** ([licenses/GPL-3.0.txt](licenses/GPL-3.0.txt), [licenses/BBHOST-PORTS.md](licenses/BBHOST-PORTS.md)).
Special thanks to the original creators and open source projects that made this port possible:
- **deadinside28**: Creator of the original Linux port (`bbport`), pioneering the flat memory image architecture, custom Vulkan two-stage pipeline, relative mouse look implementation, and synthetic motion vector generation.
- **shadPS4 Team**: Base Vulkan video core and shader recompiler.
- **droogie and the bbhost contributors**: game menu mouse pointer ([bbhost](https://github.com/droogie/bbhost)), via **DarkIzuku**'s bloodborne_pc port.
- **FireBurn**: FSR-Vulkan runtime and temporal upscaling backend.
- **Thealexbarney**: LibAtrac9 audio decoding library.
- **ocornut**: Dear ImGui library for the in-game settings overlay.
@@ -205,3 +226,4 @@ Special thanks to the original creators and open source projects that made this
- **[parsifal295](https://github.com/parsifal295)**: pull requests [#35](https://github.com/Mrsuss60/bloodborne_pc_windows_port/pull/35), [#36](https://github.com/Mrsuss60/bloodborne_pc_windows_port/pull/36), [#37](https://github.com/Mrsuss60/bloodborne_pc_windows_port/pull/37).
- **[wizardnun](https://github.com/wizardnun)**: pull request [#39](https://github.com/Mrsuss60/bloodborne_pc_windows_port/pull/39).
- **[Vorshim92](https://github.com/Vorshim92)**: pull requests [#65](https://github.com/Mrsuss60/bloodborne_pc_windows_port/pull/65), [#66](https://github.com/Mrsuss60/bloodborne_pc_windows_port/pull/66), [#67](https://github.com/Mrsuss60/bloodborne_pc_windows_port/pull/67), [#73](https://github.com/Mrsuss60/bloodborne_pc_windows_port/pull/73), [#74](https://github.com/Mrsuss60/bloodborne_pc_windows_port/pull/74), [#76](https://github.com/Mrsuss60/bloodborne_pc_windows_port/pull/76), [#77](https://github.com/Mrsuss60/bloodborne_pc_windows_port/pull/77).
- **[HatsyRei](https://github.com/HatsyRei)**: pull requests [#103](https://github.com/Mrsuss60/bloodborne_pc_windows_port/pull/103), [#123](https://github.com/Mrsuss60/bloodborne_pc_windows_port/pull/123), [#147](https://github.com/Mrsuss60/bloodborne_pc_windows_port/pull/147), [#150](https://github.com/Mrsuss60/bloodborne_pc_windows_port/pull/150), [#152](https://github.com/Mrsuss60/bloodborne_pc_windows_port/pull/152).
+3
View File
@@ -229,3 +229,6 @@ bbport распространяется по **GNU GPL v2 или новее** ([
[dxil-spirv](https://github.com/HansKristian-Work/dxil-spirv) (MIT, для сборки ассетов FSR 4.1.1).
Патчи игры — Kyo, Lance McDonald, auser1337, illusion, emoose и другие участники сообщества
(`patches/Bloodborne.xml`). DLL и данные модели FSR 4 от AMD здесь не распространяются.
Указатель мыши в меню игры взят из [bbhost](https://github.com/droogie/bbhost) (GPL-3.0-or-later,
через порт DarkIzuku), поэтому сборки с ним распространяются по **GNU GPL v3 или новее**
([licenses/GPL-3.0.txt](licenses/GPL-3.0.txt), [licenses/BBHOST-PORTS.md](licenses/BBHOST-PORTS.md)).
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+26
View File
@@ -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" ^
@@ -104,6 +111,25 @@ echo.
--exclude-module "PySide6.Qt3DCore" ^
--exclude-module "PySide6.QtNetwork" ^
--exclude-module "PySide6.QtMultimedia" ^
--exclude-module "PySide6.QtVirtualKeyboard" ^
--exclude-module "PySide6.QtPdf" ^
--exclude-module "PySide6.QtPdfWidgets" ^
--exclude-module "PySide6.QtSvg" ^
--exclude-module "PySide6.QtOpenGL" ^
--exclude-module "PySide6.QtOpenGLWidgets" ^
--exclude-module "PySide6.QtSql" ^
--exclude-module "PySide6.QtTest" ^
--exclude-module "PySide6.QtXml" ^
--exclude-module "PySide6.QtPrintSupport" ^
--exclude-module "PySide6.QtDesigner" ^
--exclude-module "PySide6.QtHelp" ^
--exclude-module "PySide6.QtUiTools" ^
--exclude-module "tkinter" ^
--exclude-module "unittest" ^
--exclude-module "pydoc" ^
--exclude-module "doctest" ^
--exclude-module "email" ^
--exclude-module "http" ^
bblauncher_app.py
if errorlevel 1 (
echo.
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

+62
View File
@@ -0,0 +1,62 @@
# bbport settings (in-game menu: Insert / L3+R3)
upscaler=off
preset=1
sharpen=1
sharpness=0.30
jitter=0
reactive=0
object_motion=0
reactive_scale=1.00
reactive_threshold=0.20
reactive_max=0.90
debug_view=0
show_fps=0
show_hud=1
hud_quadrant=0
hud_opacity=0.75
hud_scale=1.00
fsr4_auto_exposure=1
fsr4_invert_jitter=0
mk_enabled=1
mk_sens_x=3.20
mk_sens_y=3.26
mk_invert_x=0
mk_invert_y=0
mk_deadzone=0.00
mk_smoothing=0.03
effect_chromatic_aberration=1
effect_dof=1
effect_motion_blur=1
effect_ssao=1
effect_game_aa=1
effect_dynamic_shadows=1
effect_ssr=0
skip_intro=0
debug_camera=0
debug_menu=0
model_lod=0
output_res=1920x1080
prep_workers=auto
live_resolution=0
language=en
key.attack=Mouse Left
key.heavy_attack=Shift + Mouse Left
key.firearm=Mouse Right
key.transform=Tab
key.lock_on=Mouse Middle
key.move_forward=W
key.move_backward=S
key.move_left=A
key.move_right=D
key.dodge=Space
key.interact=E
key.use_item=R
key.heal=F
key.dpad_up=1
key.dpad_down=2
key.dpad_left=3
key.dpad_right=4
key.gestures=G
key.personal_effects=Backspace
key.menu=Escape
key.walk=Left Alt
+83 -8
View File
@@ -82,10 +82,21 @@ if errorlevel 1 (
)
:submodules_ok
rem Build LibAtrac9 static archive once (skip already-compiled .o files and archive directly)
if exist "out\libatrac9.a" goto atrac9_done
rem Build LibAtrac9 static archive (rebuild if missing or lacking Atrac9 symbols)
if not exist "third_party\LibAtrac9\C\src\libatrac9.c" (
echo LibAtrac9 sources missing. Run: git submodule update --init --recursive
exit /b 1
)
if not exist "out\libatrac9.a" goto atrac9_build
nm out\libatrac9.a 2>nul | findstr /c:"Atrac9Decode" >nul
if not errorlevel 1 goto atrac9_done
echo out\libatrac9.a is stale or incomplete - rebuilding...
del /f /q out\libatrac9.a 2>nul
del /f /q out\atrac9\*.o 2>nul
:atrac9_build
echo Building LibAtrac9...
if not exist "out\atrac9" mkdir out\atrac9
set "AT9_OBJS="
for %%f in (third_party\LibAtrac9\C\src\*.c) do (
if not exist "out\atrac9\%%~nf.o" (
gcc -std=c99 -O2 -g -w -c "%%f" -o "out\atrac9\%%~nf.o"
@@ -94,13 +105,10 @@ for %%f in (third_party\LibAtrac9\C\src\*.c) do (
exit /b 1
)
)
call set "AT9_OBJS=%%AT9_OBJS%% out\atrac9\%%~nf.o"
)
pushd out\atrac9
del /f /q ..\libatrac9.a 2>nul
ar rcs ..\libatrac9.a *.o
set "AR_ERR=%ERRORLEVEL%"
popd
if not "%AR_ERR%"=="0" (
ar rcs out\libatrac9.a %AT9_OBJS%
if errorlevel 1 (
echo Failed to create out\libatrac9.a
exit /b 1
)
@@ -168,6 +176,12 @@ if errorlevel 1 (
)
if exist "out\bbport.exe" (
rem Strip unneeded debug symbols and relocations to reduce binary size from ~260MB to ~12MB
where strip.exe >nul 2>nul
if not errorlevel 1 (
echo Stripping debug symbols from out\bbport.exe...
strip -s "out\bbport.exe"
)
copy /Y "out\bbport.exe" "out\bb-probe.exe" >nul
)
@@ -182,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
@@ -237,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
+48
View File
@@ -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
View File
@@ -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 -97
View File
@@ -1,97 +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);
/* 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);
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
+59
View File
@@ -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()
+27
View File
@@ -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.
+89
View File
@@ -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.
+265
View File
@@ -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, &parameters))
? 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;
}
+78
View File
@@ -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"
@@ -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
+227
View File
@@ -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
+8
View File
@@ -0,0 +1,8 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
namespace BbNvidiaProfile {
void Apply();
} // namespace BbNvidiaProfile
+26 -7
View File
@@ -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();
@@ -417,7 +417,7 @@ void DefineEntryPoint(const Info& info, EmitContext& ctx, Id main) {
: spv::ExecutionMode::VertexOrderCw);
break;
}
case SwStage::Fragment:
case SwStage::Fragment: {
execution_model = spv::ExecutionModel::Fragment;
if (ctx.profile.lower_left_origin_mode) {
ctx.AddExecutionMode(main, spv::ExecutionMode::OriginLowerLeft);
@@ -427,10 +427,16 @@ void DefineEntryPoint(const Info& info, EmitContext& ctx, Id main) {
if (info.has_discard) {
ctx.AddCapability(spv::Capability::DemoteToHelperInvocation);
}
if (info.stores.GetAny(IR::Attribute::Depth)) {
const bool stores_depth = info.stores.GetAny(IR::Attribute::Depth);
if (stores_depth) {
ctx.AddExecutionMode(main, spv::ExecutionMode::DepthReplacing);
}
if (ctx.runtime_info.hw.fs.depth_before_shader) {
ctx.AddExecutionMode(main, spv::ExecutionMode::EarlyFragmentTests);
ASSERT_MSG(!stores_depth, "DEPTH_BEFORE_SHADER enabled with depth exporting shader");
}
break;
}
case SwStage::Geometry:
execution_model = spv::ExecutionModel::Geometry;
ctx.AddExecutionMode(main, GetInputPrimitiveType(ctx.runtime_info.hw.gs.in_primitive));
@@ -585,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) {
@@ -33,6 +33,13 @@ void EmitBarrier(EmitContext& ctx) {
ctx.ConstU32(static_cast<u32>(memory_semantics)));
}
void EmitSubgroupBarrier(EmitContext& ctx) {
const auto semantics{static_cast<u32>(spv::MemorySemanticsMask::AcquireRelease |
spv::MemorySemanticsMask::WorkgroupMemory)};
ctx.OpMemoryBarrier(ctx.ConstU32(static_cast<u32>(spv::Scope::Subgroup)),
ctx.ConstU32(semantics));
}
void EmitWorkgroupMemoryBarrier(EmitContext& ctx) {
MemoryBarrier(ctx, spv::Scope::Workgroup);
}
@@ -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;
}
@@ -44,6 +44,7 @@ void EmitDiscardCond(EmitContext& ctx, Id condition);
void EmitDebugPrint(EmitContext& ctx, IR::Inst* inst, Id arg0, Id arg1, Id arg2, Id arg3, Id arg4);
Id EmitMemtime(EmitContext& ctx);
void EmitBarrier(EmitContext& ctx);
void EmitSubgroupBarrier(EmitContext& ctx);
void EmitWorkgroupMemoryBarrier(EmitContext& ctx);
void EmitDeviceMemoryBarrier(EmitContext& ctx);
Id EmitGetUserData(EmitContext& ctx, IR::ScalarReg reg);
@@ -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
+16
View File
@@ -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));
@@ -114,6 +114,10 @@ void IREmitter::DeviceMemoryBarrier() {
Inst(Opcode::DeviceMemoryBarrier);
}
void IREmitter::SubgroupBarrier() {
Inst(Opcode::SubgroupBarrier);
}
U32 IREmitter::GetUserData(IR::ScalarReg reg) {
ASSERT(static_cast<u32>(reg) < IR::NumScalarRegs);
return Inst<U32>(Opcode::GetUserData, reg);
@@ -45,6 +45,7 @@ public:
void Barrier();
void WorkgroupMemoryBarrier();
void DeviceMemoryBarrier();
void SubgroupBarrier();
[[nodiscard]] U32 GetUserData(IR::ScalarReg reg);
@@ -40,6 +40,7 @@ bool Inst::MayHaveSideEffects() const noexcept {
case Opcode::Barrier:
case Opcode::WorkgroupMemoryBarrier:
case Opcode::DeviceMemoryBarrier:
case Opcode::SubgroupBarrier:
case Opcode::ConditionRef:
case Opcode::Prologue:
case Opcode::Epilogue:
@@ -21,6 +21,7 @@ OPCODE(ReadConstBuffer, U32, Opaq
OPCODE(Barrier, Void, )
OPCODE(WorkgroupMemoryBarrier, Void, )
OPCODE(DeviceMemoryBarrier, Void, )
OPCODE(SubgroupBarrier, Void, )
// Geometry shader specific
OPCODE(EmitVertex, Void, )
@@ -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;
}
}
@@ -25,7 +25,14 @@ static bool IsWriteShared(const IR::Inst& inst) {
}
// Inserts barriers when a shared memory write and read occur in the same basic block.
static void EmitBarrierInBlock(IR::Block* block) {
static void EmitBarrierInBlock(IR::Block* block, bool subgroup = false) {
const auto emit_barrier = [subgroup](IR::IREmitter& ir) {
if (subgroup) {
ir.SubgroupBarrier();
} else {
ir.Barrier();
}
};
enum class BarrierAction : u32 {
None,
BarrierOnWrite,
@@ -36,7 +43,7 @@ static void EmitBarrierInBlock(IR::Block* block) {
if (IsLoadShared(inst)) {
if (action == BarrierAction::BarrierOnRead) {
IR::IREmitter ir{*block, IR::Block::InstructionList::s_iterator_to(inst)};
ir.Barrier();
emit_barrier(ir);
}
action = BarrierAction::BarrierOnWrite;
continue;
@@ -44,14 +51,14 @@ static void EmitBarrierInBlock(IR::Block* block) {
if (IsWriteShared(inst)) {
if (action == BarrierAction::BarrierOnWrite) {
IR::IREmitter ir{*block, IR::Block::InstructionList::s_iterator_to(inst)};
ir.Barrier();
emit_barrier(ir);
}
action = BarrierAction::BarrierOnRead;
}
}
if (action != BarrierAction::None) {
IR::IREmitter ir{*block, --block->end()};
ir.Barrier();
emit_barrier(ir);
}
}
@@ -63,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;
@@ -76,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);
}
@@ -89,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;
@@ -121,16 +133,26 @@ void SharedMemoryBarrierPass(IR::Program& program, const RuntimeInfo& runtime_in
const u32 shared_memory_size = cs_info.shared_memory_size;
const u32 threadgroup_size =
cs_info.workgroup_size[0] * cs_info.workgroup_size[1] * cs_info.workgroup_size[2];
if (shared_memory_size == 0) {
return;
}
// The compiler can only omit barriers when the local workgroup size is the same as the HW
// subgroup.
if (shared_memory_size == 0 || threadgroup_size != GcnSubgroupSize ||
!profile.needs_lds_barriers) {
if (threadgroup_size != GcnSubgroupSize || !profile.needs_lds_barriers) {
// GCN waves can use shared memory between invocations without explicit barriers because
// they run in lockstep. Host compilers can reorder these accesses, so keep their order
// with subgroup memory barriers.
for (const IR::AbstractSyntaxNode& node : program.syntax_list) {
if (node.type == IR::AbstractSyntaxNode::Type::Block) {
EmitBarrierInBlock(node.data.block, true);
}
}
return;
}
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)) {
@@ -141,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)) {
+1
View File
@@ -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;
};
@@ -227,6 +227,7 @@ struct HwFragmentRuntimeInfo {
bool front_face_all_bits{false};
bool dual_source_blending{false};
bool clip_distance_emulation{false};
bool depth_before_shader{false};
/// bbport: writes the object motion vector to MotionVectors::Output.
bool motion_vectors{false};
@@ -238,6 +239,7 @@ struct HwFragmentRuntimeInfo {
front_face_all_bits == other.front_face_all_bits &&
dual_source_blending == other.dual_source_blending &&
clip_distance_emulation == other.clip_distance_emulation &&
depth_before_shader == other.depth_before_shader &&
motion_vectors == other.motion_vectors &&
std::ranges::equal(inputs.begin(), inputs.begin() + num_inputs, other.inputs.begin(),
other.inputs.begin() + num_inputs);
+348 -89
View File
@@ -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,6 +568,9 @@ 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()) {
@@ -488,12 +579,21 @@ Liverpool::Task Liverpool::ProcessCeUpdate(std::span<const u32> ccb) {
}
break;
}
default:
const u32 count = header->type3.NumWords();
UNREACHABLE_MSG("Unknown PM4 type 3 opcode {:#x} with count {}",
static_cast<u32>(opcode), count);
case PM4ItOpcode::Rewind: {
if (!rasterizer) {
break;
}
const auto* rewind = reinterpret_cast<const PM4CmdRewind*>(header);
while (!rewind->Valid()) {
YIELD_CE();
}
break;
}
ccb = NextPacket(ccb, header->type3.NumWords() + 1);
default:
// 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, packet_words);
}
FIBER_EXIT;
@@ -735,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 =
@@ -750,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();
@@ -771,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.
@@ -900,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;
@@ -923,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;
@@ -951,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);
@@ -1158,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;
}
@@ -1223,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,
@@ -1315,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);
@@ -1333,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;
}
@@ -1343,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: {
@@ -1369,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
}
@@ -1486,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;
@@ -1500,8 +1665,19 @@ 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()) {
@@ -1515,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);
@@ -1551,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;
}
@@ -1575,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);
@@ -1649,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: {
@@ -1672,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);
}
@@ -1702,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);
@@ -1718,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()));
@@ -1764,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;
+6 -8
View File
@@ -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();
}
+32 -3
View File
@@ -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
+26
View File
@@ -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;
}
+18 -2
View File
@@ -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>
@@ -28,6 +30,7 @@
namespace VideoCore {
static constexpr size_t GDS_BUFFER_SIZE = 64_KB;
static constexpr size_t NULL_INDEX_BUFFER_SIZE = 16;
static constexpr size_t STREAM_BUFFER_SIZE = 128_MB;
static constexpr auto ARENA_USAGE =
@@ -90,13 +93,18 @@ BufferCache::BufferCache(const Vulkan::Instance& instance_, Vulkan::Scheduler& s
bda_pagetable_buffer = std::make_unique<Buffer>(
instance, 0, bda_pagetable_size, MemoryType::DeviceLocal, "BDA Page Table Buffer");
runtime.FillBuffer(bda_pagetable_buffer.get(), 0u, bda_pagetable_size, 0u);
if (!instance.IsMaintenance6Supported()) {
null_index_buffer = std::make_unique<Buffer>(instance, 0, NULL_INDEX_BUFFER_SIZE,
MemoryType::DeviceLocal, "Null Index Buffer");
runtime.FillBuffer(null_index_buffer.get(), 0u, NULL_INDEX_BUFFER_SIZE, 0u);
}
}
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);
});
}
@@ -140,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);
@@ -154,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();
@@ -166,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;
@@ -190,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 {
@@ -337,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)};
@@ -383,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;
@@ -58,6 +59,10 @@ public:
return &gds_buffer;
}
[[nodiscard]] const Buffer* GetNullIndexBuffer() const noexcept {
return null_index_buffer.get();
}
/// Retrieves the device local DBA page table buffer.
[[nodiscard]] Buffer* GetBdaPageTableBuffer() noexcept {
return bda_pagetable_buffer.get();
@@ -84,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,
@@ -128,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);
@@ -160,6 +175,7 @@ private:
StreamBuffer stream_buffer;
Buffer gds_buffer;
std::unique_ptr<Buffer> null_index_buffer;
RangeSet gpu_modified_ranges;
std::unique_ptr<FaultManager> fault_manager;
@@ -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;
+35 -5
View File
@@ -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) {
{
+8
View File
@@ -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
+3 -1
View File
@@ -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;
@@ -262,6 +262,26 @@ vk::BlendOp BlendOp(AmdGpu::BlendControl::BlendFunc func) {
}
}
void NormalizeMinMaxBlend(vk::BlendOp& op, vk::BlendFactor& src, vk::BlendFactor& dst,
AmdGpu::NumberFormat format) {
if (format != AmdGpu::NumberFormat::Unorm && format != AmdGpu::NumberFormat::Srgb) {
return;
}
if (op != vk::BlendOp::eMin && op != vk::BlendOp::eMax) {
return;
}
if ((src != vk::BlendFactor::eZero && src != vk::BlendFactor::eOne) ||
(dst != vk::BlendFactor::eZero && dst != vk::BlendFactor::eOne) ||
(src != vk::BlendFactor::eZero && dst != vk::BlendFactor::eZero)) {
return;
}
if (op == vk::BlendOp::eMin) {
src = vk::BlendFactor::eZero;
dst = vk::BlendFactor::eZero;
}
op = vk::BlendOp::eAdd;
}
vk::LogicOp LogicOp(AmdGpu::ColorControl::LogicOp logic_op) {
using LogicOp = AmdGpu::ColorControl::LogicOp;
switch (logic_op) {
@@ -35,6 +35,9 @@ bool IsDualSourceBlendFactor(AmdGpu::BlendControl::BlendFactor factor);
vk::BlendOp BlendOp(AmdGpu::BlendControl::BlendFunc func);
void NormalizeMinMaxBlend(vk::BlendOp& op, vk::BlendFactor& src, vk::BlendFactor& dst,
AmdGpu::NumberFormat format);
vk::LogicOp LogicOp(AmdGpu::ColorControl::LogicOp logic_op);
vk::SamplerAddressMode ClampMode(AmdGpu::ClampMode mode);
@@ -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, &parameters) != 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
@@ -7,6 +7,7 @@
#include <cstdlib>
#include <cstring>
#include "bbport_settings.h"
#include "bbport_threads.h"
#include "bbport_toggles.h"
#include "common/thread.h"
@@ -51,6 +52,10 @@ u32 DefaultWorkerCount() {
if (const char* env = std::getenv("BB_PREP_WORKERS")) {
return static_cast<u32>(std::clamp(std::atoi(env), 0, 16));
}
const int cfg_workers = BbSettings::Get().prep_workers.load();
if (cfg_workers >= 0) {
return static_cast<u32>(std::clamp(cfg_workers, 0, 16));
}
// Workers are SCHED_IDLE and claim whole buffers, so more of them only use more idle
// cores: half the hardware threads (Steam Deck 4, 16-thread desktop 8).
return std::clamp<u32>(BbThreads::Available() / 2, 1, 8);
@@ -189,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;
}
@@ -265,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",
});
}
@@ -308,47 +397,14 @@ GraphicsPipeline::GraphicsPipeline(
const auto alpha_blend =
control.separate_alpha_blend ? LiverpoolToVK::BlendOp(control.alpha_func) : color_blend;
// Vulkan ignores blend factors for min/max, but a factor that zeroes one operand
// makes the operation collapse to a plain selection: min(s, 0) is 0 and max(s, 0)
// is s for normalized alpha. Rewrite those to the equivalent add so the result is
// exact instead of leaving the other operand to survive.
auto eff_src_alpha = src_alpha;
auto eff_dst_alpha = dst_alpha;
auto eff_alpha_blend = alpha_blend;
if (alpha_blend == vk::BlendOp::eMin || alpha_blend == vk::BlendOp::eMax) {
const bool takes_max = alpha_blend == vk::BlendOp::eMax;
if (src_alpha == vk::BlendFactor::eOne && dst_alpha == vk::BlendFactor::eZero) {
eff_alpha_blend = vk::BlendOp::eAdd;
eff_src_alpha = takes_max ? vk::BlendFactor::eOne : vk::BlendFactor::eZero;
eff_dst_alpha = vk::BlendFactor::eZero;
} else if (src_alpha == vk::BlendFactor::eZero && dst_alpha == vk::BlendFactor::eOne) {
eff_alpha_blend = vk::BlendOp::eAdd;
eff_src_alpha = vk::BlendFactor::eZero;
eff_dst_alpha = takes_max ? vk::BlendFactor::eOne : vk::BlendFactor::eZero;
}
}
const auto color_scaled_min_max =
(color_blend == vk::BlendOp::eMin || color_blend == vk::BlendOp::eMax) &&
(src_color != vk::BlendFactor::eOne || dst_color != vk::BlendFactor::eOne) &&
!key.color_buffers[i].blend_self_scale;
const auto alpha_scaled_min_max =
(eff_alpha_blend == vk::BlendOp::eMin || eff_alpha_blend == vk::BlendOp::eMax) &&
(eff_src_alpha != vk::BlendFactor::eOne || eff_dst_alpha != vk::BlendFactor::eOne);
if (color_scaled_min_max || alpha_scaled_min_max) {
LOG_WARNING(
Render_Vulkan,
"Unimplemented use of min/max blend op with blend factor not equal to one.");
}
attachments[i] = vk::PipelineColorBlendAttachmentState{
.blendEnable = control.enable,
.srcColorBlendFactor = src_color,
.dstColorBlendFactor = dst_color,
.colorBlendOp = color_blend,
.srcAlphaBlendFactor = eff_src_alpha,
.dstAlphaBlendFactor = eff_dst_alpha,
.alphaBlendOp = eff_alpha_blend,
.srcAlphaBlendFactor = src_alpha,
.dstAlphaBlendFactor = dst_alpha,
.alphaBlendOp = alpha_blend,
.colorWriteMask =
instance.IsDynamicColorWriteMaskSupported()
? vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG |
@@ -388,6 +444,30 @@ GraphicsPipeline::GraphicsPipeline(
? vk::BlendFactor::eOne
: vk::BlendFactor::eZero; // 1-A
}
auto& attachment = attachments[i];
LiverpoolToVK::NormalizeMinMaxBlend(attachment.colorBlendOp, attachment.srcColorBlendFactor,
attachment.dstColorBlendFactor,
key.color_buffers[i].num_format);
LiverpoolToVK::NormalizeMinMaxBlend(attachment.alphaBlendOp, attachment.srcAlphaBlendFactor,
attachment.dstAlphaBlendFactor,
key.color_buffers[i].num_format);
const auto color_scaled_min_max =
(attachment.colorBlendOp == vk::BlendOp::eMin ||
attachment.colorBlendOp == vk::BlendOp::eMax) &&
(attachment.srcColorBlendFactor != vk::BlendFactor::eOne ||
attachment.dstColorBlendFactor != vk::BlendFactor::eOne);
const auto alpha_scaled_min_max =
(attachment.alphaBlendOp == vk::BlendOp::eMin ||
attachment.alphaBlendOp == vk::BlendOp::eMax) &&
(attachment.srcAlphaBlendFactor != vk::BlendFactor::eOne ||
attachment.dstAlphaBlendFactor != vk::BlendFactor::eOne);
if (control.enable && (color_scaled_min_max || alpha_scaled_min_max)) {
LOG_WARNING(
Render_Vulkan,
"Unimplemented use of min/max blend op with blend factor not equal to one.");
}
}
const vk::PipelineColorBlendStateCreateInfo color_blending = {
@@ -420,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);
}
@@ -533,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,13 +13,20 @@
#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"
#include <vk_mem_alloc.h>
namespace Vulkan {
char g_gpu_vendor_name[128] = "Unknown Vendor";
char g_gpu_model_name[256] = "Unknown GPU";
char g_gpu_driver_name[128] = "Unknown Driver";
char g_gpu_api_version[64] = "Unknown API";
namespace {
/// bbport BB_VRAM_LIMIT_MB=N (tests): the driver's VRAM budget taken as at most N MiB, at startup
@@ -193,13 +202,21 @@ 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();
CollectToolingInfo();
}
Instance::~Instance() {
if (Dlss* dlss = Dlss::Get()) {
dlss->Shutdown(); // NGX before the VkDevice and its images go away
}
ImGui::Core::Shutdown(GetDevice());
vmaDestroyAllocator(allocator);
}
@@ -252,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(),
@@ -289,6 +306,7 @@ bool Instance::CreateDevice() {
// Optional
maintenance_5 = add_extension(VK_KHR_MAINTENANCE_5_EXTENSION_NAME);
maintenance_6 = add_extension(VK_KHR_MAINTENANCE_6_EXTENSION_NAME);
maintenance_8 = add_extension(VK_KHR_MAINTENANCE_8_EXTENSION_NAME);
buffer_marker = add_extension(VK_AMD_BUFFER_MARKER_EXTENSION_NAME);
attachment_feedback_loop = add_extension(VK_EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_EXTENSION_NAME);
@@ -529,6 +547,9 @@ bool Instance::CreateDevice() {
vk::PhysicalDeviceMaintenance5FeaturesKHR{
.maintenance5 = true,
},
vk::PhysicalDeviceMaintenance6FeaturesKHR{
.maintenance6 = true,
},
vk::PhysicalDeviceMaintenance8FeaturesKHR{
.maintenance8 = true,
},
@@ -601,6 +622,9 @@ bool Instance::CreateDevice() {
if (!maintenance_5) {
device_chain.unlink<vk::PhysicalDeviceMaintenance5FeaturesKHR>();
}
if (!maintenance_6) {
device_chain.unlink<vk::PhysicalDeviceMaintenance6FeaturesKHR>();
}
if (!maintenance_8) {
device_chain.unlink<vk::PhysicalDeviceMaintenance8FeaturesKHR>();
}
@@ -630,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;
@@ -639,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);
@@ -730,6 +784,13 @@ void Instance::CollectDeviceParameters() {
LOG_INFO(Render_Vulkan, "GPU_Vulkan_Driver: {}", driver_name);
LOG_INFO(Render_Vulkan, "GPU_Vulkan_Version: {}", api_version);
LOG_INFO(Render_Vulkan, "GPU_Vulkan_Extensions: {}", extensions);
std::snprintf(g_gpu_vendor_name, sizeof(g_gpu_vendor_name), "%s", vendor_name.c_str());
std::snprintf(g_gpu_model_name, sizeof(g_gpu_model_name), "%s", model_name.c_str());
std::snprintf(g_gpu_driver_name, sizeof(g_gpu_driver_name), "%s", driver_name.c_str());
std::snprintf(g_gpu_api_version, sizeof(g_gpu_api_version), "%s", api_version.c_str());
std::printf("GPU: Model='%s', Driver='%s', Vulkan='%s'\n", g_gpu_model_name, g_gpu_driver_name, g_gpu_api_version);
std::fflush(stdout);
}
void Instance::CollectPhysicalMemoryInfo() {
@@ -128,6 +128,16 @@ public:
return vk12_features.shaderInt8;
}
/// Returns true if VK_KHR_maintenance5 is supported
bool IsMaintenance5Supported() const {
return maintenance_5;
}
/// Returns true if VK_KHR_maintenance6 is supported
bool IsMaintenance6Supported() const {
return maintenance_6;
}
/// Returns true if VK_KHR_maintenance8 is supported
bool IsMaintenance8Supported() const {
return maintenance_8;
@@ -567,6 +577,7 @@ private:
bool shader_atomic_float2{};
bool workgroup_memory_explicit_layout{};
bool maintenance_5{};
bool maintenance_6{};
bool maintenance_8{};
bool buffer_marker{};
bool attachment_feedback_loop{};
@@ -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 = {
@@ -182,6 +190,7 @@ const Shader::RuntimeInfo& PipelineCache::BuildRuntimeInfo(PipelineSelection& se
info.hw.fs.addr_flags = regs.ps_input_addr;
info.hw.fs.num_inputs = regs.num_interp;
info.hw.fs.front_face_all_bits = regs.barycentric_control.front_face_all_bits;
info.hw.fs.depth_before_shader = regs.depth_shader_control.depth_before_shader != 0;
info.hw.fs.num_samples =
regs.ps_input_addr.sample_coverage_ena && regs.ps_input_ena.sample_coverage_ena
? regs.aa_config.NumSamples()
@@ -346,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()) {
@@ -367,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();
@@ -446,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);
}
};
@@ -455,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) {
@@ -519,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;
@@ -532,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) {
@@ -540,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);
@@ -609,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;
@@ -631,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) {
@@ -641,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();
@@ -654,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;
@@ -684,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;
}
@@ -702,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);
@@ -712,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;
@@ -1048,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;
@@ -1129,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();
{
@@ -1171,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
Loaded 100 of 205 files, more files were not shown because too many files have changed in this diff. Show more