Showing preview only (1,578K chars total). Download the full file or copy to clipboard to get everything.
Repository: NVIDIA-RTX/RTXMG
Branch: main
Commit: 230a15c6a4bc
Files: 171
Total size: 1.5 MB
Directory structure:
gitextract_4m5g8eoe/
├── .editorconfig
├── .gitattributes
├── .gitignore
├── .gitlab-ci.yml
├── .gitmodules
├── CHANGELOG.md
├── CMake/
│ ├── FetchDXC.cmake
│ ├── FetchImplot.cmake
│ └── FetchNVAPI.cmake
├── CMakeLists.txt
├── LICENSE.txt
├── README.md
├── demo/
│ ├── CMakeLists.txt
│ ├── args.cpp
│ ├── args.h
│ ├── audio/
│ │ ├── CMakeLists.txt
│ │ ├── audio.cpp
│ │ ├── audio.h
│ │ ├── waveFile.cpp
│ │ ├── waveFile.h
│ │ └── xaudiofaudio.h
│ ├── blit_params.h
│ ├── envmap/
│ │ ├── CMakeLists.txt
│ │ ├── preprocess_envmap.h
│ │ ├── preprocess_envmap_params.h
│ │ ├── scan_system.cpp
│ │ ├── scan_system.h
│ │ ├── scan_system_shared.h
│ │ ├── shaders/
│ │ │ ├── compute_conditional.hlsl
│ │ │ ├── compute_marginal.hlsl
│ │ │ ├── envmap.hlsli
│ │ │ └── prefix_scan.hlsl
│ │ └── shaders.cfg
│ ├── gbuffer.h
│ ├── gui.cpp
│ ├── gui.h
│ ├── gui_fonts.cpp
│ ├── korgi.cpp
│ ├── korgi.h
│ ├── lerp_keyframes_params.h
│ ├── lighting_cb.h
│ ├── maya_logger.cpp
│ ├── maya_logger.h
│ ├── motion_vectors_params.h
│ ├── ray_payload.h
│ ├── render_params.h
│ ├── render_targets.cpp
│ ├── render_targets.h
│ ├── rtxmg_demo.cpp
│ ├── rtxmg_demo.h
│ ├── rtxmg_demo_app.cpp
│ ├── rtxmg_demo_app.h
│ ├── rtxmg_renderer.cpp
│ ├── rtxmg_renderer.h
│ ├── shaders/
│ │ ├── blit.hlsl
│ │ ├── brdf.hlsli
│ │ ├── color.hlsli
│ │ ├── lerp_keyframes.hlsl
│ │ ├── motion_vectors.hlsl
│ │ ├── rtxmg_demo_path_tracer.hlsl
│ │ ├── self_intersection_avoidance.hlsli
│ │ ├── utils.hlsli
│ │ └── zrender.hlsl
│ ├── shaders.cfg
│ ├── trackball.cpp
│ ├── trackball.h
│ ├── zrender_params.h
│ ├── zrenderer.cpp
│ └── zrenderer.h
├── docs/
│ └── QuickStart.md
├── extern/
│ ├── CMakeLists.txt
│ └── nrd.cfg
├── notice.txt
├── rtxmg/
│ ├── CMakeLists.txt
│ ├── cluster_builder/
│ │ ├── CMakeLists.txt
│ │ ├── cluster_accel_builder.cpp
│ │ ├── shaders/
│ │ │ ├── compute_cluster_tiling.hlsl
│ │ │ ├── copy_cluster_offset.hlsl
│ │ │ ├── fill_blas_from_clas_args.hlsl
│ │ │ ├── fill_clusters.hlsl
│ │ │ ├── fill_instance_descs.hlsl
│ │ │ └── fill_instantiate_template_args.hlsl
│ │ └── shaders.cfg
│ ├── hiz/
│ │ ├── CMakeLists.txt
│ │ ├── hiz_buffer.cpp
│ │ ├── shaders/
│ │ │ ├── hiz_display.hlsl
│ │ │ ├── hiz_pass1.hlsl
│ │ │ ├── hiz_pass2.hlsl
│ │ │ ├── zbuffer_display.hlsl
│ │ │ └── zbuffer_minmax.hlsl
│ │ ├── shaders.cfg
│ │ └── zbuffer.cpp
│ ├── include/
│ │ └── rtxmg/
│ │ ├── cluster_builder/
│ │ │ ├── cluster.h
│ │ │ ├── cluster_accel_builder.h
│ │ │ ├── cluster_accels.h
│ │ │ ├── compute_cluster_tiling_params.h
│ │ │ ├── copy_cluster_offset_params.h
│ │ │ ├── displacement.hlsli
│ │ │ ├── fill_blas_from_clas_args_params.h
│ │ │ ├── fill_clusters_params.h
│ │ │ ├── fill_instance_descs_params.h
│ │ │ ├── fill_instantiate_template_args_params.h
│ │ │ ├── tessellation_counters.h
│ │ │ ├── tessellator_config.h
│ │ │ ├── tessellator_constants.h
│ │ │ └── tilings.h
│ │ ├── hiz/
│ │ │ ├── hiz_buffer.h
│ │ │ ├── hiz_buffer_constants.h
│ │ │ ├── hiz_buffer_display_params.h
│ │ │ ├── hiz_buffer_reduce_params.h
│ │ │ └── zbuffer.h
│ │ ├── profiler/
│ │ │ ├── gui.h
│ │ │ ├── profiler.h
│ │ │ ├── sampler.h
│ │ │ ├── statistics.h
│ │ │ └── stopwatch.h
│ │ ├── scene/
│ │ │ ├── box_extent.h
│ │ │ ├── camera.h
│ │ │ ├── json.h
│ │ │ ├── model.h
│ │ │ ├── obj_importer.h
│ │ │ ├── scene.h
│ │ │ └── string_utils.h
│ │ ├── subdivision/
│ │ │ ├── far.h
│ │ │ ├── osd_ports/
│ │ │ │ └── tmr/
│ │ │ │ ├── nodeDescriptor.h
│ │ │ │ ├── subdivisionNode.h
│ │ │ │ ├── surfaceDescriptor.h
│ │ │ │ ├── treeDescriptor.h
│ │ │ │ └── types.h
│ │ │ ├── patch_param.h
│ │ │ ├── segmented_vector.h
│ │ │ ├── shape.h
│ │ │ ├── subdivision_eval.hlsli
│ │ │ ├── subdivision_plan_hlsl.h
│ │ │ ├── subdivision_surface.h
│ │ │ ├── topology_cache.h
│ │ │ ├── topology_map.h
│ │ │ └── vertex.h
│ │ └── utils/
│ │ ├── box3.h
│ │ ├── buffer.h
│ │ ├── constants.h
│ │ ├── debug.h
│ │ ├── formatters.h
│ │ ├── shader_debug.h
│ │ └── vectorlog.h
│ ├── profiler/
│ │ ├── CMakeLists.txt
│ │ ├── gui.cpp
│ │ ├── profiler.cpp
│ │ ├── statistics.cpp
│ │ └── stopwatch.cpp
│ ├── scene/
│ │ ├── CMakeLists.txt
│ │ ├── box_extent.cpp
│ │ ├── camera.cpp
│ │ ├── json.cpp
│ │ ├── obj_importer.cpp
│ │ ├── scene.cpp
│ │ └── string_utils.cpp
│ ├── subdivision/
│ │ ├── CMakeLists.txt
│ │ ├── shape.cpp
│ │ ├── subdivision_surface.cpp
│ │ ├── topology_cache.cpp
│ │ └── topology_map.cpp
│ └── utils/
│ ├── CMakeLists.txt
│ ├── buffer.cpp
│ ├── csvdump.cpp
│ ├── debug.cpp
│ └── formatters.cpp
├── rtxmg_static_analysis.props
├── rtxmg_static_analysis.ruleset
├── shadertoolsconfig.json
└── tools/
└── set_vs_vars.ps1
================================================
FILE CONTENTS
================================================
================================================
FILE: .editorconfig
================================================
# Visual Studio generated .editorconfig file with C++ settings.
root = true
[*.{c++,cc,cpp,cppm,cu,cuh,cxx,fx,h,h++,hh,hlsl,hpp,hxx,inl,ipp,ixx,tlh,tli}]
indent_size = 4;
indent_style = space;
# Visual C++ Code Style settings
cpp_generate_documentation_comments = xml
# Visual C++ Formatting settings
cpp_indent_braces = false
cpp_indent_multi_line_relative_to = innermost_parenthesis
cpp_indent_within_parentheses = indent
cpp_indent_preserve_within_parentheses = true
cpp_indent_case_contents = true
cpp_indent_case_labels = false
cpp_indent_case_contents_when_block = false
cpp_indent_lambda_braces_when_parameter = true
cpp_indent_goto_labels = one_left
cpp_indent_preprocessor = leftmost_column
cpp_indent_access_specifiers = false
cpp_indent_namespace_contents = true
cpp_indent_preserve_comments = false
cpp_new_line_before_open_brace_namespace = new_line
cpp_new_line_before_open_brace_type = new_line
cpp_new_line_before_open_brace_function = new_line
cpp_new_line_before_open_brace_block = new_line
cpp_new_line_before_open_brace_lambda = new_line
cpp_new_line_scope_braces_on_separate_lines = true
cpp_new_line_close_brace_same_line_empty_type = false
cpp_new_line_close_brace_same_line_empty_function = false
cpp_new_line_before_catch = true
cpp_new_line_before_else = true
cpp_new_line_before_while_in_do_while = false
cpp_space_before_function_open_parenthesis = remove
cpp_space_within_parameter_list_parentheses = false
cpp_space_between_empty_parameter_list_parentheses = false
cpp_space_after_keywords_in_control_flow_statements = true
cpp_space_within_control_flow_statement_parentheses = false
cpp_space_before_lambda_open_parenthesis = false
cpp_space_within_cast_parentheses = false
cpp_space_after_cast_close_parenthesis = false
cpp_space_within_expression_parentheses = false
cpp_space_before_block_open_brace = true
cpp_space_between_empty_braces = false
cpp_space_before_initializer_list_open_brace = false
cpp_space_within_initializer_list_braces = true
cpp_space_preserve_in_initializer_list = true
cpp_space_before_open_square_bracket = false
cpp_space_within_square_brackets = false
cpp_space_before_empty_square_brackets = false
cpp_space_between_empty_square_brackets = false
cpp_space_group_square_brackets = true
cpp_space_within_lambda_brackets = false
cpp_space_between_empty_lambda_brackets = false
cpp_space_before_comma = false
cpp_space_after_comma = true
cpp_space_remove_around_member_operators = true
cpp_space_before_inheritance_colon = true
cpp_space_before_constructor_colon = true
cpp_space_remove_before_semicolon = true
cpp_space_after_semicolon = true
cpp_space_remove_around_unary_operator = true
cpp_space_around_binary_operator = insert
cpp_space_around_assignment_operator = insert
cpp_space_pointer_reference_alignment = left
cpp_space_around_ternary_operator = insert
cpp_use_unreal_engine_macro_formatting = true
cpp_wrap_preserve_blocks = one_liners
# Visual C++ Inlcude Cleanup settings
cpp_include_cleanup_add_missing_error_tag_type = suggestion
cpp_include_cleanup_remove_unused_error_tag_type = dimmed
cpp_include_cleanup_sort_after_edits = false
cpp_sort_includes_error_tag_type = none
cpp_sort_includes_priority_case_sensitive = false
cpp_sort_includes_priority_style = quoted
cpp_includes_style = default
cpp_includes_use_forward_slash = true
[*.md]
spelling_languages = en-us
spelling_error_severity = warning
================================================
FILE: .gitattributes
================================================
# Default behavior in case core.autocrlf set
* text=auto
*.dll filter=lfs diff=lfs merge=lfs -text
*.pdb filter=lfs diff=lfs merge=lfs -text
================================================
FILE: .gitignore
================================================
*.*~
scenes
bin/
_build/
_install/
build/
.vscode/
================================================
FILE: .gitlab-ci.yml
================================================
stages:
- build
variables:
GIT_SUBMODULE_STRATEGY: recursive
build-windows:
stage: build
tags:
- os/win11
rules:
- if: '$ENABLE_JOBS =~ /build-windows/'
parallel:
matrix:
- BUILD_TYPE: ['Release', 'Debug']
DX12: 'ON'
VULKAN: 'OFF'
script:
- tools/set_vs_vars.ps1
- mkdir build
- cd build
- cmake .. -G "Visual Studio 17 2022" -A x64 "-DCMAKE_BUILD_TYPE=$BUILD_TYPE" "-DDONUT_WITH_DX12=$DX12" "-DDONUT_WITH_VULKAN=$VULKAN"
- cmake --build . --config "$BUILD_TYPE" --target package
artifacts:
when: on_success
access: all
expire_in: 30 days
paths: ['build/rtxmg.*.zip']
================================================
FILE: .gitmodules
================================================
[submodule "extern/donut"]
path = extern/donut
url = https://github.com/NVIDIA-RTX/Donut.git
[submodule "assets"]
path = assets
url = https://github.com/NVIDIA-RTX/RTXMG-Sample-Assets.git
[submodule "extern/osd_lite"]
path = extern/osd_lite
url = https://github.com/NVIDIA-RTX/OSD-Lite.git
================================================
FILE: CHANGELOG.md
================================================
# RTX Mega Geometry SDK Change Log
## 1.0.1
Improvements
* Add smooth vertex normal support which allows for lower tessellation rates and includes memory profiler row for vertex normals
* Filter out degenerate normals for backface culling to improve backface test and reduce triangle count
Debugging Improvements
* Improve shader debug with stable cluster index output from path tracing shader
* Add surface highlighting feature where path-tracer will blink highlight a selected debug surface
* Add utilities to shader debug to force output
Bug Fixes
* Fix regression in surface 1-ring culling caused by 1D thread-ordering change, which resulted in incorrect lanes doing work for unrelated waves
* Fix crash when refreshing media list after changing json/obj filters with an asset already loaded
## 1.0.0
Vulkan Support
* Requires Vulkan SDK 1.4.313 or greater which uses Cluster SPIRV intrinsics
* Convert all bindless arrays to use ResourceDescriptorHeap via Vulkan's mutable descriptor extension
* Fix validation warnings and Vulkan shutdown crashes
Minor Changes
* Expose isolation level in the UI
* Add smooth single crease sharpness, which prevents transition artifacts between single and multicrease edges. Only visible if the isolation level is lowered.
* Improve Profiler "Frame" Tab, add average times in tool tip, expose motion vector pass time
* Update to Streamline v2.8.0
Bug Fixes
* Fix thread-ordering to be compliant with SM6.6 1D quad lane ordering.
* Fix micro-triangle view toggle when in DLAA mode.
* Fix cases where a surface resulted in over U16_MAX clusters
* Fix tessellation for when there was per-material displacement scaling
* Fix crash for some malformed OBJ files with '0' values for some indices.
## 0.9.2
Performance Improvements
Test Scene: amy_kitchenset.scene.json (default camera: 79M microtriangles)
Hardware: RTX 5090 @ 4K Render Resolution (r572.83)
* Compute Cluster tiling: 4.0ms -> 1.0ms (300% speedup)
* Coalesced UAV writes for structs, unaligned members were causing UAV readbacks
* Coalesce per wave atomics into a groupshared atomic to reduce pressure on global/UAV atomics by 4x
* Fill clusters: 4.9ms to -> 1.0ms (390% speedup)
* Fixed cases where the compiler was unable to unroll loops due to dynamic loop counts
* Specialized shaders by subdivision surface type, with a special path for Pure BSpline surfaces. Prefetch all control points into shared memory to be used wave wide.
Minor Fixes
* Fix SpecularHitT guide buffer to DLSS-RR to improve coherence of specular rays.
## 0.9.1
Stability
* Fix crash on scenes with multiple subdivision mesh instances when the topology quality color mode was selected
* Fix a crash if scene with audio is loaded and no audio devices are present.
Topology Quality
* Add button in the Subdivision Evaluator tab to switch to topology quality view if issues are detected
* Fix Subdivision Evaluator UI not resetting upon scene load.
UI
* Application Window Size/Maximized/Fullscreen and Window state is now saved to and restored from imgui.ini. Delete imgui.ini to reset layout
Minor
* Make initial VRAM check non-fatal but add warnings about performance degradation, memory budgets.
* Made localToWorld transform use Matrix3x4 for consistency
* Style clean-up
* Update donut version
## 0.9.0
Initial beta release.
================================================
FILE: CMake/FetchDXC.cmake
================================================
#
# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of NVIDIA CORPORATION nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
include(FetchContent)
set(DXC_URL https://github.com/microsoft/DirectXShaderCompiler/releases/download/v1.8.2407/dxc_2024_07_31.zip)
set(DXC_SHA256_HASH e2627f004f0f9424d8c71ea1314d04f38c5a5096884ae9217f1f18bd320267b5)
FetchContent_Declare(
DXC
URL ${DXC_URL}
URL_HASH SHA256=${DXC_SHA256_HASH}
DOWNLOAD_EXTRACT_TIMESTAMP ON
)
FetchContent_MakeAvailable(DXC)
message(STATUS "Updating DXC from ${DXC_URL}, SHA256 ${DXC_SHA256_HASH}, into folder ${dxc_SOURCE_DIR}")
set(SHADERMAKE_FIND_DXC OFF CACHE BOOL "" FORCE)
set(DXC_PATH "${dxc_SOURCE_DIR}/bin/x64/dxc.exe" CACHE STRING "" FORCE)
================================================
FILE: CMake/FetchImplot.cmake
================================================
#
# Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of NVIDIA CORPORATION nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
if( TARGET implot )
return()
endif()
if (NOT TARGET imgui)
message(FATAL_ERROR "Implot requires imgui")
endif()
include(FetchContent)
FetchContent_Declare(
implot
GIT_REPOSITORY https://github.com/epezent/implot.git
GIT_TAG v0.16
)
FetchContent_MakeAvailable(implot)
# Override Imgui build - we want a lean static library
set(implot_srcs
${CMAKE_BINARY_DIR}/_deps/implot-src/implot.cpp
${CMAKE_BINARY_DIR}/_deps/implot-src/implot.h
${CMAKE_BINARY_DIR}/_deps/implot-src/implot_internal.h
${CMAKE_BINARY_DIR}/_deps/implot-src/implot_items.cpp
)
add_library(implot STATIC ${implot_srcs})
set_target_properties(implot PROPERTIES POSITION_INDEPENDENT_CODE ON)
add_compile_definitions(implot PRIVATE IMGUI_DEFINE_MATH_OPERATORS)
target_include_directories(implot PUBLIC "${CMAKE_BINARY_DIR}/_deps/implot-src/")
target_link_libraries(implot imgui)
================================================
FILE: CMake/FetchNVAPI.cmake
================================================
#
# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of NVIDIA CORPORATION nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
include(FetchContent)
set(NVAPI_FETCH_URL "https://github.com/NVIDIA/nvapi.git" CACHE STRING "Url to nvapi git repo to fetch")
set(NVAPI_FETCH_TAG "ce6d2a183f9559f717e82b80333966d19edb9c8c" CACHE STRING "Tag of nvapi git repo")
set(NVAPI_FETCH_DIR "" CACHE STRING "Directory to fetch streamline to, empty uses build directory default")
include(FetchContent)
FetchContent_Declare(
nvapi
GIT_REPOSITORY ${NVAPI_FETCH_URL}
GIT_TAG ${NVAPI_FETCH_TAG}
SOURCE_DIR ${NVAPI_FETCH_DIR}
)
FetchContent_MakeAvailable(nvapi)
message(STATUS "Updating nvapi from ${NVAPI_FETCH_URL}, tag ${NVAPI_FETCH_TAG}, into folder ${nvapi_SOURCE_DIR}")
set(NVAPI_SEARCH_PATHS "${nvapi_SOURCE_DIR}")
================================================
FILE: CMakeLists.txt
================================================
cmake_minimum_required(VERSION 3.10)
project(rtxmg LANGUAGES C CXX VERSION 1.0.1)
set(CMAKE_CONFIGURATION_TYPES "Debug;Release;RelWithDebInfo;ReleaseAsan" CACHE STRING "Configurations" FORCE)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS ON)
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SOURCE_DIR}/extern)
####################################
# Static analysis
####################################
set(RULESET_PATH "${CMAKE_SOURCE_DIR}/rtxmg_static_analysis.ruleset")
add_compile_options("-wd26495")
set_property( GLOBAL PROPERTY VS_USER_PROPS "rtxmg_static_analysis.props")
####################################
# ASAN
####################################
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/bin")
foreach(CONFIG_TYPE DEBUG RELEASE MINSIZEREL RELWITHDEBINFO RELEASEASAN)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CONFIG_TYPE} "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
endforeach()
set(CMAKE_CXX_FLAGS_RELEASEASAN "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -fsanitize=address")
set(CMAKE_EXE_LINKER_FLAGS_RELEASEASAN "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}")
set(CMAKE_SHARED_LINKER_FLAGS_RELEASEASAN "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO}")
####################################
# AgilitySDK
####################################
if(WIN32)
# this SDK requires features from the D3D12 Agility SDK on Win 10
if(CMAKE_SYSTEM_VERSION LESS 11.0)
set(DONUT_D3D_AGILITY_SDK_URL "https://www.nuget.org/api/v2/package/Microsoft.Direct3D.D3D12/1.614.1")
# set fetch destination to cmake default build/_deps folder
set(DONUT_D3D_AGILITY_SDK_FETCH_DIR "" CACHE STRING "")
include("${PROJECT_SOURCE_DIR}/extern/donut/cmake/FetchAgilitySDK.cmake")
else()
message(STATUS "Windows 11 or newer detected: disabling Agility SDK")
endif()
endif()
####################################
# DXC
# WindowsSDK version is buggy and the compiler crashes
####################################
set(SHADERMAKE_FIND_DXC ON CACHE BOOL "" FORCE)
####################################
# Streamline
####################################
set(DONUT_WITH_STREAMLINE ON CACHE BOOL "" FORCE)
set(DONUT_STREAMLINE_FETCH_URL "https://github.com/NVIDIA-RTX/Streamline/releases/download/v2.8.0/streamline-sdk-v2.8.0.zip" CACHE STRING "")
set(DONUT_STREAMLINE_FETCH_SHA256 "313669f8cf886f823ea0518a50712efa5e2e8623689ed2a6bd0d9353e475bc47" CACHE STRING "")
set(STREAMLINE_FEATURE_DLSS_SR ON CACHE BOOL "" FORCE)
set(STREAMLINE_FEATURE_DLSS_RR ON CACHE BOOL "" FORCE)
set(STREAMLINE_INSTALL_DIR "bin" CACHE STRING "" FORCE)
####################################
# NVAPI
####################################
include("${PROJECT_SOURCE_DIR}/CMake/FetchNVAPI.cmake")
####################################
# DONUT
####################################
option(DONUT_WITH_DX11 OFF)
set(DONUT_WITH_VULKAN ON CACHE BOOL "Enable the Vulkan version of Donut")
set(NVRHI_WITH_NVAPI ON CACHE BOOL "" FORCE)
set(DONUT_WITH_AFTERMATH ON CACHE BOOL "" FORCE)
set(NVRHI_INSTALL OFF CACHE BOOL "" FORCE)
# Shaders
set(DONUT_SHADERS_OUTPUT_DIR "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/shaders/framework")
set(DONUT_DIR "${PROJECT_SOURCE_DIR}/extern/donut")
list(APPEND RTXMG_SHADERS_INCLUDE_DIR
"${PROJECT_SOURCE_DIR}"
"${PROJECT_SOURCE_DIR}/extern"
"${PROJECT_SOURCE_DIR}/extern/donut/include"
"${PROJECT_SOURCE_DIR}/rtxmg/include"
"${nvapi_SOURCE_DIR}"
"${PROJECT_SOURCE_DIR}/extern/donut/nvrhi/include")
set(RTXMG_SHADERMAKE_OPTIONS "--embedPDB --hlsl2021")
#-vd disable validator due to a bug in
# https://github.com/microsoft/DirectXShaderCompiler/issues/7181
# should be fixed in version 1.8.2505
set(RTXMG_SHADERMAKE_OPTIONS_SPIRV "--vulkanMemoryLayout scalar --compilerOptions -Vd")
set(RTXMG_SHADERS_SHADERMODEL "6_6")
set(RTXMG_SHADERS_IGNORED_INCLUDES "")
list(APPEND RTXMG_SHADERS_IGNORED_INCLUDES
"donut/core/math/math.h"
"nvrhi/nvrhi.h"
"array"
"assert.h"
"cstdint"
"cstdio"
"stdio.h"
"cmath"
"ostream"
"rtxmg/utils/buffer.h"
)
add_subdirectory(extern/donut)
add_subdirectory(extern/osd_lite EXCLUDE_FROM_ALL)
add_subdirectory(rtxmg)
add_subdirectory(demo)
add_subdirectory(extern)
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT rtxmg_demo)
================================================
FILE: LICENSE.txt
================================================
NVIDIA RTX SDKs LICENSE
This license is a legal agreement between you and NVIDIA Corporation ("NVIDIA") and governs the use of the NVIDIA RTX
software development kits, including the DLSS SDK, NGX SDK, RTXGI SDK, RTXDI SDK, RTX Video SDK and/or NRD SDK, if and
when made available to you under this license (in each case, the SDK).
This license can be accepted only by an adult of legal age of majority in the country in which the SDK is used. If you are
under the legal age of majority, you must ask your parent or legal guardian to consent to this license. If you are entering this
license on behalf of a company or other legal entity, you represent that you have legal authority and you will mean the
entity you represent.
By using the SDK, you affirm that you have reached the legal age of majority, you accept the terms of this license, and you
take legal and financial responsibility for the actions of your permitted users.
You agree to use the SDK only for purposes that are permitted by (a) this license, and (b) any applicable law, regulation or
generally accepted practices or guidelines in the relevant jurisdictions.
1. LICENSE. Subject to the terms of this license and the terms in the supplement attached, NVIDIA hereby grants you a non-
exclusive, non-transferable license, without the right to sublicense (except as expressly provided in this license) to:
a. Install and use the SDK,
b. Modify and create derivative works of sample source code delivered in the SDK, and
c. Distribute any software and materials within the SDK, other than developer tools provided for your internal use, as
incorporated in object code format into a software application subject to the distribution requirements indicated in this
license.
2. DISTRIBUTION REQUIREMENTS. These are the distribution requirements for you to exercise the grants above:
a. An application must have material additional functionality, beyond the included portions of the SDK.
b. The following notice shall be included in modifications and derivative works of source code distributed: This software
contains source code provided by NVIDIA Corporation.
c. You agree to distribute the SDK subject to the terms at least as protective as the terms of this license, including (without
limitation) terms relating to the license grant, license restrictions and protection of NVIDIAs intellectual property rights.
Additionally, you agree that you will protect the privacy, security and legal rights of your application users.
d. You agree to notify NVIDIA in writing of any known or suspected distribution or use of the SDK not in compliance with
the requirements of this license, and to enforce the terms of your agreements with respect to the distributed portions of
the SDK.
3. AUTHORIZED USERS. You may allow employees and contractors of your entity or of your subsidiary(ies) to access and use
the SDK from your secure network to perform work on your behalf. If you are an academic institution you may allow users
enrolled or employed by the academic institution to access and use the SDK from your secure network. You are responsible
for the compliance with the terms of this license by your authorized users.
4. LIMITATIONS. Your license to use the SDK is restricted as follows:
a. You may not reverse engineer, decompile or disassemble, or remove copyright or other proprietary notices from any
portion of the SDK or copies of the SDK.
b. Except as expressly provided in this license, you may not copy, sell, rent, sublicense, transfer, distribute, modify, or
create derivative works of any portion of the SDK. For clarity, you may not distribute or sublicense the SDK as a stand-alone
product.
c. Unless you have an agreement with NVIDIA for this purpose, you may not indicate that an application created with the
SDK is sponsored or endorsed by NVIDIA.
d. You may not bypass, disable, or circumvent any technical limitation, encryption, security, digital rights management or
authentication mechanism in the SDK.
e. You may not use the SDK in any manner that would cause it to become subject to an open source software license. As
examples, licenses that require as a condition of use, modification, and/or distribution that the SDK be: (i) disclosed or
distributed in source code form; (ii) licensed for the purpose of making derivative works; or (iii) redistributable at no charge.
f. Unless you have an agreement with NVIDIA for this purpose, you may not use the SDK with any system or application
where the use or failure of the system or application can reasonably be expected to threaten or result in personal injury,
death, or catastrophic loss. Examples include use in avionics, navigation, military, medical, life support or other life critical
applications. NVIDIA does not design, test or manufacture the SDK for these critical uses and NVIDIA shall not be liable to
you or any third party, in whole or in part, for any claims or damages arising from such uses.
g. You agree to defend, indemnify and hold harmless NVIDIA and its affiliates, and their respective employees, contractors,
agents, officers and directors, from and against any and all claims, damages, obligations, losses, liabilities, costs or debt,
fines, restitutions and expenses (including but not limited to attorneys fees and costs incident to establishing the right of
indemnification) arising out of or related to your use of the SDK outside of the scope of this license, or not in compliance
with its terms.
5. UPDATES. NVIDIA may, at its option, make available patches, workarounds or other updates to this SDK. Unless the
updates are provided with their separate governing terms, they are deemed part of the SDK licensed to you as provided in
this license. Further, NVIDIA may, at its option, automatically update the SDK or other software in the system, except for
those updates that you may opt-out via the SDK API. You agree that the form and content of the SDK that NVIDIA provides
may change without prior notice to you. While NVIDIA generally maintains compatibility between versions, NVIDIA may in
some cases make changes that introduce incompatibilities in future versions of the SDK.
6. PRE-RELEASE VERSIONS. SDK versions identified as alpha, beta, preview, early access or otherwise as pre-release may not
be fully functional, may contain errors or design flaws, and may have reduced or different security, privacy, availability, and
reliability standards relative to commercial versions of NVIDIA software and materials. You may use a pre-release SDK
version at your own risk, understanding that these versions are not intended for use in production or business-critical
systems. NVIDIA may choose not to make available a commercial version of any pre-release SDK. NVIDIA may also choose to
abandon development and terminate the availability of a pre-release SDK at any time without liability.
7. THIRD-PARTY COMPONENTS. The SDK may include third-party components with separate legal notices or terms as may
be described in proprietary notices accompanying the SDK. If and to the extent there is a conflict between the terms in this
license and the third-party license terms, the third-party terms control only to the extent necessary to resolve the conflict.
8. OWNERSHIP.
8.1 NVIDIA reserves all rights, title and interest in and to the SDK not expressly granted to you under this license. NVIDIA
and its suppliers hold all rights, title and interest in and to the SDK, including their respective intellectual property rights.
The SDK is copyrighted and protected by the laws of the United States and other countries, and international treaty
provisions.
8.2 Subject to the rights of NVIDIA and its suppliers in the SDK, you hold all rights, title and interest in and to your
applications and your derivative works of the sample source code delivered in the SDK including their respective intellectual
property rights.
9. FEEDBACK. You may, but are not obligated to, provide Feedback to NVIDIA. Feedback means all suggestions, fixes,
modifications, feature requests or other feedback regarding the SDK. Feedback, even if designated as confidential by you,
shall not create any confidentiality obligation for NVIDIA. If you provide Feedback, you hereby grant NVIDIA, its affiliates
and its designees a non-exclusive, perpetual, irrevocable, sublicensable, worldwide, royalty-free, fully paid-up and
transferable license, under your intellectual property rights, to publicly perform, publicly display, reproduce, use, make,
have made, sell, offer for sale, distribute (through multiple tiers of distribution), import, create derivative works of and
otherwise commercialize and exploit the Feedback at NVIDIAs discretion. You will not give Feedback (i) that you have
reason to believe is subject to any restriction that impairs the exercise of the grant stated in this section, such as third-party
intellectual property rights or (ii) subject to license terms which seek to require any product incorporating or developed
using such Feedback, or other intellectual property of NVIDIA or its affiliates, to be licensed to or otherwise shared with any
third party.
10. NO WARRANTIES. THE SDK IS PROVIDED AS-IS. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW NVIDIA AND
ITS AFFILIATES EXPRESSLY DISCLAIM ALL WARRANTIES OF ANY KIND OR NATURE, WHETHER EXPRESS, IMPLIED OR
STATUTORY, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT, FITNESS FOR A
PARTICULAR PURPOSE, USAGE OF TRADE AND COURSE OF DEALING. NVIDIA DOES NOT WARRANT THAT THE SDK WILL
MEET YOUR REQUIREMENTS OR THAT THE OPERATION THEREOF WILL BE UNINTERRUPTED OR ERROR-FREE, OR THAT ALL
ERRORS WILL BE CORRECTED.
11. LIMITATIONS OF LIABILITY. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW NVIDIA AND ITS AFFILIATES SHALL
NOT BE LIABLE FOR ANY (I) SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL DAMAGES, OR FOR DAMAGES FOR (A)
ANY LOST PROFITS, PROJECT DELAYS, LOSS OF USE, LOSS OF DATA OR LOSS OF GOODWILL, OR (B) THE COSTS OF
PROCURING SUBSTITUTE PRODUCTS, ARISING OUT OF OR IN CONNECTION WITH THIS LICENSE OR THE USE OR
PERFORMANCE OF THE SDK, WHETHER SUCH LIABILITY ARISES FROM ANY CLAIM BASED UPON BREACH OF CONTRACT,
BREACH OF WARRANTY, TORT (INCLUDING NEGLIGENCE), PRODUCT LIABILITY OR ANY OTHER CAUSE OF ACTION OR
THEORY OF LIABILITY, EVEN IF NVIDIA HAS PREVIOUSLY BEEN ADVISED OF, OR COULD REASONABLY HAVE FORESEEN, THE
POSSIBILITY OF SUCH DAMAGES. IN NO EVENT WILL NVIDIAS AND ITS AFFILIATES TOTAL CUMULATIVE LIABILITY UNDER OR
ARISING OUT OF THIS LICENSE EXCEED US$10.00. THE NATURE OF THE LIABILITY OR THE NUMBER OF CLAIMS OR SUITS
SHALL NOT ENLARGE OR EXTEND THIS LIMIT.
12. TERMINATION. Your rights under this license will terminate automatically without notice from NVIDIA if you fail to
comply with any term and condition of this license or if you commence or participate in any legal proceeding against
NVIDIA with respect to the SDK. NVIDIA may terminate this license with advance written notice to you, if NVIDIA decides to
no longer provide the SDK in a country or, in NVIDIAs sole discretion, the continued use of it is no longer commercially
viable. Upon any termination of this license, you agree to promptly discontinue use of the SDK and destroy all copies in your
possession or control. Your prior distributions in accordance with this license are not affected by the termination of this
license. All provisions of this license will survive termination, except for the license granted to you.
13. APPLICABLE LAW. This license will be governed in all respects by the laws of the United States and of the State of
Delaware, without regard to the conflicts of laws principles. The United Nations Convention on Contracts for the
International Sale of Goods is specifically disclaimed. You agree to all terms of this license in the English language. The state
or federal courts residing in Santa Clara County, California shall have exclusive jurisdiction over any dispute or claim arising
out of this license. Notwithstanding this, you agree that NVIDIA shall still be allowed to apply for injunctive remedies or
urgent legal relief in any jurisdiction.
14. NO ASSIGNMENT. This license and your rights and obligations thereunder may not be assigned by you by any means or
operation of law without NVIDIAs permission. Any attempted assignment not approved by NVIDIA in writing shall be void
and of no effect. NVIDIA may assign, delegate or transfer this license and its rights and obligations, and if to a non-affiliate
you will be notified.
15. EXPORT. The SDK is subject to United States export laws and regulations. You agree to comply with all applicable U.S.
and international export laws, including the Export Administration Regulations (EAR) administered by the U.S. Department
of Commerce and economic sanctions administered by the U.S. Department of Treasurys Office of Foreign Assets Control
(OFAC). These laws include restrictions on destinations, end-users and end-use. By accepting this license, you confirm that
you are not currently residing in a country or region currently embargoed by the U.S. and that you are not otherwise
prohibited from receiving the SDK.
16. GOVERNMENT USE. The SDK, documentation and technology (Protected Items) are Commercial products as this
term is defined at 48 C.F.R. 2.101, consisting of commercial computer software and commercial computer software
documentation as such terms are used in, respectively, 48 C.F.R. 12.212 and 48 C.F.R. 227.7202 & 252.227-7014(a)(1).
Before any Protected Items are supplied to the U.S. Government, you will (i) inform the U.S. Government in writing that the
Protected Items are and must be treated as commercial computer software and commercial computer software
documentation developed at private expense; (ii) inform the U.S. Government that the Protected Items are provided
subject to the terms of the Agreement; and (iii) mark the Protected Items as commercial computer software and
commercial computer software documentation developed at private expense. In no event will you permit the U.S.
Government to acquire rights in Protected Items beyond those specified in 48 C.F.R. 52.227-19(b)(1)-(2) or 252.227-7013(c)
except as expressly approved by NVIDIA in writing.
17. NOTICES. You agree that any notices that NVIDIA sends you electronically, such as via email, will satisfy any legal
communication requirements. Please direct your legal notices or other correspondence to NVIDIA Corporation, 2788 San
Tomas Expressway, Santa Clara, California 95051, United States of America, Attention: Legal Department.
18. ENTIRE AGREEMENT. This license is the final, complete and exclusive agreement between the parties relating to the
subject matter of this license and supersedes all prior or contemporaneous understandings and agreements relating to this
subject matter, whether oral or written. If any court of competent jurisdiction determines that any provision of this license
is illegal, invalid or unenforceable, the remaining provisions will remain in full force and effect. Any amendment or waiver
under this license shall be in writing and signed by representatives of both parties.
19. LICENSING. If the distribution terms in this license are not suitable for your organization, or for any questions regarding
this license, please contact NVIDIA at nvidia-rtx-license-questions@nvidia.com.
(v. February 23, 2024)
NVIDIA RTX SUPPLEMENT TO SOFTWARE LICENSE AGREEMENT FOR NVIDIA SOFTWARE DEVELOPMENT KITS
The terms in this supplement govern your use of the NVIDIA RTX SDKs, including the DLSS SDK, NGX SDK, RTXGI SDK, RTXDI
SDK, Video SDK and/or NRD SDK, if and when made available to you (in each case, the SDK) under the terms of your
license agreement (Agreement) as modified by this supplement. Capitalized terms used but not defined below have the
meaning assigned to them in the Agreement.
This supplement is an exhibit to the Agreement and is incorporated as an integral part of the Agreement. In the event of
conflict between the terms in this supplement and the terms in the Agreement, the terms in this supplement govern.
1. Interoperability. Your applications that incorporate, or are based on, the SDK must be fully interoperable with
compatible GPU hardware products designed by NVIDIA or its affiliates. Further, the DLSS SDK and NGX SDK are licensed for
you to develop applications only for their use in systems with NVIDIA GPUs.
2. Game License. You may, but are not obligated to, provide your game or related content (Game Content) to NVIDIA. If
you provide Game Content, you hereby grant NVIDIA, its affiliates and its designees a non-exclusive, perpetual, irrevocable,
worldwide, royalty-free, fully paid-up license, to use the Game Content to improve NVIDIA DLSS SDK and DLSS Model
Training. The terms in this section do not apply to the Video SDK.
3. Limitations for the DLSS SDK and NGX SDK. Your applications that incorporate, or are based on, the DLSS SDK or NGX SDK
may be deployed in a cloud service that runs on systems that consume NVIDIA vGPU software, and any other cloud service
use of such SDKs or their functionality is outside of the scope of the Agreement. For the purpose of this section, cloud
services include application service providers or service bureaus, operators of hosted/virtual system environments, or
hosting, time sharing or providing any other type of service to others.
4. Notification for the DLSS SDK and NGX SDK. You are required to notify NVIDIA prior to commercial release of an
application (including a plug-in to a commercial application) that incorporates, or is based on, the DLSS SDK or NGX SDK.
Please send notifications to: https://developer.nvidia.com/sw-notification and provide the following information in the
email: company name, publisher and developer name, NVIDIA SDK used, application name, platform (i.e. PC, Linux),
scheduled ship date, and weblink to product/video.
5. Audio and Video Encoders and Decoders. You acknowledge and agree that it is your sole responsibility to obtain any
additional third-party licenses required to make, have made, use, have used, sell, import, and offer for sale your products or
services that include or incorporate any third-party software and content relating to audio and/or video encoders and
decoders from, including but not limited to, Microsoft, Thomson, Fraunhofer IIS, Sisvel S.p.A., MPEG-LA, and Coding
Technologies. NVIDIA does not grant to you under this Agreement any necessary patent or other rights with respect to any
audio and/or video encoders and decoders. The terms in this section do not apply to the Video SDK.
6. DLSS SDK Terms. By installing or using the DLSS SDK you agree that NVIDIA can make over-the-air updates of DLSS in
systems that have DLSS installed, including (without limitation) for quality, stability or performance improvements or to
support new hardware. If you publicly release a DLSS integration in an end user game or application that presents material
stability, performance, image quality, or other technical issues impacting the user experience, you will work to quickly
address the integration issues. In the case issues are not addressed, NVIDIA reserves the right, as a last resort, to
temporarily disable the DLSS integration until the issues can be fixed.
7. Marketing.
7.1 Marketing Activities. Your license to the SDK(s) under the Agreement is subject to your compliance with the following
marketing terms:
(a) Identification by You in the DLSS SDK, Video SDK or NGX SDK. During the term of the Agreement, NVIDIA agrees that
you may identify NVIDIA on your websites, printed collateral, trade-show displays and other retail packaging materials, as
the supplier of the DLSS SDK, Video SDK or NGX SDK for the applications that were developed with use of such SDKs,
provided that all such references to NVIDIA will be subject to NVIDIA's prior review and written approval, which will not be
unreasonably withheld or delayed.
(b) NVIDIA Trademark Placement in Applications with the DLSS SDK or NGX SDK. For applications that incorporate the DLSS
SDK or NGX SDK or portions thereof, you must attribute the use of the applicable SDK and include the NVIDIA Marks on
splash screens, in the about box of the application (if present), and in credits for game applications.
(c) NVIDIA Trademark Placement in Applications with a licensed SDK, other than the DLSS SDK, Video SDK or NGX SDK. For
applications that incorporates and/or makes use of a licensed SDK, other than the DLSS SDK, Video SDK or NGX SDK, you
must attribute the use of the applicable SDK and include the NVIDIA Marks on the credit screen for applications that have
such credit screen, or where a credit screen is not present prominently in end user documentation for the application.
(d) Identification by NVIDIA in the DLSS SDK, Video SDK or NGX SDK. You agree that NVIDIA may identify you on NVIDIA's
websites, printed collateral, trade-show displays, and other retail packaging materials as an individual or entity that
produces products and services which incorporate the DLSS SDK, Video SDK or NGX SDK as applicable. To the extent that
you provide NVIDIA with input or usage requests with regard to the use of your logo or materials, NVIDIA will use
commercially reasonable efforts to comply with such requests. For the avoidance of doubt, NVIDIAs rights pursuant to this
section shall survive any expiration or termination of the Agreement with respect to existing applications which incorporate
the DLSS SDK, Video SDK or NGX SDK.
(e) Applications Marketing Material in the DLSS SDK Video SDK or NGX SDK. You may provide NVIDIA with screenshots,
imagery, and video footage of applications representative of your use of the NVIDIA DLSS SDK or NGX SDKs in your
application (collectively, Assets). You hereby grant to NVIDIA the right to create and display self-promotional demo
materials using the Assets, and after release of the application to the public to distribute, sub-license, and use the Assets to
promote and market the NVIDIA RTX SDKs. To the extent you provide NVIDIA with input or usage requests with regard to
the use of your logo or materials, NVIDIA will use commercially reasonable efforts to comply with such requests. For the
avoidance of doubt, NVIDIAs rights pursuant to this section shall survive any termination of the Agreement with respect to
applications which incorporate the NVIDIA RTX SDK.
7.2 Trademark Ownership and Licenses. Trademarks are owned and licenses as follows:
(a) Ownership of Trademarks. Each party owns the trademarks, logos, and trade names (collectively "Marks") for their
respective products or services, including without limitation in applications, and the NVIDIA RTX SDKs. Each party agrees to
use the Marks of the other only as permitted in this exhibit.
(b) Trademark License to NVIDIA. You grant to NVIDIA a non-exclusive, non-sub licensable, non-transferable (except as set
forth in the assignment provision of the Agreement), worldwide license to refer to you and your applications, and to use
your Marks on NVIDIA's marketing materials and on NVIDIA's website (subject to any reasonable conditions of you) solely
for NVIDIAs marketing activities set forth in this exhibit Sections (d)-(e) above. NVIDIA will follow your specifications for
your Marks as to style, color, and typeface as reasonably provided to NVIDIA.
(c) Trademark License to You. NVIDIA grants to you a non-exclusive, non-sub licensable, non-transferable (except as set
forth in the assignment provision of the Agreement), worldwide license, subject to the terms of this exhibit and the
Agreement, to use NVIDIA RTX, NVIDIA GeForce RTX in combination with GeForce products, and/or NVIDIA Quadro
RTX in combination with Quadro products (collectively, the NVIDIA Marks) on your marketing materials and on your
website (subject to any reasonable conditions of NVIDIA) solely for your marketing activities set forth in this exhibit Sections
6.1 (a)-(c) above. For the avoidance of doubt, you will not and will not permit others to use any NVIDIA Mark for any other
goods or services, or in a way that tarnishes, degrades, disparages or reflects adversely any of the NVIDIA Marks or NVIDIAs
business or reputation, or that dilutes or otherwise harms the value, reputation or distinctiveness of or NVIDIAs goodwill in
any NVIDIA Mark. In addition to the termination rights set forth in the Agreement, NVIDIA may terminate this trademark
license at any time upon written notice to you. You will follow NVIDIA's use guidelines and specifications for NVIDIA's Marks
as to style, color and typeface as provided in NVIDIA Marks and submit a sample of each proposed use of NVIDIA's Marks at
least two (2) weeks prior to the desired implementation of such use to obtain NVIDIA's prior written approval (which
approval will not be unreasonably withheld or delayed). If NVIDIA does not respond within ten (10) business days of your
submission of such sample, the sample will be deemed unapproved. All goodwill associated with use of NVIDIA Marks will
inure to the sole benefit of NVIDIA. For the video SDK, contact NVIDIA at nvidia-rtx-video-sdk-license-
questions@nvidia.com.
7.3 Use Guidelines. Use of the NVIDIA Marks is subject to the following guidelines:
(a) Business Practices. You covenant that you will: (a) conduct business with respect to NVIDIAs products in a manner that
reflects favorably at all times on the good name, goodwill and reputation of such products; (b) avoid deceptive, misleading
or unethical practices that are detrimental to NVIDIA, its customers, or end users; (c) make no false or misleading
representations with regard to NVIDIA or its products; and (d) not publish or employ or cooperate in the publication or
employment of any misleading or deceptive advertising or promotional materials.
(b) No Combination Marks or Similar Marks. You agree not to (a) combine NVIDIA Marks with any other content without
NVIDIAs prior written approval, or (b) use any other trademark, trade name, or other designation of source which creates a
likelihood of confusion with NVIDIA Marks.
(v. February 23, 2024)
================================================
FILE: README.md
================================================
# RTX Mega Geometry

<br/>
<div align="center">
·
<a href="CHANGELOG.md">Change Log </a>
·
<a href="docs/QuickStart.md">Quick Start</a>
·
</div>
<br/>
## Overview
RTX Mega Geometry (RTX MG) is a DX12 and Vulkan code sample that shows how to quickly
build ray-tracing acceleration structures for subdivision surfaces with structured
clusters. It contains a reference HLSL path tracing demo app that can be used as a
learning tool to begin integration with your own graphics engine.
## Features
* Real-time adaptive sampling of Catmull-Clark limit surfaces
* Structured cluster tessellation and displacement mapping
* BVH build with cluster templates using NVAPI for DXR, and the VK_NV_cluster_acceleration_structure extension for Vulkan.
* Hierarchical Z-buffer for reducing tessellation rate of non-primary ray geometry
* DLSS Ray Reconstruction denoising
## Requirements
To Run:
- Windows 10
- NVIDIA RTX GPU (10 GB VRAM or greater)
- GeForce Game Ready Driver 570 or later
- DirectX Raytracing 1.1 API or later
To Build:
- CMake v3.31+
- Windows 10 SDK 10.0.20348.0 or later
- MSVC Compiler 19.43.34810 (Visual Studio 2022 17.13) or later
- For Windows: DirectX 12 AgilitySDK will be fetched automatically
- For Vulkan: Vulkan SDK 1.4.313 or later
## Folder Structure
| | |
| - | - |
| /bin | default CMake folder for binaries and compiled shaders |
| /build | default CMake folder for build files |
| /external | external submoduled libraries and SDKs, including osd_lite and donut |
| /assets | models, textures, scene files (git submodule) |
| /rtxmg | **RTX Mega Geometry core** |
## Build
At the moment, only Windows builds are supported.
1. Clone the repository **with all submodules recursively**:
`git clone --recurse-submodules https://github.com/NVIDIA-RTX/rtxmg.git`
2. Use CMake to configure the build and generate the project files.
```
cd rtxmg
cmake CMakeLists.txt -B ./build
```
Use `-G "some tested VS version"` if specific Visual Studio or other environment
version required. Make sure the x64 platform is used.
3. Build the solution generated by CMake in the `./build/` folder.
For example, if using Visual Studio, open the generated solution `build/rtxmg.sln`
and build it.
4. Select and run the `rtxmg_demo` project. Binaries get built to the `bin` folder.
Media assets are loaded from the `assets` folder.
## User Interface
Once the application is running, most of the SDK features can be accessed via the
UI window on the left hand side. The UI is self-documenting : hover the mouse over
widgets to read tool-tips. See the <a href="docs/QuickStart.md">Quick Start guide</a>
for more details.
Camera can be moved using W/S/A/D keys and rotated by dragging with the left mouse
cursor. Holding the Alt key and left-click dragging will orbit the camera around
the scene's center.
## Command Line
- `-mf` loads a specific .scene.json or OBJ file;
example: `-mf programmer-art.scene.json`
- `-d` to enable the graphics API debug layer or runtime,
and the [NVRHI](https://github.com/NVIDIA-RTX/NVRHI) validation layer.
Additional command line flags can be found by running with the `-h` flag.
## Contact
RTX Mega Geometry is under active development. Please report any issues directly
through GitHub issue tracker, and for any information, suggestions or general
requests please feel free to contact us at rtxmg-sdk-support@nvidia.com
## Related RTX Mega Geometry Repositories
Vulkan
* [vk_animated_clusters](https://github.com/nvpro-samples/vk_animated_clusters) :
`VK_NV_cluster_acceleration_structure` for animated content.
* [vk_tessellated_clusters](https://github.com/nvpro-samples/vk_tessellated_clusters) :
adaptive triangle tessellation and displacement using `VK_NV_cluster_acceleration_structure`
* [vk_lod_clusters](https://github.com/nvpro-samples/vk_lod_clusters) :
cluster-lod system and streaming using `VK_NV_cluster_acceleration_structure`
* [vk_partitioned_tlas](https://github.com/nvpro-samples/vk_partitioned_tlas)
update the TLAS of large dynamic scenes with `VK_NV_partitioned_acceleration_structure`
Tools
* [meshoptimizer.org](https://meshoptimizer.org) - meshoptimizer provides ray tracing friendly clusterization through `meshopt_buildMeshletsSpatial`. If you are interested in building a continuous level of detail system, have a look at its clusterlod.h demo, it shows the necessary steps.
## Citation
If you use RTX Mega Geometry in a research project leading to a publication,
please cite the project.
BibTex:
```bibtex
@online{RTX MG,
title = {{{NVIDIA}}\textregistered{} {RTX Mega Geometry}},
author = {{NVIDIA}},
year = 2025,
url = {https://github.com/NVIDIA-RTX/rtxmg.git},
urldate = {2025-02-06},
}
```
## Known Issues
1. The RTX MG SDK does not currently support unstructured clusters or rasterization.
## License
See [LICENSE.txt](LICENSE.txt)
This project includes NVAPI software. All uses of NVAPI software are governed by the license terms specified here: https://github.com/NVIDIA/nvapi/blob/main/License.txt.
================================================
FILE: demo/CMakeLists.txt
================================================
# include ("private.cmake" OPTIONAL)
include ("${DONUT_DIR}/compileshaders.cmake")
add_subdirectory(audio)
file(GLOB shaders "shaders/*")
file(GLOB sources "*.cpp" "*.h" "osd_port_sources/tmr/*.h" *.cfg)
if(NOT EXISTS "${PROJECT_SOURCE_DIR}/CMake/FetchImplot.cmake")
message(FATAL_ERROR "Missing FetchImplot.cmake file")
endif()
include("${PROJECT_SOURCE_DIR}/CMake/FetchImplot.cmake")
set_target_properties(implot PROPERTIES FOLDER "Third-Party Libraries")
set(app rtxmg_demo)
set(folder "Demo")
list(APPEND RTXMG_SHADERS_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
donut_compile_shaders_all_platforms(
TARGET ${app}_shaders
CONFIG ${CMAKE_CURRENT_SOURCE_DIR}/shaders.cfg
FOLDER ${folder}
SOURCES ${shaders}
OUTPUT_BASE ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/shaders/${app}
SHADERMAKE_OPTIONS ${RTXMG_SHADERMAKE_OPTIONS}
SHADERMAKE_OPTIONS_SPIRV ${RTXMG_SHADERMAKE_OPTIONS_SPIRV}
SHADER_MODEL ${RTXMG_SHADERS_SHADERMODEL}
IGNORE_INCLUDES ${RTXMG_SHADERS_IGNORED_INCLUDES}
INCLUDES ${RTXMG_SHADERS_INCLUDE_DIR}
)
add_executable(${app}
${sources}
)
target_link_libraries(${app} PUBLIC envmap rtxmg donut_render donut_app donut_engine implot)
option(RTXMG_DEV_FEATURES "Enable development features (debugging, etc)" OFF)
if(RTXMG_DEV_FEATURES)
target_compile_definitions(${app} PUBLIC RTXMG_DEV_FEATURES=1)
endif()
target_compile_definitions(${app} PUBLIC RTXMG_VERSION="${PROJECT_VERSION}")
if(ENABLE_AUDIO_ENGINE)
if(TARGET audio_engine)
target_link_libraries(${app} PRIVATE audio_engine)
else()
message(WARNING "Audio engine option is enabled, but configuration failed")
endif()
endif()
add_dependencies(${app} ${app}_shaders)
set_target_properties(${app} PROPERTIES FOLDER ${folder})
add_compile_definitions( "_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING=1")
target_include_directories(${app} PUBLIC
${PROJECT_SOURCE_DIR}
${PROJECT_SOURCE_DIR}/extern
)
add_subdirectory(envmap)
if(DONUT_D3D_AGILITY_SDK_ENABLED)
target_compile_definitions(${app} PUBLIC DONUT_D3D_AGILITY_SDK_ENABLED=1)
target_compile_definitions(${app} PUBLIC DONUT_D3D_AGILITY_SDK_VERSION=${DONUT_D3D_AGILITY_SDK_VERSION})
add_custom_command(TARGET ${app} POST_BUILD
COMMAND
${CMAKE_COMMAND} -E make_directory "$<TARGET_FILE_DIR:${app}>/D3D12/"
COMMAND
${CMAKE_COMMAND} -E copy_if_different ${DONUT_D3D_AGILITY_SDK_CORE_DLL} "$<TARGET_FILE_DIR:${app}>/D3D12/"
)
endif()
if(WIN32)
add_custom_command( TARGET ${app} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_RUNTIME_DLLS:${app}> $<TARGET_FILE_DIR:${app}>
COMMAND_EXPAND_LISTS)
endif()
#
# Installation & packaging
#
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "${CMAKE_SOURCE_DIR}/_install" CACHE PATH "Installation directory" FORCE)
endif()
install(TARGETS ${app} DESTINATION "bin")
install(DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/shaders" DESTINATION "bin" )
if(WIN32)
install(FILES $<TARGET_RUNTIME_DLLS:${app}> DESTINATION "bin")
# generate some shortcuts to run various scenes
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/run_rtxmg.bat" "start \"\" bin/rtxmg_demo.exe")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/run_rtxmg.bat" DESTINATION ".")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/run_amy_kitchenset.bat" "start \"\" bin/rtxmg_demo.exe -mf amy_kitchenset.scene.json")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/run_amy_kitchenset.bat" DESTINATION ".")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/run_barbarian.bat" "start \"\" bin/rtxmg_demo.exe -mf barbarian_pt.scene.json")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/run_barbarian.bat" DESTINATION ".")
set(_os "win64")
elseif (UNIX AND NOT APPLE)
set(_os "linux64")
endif()
if(DONUT_D3D_AGILITY_SDK_ENABLED)
install(DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/D3D12" DESTINATION "bin" )
endif()
if(IS_DIRECTORY "${PROJECT_SOURCE_DIR}/assets")
install(
DIRECTORY "${PROJECT_SOURCE_DIR}/assets"
DESTINATION "."
PATTERN "*.bin" EXCLUDE)
endif()
set(CPACK_GENERATOR "ZIP")
set(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}.${PROJECT_VERSION}.${_os}")
include(CPack)
================================================
FILE: demo/args.cpp
================================================
//
// Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of NVIDIA CORPORATION nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// clang-format off
#include "args.h"
#include "rtxmg_demo.h"
#include <assert.h>
#include <cstdio>
#include <functional>
#include <map>
#include <numbers>
#include <stdexcept>
#include "rtxmg/scene/json.h"
// clang-format on
static void printUsageAndExit(const char* argv0,
const std::string& token = {})
{
// clang-format off
static char const* msg =
"Usage : &s [options]\n"
"Options: \n"
" -h | --help Print this usage message\n"
" -at <mode> | --adaptiveTessellation Mode is: [uniform | world | sphere]\n"
" | --aftermath Enable Aftermath for GPU Crash debugging (not compatible with --debug)"
" -a <true|false> | --amplification Tessellation amplification (default true).\n"
" -bbt <t|c> | --bvhBuildType [t (triangles) | c (clusters)]\n"
" -cc <mode> | --clusterColor Mode is: [base | level (isolation) | uv | bid (block id) | tid (tri id) | \n"
" cid (cluster id) | n (normal) | bNum (# blocks) | tArea (utri area)]\n"
" -ctr <f> | --coarseTessellationRate Coarse adaptive edge sampling rate\n"
" -d | --debug Enable D3D12 Debug Layer\n"
" -gd | --gpudebug Enable D3D12 GPU Validation\n"
" -ds <float> | --displacementScale Displacement scale along normal (relative to the largest extent of the object's AABB)\n"
" -ed <true|false> | --enableDenoiser Enable Denoiser\n"
" -envmap <envmap.exr> | Specify the environment map to use\n"
" -es <e0> <e1> <e2> <e3> | --edgeSegments Cluster edge m_size for all four edges (default 5 5 5 5)\n"
" -f <filename> | --file Specify file for image output\n"
" -ftr <f> | --fineTessellationRate Fine adaptive edge sampling rate\n"
" -isoLevelSharp <int> Max isolation level near sharp features such as creases (default 6)\n"
" -isoLevelSmooth <int> Max isolation level near smooth features such as extraordinary vertices (default 3)\n"
" -ll <n> | --loglevel Set logCallbackLevel (default: 2)\n"
" | --logAccelBuild Log each buffer of the acceleration build (slow!)\n"
" | --maxClusters Memory budget Set the max num of clustersverts\n"
" | --maxVerts Memory budget Set the max num of verts\n"
" | --maxClasMB Memory budget Set the max num of clas memory in MB\n"
" -mrl <int> | --maxRefinementLevel Legacy: same as isoLevelSharp\n"
" -mc <r> <g> <b> | --missColor Miss color\n"
" -mf <filepath> | --meshInputFile Read .obj or scene file\n"
" -p \"[eye][at][up]fov\" | --cameraPos Camera pose\n"
" -ptmb <n> | --ptMaxBounces Max PT bounces\n"
" -qbits <n> | --quantizeBits Quantize vertex positions by n bits [0,32)\n"
" -qf <true|false> | --quadFiltering Filter out 1x1 clusters during metric tessellation phase\n"
" -res <w> <h> | --resolution Set image dimensions to <w>x<h> (default 768 768)\n"
" -sm [prim_rays|ao|pt] | --shadingMode primary rays or AO or path tracing\n"
" -spp <n> Number of samples per pixel (need to use a perfect square number, default 1)\n"
" -tv <true|false> | --timeview Enable Timeview (default false)\n"
" -vn <true|false> | --vertexNormals Enable vertex normals computation (default false)\n"
" -wf <true|false> | --wireframe Set wireframe (default true)\n"
" -wm | --windowMaximized Start window maximized (default false)\n";
// clang-format on
std::fprintf(stderr, msg, argv0);
if (token.find("Unknown option") != std::string::npos)
std::fprintf(stderr, "\n****** %s ******", token.c_str());
else if (!token.empty())
std::fprintf(stderr, "\n****** Invalid usage of '%s' ******",
token.c_str());
exit(1);
}
static bool parseBooleanArg(char const* token,
char const* value, bool defaultValue)
{
if (std::strncmp(value, "true", 4) == 0)
return true;
if (std::strncmp(value, "false", 5) == 0)
return false;
printUsageAndExit("rtxmg_demo", token);
return defaultValue;
}
void Args::Parse(int argc, char const* const* argv)
{
static std::map<std::string, ShadingMode> shadingModes{
{"prim_rays", ShadingMode::PRIMARY_RAYS},
{"ao", ShadingMode::AO},
{"pt", ShadingMode::PT} };
static std::map<std::string, ColorMode> colorModes{
{"base", ColorMode::BASE_COLOR},
{"uv", ColorMode::COLOR_BY_CLUSTER_UV},
{"cid", ColorMode::COLOR_BY_CLUSTER_ID},
{"tid", ColorMode::COLOR_BY_MICROTRI_ID},
{"n", ColorMode::COLOR_BY_NORMAL},
{"texcoord", ColorMode::COLOR_BY_TEXCOORD},
{"mat", ColorMode::COLOR_BY_MATERIAL},
{"tArea", ColorMode::COLOR_BY_MICROTRI_AREA} };
static const std::map<std::string, TextureType> TextureTypes = {
{ "-envmap", TextureType::ENVMAP }
};
static std::map <std::string, TessellatorConfig::AdaptiveTessellationMode> adaptiveTessellationModes = {
{"uniform", TessellatorConfig::AdaptiveTessellationMode::UNIFORM},
{"sphere", TessellatorConfig::AdaptiveTessellationMode::SPHERICAL_PROJECTION},
{"world", TessellatorConfig::AdaptiveTessellationMode::WORLD_SPACE_EDGE_LENGTH}
};
auto parseEnum = [&argv]<typename T>(std::string const& arg, std::map<std::string, T> const& enumModes)
{
if (const auto it = enumModes.find(arg); it != enumModes.end())
return it->second;
else
printUsageAndExit(argv[0], arg);
return T(0);
};
for (int i = 1; i < argc; ++i)
{
const std::string arg(argv[i]);
if (arg == "-d3d12" || arg == "-dx12" || arg == "--d3d12" || arg == "--dx12")
continue;
if (arg == "-vk" || arg == "-vulkan" || arg == "--vk" || arg == "--vulkan")
continue;
auto parseArgValues = [&argc, &argv, &i, &arg](int n,
std::function<void()> func)
{
if (i >= argc - n)
printUsageAndExit(argv[0], argv[i]);
func();
};
if (arg == "--debug" || arg == "-d")
{
debug = true;
}
else if (arg == "--gpudebug" || arg == "-gd")
{
gpuValidation = true;
}
else if (arg == "--aftermath")
{
aftermath = true;
}
else if (arg == "--sllog")
{
enableStreamlineLog = true;
}
else if (arg == "--help" || arg == "-h")
{
printUsageAndExit(argv[0]);
}
else if (arg == "--file" || arg == "-f")
{
parseArgValues(1, [&]() { outfile = argv[++i]; });
}
else if (arg == "--timeview" || arg == "-tv")
{
parseArgValues(1, [&]() { enableTimeView = parseBooleanArg(arg.c_str(), argv[++i], enableTimeView); });
}
else if (arg == "-p" || arg == "--cameraPos")
{
parseArgValues(1, [&]() { camString = std::string(argv[++i]); });
}
else if (arg == "-res" || arg == "--resolution")
{
parseArgValues(2, [&]()
{
width = atoi(argv[++i]);
height = atoi(argv[++i]);
});
resolutionSetByCmdLine = true;
}
else if (arg == "--wireframe" || arg == "-wf")
{
parseArgValues(1, [&]()
{
enableWireframe =
parseBooleanArg(arg.c_str(), argv[++i], enableWireframe);
});
}
else if (arg == "--displacementScale" || arg == "-ds")
{
parseArgValues(1, [&]() { dispScale = (float)atof(argv[++i]); });
}
else if (arg == "--adaptiveTessellation" || arg == "-at")
{
parseArgValues(
1, [&]() { tessMode = parseEnum(argv[++i], adaptiveTessellationModes); });
}
else if (arg == "--edgeSegments" || arg == "-es")
{
parseArgValues(4, [&]()
{
edgeSegments.x = static_cast<uint32_t>(atoi(argv[++i]));
edgeSegments.y = static_cast<uint32_t>(atoi(argv[++i]));
edgeSegments.z = static_cast<uint32_t>(atoi(argv[++i]));
edgeSegments.w = static_cast<uint32_t>(atoi(argv[++i]));
});
}
else if (arg == "--missColor" || arg == "-mc")
{
parseArgValues(3, [&]()
{
missColor = { (float)atof(argv[++i]), (float)atof(argv[++i]),
(float)atof(argv[++i]) };
});
}
else if (arg == "--ptMaxBounces" || arg == "-ptmb")
{
parseArgValues(1, [&]() { ptMaxBounces = atoi(argv[++i]); });
}
else if (arg == "--meshInputFile" || arg == "-mf")
{
parseArgValues(1, [&]() { meshInputFile = argv[++i]; });
}
else if (arg == "--maxRefinementLevel" || arg == "-mrl" ||
arg == "-isoLevelSharp")
{
parseArgValues(1, [&]() { isoLevelSharp = atoi(argv[++i]); });
}
else if (arg == "-isoLevelSmooth")
{
parseArgValues(1, [&]() { isoLevelSmooth = atoi(argv[++i]); });
}
else if (arg == "-envmap")
{
try
{
textures[parseEnum(arg, TextureTypes)] = argv[++i];
}
catch (std::exception& e)
{
std::fprintf(stderr, "Invalid option in '%s %s' : %s\n", arg.c_str(), argv[i], e.what());
exit(1);
}
}
else if (arg == "--shadingMode" || arg == "-sm")
{
parseArgValues(
1, [&]() { shadingMode = parseEnum(argv[++i], shadingModes); });
}
else if (arg == "-spp")
{
parseArgValues(1, [&]()
{
spp = atoi(argv[++i]);
const int sqrt_spp =
static_cast<int>(std::sqrt(static_cast<float>(spp)));
if (sqrt_spp * sqrt_spp !=
spp) // check if spp is a perfect sqare number
printUsageAndExit(argv[0], arg);
});
}
else if (arg == "--logAccelBuild")
{
enableAccelBuildLogging = true;
}
else if (arg == "--vertBufferMB")
{
parseArgValues(1, [&]() { tessMemorySettings.vertexBufferBytes = size_t(atoi(argv[++i])) << 20ull; });
}
else if (arg == "--maxClusters")
{
parseArgValues(1, [&]() { tessMemorySettings.maxClusters = atoi(argv[++i]); });
}
else if (arg == "--clasBufferMB")
{
parseArgValues(1, [&]() { tessMemorySettings.clasBufferBytes = size_t(atoi(argv[++i])) << 20ull; });
}
else if (arg == "--fineTessellationRate" || arg == "-ftr")
{
parseArgValues(1, [&]() { fineTessellationRate = (float)atof(argv[++i]); });
}
else if (arg == "--coarseTessellationRate" || arg == "-ctr")
{
parseArgValues(1, [&]() { coarseTessellationRate = (float)atof(argv[++i]); });
}
else if (arg == "--enableDenoiser" || arg == "-ed")
{
enableDenoiser = true;
}
else if (arg == "--windowMaximized" || arg == "-wm")
{
startMaximized = true;
}
else if (arg == "--vertexNormals" || arg == "-vn")
{
parseArgValues(1, [&]() { enableVertexNormals = parseBooleanArg(arg.c_str(), argv[++i], enableVertexNormals); });
}
else
printUsageAndExit(argv[0], std::string("Unknown option: ") + argv[i]);
}
}
auto parseJsonEnum = []<typename T, size_t N>(const Json::Value & node,
const std::array<const char*, N> &enums, T & result) constexpr
{
uint8_t index = 0;
for (const char* e : enums)
{
if (std::strncmp(node.asString().c_str(), e, std::strlen(e)) == 0)
{
result = T(index);
break;
}
++index;
}
};
Args& operator << (Args& args, const Json::Value& node)
{
if (const auto& value = node["envmap rotation"]; value.isDouble())
{
value >> args.envmapAzimuth;
args.envmapAzimuth = (args.envmapAzimuth / 180.f) * float(std::numbers::pi);
}
if (const auto& value = node["envmap elevation"]; value.isDouble())
{
value >> args.envmapElevation;
args.envmapElevation = (args.envmapElevation / 180.f) * float(std::numbers::pi);
}
if (const auto& value = node["envmap intensity"]; value.isDouble())
{
value >> args.envmapIntensity;
}
if (const auto& value = node["shading mode"]; value.isString())
parseJsonEnum(value, kShadingModeNames, args.shadingMode);
if (const auto& value = node["color mode"]; value.isString())
{
parseJsonEnum(value, kColorModeNames, args.colorMode);
}
if (const auto& value = node["spp"]; value.isIntegral())
value >> args.spp;
if (const auto& value = node["max bounces"]; value.isIntegral())
value >> args.ptMaxBounces;
if (const auto& value = node["firefly max intensity"]; value.isDouble())
value >> args.firefliesClamp;
if (const auto& value = node["exposure"]; value.isDouble())
value >> args.exposure;
if (const auto& value = node["tonemap operator"]; value.isString())
parseJsonEnum(value, kToneMapOperatorNames, args.tonemapOperator);
// displacement
if (const auto& value = node["displacementScale"]; value.isDouble())
value >> args.dispScale;
if (const auto& value = node["displacementBias"]; value.isDouble())
{
value >> args.dispBias;
donut::log::warning("Scene arg displacementBias is not supported, ignoring");
}
if (const auto& value = node["wireframe"]; value.isBool())
value >> args.enableWireframe;
if (const auto& value = node["wireframe thickness"]; value.isDouble())
value >> args.wireframeThickness;
if (const auto& value = node["enableDenoiser"]; value.isBool())
value >> args.enableDenoiser;
return args;
}
================================================
FILE: demo/args.h
================================================
//
// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of NVIDIA CORPORATION nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// clang-format off
#pragma once
#include "rtxmg_demo.h"
#include "rtxmg/cluster_builder/tessellator_config.h"
#include "rtxmg/scene/scene.h"
#include <array>
#include <string>
#include <json/json.h>
#include <donut/core/math/math.h>
using namespace donut::math;
// clang-format on
// All state & values controllable from the command-line
// used to initialize the application on launch.
//
// note: much of this state should be broken up into sub-sections
// note: currently the application owns this struct and can override
// some of its values interactively (which is less than ideal).
// Things that can be modified by a scene.json file
struct SceneArgs
{
std::array<std::string, TextureType::TEXTURE_TYPE_COUNT> textures;
float envmapAzimuth = 0.f;
float envmapElevation = 0.f;
float envmapIntensity = 1.f;
ColorMode colorMode = ColorMode::BASE_COLOR;
ShadingMode shadingMode = ShadingMode::PT;
TonemapOperator tonemapOperator = TonemapOperator::Aces;
float wireframeThickness = .1f;
int spp = 1;
int ptMaxBounces = 2;
float firefliesClamp = 0.f;
float exposure = 1.f;
float dispScale = 1.f;
float dispBias = 0.f;
float roughnessOverride = 0.f;
bool enableWireframe = false;
bool enableDenoiser = true;
};
struct Args : SceneArgs
{
// convenience accessors for legacy code
using SceneArgs::colorMode;
using SceneArgs::dispBias;
using SceneArgs::dispScale;
using SceneArgs::enableWireframe;
using SceneArgs::envmapAzimuth;
using SceneArgs::envmapElevation;
using SceneArgs::envmapIntensity;
using SceneArgs::exposure;
using SceneArgs::firefliesClamp;
using SceneArgs::ptMaxBounces;
using SceneArgs::shadingMode;
using SceneArgs::spp;
using SceneArgs::wireframeThickness;
SceneArgs& sceneArgs() { return *this; }
int width = 1920;
int height = 1080;
bool resolutionSetByCmdLine = false;
std::string outfile;
std::string meshInputFile = std::string{};
std::string camString;
uint4 edgeSegments = { 8, 8, 8, 8 };
unsigned char quantNBits{ 0 };
bool enableFrustumVisibility = true;
bool enableBackfaceVisibility = true;
bool enableHiZVisibility = true;
bool updateTessCamera = true;
bool enableVertexNormals = false;
TessellatorConfig::MemorySettings tessMemorySettings;
TessellatorConfig::VisibilityMode visMode = TessellatorConfig::VisibilityMode::VIS_LIMIT_EDGES;
TessellatorConfig::AdaptiveTessellationMode tessMode = TessellatorConfig::AdaptiveTessellationMode::SPHERICAL_PROJECTION;
// Note: the defaults here are intended for TMR
int isoLevelSharp = 6;
int isoLevelSmooth = 3;
uint32_t globalIsolationLevel = TessellatorConfig::kMaxIsolationLevel;
float fineTessellationRate = TessellatorConfig::kDefaultFineTessellationRate;
float coarseTessellationRate = TessellatorConfig::kDefaultCoarseTessellationRate;
ClusterPattern clusterPattern = ClusterPattern::SLANTED;
float3 missColor = { .75, .75, .75 };
bool debug = false;
bool gpuValidation = false;
bool aftermath = false;
bool enableStreamlineLog = false;
bool enableAccelBuildLogging = false;
bool enableTimeView = false;
bool startMaximized = false;
void Parse(int argc, char const* const* argv);
};
Args& operator << (Args& args, const Json::Value& node);
================================================
FILE: demo/audio/CMakeLists.txt
================================================
option(ENABLE_AUDIO_ENGINE "Enable audio playback" ON)
if (ENABLE_AUDIO_ENGINE)
set(_audio_src_files
audio.cpp
audio.h
waveFile.cpp
waveFile.h
xaudiofaudio.h)
if (UNIX)
# Linux builds emulate XAudio with the FAudio library ; typical installation with
# 'sudo apt install libfaudio-dev' (same on Windows Subsystem for Linux)
find_path(_faudio_include_dir FAudio.h HINTS "/usr/include")
find_library(_faudio_lib libFAudio.so HINTS "/usr/lib/" "/usr/lib/x86_64-linux-gnu/" )
if (_faudio_include_dir AND _faudio_lib)
add_library(FAudio INTERFACE)
target_include_directories(FAudio INTERFACE ${_faudio_include_dir})
target_link_libraries(FAudio INTERFACE ${_faudio_lib})
target_compile_definitions(FAudio INTERFACE AUDIO_ENGINE_XAUDIO_ON_FAUDIO)
message(STATUS "Found FAudio: ${_faudio_include_dir}")
endif()
if (NOT TARGET FAudio)
message(WARNING
"Audio engine is enabled but missing libfaudio-dev (disabling audio). "
"Set ENABLE_AUDIO_ENGINE=OFF to skip this warning.")
return()
endif()
endif()
add_library(audio_engine STATIC ${_audio_src_files})
target_include_directories(audio_engine PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/..")
target_compile_definitions(audio_engine PUBLIC AUDIO_ENGINE_ENABLED)
if (TARGET FAudio)
target_link_libraries(audio_engine FAudio)
endif()
if (MSVC)
target_compile_definitions(audio_engine PUBLIC AUDIO_ENGINE_WITH_XAUDIO)
endif()
set_target_properties(audio_engine PROPERTIES FOLDER Demo)
endif()
================================================
FILE: demo/audio/audio.cpp
================================================
// clang-format off
#include "./audio.h"
#include "./waveFile.h"
#include <cstring>
// clang-format on
#ifndef SAFE_RELEASE
#define SAFE_RELEASE(x) \
if(x != NULL) \
{ \
x->Release(); \
x = NULL; \
}
#endif
namespace audio {
static std::vector<std::string> _errors;
std::unique_ptr<Voice> Voice::create(Engine& engine, std::filesystem::path const& m_filepath, bool loop) {
if (!engine.isReady())
return nullptr;
if (auto wave = WaveFile::read(m_filepath))
return Voice::create(engine, std::move(wave), loop);
else
engine.error((std::string("cannpt read: ")+ m_filepath.generic_string()).c_str());
return nullptr;
}
std::unique_ptr<Voice> Voice::create(Engine& engine, std::shared_ptr<WaveFile const> wave, bool loop)
{
if (!engine._xaudio2)
return nullptr;
WaveFile::Fmt const& fmt = wave->getFormat();
IXAudio2SourceVoice * voice = nullptr;
WAVEFORMATEX wfmtx;
wfmtx.wFormatTag = WAVE_FORMAT_PCM;
wfmtx.nChannels = fmt.numChannels;
wfmtx.nSamplesPerSec = fmt.samplesPerSec;
wfmtx.nAvgBytesPerSec = fmt.bytesPerSec;
wfmtx.nBlockAlign = fmt.blockAlign;
wfmtx.wBitsPerSample = fmt.bitsPerSample;
wfmtx.cbSize = 0;
XAUDIO2_SEND_DESCRIPTOR sendDescriptors[1];
sendDescriptors[0].Flags = XAUDIO2_SEND_USEFILTER;
sendDescriptors[0].pOutputVoice = GRAB_VOICE_OBJ(engine._masteringVoice);
const XAUDIO2_VOICE_SENDS sendList = { 1, sendDescriptors };
HRESULT hr;
hr = engine._xaudio2->CreateSourceVoice(&voice, &wfmtx, 0, 2.0f, NULL, &sendList);
if (FAILED(hr)) {
engine.error((std::string("error CreateSourceVoice : ")+wave->m_filepath.generic_string()).c_str());
return nullptr;
}
std::unique_ptr<Voice> result(new Voice);
result->_voice = voice;
result->_wave = std::move(wave);
std::memset(&result->_buffer, 0, sizeof(XAUDIO2_BUFFER));
result->_buffer.pAudioData = (BYTE const *)result->_wave->getSamplesData();
result->_buffer.Flags = XAUDIO2_END_OF_STREAM;
result->_buffer.AudioBytes = result->_wave->getSamplesDataSize();
result->_buffer.LoopCount = loop ? XAUDIO2_LOOP_INFINITE : XAUDIO2_NO_LOOP_REGION;
if (result->submitBuffer(engine))
return result;
return nullptr;
}
Voice::~Voice() {
if (_voice)
_voice->DestroyVoice();
}
bool Voice::submitBuffer(Engine& engine, float offset) {
_voice->Stop();
WaveFile::Fmt const& fmt = _wave->getFormat();
if (offset > 0.f)
_buffer.PlayBegin = _buffer.LoopBegin = uint32_t(offset * float(fmt.samplesPerSec));
if (FAILED(_voice->SubmitSourceBuffer(&_buffer))) {
engine.error("SubmitSourceBuffer failed");
return false;
}
return true;
}
bool Voice::setStart(Engine& engine, float offset)
{
if (offset < 0.f)
return false;
_voice->FlushSourceBuffers();
return submitBuffer(engine, offset);
}
bool Voice::rewind() {
_voice->Stop();
_voice->FlushSourceBuffers();
return _voice->SubmitSourceBuffer(&_buffer)==S_OK;
}
int Voice::getBuffersQueued() {
XAUDIO2_VOICE_STATE xstate;
_voice->GetState(&xstate, 0);
return xstate.BuffersQueued;
}
int Voice::getSamplesPlayed() {
XAUDIO2_VOICE_STATE xstate;
_voice->GetState(&xstate, 0);
return (int)xstate.SamplesPlayed;
}
//
//
//
Engine::~Engine() {
if (_masteringVoice)
_masteringVoice->DestroyVoice();
if (_xaudio2)
_xaudio2->Release();
}
std::shared_ptr<Engine> Engine::create() {
static std::shared_ptr<Engine> _engine;
if (_engine && _engine->isReady()) {
return _engine;
}
if (!_engine) {
_engine = std::make_shared<Engine>(*new Engine);
HRESULT hr;
if (FAILED(hr = CoInitializeEx(NULL, COINIT_MULTITHREADED))) {
_errors.push_back("Error initializing multi-threaded mode");
return _engine;
}
if (FAILED(hr = XAudio2Create(&_engine->_xaudio2, 0))) {
_errors.push_back("XAudio2Create failed");
return _engine;
}
if (FAILED(hr = _engine->_xaudio2->CreateMasteringVoice(&_engine->_masteringVoice))) {
SAFE_RELEASE(_engine->_xaudio2);
_errors.push_back("CreateMasteringVoice failed");
}
}
return _engine;
}
void Engine::mute(bool mute) {
if (!isReady())
return;
if (mute) {
_masteringVoice->GetVolume(&_masterVolume);
_masteringVoice->SetVolume(0.f);
} else {
_masteringVoice->SetVolume(_masterVolume);
_masterVolume = -1.f;
}
}
std::vector<std::string> const & Engine::getErrors() {
return _errors;
}
void Engine::error(char const * msg) {
_errors.push_back(msg);
}
};
================================================
FILE: demo/audio/audio.h
================================================
#pragma once
// clang-format off
#if defined(AUDIO_ENGINE_WITH_XAUDIO)
#include <xaudio2.h>
#include <XAudio2fx.h>
#define GRAB_VOICE_OBJ(P) (P)
#elif defined(AUDIO_ENGINE_XAUDIO_ON_FAUDIO)
#include <audio/xaudiofaudio.h>
#endif
#include <memory>
#include <string>
#include <vector>
#include <filesystem>
// clang-format on
namespace donut::vfs
{
class IFileSystem;
}
namespace audio {
class Engine;
class WaveFile;
//
// Voice
//
class Voice {
public:
static std::unique_ptr<Voice> create(Engine& engine,
std::filesystem::path const& wavefile, bool loop=true);
static std::unique_ptr<Voice> create(Engine& engine,
std::shared_ptr<WaveFile const> wav, bool loop=true);
~Voice();
void start() { _voice->Start(0); }
void stop() { _voice->Stop(0); }
void playOnce() { _voice->Start(0); _voice->ExitLoop(); }
bool rewind();
// sets the audio playback starting point (offset in seconds)
bool setStart(Engine& engine, float offset);
// returns the number of buffers queued for this voice
int getBuffersQueued();
// total number of samples played by the voice since creation
int getSamplesPlayed();
void setVolume(float volume) { _voice->SetVolume(volume); }
float getVolume() { float v; _voice->GetVolume(&v); return v; }
void setPitch(float pitch) { _voice->SetFrequencyRatio(pitch); }
float getPitch() { float p; _voice->GetFrequencyRatio(&p); return p; }
private:
bool submitBuffer(Engine& engine, float offset = 0.f);
Voice() = default;
IXAudio2SourceVoice * _voice = nullptr;
XAUDIO2_BUFFER _buffer;
std::shared_ptr<WaveFile const> _wave;
};
//
// Engine
//
class Engine {
public:
static std::shared_ptr<Engine> create();
~Engine();
void mute(bool mute);
static std::weak_ptr<Engine> get();
bool isReady() const { return _xaudio2 && _masteringVoice; }
void error(char const * msg);
static std::vector<std::string> const & getErrors();
private:
friend class Voice;
float _masterVolume = 1.f;
IXAudio2 * _xaudio2 = nullptr;
IXAudio2MasteringVoice * _masteringVoice = nullptr;
};
}; // end namespace audio
================================================
FILE: demo/audio/waveFile.cpp
================================================
// clang-format off
#include "./waveFile.h"
#include <cassert>
#include <cmath>
#include <cstring>
#include <fstream>
namespace fs = std::filesystem;
static std::vector<uint8_t> readFile(fs::path const& m_filepath) {
std::ifstream file(m_filepath.generic_string().c_str(), std::ios::binary);
if (!file.is_open())
return {};
file.seekg(0, std::ios::end);
size_t size = file.tellg();
file.seekg(0, std::ios::beg);
std::vector<uint8_t> data(size);
file.read((char*)data.data(), size);
if (!file.good())
return {};
return data;
}
// clang-format on
namespace audio {
struct WaveFile::Chunk{
char id[4]; // "data" string
uint32_t size; // Sampled data length
inline uint8_t const* data() const {
return reinterpret_cast<uint8_t const*>(this) + sizeof(Chunk);
}
};
struct WaveFile::Header {
char id[4]; // "data" string
uint32_t size; // Sampled data length
char wave[4]; // WAVE signature
inline bool validate() const {
if (std::memcmp(id, "RIFF", 4) != 0)
return false;
if (std::memcmp(wave, "WAVE", 4) != 0)
return false;
return true;
}
};
WaveFile::Chunk const* WaveFile::getSubChunk(std::vector<uint8_t> const& data, char const* name) {
// some WAV files have additional undocumented sub-chunks within the header ;
// this searches for a specific sub-chunk by name.
for (uint8_t const* ptr = data.data() + sizeof(Header); ptr < (data.data() + data.size()); ) {
Chunk const* chunk = reinterpret_cast<Chunk const*>(ptr);
if (std::memcmp(chunk->id, name, 4) == 0)
return chunk;
ptr += sizeof(Chunk) + chunk->size;
}
return nullptr;
}
std::unique_ptr<WaveFile> WaveFile::read(fs::path const& m_filepath) {
auto wave = create(std::move(readFile(m_filepath)));
if (wave)
wave->m_filepath = m_filepath;
return wave;
}
std::unique_ptr<WaveFile> WaveFile::create(std::vector<uint8_t>&& data) {
// see: http://tiny.systems/software/soundProgrammer/WavFormatDocs.pdf
if (data.empty())
return nullptr;
// header chunk
Header const* header = reinterpret_cast<Header const*>(data.data());
if (!header->validate())
return nullptr;
// format sub-chunk
Fmt const* fmt = nullptr;
if (Chunk const* chunk = getSubChunk(data, "fmt "))
fmt = reinterpret_cast<Fmt const*>(chunk->data());
else
return nullptr;
if (fmt->audioFormat != 1)
return nullptr;
// data sub-chunk
Chunk const* dataChunk = getSubChunk(data, "data");
if (!dataChunk)
return nullptr;
auto wave = new WaveFile;
wave->_fmt = fmt;
wave->_dataChunk = dataChunk;
wave->_data = std::move(data);
return std::unique_ptr<WaveFile>(wave);
}
WaveFile::Fmt const& WaveFile::getFormat() const {
return *_fmt;
}
uint32_t WaveFile::getSamplesDataSize() const {
return _dataChunk->size;
}
void const* WaveFile::getSamplesData() const {
return _dataChunk->data();
}
uint32_t WaveFile::getNumSamplesTotal() const {
return _dataChunk->size / (_fmt->numChannels * _fmt->bitsPerSample / 8);
}
float WaveFile::duration() const {
return float(getNumSamplesTotal() / _fmt->samplesPerSec);
}
std::unique_ptr<WaveForm> WaveFile::computeWaveform(
uint32_t size, float start_time, float end_time, int channel) const {
uint32_t start_index = static_cast<uint32_t>( std::max( 0.f, start_time * static_cast<float>( _fmt->samplesPerSec ) ) );
uint32_t end_index = end_time < 0.f ? getNumSamplesTotal() :
static_cast<uint32_t>( end_time * static_cast<float>( _fmt->samplesPerSec ) );
start_index = std::min(start_index, getNumSamplesTotal());
end_index = std::min(end_index, getNumSamplesTotal());
if (start_index >= end_index)
return nullptr;
auto process = [this, &size]<typename T>(uint32_t start, uint32_t end, int channel) {
assert(end > start);
T const* ptr = reinterpret_cast<T const*>(_data.data());
T const* data_end = reinterpret_cast<T const*>(_data.data() + _data.size());
uint32_t nsamples = end - start;
uint16_t nchannels = _fmt->numChannels;
uint32_t block_count = size;
uint32_t block_size =
static_cast<uint32_t>( std::ceil( float( nsamples ) / float( 2 * static_cast<float>( block_count ) ) ) );
auto wform = std::make_unique<WaveForm>();
wform->maxs.resize(block_count);
wform->mins.resize(block_count);
for (uint32_t block = 0; (block < block_count) && (ptr < data_end); ++block) {
float min = std::numeric_limits<T>::max();
float max = std::numeric_limits<T>::min();
for (uint32_t sample = 0; (sample < block_size) && (ptr < data_end); ++sample) {
if (channel == -1) {
for (uint16_t channel = 0; channel < nchannels; ++channel) {
min = std::min(min, float(*ptr++) / std::numeric_limits<T>::max());
max = std::max(max, float(*ptr++) / std::numeric_limits<T>::max());
}
} else {
T const* channelPtr = ptr + (channel * 2);
min = std::min(min, float(*channelPtr++) / std::numeric_limits<T>::max());
max = std::max(max, float(*channelPtr) / std::numeric_limits<T>::max());
ptr += nchannels * 2;
}
}
wform->mins[block] = min;
wform->maxs[block] = max;
}
return wform;
};
switch (_fmt->bitsPerSample) {
case 8: return process.template operator()<int8_t>(start_index, end_index, channel);
case 16: return process.template operator()<int16_t>(start_index, end_index, channel);
}
return nullptr;
}
} // end namespace audio
================================================
FILE: demo/audio/waveFile.h
================================================
#pragma once
// clang-format off
#include <cstdint>
#include <memory>
#include <limits>
#include <filesystem>
#include <vector>
// clang-format on
namespace audio {
struct WaveForm {
std::vector<float> mins;
std::vector<float> maxs;
};
class WaveFile {
public:
struct Fmt {
uint16_t audioFormat; // Audio format 1=PCM,6=mulaw,7=alaw, 257=IBM Mu-Law, 258=IBM A-Law, 259=ADPCM
uint16_t numChannels; // Number of channels 1=Mono 2=Sterio
uint32_t samplesPerSec; // Sampling Frequency in Hz
uint32_t bytesPerSec; // bytes per second
uint16_t blockAlign; // 2=16-bit mono, 4=16-bit stereo
uint16_t bitsPerSample; // Number of bits per sample
};
static std::unique_ptr<WaveFile> read(std::filesystem::path const& m_filepath);
static std::unique_ptr<WaveFile> create(std::vector<uint8_t>&& data);
std::filesystem::path m_filepath;
Fmt const& getFormat() const;
void const * getSamplesData() const;
uint32_t getSamplesDataSize() const;
uint32_t getNumSamplesTotal() const;
float duration() const;
std::unique_ptr<WaveForm> computeWaveform(
uint32_t size, float start_time = 0.f, float end_time = -1.f, int channel = -1) const;
private:
WaveFile() = default;
struct Chunk;
struct Header;
static Chunk const* getSubChunk(std::vector<uint8_t> const& data, char const* name);
mutable Fmt const* _fmt = nullptr;
mutable Chunk const* _dataChunk = nullptr;
std::vector<uint8_t> _data;
};
}; // end namespace audio
================================================
FILE: demo/audio/xaudiofaudio.h
================================================
#pragma once
#include <cstring>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <FAudio.h>
#include <FAudioFX.h>
/////////////////
// imitate the smallest subset of the XAudio2 COM interface that MeshletsDemo wants, on top of FAudio
typedef FAudioBuffer XAUDIO2_BUFFER;
typedef FAudioBufferWMA XAUDIO2_BUFFER_WMA;
typedef FAudioVoiceSends XAUDIO2_VOICE_SENDS;
typedef FAudioVoiceState XAUDIO2_VOICE_STATE;
typedef FAudioSendDescriptor XAUDIO2_SEND_DESCRIPTOR;
typedef FAudioEffectChain XAUDIO2_EFFECT_CHAIN;
typedef FAudioProcessor XAUDIO2_PROCESSOR;
typedef FAudioWaveFormatEx WAVEFORMATEX;
typedef FAudioVoiceCallback IXAudio2VoiceCallback;
#define XAUDIO2_COMMIT_NOW FAUDIO_COMMIT_NOW
#define XAUDIO2_SEND_USEFILTER FAUDIO_SEND_USEFILTER
#define XAUDIO2_DEFAULT_FREQ_RATIO FAUDIO_DEFAULT_FREQ_RATIO
#define XAUDIO2_LOOP_INFINITE FAUDIO_LOOP_INFINITE
#define XAUDIO2_NO_LOOP_REGION FAUDIO_NO_LOOP_REGION
#define XAUDIO2_END_OF_STREAM FAUDIO_END_OF_STREAM
#define XAUDIO2_DEFAULT_CHANNELS FAUDIO_DEFAULT_CHANNELS
#define XAUDIO2_DEFAULT_SAMPLERATE FAUDIO_DEFAULT_SAMPLERATE
#define XAUDIO2_DEFAULT_PROCESSOR FAUDIO_DEFAULT_PROCESSOR
class IXAudio2;
class IXAudio2SourceVoice;
class IXAudio2MasteringVoice;
#define GRAB_VOICE_OBJ(P) ((P)->_GetFAudioVoidPtr()) /* fudge because of how I've implemented the shim */
/////////////////
// ... plus some basic win32-alikes to make the shim easier to use transparently
#ifndef _WIN32
typedef uint32_t HRESULT;
typedef uint8_t BYTE;
#define S_OK 0
#define FAILED(R) ((HRESULT)(R) < 0)
#define CoInitializeEx(FOO,BAR) S_OK /* not really using COM, pretend we're fine */
#define COINIT_MULTITHREADED
#define WAVE_FORMAT_PCM FAUDIO_FORMAT_PCM
#endif // _WIN32
/////////////////
// here's the core of the fakey XAudio2 COM interface
class IXAudio2MasteringVoice
{
public:
static IXAudio2MasteringVoice* _XAudio2MasteringVoiceCreateFromFAudioMasteringVoice(FAudioMasteringVoice *faudiomv)
{
IXAudio2MasteringVoice* rtn = new IXAudio2MasteringVoice;
rtn->_fa_voice = faudiomv;
return rtn;
};
FAudioVoice* _GetFAudioVoidPtr() {return _fa_voice;};
HRESULT SetVolume(float Volume, uint32_t OperationSet=XAUDIO2_COMMIT_NOW) { return FAudioVoice_SetVolume(_fa_voice,Volume,OperationSet); };
void GetVolume(float *pVolume) { FAudioVoice_GetVolume(_fa_voice,pVolume); };
void DestroyVoice() noexcept { FAudioVoice_DestroyVoice(_fa_voice); _fa_voice = NULL; }
private:
FAudioMasteringVoice* _fa_voice;
};
class IXAudio2SourceVoice
{
public:
static IXAudio2SourceVoice* _XAudio2SourceVoiceCreateFromFAudioSourceVoice(FAudioSourceVoice *faudiosv)
{
IXAudio2SourceVoice* rtn = new IXAudio2SourceVoice;
rtn->_fa_voice = faudiosv;
return rtn;
};
void DestroyVoice() { FAudioVoice_DestroyVoice(_fa_voice); _fa_voice = NULL; };
HRESULT Start(uint32_t Flags=0, uint32_t OperationSet=XAUDIO2_COMMIT_NOW) { return FAudioSourceVoice_Start(_fa_voice,Flags,OperationSet); };
HRESULT Stop(uint32_t Flags=0, uint32_t OperationSet=XAUDIO2_COMMIT_NOW) { return FAudioSourceVoice_Stop(_fa_voice,Flags,OperationSet); };
HRESULT ExitLoop(uint32_t OperationSet=XAUDIO2_COMMIT_NOW) { return FAudioSourceVoice_ExitLoop(_fa_voice,OperationSet); };
HRESULT SetVolume(float Volume, uint32_t OperationSet=XAUDIO2_COMMIT_NOW) { return FAudioVoice_SetVolume(_fa_voice,Volume,OperationSet); };
void GetVolume(float *pVolume) { FAudioVoice_GetVolume(_fa_voice,pVolume); };
HRESULT SetFrequencyRatio(float Ratio, uint32_t OperationSet=XAUDIO2_COMMIT_NOW) { return FAudioSourceVoice_SetFrequencyRatio(_fa_voice,Ratio,OperationSet); };
void GetFrequencyRatio(float *pRatio) { FAudioSourceVoice_GetFrequencyRatio(_fa_voice,pRatio); };
HRESULT SubmitSourceBuffer(const XAUDIO2_BUFFER* pBuffer, const XAUDIO2_BUFFER_WMA* pBufferWMA = NULL) { return FAudioSourceVoice_SubmitSourceBuffer(_fa_voice,pBuffer,pBufferWMA); };
HRESULT FlushSourceBuffers() { return FAudioSourceVoice_FlushSourceBuffers(_fa_voice); };
void GetState(XAUDIO2_VOICE_STATE* pVoiceState, uint32_t Flags=0) { FAudioSourceVoice_GetState(_fa_voice,pVoiceState,Flags); };
private:
FAudioSourceVoice* _fa_voice;
};
class IXAudio2
{
public:
static IXAudio2* _XAudio2CreateFromFAudio(FAudio *faudio)
{
IXAudio2* rtn = new IXAudio2;
rtn->_faudio = faudio;
return rtn;
};
unsigned long Release()
{ uint32_t refcount = FAudio_Release(_faudio); if (!refcount) _faudio = nullptr; return refcount; };
HRESULT CreateSourceVoice(
IXAudio2SourceVoice **ppSourceVoice,
const WAVEFORMATEX *pSourceFormat,
uint32_t Flags = 0,
float MaxFrequencyRatio = XAUDIO2_DEFAULT_FREQ_RATIO,
IXAudio2VoiceCallback *pCallback = NULL,
const XAUDIO2_VOICE_SENDS *pSendList = NULL,
const XAUDIO2_EFFECT_CHAIN *pEffectChain = NULL)
{
FAudioSourceVoice* faudiosv;
HRESULT rtn = FAudio_CreateSourceVoice(_faudio,&faudiosv,pSourceFormat,Flags,MaxFrequencyRatio,pCallback,pSendList,pEffectChain);
*ppSourceVoice = IXAudio2SourceVoice::_XAudio2SourceVoiceCreateFromFAudioSourceVoice(faudiosv);
return rtn;
}
HRESULT CreateMasteringVoice(
IXAudio2MasteringVoice **ppMasteringVoice,
uint32_t InputChannels = XAUDIO2_DEFAULT_CHANNELS,
uint32_t InputSampleRate = XAUDIO2_DEFAULT_SAMPLERATE,
uint32_t Flags = 0,
uint32_t DeviceIndex = 0,
const XAUDIO2_EFFECT_CHAIN *pEffectChain = NULL)
{
FAudioMasteringVoice* faudiomv;
HRESULT rtn = FAudio_CreateMasteringVoice(_faudio,&faudiomv,InputChannels,InputSampleRate,Flags,DeviceIndex,pEffectChain);
*ppMasteringVoice = IXAudio2MasteringVoice::_XAudio2MasteringVoiceCreateFromFAudioMasteringVoice(faudiomv);
return rtn;
}
private:
FAudio* _faudio;
};
static HRESULT XAudio2Create(
IXAudio2 **ppXAudio2,
uint32_t Flags = 0,
XAUDIO2_PROCESSOR XAudio2Processor = XAUDIO2_DEFAULT_PROCESSOR
)
{
FAudio* faudio;
HRESULT rtn = FAudioCreate(&faudio,Flags,XAudio2Processor);
*ppXAudio2 = IXAudio2::_XAudio2CreateFromFAudio(faudio);
return rtn;
};
================================================
FILE: demo/blit_params.h
================================================
/*
* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.
*
* 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.
*/
#ifndef BLIT_PARAMS_H // using instead of "#pragma once" due to https://github.com/microsoft/DirectXShaderCompiler/issues/3943
#define BLIT_PARAMS_H
#include "rtxmg_demo.h"
#ifdef __cplusplus
#include <donut/core/math/math.h>
using namespace donut::math;
#endif
struct BlitParams
{
BlitDecodeMode m_blitDecodeMode;
TonemapOperator m_tonemapOperator;
float m_exposure;
float m_zNear;
float m_zFar;
float m_separator;
uint _pad[2];
#ifdef __cplusplus
BlitParams()
: m_blitDecodeMode(BlitDecodeMode::None)
, m_tonemapOperator(TonemapOperator::Linear)
, m_exposure(1.0f)
, m_zNear(1.0f)
, m_zFar(100.f)
, m_separator(0.5f)
, _pad{ 0,0 }
{
}
#endif
};
#endif // BLIT_PARAMS_H
================================================
FILE: demo/envmap/CMakeLists.txt
================================================
set(lib envmap)
set(folder "Demo")
include ("${DONUT_DIR}/compileshaders.cmake")
file(GLOB shaders "shaders/*")
file(GLOB sources "*.cpp" "*.h" *.cfg)
add_library(${lib} OBJECT ${sources})
target_include_directories(${lib} PUBLIC
"${PROJECT_SOURCE_DIR}/rtxmg/include"
)
target_link_libraries(${lib} donut_engine)
set_target_properties(${lib} PROPERTIES FOLDER ${folder})
donut_compile_shaders_all_platforms(
TARGET ${lib}_shaders
CONFIG ${CMAKE_CURRENT_SOURCE_DIR}/shaders.cfg
FOLDER ${folder}
SOURCES ${shaders}
OUTPUT_BASE ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/shaders/${lib}
SHADERMAKE_OPTIONS ${RTXMG_SHADERMAKE_OPTIONS}
SHADERMAKE_OPTIONS_SPIRV ${RTXMG_SHADERMAKE_OPTIONS_SPIRV}
SHADER_MODEL ${RTXMG_SHADERS_SHADERMODEL}
IGNORE_INCLUDES ${RTXMG_SHADERS_IGNORED_INCLUDES}
INCLUDES ${RTXMG_SHADERS_INCLUDE_DIR}
)
add_dependencies(${lib} ${lib}_shaders)
================================================
FILE: demo/envmap/preprocess_envmap.h
================================================
/*
* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.
*
* 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.
*/
#pragma once
#include <nvrhi/nvrhi.h>
#include "rtxmg/utils/buffer.h"
struct PreprocessEnvMapShaders
{
nvrhi::ComputePipelineHandle m_computeConditionalPSO;
nvrhi::ComputePipelineHandle m_computeMarginalPSO;
nvrhi::BindingLayoutHandle m_bindingLayout;
};
struct PreprocessEnvMapResources
{
RTXMGBuffer<float> m_conditionalFunc;
RTXMGBuffer<float> m_conditionalCdf;
RTXMGBuffer<float> m_marginalFunc;
RTXMGBuffer<float> m_marginalCdf;
nvrhi::BufferHandle m_params;
nvrhi::SamplerHandle m_sampler;
};
================================================
FILE: demo/envmap/preprocess_envmap_params.h
================================================
/*
* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.
*
* 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.
*/
#ifndef PREPROCESS_ENVMAP_PARAMS_H // using instead of "#pragma once" due to https://github.com/microsoft/DirectXShaderCompiler/issues/3943
#define PREPROCESS_ENVMAP_PARAMS_H
struct PreprocessEnvMapParams
{
uint32_t envMapWidth;
uint32_t envMapHeight;
};
#endif // PREPROCESS_ENVMAP_PARAMS_H
================================================
FILE: demo/envmap/scan_system.cpp
================================================
/*
* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.
*
* 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.
*/
#pragma once
#include "scan_system.h"
#include <nvrhi/utils.h>
#include <donut/core/log.h>
#include <donut/core/math/math.h>
#include "rtxmg/utils/buffer.h"
using namespace donut;
using namespace donut::math;
void ScanSystem::Init(std::shared_ptr<donut::engine::ShaderFactory> shaderFactory, nvrhi::IDevice* device)
{
m_prefixScan = shaderFactory->CreateShader("envmap/prefix_scan.hlsl", "main", nullptr, nvrhi::ShaderType::Compute);
m_prefixScanPSO.Reset();
if (!m_prefixScan)
{
log::fatal("Failed to create prefix scan shader");
}
m_prefixScanParams = device->createBuffer(nvrhi::utils::CreateVolatileConstantBufferDesc(
sizeof(PrefixScanParams), "prefixScanParams",
engine::c_MaxRenderPassConstantBufferVersions));
}
void ScanSystem::PrefixScan(nvrhi::IBuffer* inputBuffer, nvrhi::IBuffer* outputBuffer, int inputWidth, int inputHeight, nvrhi::ICommandList* commandList)
{
auto device = commandList->getDevice();
PrefixScanParams params = {};
params.elementCountX = inputWidth;
params.elementCountY = inputHeight;
params.outputWidth = inputWidth + 2;
commandList->writeBuffer(m_prefixScanParams, ¶ms, sizeof(params));
auto bindingSetDesc = nvrhi::BindingSetDesc()
.addItem(nvrhi::BindingSetItem::TypedBuffer_SRV(0, inputBuffer))
.addItem(nvrhi::BindingSetItem::TypedBuffer_UAV(0, outputBuffer))
.addItem(nvrhi::BindingSetItem::ConstantBuffer(0, m_prefixScanParams));
nvrhi::BindingSetHandle bindingSet;
if (!nvrhi::utils::CreateBindingSetAndLayout(device, nvrhi::ShaderType::Compute, 0, bindingSetDesc, m_prefixScanBSL, bindingSet))
{
log::fatal("Failed to create binding set and layout for prefix scan shader");
}
if (!m_prefixScanPSO)
{
auto computePipelineDesc = nvrhi::ComputePipelineDesc()
.setComputeShader(m_prefixScan)
.addBindingLayout(m_prefixScanBSL);
m_prefixScanPSO = device->createComputePipeline(computePipelineDesc);
}
auto state = nvrhi::ComputeState()
.setPipeline(m_prefixScanPSO)
.addBindingSet(bindingSet);
commandList->setComputeState(state);
const uint32_t launchDimY = div_ceil(inputHeight, 16);
commandList->dispatch(1, launchDimY);
}
================================================
FILE: demo/envmap/scan_system.h
================================================
/*
* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.
*
* 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.
*/
#pragma once
#include <nvrhi/nvrhi.h>
#include <donut/engine/ShaderFactory.h>
#include <donut/engine/CommonRenderPasses.h>
#include "scan_system_shared.h"
struct ScanSystem
{
nvrhi::BufferHandle m_prefixScanParams;
nvrhi::ShaderHandle m_prefixScan;
nvrhi::ComputePipelineHandle m_prefixScanPSO;
nvrhi::BindingLayoutHandle m_prefixScanBSL;
void Init(std::shared_ptr<donut::engine::ShaderFactory> shaderFactory, nvrhi::IDevice* device);
void PrefixScan(nvrhi::IBuffer* inputBuffer, nvrhi::IBuffer* outputBuffer, int inputWidth, int inputHeight, nvrhi::ICommandList* commandList);
};
================================================
FILE: demo/envmap/scan_system_shared.h
================================================
/*
* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.
*
* 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.
*/
#ifndef SCAN_SYSTEM_SHARED_H // using instead of "#pragma once" due to https://github.com/microsoft/DirectXShaderCompiler/issues/3943
#define SCAN_SYSTEM_SHARED_H
/// Number of threads per block that are used for computing the horizontal prefix scans for a 2D buffer.
/// To handle 8k textures this must be at least 128, otherwise a 3-level scan would be required.
#define PREFIX_SCAN_THREAD_BLOCK_SIZE 512
/// Number of image rows that each kernel invocation will handle during horizontal prefix scans.
#define PREFIX_SCAN_ROWS_PER_BLOCK 1
struct PrefixScanParams
{
uint32_t elementCountX;
uint32_t elementCountY;
uint32_t outputWidth;
};
#endif // SCAN_SYSTEM_SHARED_H
================================================
FILE: demo/envmap/shaders/compute_conditional.hlsl
================================================
/*
* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.
*
* 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.
*/
#include "envmap/preprocess_envmap_params.h"
#include "rtxmg/utils/constants.h"
ConstantBuffer<PreprocessEnvMapParams> gPreprocessEnvMapParams : register(b0);
Texture2D<float4> gTextureColorIn : register(t0);
RWBuffer<float> g_ConditionalFunc : register(u0);
SamplerState gTextureColorInSampler : register(s0);
// clang-format off
[numthreads(16, 16, 1)]
[shader("compute")]
void main(uint2 dispatchThreadId : SV_DispatchThreadID)
// clang-format on
{
if (dispatchThreadId.y >= gPreprocessEnvMapParams.envMapHeight || dispatchThreadId.x >= gPreprocessEnvMapParams.envMapWidth)
{
return;
}
float2 uv = (float2(dispatchThreadId) + 0.5f) / float2(gPreprocessEnvMapParams.envMapWidth, gPreprocessEnvMapParams.envMapHeight);
float3 color = gTextureColorIn.SampleLevel(gTextureColorInSampler, uv, 0).xyz;
// float3 color = gTextureColorIn[dispatchThreadId].xyz;
const float3 lumConverter = float3(0.299f, 0.587f, 0.114f);
float lum = dot(lumConverter, color);
float sinTheta = sin(uv[1] * M_PIf); // prefer values away from the poles to compensate for distortion in latlong mapping (PBRT V3 section 14.2.4)
g_ConditionalFunc[dispatchThreadId.y * gPreprocessEnvMapParams.envMapWidth + dispatchThreadId.x] = lum * sinTheta;
}
================================================
FILE: demo/envmap/shaders/compute_marginal.hlsl
================================================
/*
* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.
*
* 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.
*/
#include "envmap/preprocess_envmap_params.h"
#include "rtxmg/utils/constants.h"
ConstantBuffer<PreprocessEnvMapParams> gPreprocessEnvMapParams : register(b0);
Texture2D<float4> gTextureColorIn : register(t0);
RWBuffer<float> gConditionalCdf : register(u1);
RWBuffer<float> gMarginalFunc : register(u2);
// clang-format off
[numthreads(1, 32, 1)]
[shader("compute")]
void main(uint2 dispatchThreadId : SV_DispatchThreadID)
// clang-format on
{
if (dispatchThreadId.y >= gPreprocessEnvMapParams.envMapHeight)
{
return;
}
const float funcInt = gConditionalCdf[dispatchThreadId.y * (gPreprocessEnvMapParams.envMapWidth + 2) + gPreprocessEnvMapParams.envMapWidth + 1];
gMarginalFunc[dispatchThreadId.y] = funcInt;
}
================================================
FILE: demo/envmap/shaders/envmap.hlsli
================================================
//
// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of NVIDIA CORPORATION nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ENVMAP_HLSLI // using instead of "#pragma once" due to https://github.com/microsoft/DirectXShaderCompiler/issues/3943
#define ENVMAP_HLSLI
float sphericalPhi(float3 v)
{
const float p = atan2(v.z, v.x);
return (p < 0) ? (p + TWO_PI) : p;
}
float sphericalTheta(float3 v)
{
return acos(clamp(v.y, -1.f, 1.f));
}
float2 sphericalProjection(float3 d)
{
d = normalize(d);
const float u = fmod(sphericalPhi(d), TWO_PI) * INV_2PI;
const float v = sphericalTheta(d) * M_1_PIf;
return float2(u, v);
}
float3
sphericalDirection(const float2 u, out float sinTheta)
{
const float phi = u.x * TWO_PI;
const float theta = u.y * M_PIf;
const float cosTheta = cos(theta);
sinTheta = sin(theta);
return normalize(float3(sinTheta * cos(phi), cosTheta, sinTheta * sin(phi)));
}
float2 convertDirToTexCoords(float3 d, float4x4 rotation)
{
float4 transformed = mul(rotation, float4(d, 1.0f));
return sphericalProjection(transformed.xyz);
}
float3 convertTexCoordsToDir(float2 uv, float4x4 rotationInv, out float sinTheta)
{
float3 dir = sphericalDirection(uv, sinTheta);
float4 transformed = mul(rotationInv, float4(dir, 1.f));
return transformed.xyz;
}
float3 envMapEvaluate(float2 u, Texture2D<float4> tex, float intensity, SamplerState sampler)
{
return intensity * (tex.SampleLevel(sampler, u, 0).rgb);
}
float3 envMapEvaluate(float3 dir, Texture2D<float4> tex, float intensity, SamplerState sampler, float4x4 rotation)
{
const float2 u = convertDirToTexCoords(dir, rotation);
return envMapEvaluate(u, tex, intensity, sampler);
}
float envMapPdf(float2 u, Texture2D<float4> envMap, StructuredBuffer<float> conditional, StructuredBuffer<float> marginalCDF, SamplerState sampler)
{
uint width, height;
envMap.GetDimensions(width, height);
uint iu = clamp(int(u[0] * width), 0, width - 1);
uint iv = clamp(int(u[1] * height), 0, height - 1);
float conditionalValue = conditional[iv * width + iu];
float marginalIntegral = marginalCDF[height+1];
float sinTheta = sin(u[1] * M_PIf);
return conditionalValue / (marginalIntegral * TWO_PI * M_PI * sinTheta); // Jacobian term for latlong conversion; see PBRT V3 section 14.2.4.);
}
float envMapPdf(float3 dir, float4x4 rotation, Texture2D<float4> envMap, StructuredBuffer<float> conditional, StructuredBuffer<float> marginalCDF, SamplerState sampler)
{
const float2 u = convertDirToTexCoords(dir, rotation);
return envMapPdf(u, envMap, conditional, marginalCDF, sampler);
}
uint FindInterval(StructuredBuffer<float> cdf, float u, uint row, uint width)
{
// cdf buffer is padded on both sides (firstpad, first, ... , last, lastpad)
uint cdfPaddedWidth = width + 2;
uint size = width;
uint first = 1;
while (size > 0)
{
uint halfSize = size >> 1;
uint middle = first + halfSize;
uint middleOffset = row * cdfPaddedWidth + middle;
bool predResult = cdf[middleOffset] <= u;
first = predResult ? middle + 1 : first;
size = predResult ? size - halfSize - 1 : halfSize;
}
return clamp(first - 1, 0, width - 1);
}
float Sample1D(float u, StructuredBuffer<float> func, StructuredBuffer<float> cdf, uint row, uint width, out float pdf, out uint offset)
{
offset = FindInterval(cdf, u, row, width);
uint cdfPaddedWidth = width + 2;
uint cdfOffset = row * cdfPaddedWidth + offset;
uint funcOffset = row * width + offset;
float du = u - cdf[cdfOffset];
if (cdf[cdfOffset + 1] - cdf[cdfOffset] > 0)
{
du /= (cdf[cdfOffset + 1] - cdf[cdfOffset]);
}
float funcInt = cdf[row * (width + 2) + width + 1];
pdf = func[funcOffset] / funcInt;
return (offset + du) / width;
}
float3 envMapImportanceSample(float2 rndSample, float4x4 rotationInv, out float pdf,
out float3 envMapColor, Texture2D<float4> envMap, float intensity, StructuredBuffer<float>conditional,
StructuredBuffer<float>marginal, StructuredBuffer<float> conditionalCDF, StructuredBuffer<float> marginalCDF, SamplerState sampler)
{
uint width, height;
float pdfs[2];
uint indices[2];
float2 latLongUv;
envMap.GetDimensions(width, height);
latLongUv[1] = Sample1D(rndSample[1], marginal, marginalCDF, 0, height, pdfs[1], indices[1]);
latLongUv[0] = Sample1D(rndSample[0], conditional, conditionalCDF, indices[1], width, pdfs[0], indices[0]);
envMapColor = envMapEvaluate(latLongUv, envMap, intensity, sampler);
float sinTheta = 0.f;
const float3 dir = convertTexCoordsToDir(latLongUv, rotationInv, sinTheta);
pdf = (pdfs[0] * pdfs[1]) / (TWO_PI * M_PI * sinTheta); // Jacobian term for latlong conversion; see PBRT V3 section 14.2.4.
return dir;
}
#endif // ENVMAP_HLSLI
================================================
FILE: demo/envmap/shaders/prefix_scan.hlsl
================================================
/*
* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.
*
* 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.
*/
#include "envmap/scan_system_shared.h"
ConstantBuffer<PrefixScanParams> gPrefixScanParams : register(b0);
Buffer<float> input: register(t0);
RWBuffer<float> output: register(u0);
// clang-format off
[numthreads(1, 16, 1)]
[shader("compute")]
void main(uint2 dispatchThreadId : SV_DispatchThreadID)
// clang-format on
{
int n = gPrefixScanParams.elementCountX;
if (dispatchThreadId.y >= gPrefixScanParams.elementCountY || dispatchThreadId.x != 0)
{
return;
}
uint32_t outputOffset = dispatchThreadId.y * gPrefixScanParams.outputWidth;
uint32_t inputOffset = dispatchThreadId.y * n;
output[outputOffset + 0] = 0;
float sum = 0;
for (int i = 1; i <= n; ++i)
{
output[outputOffset + i] = output[outputOffset + i - 1] + input[inputOffset + i - 1] / n;
}
float funcInt = output[outputOffset + n];
output[outputOffset + n + 1] = funcInt;
if (funcInt == 0)
{
for (int i = 1; i <= n; ++i)
{
output[outputOffset + i] = float(i) / float(n);
}
}
else
{
for (int i = 1; i <= n; ++i)
{
output[outputOffset + i] /= funcInt;
}
}
}
================================================
FILE: demo/envmap/shaders.cfg
================================================
shaders/prefix_scan.hlsl -T cs
shaders/compute_conditional.hlsl -T cs
shaders/compute_marginal.hlsl -T cs
================================================
FILE: demo/gbuffer.h
================================================
//
// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of NVIDIA CORPORATION nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#ifndef GBUFFER_H // using instead of "#pragma once" due to https://github.com/microsoft/DirectXShaderCompiler/issues/3943
#define GBUFFER_H
typedef float DepthFormat;
typedef float4 NormalFormat;
typedef float4 AlbedoFormat;
typedef float4 SpecularFormat;
typedef float SpecularHitTFormat;
typedef float RoughnessFormat;
static const uint32_t kInvalidInstanceId = ~0u;
static const uint32_t kInvalidSurfaceIndex = ~0u;
struct HitResult
{
uint32_t instanceId;
uint32_t surfaceIndex;
float2 surfaceUV;
float2 texcoord; // For displacement texture
};
#ifndef __cplusplus
HitResult DefaultHitResult()
{
HitResult result;
result.instanceId = kInvalidInstanceId;
result.surfaceIndex = kInvalidSurfaceIndex;
result.surfaceUV = float2(0.0f, 0.f);
result.texcoord = float2(0.0f, 0.f);
return result;
}
#endif
#endif // GBUFFER_H
================================================
FILE: demo/gui.cpp
================================================
/*
* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.
*
* 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.
*/
#include <imgui_internal.h>
#ifndef _WIN32
#include <climits>
#include <cstdio>
#include <unistd.h>
#else
#include <ShObjIdl.h>
#include <ShlObj_core.h>
#include <Windows.h>
#include <codecvt>
#include <locale>
constexpr int const PATH_MAX = MAX_PATH;
#endif // _WIN32
#include "rtxmg_demo_app.h"
#include "gui.h"
#include "implot.h"
#include <charconv>
#include <filesystem>
#include <filesystem>
#include <algorithm>
#include <string>
#include <sstream>
#include <donut/app/imgui_renderer.h>
#include "rtxmg/scene/scene.h"
#include "rtxmg/utils/constants.h"
#include "rtxmg/utils/formatters.h"
#include "rtxmg/cluster_builder/tessellator_constants.h"
#include "korgi.h"
#include "rtxmg/profiler/gui.h"
#include "rtxmg/profiler/statistics.h"
#include <donut/app/StreamlineInterface.h>
namespace fs = std::filesystem;
using namespace donut;
#define UI_RED ImVec4(1.f, 0.f, 0.f, 1.f)
#define UI_SAGE ImVec4(.3f, .4f, .35f, 1.f)
#define UI_PLUM ImVec4(.4f, .3f, .35f, 1.f)
constexpr float kItemWidth = 200.0f;
UserInterface::UserInterface(RTXMGDemoApp& app)
: ImGui_Renderer(app.GetDeviceManager()), m_app(app)
{
char const* nvidiaRgGlyphData = GetNVSansFontRgCompressedBase85TTF();
m_nvidiaRgFont =
AddFontFromMemoryCompressedBase85TTF(nvidiaRgGlyphData, 15.f, nullptr);
char const* nvidiaBldGlyphData = GetNVSansFontBoldCompressedBase85TTF();
m_nvidiaBldFont =
AddFontFromMemoryCompressedBase85TTF(nvidiaBldGlyphData, 30.f, nullptr);
ImGui::GetIO().FontDefault = m_nvidiaRgFont;
char const* iconicGlyphsData = GetOpenIconicFontCompressedBase85TTF();
uint16_t const* iconicGlyphsRange = GetOpenIconicFontGlyphRange();
m_iconicFont = AddFontFromMemoryCompressedBase85TTF(iconicGlyphsData, 14.f,
iconicGlyphsRange);
m_imgui = ImGui::GetCurrentContext();
m_implot = ImPlot::CreateContext();
ImPlotStyle& style = ImPlot::GetStyle();
style.FitPadding = ImVec2(0.1f, 0.1f);
style.PlotPadding = ImVec2(2, 5);
style.LegendPadding = ImVec2(2, 2);
m_app.SetGui(this);
SetupIniHandler();
SetupAudioEngine();
}
void UserInterface::SetupIniHandler()
{
ImGuiIO& io = ImGui::GetIO();
if (const fs::path& binaryPath = app::GetDirectoryWithExecutable(); !binaryPath.empty())
{
UIData& ui = m_app.GetUIData();
ui.iniFilepath = (binaryPath / "imgui.ini").generic_string();
io.IniFilename = ui.iniFilepath.c_str();
}
io.IniSavingRate = 60.f; // save every minute only or on quit
static struct Settings
{
bool audioMuted = false;
bool jsonAssetsFilter = false;
bool objAssetsFilter = false;
bool displayStats = false;
bool wantApply = false;
RTXMGDemoApp::WindowState windowState = {};
} settings;
ImGuiSettingsHandler ini_handler;
ini_handler.TypeName = "RTXMG";
ini_handler.TypeHash = ImHashStr(ini_handler.TypeName);
ini_handler.UserData = this;
ini_handler.ReadOpenFn = [](ImGuiContext*, ImGuiSettingsHandler*, const char* name) -> void* {
settings.wantApply = true;
return &settings;
};
ini_handler.ApplyAllFn = [](ImGuiContext* ctx, ImGuiSettingsHandler* handler) {
if (settings.wantApply)
{
auto* gui = reinterpret_cast<UserInterface*>(handler->UserData);
auto* app = &gui->m_app;
gui->GetProfilerGUI().displayGraphWindow = settings.displayStats;
gui->MuteAudio(settings.audioMuted);
UIData& ui = app->GetUIData();
ui.includeJsonAssets = settings.jsonAssetsFilter;
ui.includeObjAssets = settings.objAssetsFilter;
const fs::path& mediaPath = app->GetMediaPath();
if (!mediaPath.empty())
{
assert(ui.mediaAssets.empty());
auto folder_filters = ui.folderFilters();
auto format_filters = ui.formatFilters();
ui.mediaAssets = FindMediaAssets(mediaPath, folder_filters.data(), format_filters.data());
}
app->SetWindowState(settings.windowState);
settings.wantApply = false;
}
};
ini_handler.ReadLineFn = [](ImGuiContext*, ImGuiSettingsHandler* handler, void* entry, const char* line) {
int audioMuted = 0;
if (std::sscanf(line, "AudioMuted=%d", &audioMuted) == 1)
settings.audioMuted = audioMuted;
uint32_t json = 0, obj = 0;
if (std::sscanf(line, "FormatFilters={ json=%d, obj=%d }", &json, &obj) == 2)
{
settings.jsonAssetsFilter = (bool)json;
settings.objAssetsFilter = (bool)obj;
}
int displayStats = false;
if (std::sscanf(line, "DisplayStatistics=%d", &displayStats) == 1)
settings.displayStats = displayStats != 0;
donut::math::int2 windowSize{};
if (std::sscanf(line, "WindowSize=%d,%d", &windowSize.x, &windowSize.y) == 2)
{
settings.windowState.windowSize = windowSize;
}
int windowIsMaximized = false;
if (std::sscanf(line, "WindowIsMaximized=%d", &windowIsMaximized) == 1)
{
settings.windowState.isMaximized = windowIsMaximized != 0;
}
int windowIsFullscreen = false;
if (std::sscanf(line, "WindowIsFullscreen=%d", &windowIsFullscreen) == 1)
{
settings.windowState.isFullscreen = windowIsFullscreen != 0;
}
};
ini_handler.WriteAllFn = [](ImGuiContext* ctx, ImGuiSettingsHandler* handler, ImGuiTextBuffer* buf) {
auto* gui = reinterpret_cast<UserInterface*>(handler->UserData);
auto* app = &gui->m_app;
UIData& ui = app->GetUIData();
settings.audioMuted = ui.audioMuted;
settings.jsonAssetsFilter = ui.includeJsonAssets;
settings.objAssetsFilter = ui.includeObjAssets;
settings.displayStats = gui->GetProfilerGUI().displayGraphWindow;
settings.windowState = app->GetWindowState();
buf->reserve(buf->size() + 2); // ballpark reserve
buf->appendf("[%s][%s]\n", handler->TypeName, "Settings");
buf->appendf("AudioMuted=%d\n", settings.audioMuted);
buf->appendf("FormatFilters={ json=%d, obj=%d }\n", settings.jsonAssetsFilter, settings.objAssetsFilter);
buf->appendf("DisplayStatistics=%d\n", settings.displayStats);
buf->appendf("WindowSize=%d,%d\n", settings.windowState.windowSize.x, settings.windowState.windowSize.y);
buf->appendf("WindowIsMaximized=%d\n", settings.windowState.isMaximized);
buf->appendf("WindowIsFullscreen=%d\n", settings.windowState.isFullscreen);
buf->append("\n");
};
ImGui::AddSettingsHandler(&ini_handler);
}
void UserInterface::BackBufferResized(const uint32_t width,
const uint32_t height,
const uint32_t sampleCount)
{
}
void UserInterface::buildUI()
{
int width, height;
m_app.GetDeviceManager()->GetWindowDimensions(width, height);
float scaleX, scaleY;
m_app.GetDeviceManager()->GetDPIScaleInfo(scaleX, scaleY);
float layoutToDisplay = std::min(scaleX, scaleY);
float contentScale = layoutToDisplay > 0.f ? (1.0f / layoutToDisplay) : 1.0f;
// Layout is done at lower resolution than scaled up virtually past the render target m_size
// any element beyond this range is clipped.
width = int(width * contentScale);
height = int(height * contentScale);
BuildUIMain({ width, height });
}
template<typename E, size_t N>
static int ImGuiComboFromArray(const char* name, E* selected, const std::array<const char*, N>& labels)
{
bool valueChanged = false;
int selectedIndex = int(*selected);
const char* selectedLabel = selectedIndex < labels.size() ? labels[selectedIndex] : "Unknown";
if (ImGui::BeginCombo(name, selectedLabel))
{
int index = 0;
for (const auto& label : labels)
{
bool isSelected = selectedIndex == index;
if (ImGui::Selectable(label, isSelected))
{
*selected = (E)index;
valueChanged = true;
}
if (isSelected) ImGui::SetItemDefaultFocus();
index++;
}
ImGui::EndCombo();
}
return valueChanged;
}
void UserInterface::BuildUIMain(int2 screenLayoutSize)
{
UIData& uiData = GetApp().GetUIData();
auto& renderer = m_app.GetRenderer();
KORGI_BUTTON_CALLBACK(0, Play, [this]()
{
TimeLineEditorState& state = GetApp().GetUIData().timeLineEditorState;
state.PlayClicked();
});
KORGI_BUTTON_CALLBACK(0, Rewind, [this]()
{
TimeLineEditorState& state = GetApp().GetUIData().timeLineEditorState;
state.Rewind();
});
KORGI_BUTTON_CALLBACK(0, FastForward, [this]()
{
TimeLineEditorState& state = GetApp().GetUIData().timeLineEditorState;
state.FastForward();
});
KORGI_KNOB_CALLBACK(0, Slider1, 0.0, 10.0, [this, &renderer](float val)
{
renderer.SetExposure(val);
});
KORGI_BUTTON_CALLBACK(0, Record, [this]()
{
GetApp().SaveScreenshot();
});
KORGI_BUTTON_CALLBACK(0, S1, [this]()
{
GetApp().NextTonemapper();
});
KORGI_BUTTON_CALLBACK(0, Cycle, [this]()
{
GetApp().ResetCamera();
});
KORGI_BUTTON_CALLBACK(0, S2, [this]()
{
GetApp().IncrementMaxBounces(1);
});
KORGI_BUTTON_CALLBACK(0, M2, [this]()
{
GetApp().IncrementMaxBounces(-1);
});
KORGI_BUTTON_CALLBACK(0, S3, [this]()
{
GetApp().IncrementColorMode(1);
});
KORGI_BUTTON_CALLBACK(0, M3, [this]()
{
GetApp().IncrementColorMode(-1);
});
KORGI_BUTTON_CALLBACK(0, R3, [this]()
{
GetApp().ToggleWireframe();
});
KORGI_KNOB_CALLBACK(0, Slider2, 1, 2000, [this](float val)
{
GetApp().SetFineTessellationRate(val / 1000.0f);
});
ImVec2 itemSize = ImGui::GetItemRectSize();
const char* kWindowName = "Settings";
SetConstrainedWindowPos(kWindowName, ImVec2(10, 10), ImVec2(0.0f, 0.0f), MakeImVec2(screenLayoutSize));
ImGui::SetNextWindowSize(ImVec2(0.0f, 0.0f), ImGuiCond_Always);
ImGui::SetNextWindowSizeConstraints(ImVec2(100.f, 200.f), ImVec2(float(screenLayoutSize.x), screenLayoutSize.y - 70.0f));
ImGui::Begin(kWindowName, nullptr, ImGuiWindowFlags_None);
ImGui::PushItemWidth(kItemWidth);
#ifdef AUDIO_ENGINE_ENABLED
static const char* unmutedGlyph = (char*)(u8"\ue0d5" "## unmuted");
static const char* mutedGlyph = (char*)(u8"\ue0d7" "## muted");
bool muted = uiData.audioMuted;
if (muted)
ImGui::PushStyleColor(ImGuiCol_Button, UI_RED);
ImGui::PushFont(m_iconicFont);
if (ImGui::Button(muted ? mutedGlyph : unmutedGlyph, { 20.f, itemSize.y }))
{
if (m_audioEngine)
m_audioEngine->mute(uiData.audioMuted = !muted);
}
if (muted)
ImGui::PopStyleColor();
ImGui::PopFont();
if (ImGui::IsItemHovered() && ImGui::GetCurrentContext()->HoveredIdTimer > .5f)
ImGui::SetTooltip("Mute audio.");
ImGui::SameLine();
#endif
ImGui::PushFont(m_iconicFont);
if (ImGui::Button((char const*)(u8"\ue02c"
"## screenshot"),
{ 0.f, itemSize.y }))
{
m_app.SaveScreenshot();
}
ImGui::PopFont();
if (ImGui::IsItemHovered() && ImGui::GetCurrentContext()->HoveredIdTimer > .5f)
ImGui::SetTooltip("Capture a screenshot.");
ImGui::SameLine();
bool showMicroTriangles = renderer.GetShowMicroTriangles();
float buttonWidth = ImGui::GetTextLineHeightWithSpacing() + ImGui::CalcTextSize("Visualize Micro Triangles").x
+ ImGui::GetStyle().FramePadding.x * 2.0f;
ImGui::SetNextItemWidth(buttonWidth);
if (showMicroTriangles)
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.5f, 0.0f, 0.0f, 1.0f));
if (ImGui::Button("Micro Triangles"))
{
renderer.SetShowMicroTriangles(!showMicroTriangles);
}
if (ImGui::IsItemHovered() && ImGui::GetCurrentContext()->HoveredIdTimer > .5f)
ImGui::SetTooltip("Toggle micro triangle visualization mode with a unique color per triangle id.");
if (showMicroTriangles)
ImGui::PopStyleColor();
ImGui::Spacing();
ImGui::Separator();
ImGui::Spacing();
ImGui::PushStyleColor(ImGuiCol_Header, UI_SAGE);
if (ImGui::CollapsingHeader("Scene Loading", ImGuiTreeNodeFlags_DefaultOpen))
{
fs::path mediapath = m_app.GetMediaPath();
// media folder
bool objFilesNeedUpdate = false;
{
ImGui::PushFont(m_iconicFont);
if (ImGui::Button((char const*)(u8"\ue06b"
"## media path"),
{ 0.f, itemSize.y }))
{
std::string folderpath = mediapath.generic_string();
if (FolderDialog(folderpath))
{
mediapath = fs::path(folderpath).lexically_normal();
m_app.SetMediaPath(mediapath);
uiData.currentAsset = nullptr;
objFilesNeedUpdate = true;
}
}
ImGui::PopFont();
ImGui::SameLine();
float buttonWidth = ImGui::GetItemRectSize().x + ImGui::GetStyle().ItemSpacing.x;
ImGui::SetNextItemWidth(kItemWidth - buttonWidth);
char buf[1024] = { 0 };
std::strncpy(buf, mediapath.generic_string().c_str(), std::size(buf));
if (ImGui::InputText("Data Folder", buf, std::size(buf),
ImGuiInputTextFlags_EnterReturnsTrue))
{
mediapath = buf;
m_app.SetMediaPath(buf);
objFilesNeedUpdate = true;
}
if (ImGui::IsItemHovered() &&
ImGui::GetCurrentContext()->HoveredIdTimer > .5f && !mediapath.empty())
ImGui::SetTooltip("%s", mediapath.generic_string().c_str());
}
if (ImGui::Checkbox("Json", &uiData.includeJsonAssets))
objFilesNeedUpdate = true;
ImGui::SameLine();
if (ImGui::Checkbox("Obj", &uiData.includeObjAssets))
objFilesNeedUpdate = true;
if (objFilesNeedUpdate || uiData.mediaAssets.empty())
{
auto folderFilters = uiData.folderFilters();
auto formatFilters = uiData.formatFilters();
// Store current asset name before refreshing the map
std::string currentAssetName = uiData.currentAsset ? uiData.currentAsset->GetName() : "";
uiData.mediaAssets = FindMediaAssets(mediapath, folderFilters.data(),
formatFilters.data());
// Restore current asset selection if it still exists
if (!currentAssetName.empty())
{
uiData.SelectCurrentAsset(currentAssetName);
}
else
{
uiData.currentAsset = nullptr;
}
}
char const* currentAssetName =
uiData.currentAsset ? uiData.currentAsset->GetName() : nullptr;
if (ImGui::BeginCombo("Scene", currentAssetName,
ImGuiComboFlags_HeightLarge))
{
for (const auto& [key, asset] : uiData.mediaAssets)
{
bool isSequence = asset.IsSequence();
std::string const& name = isSequence ? asset.sequenceName : key;
bool isSelected = currentAssetName && (name == currentAssetName);
if (ImGui::Selectable(name.c_str(), isSelected))
{
LoadAsset(asset, name, asset.frameRange);
}
if (isSelected)
ImGui::SetItemDefaultFocus();
}
ImGui::EndCombo();
}
if (ImGui::IsItemHovered() &&
ImGui::GetCurrentContext()->HoveredIdTimer > .5f && uiData.currentAsset &&
!uiData.currentAsset->name.empty())
{
ImGui::SetTooltip("%s", uiData.currentAsset->GetName());
}
}
#if RTXMG_DEV_FEATURES
if (ImGui::CollapsingHeader("Debug", ImGuiTreeNodeFlags_DefaultOpen))
{
ImGui::PushFont(m_iconicFont);
if (ImGui::Button((char const*)(u8"\ue0b3"
"## reload shaders"),
{ 0.f, itemSize.y }))
{
m_app.ReloadShaders();
}
ImGui::PopFont();
if (ImGui::IsItemHovered() && ImGui::GetCurrentContext()->HoveredIdTimer > .5f)
ImGui::SetTooltip("Reload Shaders (CTRL+R)");
ImGui::SameLine();
ImGui::PushFont(m_iconicFont);
if (ImGui::Button((char const*)(u8"\ue071"
"## dump fill clusters"),
{ 0.f, itemSize.y }))
{
m_app.DumpFineTess();
}
ImGui::PopFont();
if (ImGui::IsItemHovered() && ImGui::GetCurrentContext()->HoveredIdTimer > .5f)
ImGui::SetTooltip("Dump Fill Clusters.");
ImGui::SameLine();
ImGui::PushFont(m_iconicFont);
if (ImGui::Button((char const*)(u8"\ue028"
"## dump debug buffer"),
{ 0.f, itemSize.y }))
{
m_app.DumpDebugBuffer();
}
ImGui::PopFont();
if (ImGui::IsItemHovered() && ImGui::GetCurrentContext()->HoveredIdTimer > .5f)
ImGui::SetTooltip("Dump Debug Buffer.");
ImGui::SameLine();
ImGui::Checkbox("Monolithic ClusterBuild", &uiData.enableMonolithicClusterBuild);
if (ImGui::IsItemHovered() && ImGui::GetCurrentContext()->HoveredIdTimer > .5f)
ImGui::SetTooltip(
"Use a single shader for compute cluster tiling and fill clusters.\n"
"Instead of splitting the dispatches by surface type");
bool accelBuildLoggingEnabled = m_app.GetAccelBuildLoggingEnabled();
if (ImGui::Checkbox("AS Log", &accelBuildLoggingEnabled))
{
m_app.SetAccelBuildLoggingEnabled(accelBuildLoggingEnabled);
}
if (ImGui::IsItemHovered() && ImGui::GetCurrentContext()->HoveredIdTimer > .5f)
ImGui::SetTooltip("Log accel build buffers (Syncs GPU, Slow!)");
ImGui::SameLine();
ImGui::Checkbox("Build AS", &uiData.forceRebuildAccelStruct);
if (ImGui::IsItemHovered() && ImGui::GetCurrentContext()->HoveredIdTimer > .5f)
ImGui::SetTooltip(
"Re-tessellate and rebuild acceleration structures every frame.\n"
"Disable to freeze tessellation and move the camera around.\n"
"Animation will always force a rebuild.");
if (!uiData.forceRebuildAccelStruct)
{
ImGui::SameLine();
if (ImGui::Button("Build AS Once"))
{
m_app.RebuildAS();
}
if (ImGui::IsItemHovered() && ImGui::GetCurrentContext()->HoveredIdTimer > .5f)
ImGui::SetTooltip("Force rebuild-AS one time, useful for debug logging.");
}
#if ENABLE_SHADER_DEBUG
int2& debugPixel = renderer.GetDebugPixel();
ImGui::InputInt2("DebugPixel (Right-click)", debugPixel.data());
if (ImGui::InputInt3("Tessellator Debug (Surface, Cluster, Lane)", m_app.GetDebugSurfaceClusterLaneIndex().data()))
{
// Update renderer's debug surface index for highlighting
renderer.SetDebugSurfaceIndex(m_app.GetDebugSurfaceClusterLaneIndex()[0]);
m_app.RebuildAS();
}
if (ImGui::IsItemHovered() &&
ImGui::GetCurrentContext()->HoveredIdTimer > .5f)
ImGui::SetTooltip("Set surface >=0 and lane >=0 to debug compute cluster tiling.\n"
"Set cluster >=0 and lane >=0 to debug fill clusters.\n");
#endif
}
#endif
if (!showMicroTriangles && ImGui::CollapsingHeader("Rendering", ImGuiTreeNodeFlags_DefaultOpen))
{
bool wireframe = renderer.GetWireframe();
if (ImGui::Checkbox("Wireframe", &wireframe))
{
renderer.SetWireframe(wireframe);
}
if (ImGui::IsItemHovered() &&
ImGui::GetCurrentContext()->HoveredIdTimer > .5f)
ImGui::SetTooltip("Display micro-triangles wireframe over the geometry.");
ImGui::SameLine();
bool displayZBuffer = renderer.GetDisplayZBuffer();
if (ImGui::Checkbox("Show Occlusion Depth", &displayZBuffer))
{
renderer.SetDisplayZBuffer(displayZBuffer);
}
if (ImGui::IsItemHovered() && ImGui::GetCurrentContext()->HoveredIdTimer > .5f)
ImGui::SetTooltip("Show Hi-Z Occlusion Buffer of static geometry used for reducing tessellation");
bool denoiserEnabled = m_app.GetEffectiveDenoiserMode() != DenoiserMode::None;
if (!denoiserEnabled && renderer.GetEffectiveShadingMode() == ShadingMode::PT)
{
bool timeView = renderer.GetTimeView();
if (ImGui::Checkbox("Heatmap", &timeView))
{
renderer.SetTimeView(timeView);
}
ImGui::SameLine();
int spp = static_cast<int>(std::sqrt(renderer.GetSPP()) - 1);
ImGui::PushItemWidth(65);
if (ImGui::Combo("SPP", &spp, " 1x\0 4x\0 9x\0 16x\0 25x\0 36x\0 49x\0 64x\0 81x\0 100x\0"))
{
renderer.SetSPP((spp + 1) * (spp + 1));
}
ImGui::PopItemWidth();
if (ImGui::IsItemHovered() && ImGui::GetCurrentContext()->HoveredIdTimer > .5f)
ImGui::SetTooltip("Samples Per Pixel.");
}
if (renderer.GetWireframe())
{
float wireframeThickness = renderer.GetWireframeThickness();
if (ImGui::SliderFloat("Wireframe Thickness", &wireframeThickness, 0.f,
10.f, "%.3f", ImGuiSliderFlags_Logarithmic))
{
renderer.SetWireframeThickness(wireframeThickness);
}
}
ShadingMode shadingMode = renderer.GetShadingMode();
if (ImGuiComboFromArray("Shading Mode", &shadingMode, kShadingModeNames))
{
renderer.SetShadingMode(shadingMode);
}
ColorMode colorMode = renderer.GetColorMode();
if (ImGuiComboFromArray("Color Mode", &colorMode, kColorModeNames))
{
renderer.SetColorMode(colorMode);
}
ShadingMode effectiveShadingMode = renderer.GetEffectiveShadingMode();
if (effectiveShadingMode == ShadingMode::PT)
{
int maxBounces = std::max(1, std::min(10, renderer.GetPTMaxBounces()));
if (ImGui::InputInt("Max Bounces", &maxBounces, 1, 10))
{
renderer.SetPTMaxBounces(maxBounces);
}
if (!denoiserEnabled)
{
float fireflyMaxIntensity = renderer.GetFireflyMaxIntensity();
if (ImGui::SliderFloat("Firefly Max Intensity", &fireflyMaxIntensity, 0.f, 10.f))
{
renderer.SetFireflyMaxIntensity(fireflyMaxIntensity);
}
}
float roughness = renderer.GetRoughnessOverride();
if (ImGui::SliderFloat("Roughness Override", &roughness, 0.f, 1.f))
{
renderer.SetRoughnessOverride(roughness);
}
if (ImGui::IsItemHovered() && ImGui::GetCurrentContext()->HoveredIdTimer > .5f)
ImGui::SetTooltip(
"Overrides the roughness coefficient for all the materials\n"
"in the scene. Useful for debugging materials.\n");
float exposure = renderer.GetExposure();
if (ImGui::SliderFloat("Exposure", &exposure, 0.f, 1000.f, "%.3f", ImGuiSliderFlags_Logarithmic))
{
renderer.SetExposure(exposure);
}
TonemapOperator tonemap = renderer.GetTonemapOperator();
if (ImGuiComboFromArray("Tonemapping Operator", &tonemap, kToneMapOperatorNames))
{
renderer.SetTonemapOperator(tonemap);
}
}
BuildUIEnvmap(itemSize);
}
ImGui::PopStyleColor();
ImGui::Spacing();
ImGui::PushStyleColor(ImGuiCol_Header, UI_SAGE);
if (ImGui::CollapsingHeader("Tessellation", ImGuiTreeNodeFlags_DefaultOpen))
{
TessellatorConfig::MemorySettings memSettings = m_app.GetTessMemSettings();
int32_t maxKClusters = memSettings.maxClusters >> 10u;
int vertexMB = int32_t(memSettings.vertexBufferBytes >> 20ull);
int clasMB = int32_t(memSettings.clasBufferBytes >> 20ull);
auto& stats = GetApp().m_BuildStats;
bool memSettingsChanged = false;
const float kFlashWarningPeriod = 1.0f;
float t = fmodf(float(ImGui::GetTime()), kFlashWarningPeriod); // Flashes every second (0.5s on, 0.5s off)
bool shouldHighlight = (t < 0.5f);
bool highlightMaxClusters = shouldHighlight && stats.desired.m_numClusters > stats.allocated.m_numClusters;
bool highlightVertexMemory = shouldHighlight && (stats.desired.m_vertexBufferSize > stats.allocated.m_vertexBufferSize ||
stats.desired.m_vertexNormalsBufferSize > stats.allocated.m_vertexNormalsBufferSize);
bool highlightClasMemory = shouldHighlight && stats.desired.m_clasSize > stats.allocated.m_clasSize;
const ImVec4 kHighlightColor = ImVec4(0.5f, 0.0f, 0.0f, 1.0f); // Red highlight
if (highlightMaxClusters)
ImGui::PushStyleColor(ImGuiCol_FrameBg, kHighlightColor);
if (ImGui::InputInt("Max Clusters (K)", &maxKClusters, 64, 256, ImGuiInputTextFlags_EnterReturnsTrue))
{
memSettings.maxClusters = std::min((uint32_t(std::max(maxKClusters, 64)) << 10u), kMaxApiClusterCount);
memSettingsChanged = true;
}
if (ImGui::IsItemHovered() && ImGui::GetCurrentContext()->HoveredIdTimer > .5f)
ImGui::SetTooltip("Max clusters in a scene which affects the size of cluster data buffer and BLAS memory");
if (highlightMaxClusters)
ImGui::PopStyleColor();
if (highlightVertexMemory)
ImGui::PushStyleColor(ImGuiCol_FrameBg, kHighlightColor);
if (ImGui::InputInt("Vertex Memory (MB)", &vertexMB, 128, 512, ImGuiInputTextFlags_EnterReturnsTrue))
{
memSettings.vertexBufferBytes = std::min(size_t(std::max(vertexMB, 128)), 8192ull) << 20ull;
memSettingsChanged = true;
}
if (ImGui::IsItemHovered() && ImGui::GetCurrentContext()->HoveredIdTimer > .5f)
ImGui::SetTooltip("Max memory in MB allocated for tessellated vertices (positions + normals when enabled)");
if (highlightVertexMemory)
ImGui::PopStyleColor();
if (highlightClasMemory)
ImGui::PushStyleColor(ImGuiCol_FrameBg, kHighlightColor);
if (ImGui::InputInt("CLAS Memory (MB)", &clasMB, 128, 512, ImGuiInputTextFlags_EnterReturnsTrue))
{
memSettings.clasBufferBytes = std::min(size_t(std::max(clasMB, 128)), 8192ull) << 20ull;
memSettingsChanged = true;
}
if (ImGui::IsItemHovered() && ImGui::GetCurrentContext()->HoveredIdTimer > .5f)
ImGui::SetTooltip("Max memory in megabytes allocated for cluster acceleration structures CLAS");
if (highlightClasMemory)
ImGui::PopStyleColor();
if (memSettingsChanged)
{
m_app.SetTessMemSettings(memSettings);
}
int clusterPattern = static_cast<int>(m_app.GetClusterTessellationPattern());
float comboBoxWidth = ImGui::GetTextLineHeightWithSpacing() + ImGui::CalcTextSize("Slanted ").x
+ ImGui::GetStyle().FramePadding.x * 2.0f;
ImGui::SetNextItemWidth(comboBoxWidth);
if (ImGui::Combo("Tess Pattern", &clusterPattern, "Regular\0Slanted\0"))
{
m_app.SetClusterTessellationPattern(ClusterPattern(clusterPattern));
}
if (ImGui::IsItemHovered() && ImGui::GetCurrentContext()->HoveredIdTimer > .5f)
ImGui::SetTooltip(
"Toggles the 'slanted' grid pattern on. 'Slanted' grids\n"
"allow for a smoother transition when the number of edge segments on\n"
"opposite sides of a quad don't match.\n\n");
ImGui::SameLine();
bool updateTessCamera = m_app.GetUpdateTessellationCamera();
if (ImGui::Checkbox("Update Tess Camera", &updateTessCamera))
{
m_app.SetUpdateTessellationCamera(updateTessCamera);
}
if (ImGui::IsItemHovered() && ImGui::GetCurrentContext()->HoveredIdTimer > .5f)
ImGui::SetTooltip("Keep tessellation camera in sync. Uncheck to lock the camera.");
bool enableFrustumVisibility = m_app.GetFrustumVisibilityEnabled();
if (ImGui::Checkbox("Frustum", &enableFrustumVisibility))
m_app.SetFrustumVisibilityEnabled(enableFrustumVisibility);
if (ImGui::IsItemHovered() && ImGui::GetCurrentContext()->HoveredIdTimer > .5f)
ImGui::SetTooltip("Offscreen geometry uses coarse tessellation rates");
ImGui::SameLine();
bool enableHiZVisibility = m_app.GetHiZVisibilityEnabled();
if (ImGui::Checkbox("HiZ", &enableHiZVisibility))
m_app.SetHiZVisibilityEnabled(enableHiZVisibility);
if (ImGui::IsItemHovered() && ImGui::GetCurrentContext()->HoveredIdTimer > .5f)
ImGui::SetTooltip("Dynamic geometry occluded by static geometry uses coarse tessellation rate");
TessellatorConfig::VisibilityMode visMode = m_app.GetTessellatorVisibilityMode();
if (visMode == TessellatorConfig::VisibilityMode::VIS_LIMIT_EDGES)
{
ImGui::SameLine();
bool enableBackFaceVisibility = m_app.GetBackfaceVisibilityEnabled();
if (ImGui::Checkbox("Backface", &enableBackFaceVisibility))
m_app.SetBackfaceVisibilityEnabled(enableBackFaceVisibility);
if (ImGui::IsItemHovered() && ImGui::GetCurrentContext()->HoveredIdTimer > .5f)
ImGui::SetTooltip("Back faces use coarse tessellation rate");
}
float tessRates[] = { m_app.GetFineTessellationRate(), m_app.GetCoarseTessellationRate() };
if (ImGui::SliderFloat2("Fine | Coarse Tess Rate", tessRates, 0.001f, 2.f))
{
if (tessRates[0] > 0.0f)
{
m_app.SetFineTessellationRate(tessRates[0]);
}
if (tessRates[1] > 0.0f)
{
m_app.SetCoarseTessellationRate(tessRates[1]);
}
}
if (ImGui::IsItemHovered() && ImGui::GetCurrentContext()->HoveredIdTimer > .5f)
ImGui::SetTooltip("Tessellation rates for metric:\n"
"- Fine: Affects primary visible ray geometry\n"
"- Coarse: Affects \"culled\" geometry: offscreen, backfacing, occluded\n");
TessellatorConfig::AdaptiveTessellationMode tessMode = m_app.GetAdaptiveTessellationMode();
if (ImGuiComboFromArray("Tessellation Metric", &tessMode, kAdaptiveTessellationModeNames))
{
m_app.SetAdaptiveTessellationMode(tessMode);
}
if (ImGui::IsItemHovered() && ImGui::GetCurrentContext()->HoveredIdTimer > .5f)
ImGui::SetTooltip(
"Tessellation metrics:\n\n"
"- Uniform: uniform tessellation factors (all clusters have the\n"
" same number of triangles).\n\n"
"- World space edge length: tessellation factors are derived from\n"
" the length of the control cage edges in world space (independent\n"
" the camera position).\n\n"
"- Spherical projection: tessellation factors are derived from the\n"
" length of the control cage edges scaled by their distance to the\n"
" camera location.\n");
if (ImGuiComboFromArray("Visibility Mode", &visMode, kVisibilityModeNames))
{
m_app.SetTessellatorVisibilityMode(visMode);
}
if (ImGui::IsItemHovered() && ImGui::GetCurrentContext()->HoveredIdTimer > .5f)
ImGui::SetTooltip(
"Tessellation visibility predicates:\n\n"
"- Surface 1-Ring: uses the 1-ring control cage of a surface to derive\n"
" visibility for an entire surface\n\n"
"- Limit edge: generates visibility predicate for each limit edge a\n"
" surface only.\n");
int isolationLevel = m_app.GetGlobalIsolationLevel();
if (ImGui::SliderInt("Global Isolation Level", &isolationLevel, 1, 6))
{
m_app.SetGlobalIsolationLevel(uint32_t(isolationLevel));
}
if (ImGui::IsItemHovered() && ImGui::GetCurrentContext()->HoveredIdTimer > .5f)
ImGui::SetTooltip("Global isolation level for all meshes.\n"
"- Needs to be >= the highest finite sharpness, but the default of 6 is sufficient.\n"
"- Finite sharpness is any sharpness < 10.0f.\n"
"- Infinite sharpness = 10.0f has an optimization that doesn't require isolation\n");
float displacementScale = m_app.GetDisplacementScale();
if (ImGui::SliderFloat("Displacement Scale", &displacementScale, 0.0f, 3.0f))
{
m_app.SetDisplacementScale(displacementScale);
}
if (ImGui::IsItemHovered() && ImGui::GetCurrentContext()->HoveredIdTimer > .5f)
ImGui::SetTooltip("Scaling factor for displacement maps");
bool vertexNormalsEnabled = m_app.GetVertexNormalsEnabled();
if (ImGui::Checkbox("Vertex Normals", &vertexNormalsEnabled))
{
m_app.SetVertexNormalsEnabled(vertexNormalsEnabled);
}
if (ImGui::IsItemHovered() && ImGui::GetCurrentContext()->HoveredIdTimer > .5f)
ImGui::SetTooltip("Enable computation of vertex normals from surface derivatives");
}
ImGui::PopStyleColor();
ImGui::Spacing();
#if DONUT_WITH_STREAMLINE
ImGui::PushStyleColor(ImGuiCol_Header, UI_SAGE);
if (!renderer.GetShowMicroTriangles() && ImGui::CollapsingHeader("Denoiser and Upscaling", ImGuiTreeNodeFlags_DefaultOpen))
{
using StreamlineInterface = donut::app::StreamlineInterface;
DenoiserMode denoiserMode = m_app.GetDenoiserMode();
#if ENABLE_DLSS_SR
if (ImGui::Combo("Denoiser Mode", (int*)&denoiserMode, "None\0DLSS-SR\0DLSS-RR\0"))
{
m_app.SetDenoiserMode(denoiserMode);
}
if (ImGui::IsItemHovered() && ImGui::GetCurrentContext()->HoveredIdTimer > .5f)
ImGui::SetTooltip("Set Denoiser mode");
#else
bool isDlssEnabled = denoiserMode == DenoiserMode::DlssRr;
if (ImGui::Checkbox("Enable DLSS-RR", &isDlssEnabled))
{
m_app.SetDenoiserMode(isDlssEnabled ? DenoiserMode::DlssRr : DenoiserMode::None);
}
if (ImGui::IsItemHovered() && ImGui::GetCurrentContext()->HoveredIdTimer > .5f)
ImGui::SetTooltip("Enable DLSS-RR for upscale and denoising");
#endif
if (denoiserMode != DenoiserMode::None)
{
if (denoiserMode == DenoiserMode::DlssSr ||
denoiserMode == DenoiserMode::DlssRr)
{
const std::array<std::pair<StreamlineInterface::DLSSMode, const char*>, 5> kVisibleDlssModes = { {
{StreamlineInterface::DLSSMode::eUltraPerformance, "Ultra-Performance"},
{StreamlineInterface::DLSSMode::eMaxPerformance, "Performance"},
{StreamlineInterface::DLSSMode::eBalanced, "Balanced"},
{StreamlineInterface::DLSSMode::eMaxQuality, "Quality"},
{StreamlineInterface::DLSSMode::eDLAA, "DLAA"}
} };
auto iter = std::find_if(kVisibleDlssModes.begin(), kVisibleDlssModes.end(), [&uiData](auto& m) { return m.first == uiData.dlssMode; });
if (iter == kVisibleDlssModes.end())
{
// Reset to eMaxQuality if we can't find the option
uiData.dlssMode = StreamlineInterface::DLSSMode::eMaxQuality;
iter = std::find_if(kVisibleDlssModes.begin(), kVisibleDlssModes.end(), [&uiData](auto& m) { return m.first == uiData.dlssMode; });
}
if (ImGui::BeginCombo("DLSS Mode", iter->second))
{
for (const auto& mode : kVisibleDlssModes)
{
bool isSelected = (mode.first == uiData.dlssMode);
if (ImGui::Selectable(mode.second, isSelected))
{
uiData.dlssMode = mode.first;
}
if (isSelected) ImGui::SetItemDefaultFocus();
}
ImGui::EndCombo();
}
#if ENABLE_DLSS_DEV_FEATURE
if (uiData.dlssMode != StreamlineInterface::DLSSMode::eUltraQuality &&
uiData.dlssMode != StreamlineInterface::DLSSMode::eOff)
{
std::array<const char*, 7> kDlssPresetNames = {
"Default",
"Preset A",
"Preset B",
"Preset C",
"Preset D",
"Preset E",
"Preset F"
};
std::array<const char*, 7> kDlssRRPresetNames = {
"Default",
"Preset A",
"Preset B",
"Preset C",
"Preset D",
"Preset E",
"Preset G"
};
if (denoiserMode == DenoiserMode::DlssSr)
{
if (ImGui::BeginCombo("DLSS SR Preset", kDlssPresetNames[(int)uiData.dlssPreset]))
{
for (int i = 0; i < kDlssPresetNames.size(); ++i)
{
bool isSelected = i == static_cast<int>(uiData.dlssPreset);
if (ImGui::Selectable(kDlssPresetNames[i], isSelected)) uiData.dlssPreset = (StreamlineInterface::DLSSPreset)i;
if (isSelected) ImGui::SetItemDefaultFocus();
}
ImGui::EndCombo();
}
}
else
{
if (ImGui::BeginCombo("DLSS RR Preset", kDlssRRPresetNames[(int)uiData.dlssRRPreset]))
{
for (int i = 0; i < kDlssRRPresetNames.size(); ++i)
{
bool isSelected = i == static_cast<int>(uiData.dlssRRPreset);
if (ImGui::Selectable(kDlssRRPresetNames[i], isSelected)) uiData.dlssRRPreset = (StreamlineInterface::DLSSRRPreset)i;
if (isSelected) ImGui::SetItemDefaultFocus();
}
ImGui::EndCombo();
}
}
}
ImGui::Checkbox("Overide LOD Bias", &uiData.dlssUseLodBiasOverride);
if (uiData.dlssUseLodBiasOverride)
{
ImGui::SameLine();
ImGui::SliderFloat("", &uiData.dlssLodBiasOverride, -2, 2);
}
#endif
}
if (ImGui::BeginCombo("Output", renderer.GetOutputLabel(renderer.GetOutputIndex()),
ImGuiComboFlags_HeightLarge))
{
for (uint32_t outputIndex = uint32_t(RTXMGRenderer::Output::Accumulation);
outputIndex < uint32_t(RTXMGRenderer::Output::Count);
outputIndex++)
{
bool isSelected = outputIndex == uint32_t(renderer.GetOutputIndex());
if (ImGui::Selectable(renderer.GetOutputLabel(RTXMGRenderer::Output(outputIndex)), isSelected))
{
renderer.SetOutputIndex(RTXMGRenderer::Output(outputIndex));
renderer.ResetSubframes();
}
if (isSelected)
ImGui::SetItemDefaultFocus();
}
ImGui::EndCombo();
}
float denoiserSeparator = renderer.GetDenoiserSeparator();
if (ImGui::SliderFloat("Output | Denoised", &denoiserSeparator, 0.0f, 1.0f, "%.2f"))
{
renderer.SetDenoiserSeparator(denoiserSeparator);
}
MvecDisplacement mvecDisplacement = renderer.GetMVecDisplacement();
if (ImGuiComboFromArray("Motion Vectors", &mvecDisplacement, kMvecDisplacementNames))
{
renderer.SetMvecDisplacement(mvecDisplacement);
}
if (ImGui::IsItemHovered() && ImGui::GetCurrentContext()->HoveredIdTimer > .5f)
{
ImGui::SetTooltip(
"Motion Vectors Calculation Mode:\n\n"
"- From Subd Eval: Compute displacement using the delta between\n"
" gbuffer hit point and current frame limit surface.\n"
" Expensive since it re-evalutes limit surface again, but compensates for tess rates\n\n"
"- From Material: Resample displacement from texture and apply to prev frame limit surface\n"
" If tess rates vary then there can be a mismatch with the current frame hit point.\n");
}
}
}
ImGui::PopStyleColor();
ImGui::Spacing();
#endif
ImGui::PopItemWidth();
ImGui::End();
m_profiler.fps = (int)(1000.f / (float)m_app.GetCPUFrameTime());
m_profiler.desiredTris = stats::clusterAccelSamplers.numTriangles.latest;
m_profiler.allocatedTris = stats::clusterAccelSamplers.numTriangles.max;
m_profiler.desiredClusters = stats::clusterAccelSamplers.numClusters.latest;
m_profiler.allocatedClusters = stats::clusterAccelSamplers.numClusters.max;
m_profiler.controllerWindow = {
.pos = ImVec2(float(screenLayoutSize.x) - 10.f, float(screenLayoutSize.y) - 10.f),
.pivot = ImVec2(1.f, 1.f),
.size = ImVec2(115, 0)
};
m_profiler.profilerWindow = {
.pos = ImVec2(float(screenLayoutSize.x) - 10.f, 10.f),
.pivot = ImVec2(1.f, 0.f),
.size = ImVec2(800.f, 450.f),
.screenLayoutSize = ImVec2(float(screenLayoutSize.x), float(screenLayoutSize.y))
};
m_profiler.BuildUI<stats::FrameSamplers, stats::ClusterAccelSamplers, stats::EvaluatorSamplers, stats::MemUsageSamplers>(m_iconicFont, m_implot,
stats::frameSamplers, stats::clusterAccelSamplers, stats::evaluatorSamplers, stats::memUsageSamplers);
if (stats::evaluatorSamplers.m_topologyQualityButtonPressed)
{
renderer.SetColorMode(ColorMode::COLOR_BY_TOPOLOGY);
}
float profilerWidth = m_profiler.controllerWindow.size.x;
float timelineWidth = float(screenLayoutSize.x) - 30.f - profilerWidth;
BuildUITimeline(screenLayoutSize, timelineWidth);
BuildMemoryWarning(screenLayoutSize);
}
void UserInterface::BuildMemoryWarning(int2 screenLayoutSize)
{
auto& stats = GetApp().m_BuildStats;
bool clusterCountExceeded = stats.desired.m_numClusters > stats.allocated.m_numClusters;
bool clasMemoryExceeded = stats.desired.m_clasSize > stats.allocated.m_clasSize;
bool vertexMemoryExceeded = stats.desired.m_vertexBufferSize > stats.allocated.m_vertexBufferSize;
bool vertexNormalsMemoryExceeded = stats.desired.m_vertexNormalsBufferSize > stats.allocated.m_vertexNormalsBufferSize;
if (!clusterCountExceeded && !clasMemoryExceeded && !vertexMemoryExceeded && !vertexNormalsMemoryExceeded)
return;
ImVec2 overlayPos(screenLayoutSize.x * 0.5f, 10.0f); // Center X, 10px from the top
ImVec2 overlayPivot(0.5f, 0.0f); // Center horizontally, stick to the top
ImGui::SetNextWindowPos(overlayPos, ImGuiCond_Always, overlayPivot);
ImGui::PushStyleColor(ImGuiCol_WindowBg, IM_COL32(128, 0, 0, 200)); // Dark red
ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(255, 255, 255, 255)); // White text
ImGui::Begin("Memory Exceeded", nullptr, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove |
ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_AlwaysAutoResize);
ImGui::PushFont(m_nvidiaBldFont);
ImGui::Text("Tessellation memory budget exceeded");
ImGui::PopFont();
ImGui::Text("Expect flickering. Increase memory budget in settings");
if (clasMemoryExceeded)
{
char bufDesired[64];
char bufAllocated[64];
MemoryFormatter(stats.desired.m_clasSize, bufDesired, sizeof(bufDesired));
MemoryFormatter(stats.allocated.m_clasSize, bufAllocated, sizeof(bufDesired));
ImGui::Text("CLAS %s / %s", bufDesired, bufAllocated);
}
if (clusterCountExceeded)
{
char bufDesired[64];
char bufAllocated[64];
HumanFormatter(stats.desired.m_numClusters, bufDesired, sizeof(bufDesired));
HumanFormatter(stats.allocated.m_numClusters, bufAllocated, sizeof(bufDesired));
ImGui::Text("Cluster Count %s/%s", bufDesired, bufAllocated);
MemoryFormatter(stats.desired.m_clusterDataSize, bufDesired, sizeof(bufDesired));
MemoryFormatter(stats.allocated.m_clusterDataSize, bufAllocated, sizeof(bufDesired));
ImGui::Text("Cluster Data %s/%s", bufDesired, bufAllocated);
}
if (vertexMemoryExceeded)
{
char bufDesired[64];
char bufAllocated[64];
MemoryFormatter(stats.desired.m_vertexBufferSize, bufDesired, sizeof(bufDesired));
MemoryFormatter(stats.allocated.m_vertexBufferSize, bufAllocated, sizeof(bufDesired));
ImGui::Text("Vertex Buffer %s / %s", bufDesired, bufAllocated);
}
if (vertexNormalsMemoryExceeded)
{
char bufDesired[64];
char bufAllocated[64];
MemoryFormatter(stats.desired.m_vertexNormalsBufferSize, bufDesired, sizeof(bufDesired));
MemoryFormatter(stats.allocated.m_vertexNormalsBufferSize, bufAllocated, sizeof(bufDesired));
ImGui::Text("Vertex Normals Buffer %s / %s", bufDesired, bufAllocated);
}
ImGui::End();
ImGui::PopStyleColor(2); // Restore previous colors
}
void UserInterface::BuildUITimeline(int2 screenLayoutSize, float timelineWidth)
{
auto& state = GetApp().GetUIData().timeLineEditorState;
if (state.frameRate == 0.0f || (state.frameRange.y - state.frameRange.x) == 0)
return;
float tw = timelineWidth;
ImGui::SetNextWindowPos(ImVec2(tw + 10.f, float(screenLayoutSize.y) - 10.f), 0,
ImVec2(1.f, 1.f));
ImGui::SetNextWindowSize(ImVec2(tw, 0.f));
ImGui::SetNextWindowBgAlpha(.65f);
if (ImGui::Begin("TimeLine Editor", nullptr,
ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoDecoration |
ImGuiWindowFlags_NoTitleBar))
{
if (BuildTimeLineEditor(state, float2(tw, 0.f)))
{
}
}
ImGui::End();
}
void UserInterface::BuildUIEnvmap(ImVec2 itemSize)
{
auto& renderer = m_app.GetRenderer();
if (ImGui::CollapsingHeader("Environment Map", ImGuiTreeNodeFlags_DefaultOpen))
{
if (renderer.GetEffectiveShadingMode() == ShadingMode::PT)
{
ImGui::PushFont(m_iconicFont);
if (ImGui::Button((char const*)(u8"\ue06b" "## env map"), { 0.f, itemSize.y }))
{
if (FileDialog(true, "All files\0*.*\0EXR files\0*.exr\0HDR files\0*.hdr\0\0", GetApp().GetUIData().envmapFilepath))
{
const std::string filePath = GetApp().GetUIData().envmapFilepath;
if (!filePath.empty())
m_app.SetEnvmapTex(filePath);
}
}
ImGui::PopFont();
ImGui::SameLine();
float buttonWidth = ImGui::GetItemRectSize().x + ImGui::GetStyle().ItemSpacing.x;
ImGui::SetNextItemWidth(kItemWidth - buttonWidth);
std::shared_ptr<engine::LoadedTexture> envmap = renderer.GetEnvMap();
GetApp().GetUIData().envmapFilepath = "";
GetApp().GetUIData().envmap = envmap;
if (envmap)
{
GetApp().GetUIData().envmapFilepath = envmap->path;
}
char buf[1024] = { 0 };
if (renderer.GetEnvMap() != nullptr)
{
std::strncpy(buf, renderer.GetEnvMap()->path.c_str(), std::size(buf));
}
if (ImGui::InputText("Env Map", buf, std::size(buf), ImGuiInputTextFlags_EnterReturnsTrue))
{
if (m_app.SetEnvmapTex(std::string(buf)))
GetApp().GetUIData().envmapFilepath = buf;
}
if (ImGui::IsItemHovered() && ImGui::GetCurrentContext()->HoveredIdTimer > .5f && !GetApp().GetUIData().envmapFilepath.empty())
ImGui::SetTooltip("Path to HDR environment map.");
if (renderer.GetEnvMap() != nullptr)
{
static const char* debugGlyph = (char*)(u8"\ue028" "## envmap debug");
bool debugView = !GetApp().GetUIData().envmapFilepath.empty() && renderer.GetEnableEnvmapHeatmap();
ImGui::SameLine();
if (debugView)
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1.f, 0.f, 0.f, 1.f));
ImGui::PushFont(m_iconicFont);
if (ImGui::Button(debugGlyph, { 20.f, itemSize.y }))
{
renderer.SetEnableEnvmapHeatmap(!debugView);
}
if (debugView)
ImGui::PopStyleColor();
ImGui::PopFont();
if (ImGui::IsItemHovered() && ImGui::GetCurrentContext()->HoveredIdTimer > .5f)
ImGui::SetTooltip("Heatmap of The Envmap Impostance Sampling.");
float intensity = renderer.GetEnvMapIntensity();
if (ImGui::SliderFloat("Intensity", &intensity, .001f, 2.f))
{
renderer.SetEnvMapIntensity(intensity);
}
if (ImGui::IsItemHovered() && m_imgui->HoveredIdTimer > .5f)
ImGui::SetTooltip("Intensity Scale");
float azimuth = 180.f * renderer.GetEnvMapAzimuth() / M_PIf;
if (ImGui::SliderFloat("Azimuth", &azimuth, 0.f, 360.f))
{
renderer.SetEnvMapAzimuth((azimuth / 180.f) * M_PIf);
}
if (ImGui::IsItemHovered() && m_imgui->HoveredIdTimer > .5f)
ImGui::SetTooltip("Rotation Around Y Axis");
float elevation = 180.f * renderer.GetEnvMapElevation() / M_PIf;
if (ImGui::SliderFloat("Elevation", &elevation, -90.f, 90.f))
{
renderer.SetEnvMapElevation((elevation / 180.f) * M_PIf);
}
if (ImGui::IsItemHovered() && m_imgui->HoveredIdTimer > .5f)
ImGui::SetTooltip("Rotation Around X Axis");
}
else
{
BuildMissColorUI();
}
}
else
{
BuildMissColorUI();
}
}
}
void UserInterface::BuildMissColorUI()
{
auto& renderer = m_app.GetRenderer();
float3 missColor = renderer.GetMissColor();
if (ImGui::ColorEdit3("Miss Color", &missColor.x, ImGuiColorEditFlags_Float | ImGuiColorEditFlags_PickerHueWheel))
{
renderer.SetMissColor(missColor);
}
}
void UserInterface::Animate(float elapsedTimeSeconds)
{
ImGui_Renderer::Animate(elapsedTimeSeconds);
if (GetApp().GetUIData().timeLineEditorState.IsPlaying())
{
GetApp().GetUIData().timeLineEditorState.Update(elapsedTimeSeconds);
}
}
bool UserInterface::CustomInit(std::shared_ptr<engine::ShaderFactory> shaderFactory)
{
// guaranteed to be called after first scene is loaded, so the attributes are available.
const RTXMGScene::Attributes& attrs = m_app.GetScene().GetAttributes();
SetAnimationRange(attrs.frameRange, attrs.frameRate);
if (!attrs.audio.empty())
SetupAudioVoice(attrs.audio, GetApp().GetUIData().audioStartTime = attrs.audioStartTime);
return Init(shaderFactory);
}
bool UserInterface::BuildTimeLineEditor(TimeLineEditorState& state,
float2 size)
{
assert(state.startTime <= state.endTime);
float fontScale = ImGui::GetIO().FontGlobalScale;
static float const buttonPanelWidth =
200 + fontScale * 230; // assumes a text font-m_size of ~ 14.f
bool result = false;
// current time slider
ImGui::SetNextItemWidth(
size.x -
buttonPanelWidth); // anchor the button panel to the right of the window
float currentTime = state.currentTime;
if (ImGui::SliderFloat("##Time", ¤tTime, state.startTime, state.endTime,
"%.3f s."))
{
state.currentTime = clamp(currentTime, state.startTime, state.endTime);
if (state.setTimeCallback)
state.setTimeCallback(state);
result = true;
}
ImVec2 sliderSize = ImGui::GetItemRectSize();
ImGui::SameLine();
// current frame number (editable)
ImGui::SetNextItemWidth(fontScale * 45.f);
float currentFrame = state.currentTime * state.frameRate;
if (ImGui::InputFloat("##CurrentFrame", ¤tFrame, 0.f, 0.f, "%.1f"))
{
state.currentTime =
clamp(currentFrame / state.frameRate, state.startTime, state.endTime);
if (state.setTimeCallback)
state.setTimeCallback(state);
result = true;
}
ImGui::SameLine();
if (ImGui::IsItemHovered())
ImGui::SetTooltip("Current frame of animation sequence.\n");
// start & end frame numbers (read-only)
float frameStart = state.startTime * state.frameRate;
ImGui::SetNextItemWidth(fontScale * 45.f);
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(.5f, .5f, .5f, 1.f));
ImGui::InputFloat("##FrameStart", &frameStart, 0.f, 0.f, "%.1f",
ImGuiInputTextFlags_ReadOnly);
ImGui::PopStyleColor();
ImGui::SameLine();
if (ImGui::IsItemHovered())
ImGui::SetTooltip("First frame of animation sequence.\n");
float frameEnd = state.endTime * state.frameRate;
ImGui::SetNextItemWidth(fontScale * 45.f);
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(.5f, .5f, .5f, 1.f));
ImGui::InputFloat("##FrameEnd", &frameEnd, 0.f, 0.f, "%.1f",
ImGuiInputTextFlags_ReadOnly);
ImGui::PopStyleColor();
ImGui::SameLine(0.f, 10.f);
if (ImGui::IsItemHovered())
ImGui::SetTooltip("Last frame of animation sequence.\n");
// playback media buttons
static const char* playGlyph = (char*)u8"\ue093";
static const char* pauseGlyph = (char*)u8"\ue092";
static const char* skip_backGlyph = (char*)u8"\ue097";
static const char* skip_fwdGlyph = (char*)u8"\ue098";
static const char* rewindGlyph = (char*)u8"\ue095";
static const char* fast_fwdGlyph = (char*)u8"\ue096";
static const char* repeatGlyph = (char*)u8"\ue08e";
ImGui::PushFont(m_iconicFont);
if (ImGui::Button(rewindGlyph, ImVec2(0.f, sliderSize.y)))
{
state.Rewind();
result = true;
}
ImGui::SameLine();
if (ImGui::Button(skip_backGlyph, ImVec2(0.f, sliderSize.y)))
{
state.StepBackward();
result = true;
}
ImGui::SameLine();
bool paused = state.IsPaused();
if (paused)
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1.f, 0.f, 0.f, 1.f));
if (ImGui::Button(paused ? playGlyph : pauseGlyph, { 0.f, sliderSize.y }))
{
state.PlayClicked();
}
if (paused)
ImGui::PopStyleColor();
ImGui::SameLine();
if (ImGui::Button(skip_fwdGlyph, ImVec2(0.f, sliderSize.y)))
{
state.StepForward();
result = true;
}
ImGui::SameLine();
if (ImGui::Button(fast_fwdGlyph, ImVec2(0.f, sliderSize.y)))
{
state.FastForward();
result = true;
}
ImGui::SameLine(0.f, 10.f);
bool loop = state.loop;
if (loop)
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(.03f, .08f, .3f, 1.f));
if (ImGui::Button(repeatGlyph, { 0.f, sliderSize.y }))
state.loop = !loop;
if (loop)
ImGui::PopStyleColor();
ImGui::PopFont();
if (ImGui::IsItemHovered())
ImGui::SetTooltip("Loop animation sequence.\n");
ImGui::SameLine(0.f, 10.f);
float frameRate = state.frameRate;
ImGui::SetNextItemWidth(fontScale * 40.f);
if (ImGui::InputFloat("##FrameRate", &frameRate, 0.f, 0.f, "%.1f"))
{
if (state.frameRange.y > state.frameRange.x && frameRate > 0)
{
state.startTime = float(state.frameRange.x) / frameRate;
state.endTime = float(state.frameRange.y) / frameRate;
}
else if (frameRate == 0.f)
{
state.startTime = float(state.frameRange.x);
state.endTime = float(state.frameRange.y);
}
state.frameRate = frameRate;
}
if (ImGui::IsItemHovered())
ImGui::SetTooltip("Animation frame rate (in frames per seconds).\n");
return result;
}
void UserInterface::LoadAsset(MediaAsset const& asset, std::string const& name,
int2 frameRange)
{
bool isSequence = asset.IsSequence();
const fs::path& mediapath = m_app.GetMediaPath();
std::string shapePath =
(mediapath /
(isSequence ? fs::path(asset.sequenceFormat) : fs::path(name)))
.generic_string();
m_app.HandleSceneLoad(shapePath, mediapath.generic_string(), frameRange);
const RTXMGScene::Attributes& attrs = m_app.GetScene().GetAttributes();
SetAnimationRange(attrs.frameRange, attrs.frameRate);
if (!attrs.audio.empty())
SetupAudioVoice(attrs.audio, GetApp().GetUIData().audioStartTime = attrs.audioStartTime);
else
SetupAudioVoice(asset.wavePath, GetApp().GetUIData().audioStartTime = asset.waveStartTime);
GetApp().GetUIData().showRecommendationWindow = true;
GetApp().GetUIData().currentAsset = &asset;
}
void UserInterface::SetAnimationRange(int2 frameRange, float frameRate)
{
float startTime = 0.f;
float endTime = 0.f;
if (frameRange.y > frameRange.x)
{
startTime = float(frameRange.x) / frameRate;
endTime = float(frameRange.y) / frameRate;
}
else
{
assert(frameRate == 0.f);
startTime = endTime = frameRate = 0.f;
}
auto& editor = GetApp().GetUIData().timeLineEditorState;
editor.frameRange = frameRange;
editor.startTime = startTime;
editor.endTime = endTime;
editor.currentTime = startTime;
editor.frameRate = frameRate;
}
// null-terminated array of filter strings
std::array<char const*, 4> UIData::formatFilters() const
{
std::array<char const*, 4> filters;
std::fill(filters.begin(), filters.end(), nullptr);
int idx = 0;
if (includeJsonAssets)
filters[idx++] = ".json";
if (includeObjAssets)
filters[idx++] = ".obj";
//Future: include unstructured assets
//if (includeEddAssets)
// filters[idx++] = ".eddbin";
assert(filters.back() == nullptr);
return filters;
}
std::array<char const*, 5> UIData::folderFilters() const
{
std::array<char const*, 5> filters;
std::fill(filters.begin(), filters.end(), nullptr);
int idx = 0;
// Unused: way to filter which scenes are excluded from the scene selector
// Example of use (exclude any files that include "do_not_show" in their path:
// if (!includePrivateAssets)
// filters[idx++] = "do_not_show";
assert(filters.back() == nullptr);
return filters;
}
static inline bool isFolderFiltered(fs::path const& p,
char const* const* filters)
{
for (char const* const* filter = filters; *filter != nullptr; ++filter)
if (p.generic_string().find(*filter) != std::string::npos)
return true;
return false;
}
static inline bool isFormatFiltered(fs::path const& ext,
char const* const* filters)
{
for (char const* const* filter = filters; *filter != nullptr; ++filter)
if (ext == *filter)
return true;
return false;
}
static void postProcessMediaAssets(MediaAssetsMap& assets)
{
for (auto& asset : assets)
{
if (asset.first.find("barbarian") != std::string::npos)
{
asset.second.frameRate = 30.f;
}
else if (asset.first.find("rain_restaurant") != std::string::npos)
{
// Amy's monologue starts around frame 75, and we need to cut
// some silence at the beginning.
asset.second.waveStartTime = (100.f / 24.f) - 1.083f;
}
}
}
MediaAssetsMap
UserInterface::FindMediaAssets(fs::path const& mediapath,
char const* const* folderFilters,
char const* const* formatFilters)
{
auto ToInt = [](std::string_view str) -> std::optional<int>
{
int value = 0;
if (std::from_chars(str.data(), str.data() + str.size(), value).ec ==
std::errc{})
return value;
return {};
};
auto IsPadded = [](std::string_view digits) { return digits[0] == '0'; };
auto GetSequenceStr = [](std::string const& str) -> std::string_view
{
if (auto last = std::find_if(str.rbegin(), str.rend(), ::isdigit);
last != str.rend())
if (auto first = std::find_if(last, str.rend(),
[](char c) { return !std::isdigit(c); });
first != str.rend())
return { first.base(), last.base() };
return {};
};
if (!fs::is_directory(mediapath))
return {};
MediaAssetsMap assets;
auto InsertAsset = [&mediapath, &assets](fs::path const& rp,
std::string const& name = {})
{
auto [it, success] =
assets.insert({ name.empty() ? rp.generic_string() : name, {} });
assert(success);
it->second.name = it->first;
return it;
};
auto opts = std::filesystem::directory_options::follow_directory_symlink;
for (auto it = fs::recursive_directory_iterator(mediapath, opts);
it != fs::recursive_directory_iterator(); ++it)
{
if (it->is_directory() && isFolderFiltered(it->path(), folderFilters))
it.disable_recursion_pending();
if (!isFormatFiltered(it->path().extension(), formatFilters))
{
continue;
}
fs::path rp = fs::relative(it->path(), mediapath).lexically_normal();
std::string stem = rp.stem().generic_string();
if (std::string_view seq = GetSequenceStr(stem); !seq.empty())
{
auto number = ToInt(seq);
if (!number)
continue;
std::string name =
(rp.parent_path() / std::string_view(stem.data(), seq.data()))
.generic_string();
auto it = assets.find(name);
if (it == assets.end())
{
it = InsertAsset(rp, name);
}
if (IsPadded(seq))
it->second.padding = std::max(it->second.padding, (int)seq.size());
it->second.type = MediaAsset::Type::OBJ_SEQUENCE;
it->second.GrowFrameRange(*number);
}
else
{
InsertAsset(rp);
}
}
for (auto it = assets.begin(); it != assets.end();)
{
auto& asset = *it;
if (asset.second.IsSequence())
{
char buf[1024];
if (asset.second.frameRange.x < asset.second.frameRange.y)
{
std::snprintf(buf, std::size(buf), "%s[%d-%d].obj", asset.first.c_str(),
asset.second.frameRange.x, asset.second.frameRange.y);
asset.second.sequenceName = buf;
if (asset.second.padding > 0)
std::snprintf(buf, std::size(buf), "%s%%0%dd.obj",
asset.first.c_str(), asset.second.padding);
else
std::snprintf(buf, std::size(buf), "%s%%d.obj", asset.first.c_str());
asset.second.sequenceFormat = buf;
asset.second.frameRate = 24.f;
// check for a wave audio file
std::snprintf(buf, std::size(buf), "%s%d.wav", asset.first.c_str(),
asset.second.frameRange.x);
if (fs::is_regular_file(mediapath / buf))
it->second.wavePath = buf;
it = std::next(it);
}
else // WAR for a single obj file whose name ends in a number being
// mistaken for an animation keyframe
{
std::snprintf(buf, std::size(buf), "%s%d.obj", asset.first.c_str(),
asset.second.frameRange.x);
MediaAsset asset = { .frameRange = {0, 0}, .frameRate = 0.f };
std::swap(assets[buf], asset);
it = assets.erase(it);
gitextract_4m5g8eoe/
├── .editorconfig
├── .gitattributes
├── .gitignore
├── .gitlab-ci.yml
├── .gitmodules
├── CHANGELOG.md
├── CMake/
│ ├── FetchDXC.cmake
│ ├── FetchImplot.cmake
│ └── FetchNVAPI.cmake
├── CMakeLists.txt
├── LICENSE.txt
├── README.md
├── demo/
│ ├── CMakeLists.txt
│ ├── args.cpp
│ ├── args.h
│ ├── audio/
│ │ ├── CMakeLists.txt
│ │ ├── audio.cpp
│ │ ├── audio.h
│ │ ├── waveFile.cpp
│ │ ├── waveFile.h
│ │ └── xaudiofaudio.h
│ ├── blit_params.h
│ ├── envmap/
│ │ ├── CMakeLists.txt
│ │ ├── preprocess_envmap.h
│ │ ├── preprocess_envmap_params.h
│ │ ├── scan_system.cpp
│ │ ├── scan_system.h
│ │ ├── scan_system_shared.h
│ │ ├── shaders/
│ │ │ ├── compute_conditional.hlsl
│ │ │ ├── compute_marginal.hlsl
│ │ │ ├── envmap.hlsli
│ │ │ └── prefix_scan.hlsl
│ │ └── shaders.cfg
│ ├── gbuffer.h
│ ├── gui.cpp
│ ├── gui.h
│ ├── gui_fonts.cpp
│ ├── korgi.cpp
│ ├── korgi.h
│ ├── lerp_keyframes_params.h
│ ├── lighting_cb.h
│ ├── maya_logger.cpp
│ ├── maya_logger.h
│ ├── motion_vectors_params.h
│ ├── ray_payload.h
│ ├── render_params.h
│ ├── render_targets.cpp
│ ├── render_targets.h
│ ├── rtxmg_demo.cpp
│ ├── rtxmg_demo.h
│ ├── rtxmg_demo_app.cpp
│ ├── rtxmg_demo_app.h
│ ├── rtxmg_renderer.cpp
│ ├── rtxmg_renderer.h
│ ├── shaders/
│ │ ├── blit.hlsl
│ │ ├── brdf.hlsli
│ │ ├── color.hlsli
│ │ ├── lerp_keyframes.hlsl
│ │ ├── motion_vectors.hlsl
│ │ ├── rtxmg_demo_path_tracer.hlsl
│ │ ├── self_intersection_avoidance.hlsli
│ │ ├── utils.hlsli
│ │ └── zrender.hlsl
│ ├── shaders.cfg
│ ├── trackball.cpp
│ ├── trackball.h
│ ├── zrender_params.h
│ ├── zrenderer.cpp
│ └── zrenderer.h
├── docs/
│ └── QuickStart.md
├── extern/
│ ├── CMakeLists.txt
│ └── nrd.cfg
├── notice.txt
├── rtxmg/
│ ├── CMakeLists.txt
│ ├── cluster_builder/
│ │ ├── CMakeLists.txt
│ │ ├── cluster_accel_builder.cpp
│ │ ├── shaders/
│ │ │ ├── compute_cluster_tiling.hlsl
│ │ │ ├── copy_cluster_offset.hlsl
│ │ │ ├── fill_blas_from_clas_args.hlsl
│ │ │ ├── fill_clusters.hlsl
│ │ │ ├── fill_instance_descs.hlsl
│ │ │ └── fill_instantiate_template_args.hlsl
│ │ └── shaders.cfg
│ ├── hiz/
│ │ ├── CMakeLists.txt
│ │ ├── hiz_buffer.cpp
│ │ ├── shaders/
│ │ │ ├── hiz_display.hlsl
│ │ │ ├── hiz_pass1.hlsl
│ │ │ ├── hiz_pass2.hlsl
│ │ │ ├── zbuffer_display.hlsl
│ │ │ └── zbuffer_minmax.hlsl
│ │ ├── shaders.cfg
│ │ └── zbuffer.cpp
│ ├── include/
│ │ └── rtxmg/
│ │ ├── cluster_builder/
│ │ │ ├── cluster.h
│ │ │ ├── cluster_accel_builder.h
│ │ │ ├── cluster_accels.h
│ │ │ ├── compute_cluster_tiling_params.h
│ │ │ ├── copy_cluster_offset_params.h
│ │ │ ├── displacement.hlsli
│ │ │ ├── fill_blas_from_clas_args_params.h
│ │ │ ├── fill_clusters_params.h
│ │ │ ├── fill_instance_descs_params.h
│ │ │ ├── fill_instantiate_template_args_params.h
│ │ │ ├── tessellation_counters.h
│ │ │ ├── tessellator_config.h
│ │ │ ├── tessellator_constants.h
│ │ │ └── tilings.h
│ │ ├── hiz/
│ │ │ ├── hiz_buffer.h
│ │ │ ├── hiz_buffer_constants.h
│ │ │ ├── hiz_buffer_display_params.h
│ │ │ ├── hiz_buffer_reduce_params.h
│ │ │ └── zbuffer.h
│ │ ├── profiler/
│ │ │ ├── gui.h
│ │ │ ├── profiler.h
│ │ │ ├── sampler.h
│ │ │ ├── statistics.h
│ │ │ └── stopwatch.h
│ │ ├── scene/
│ │ │ ├── box_extent.h
│ │ │ ├── camera.h
│ │ │ ├── json.h
│ │ │ ├── model.h
│ │ │ ├── obj_importer.h
│ │ │ ├── scene.h
│ │ │ └── string_utils.h
│ │ ├── subdivision/
│ │ │ ├── far.h
│ │ │ ├── osd_ports/
│ │ │ │ └── tmr/
│ │ │ │ ├── nodeDescriptor.h
│ │ │ │ ├── subdivisionNode.h
│ │ │ │ ├── surfaceDescriptor.h
│ │ │ │ ├── treeDescriptor.h
│ │ │ │ └── types.h
│ │ │ ├── patch_param.h
│ │ │ ├── segmented_vector.h
│ │ │ ├── shape.h
│ │ │ ├── subdivision_eval.hlsli
│ │ │ ├── subdivision_plan_hlsl.h
│ │ │ ├── subdivision_surface.h
│ │ │ ├── topology_cache.h
│ │ │ ├── topology_map.h
│ │ │ └── vertex.h
│ │ └── utils/
│ │ ├── box3.h
│ │ ├── buffer.h
│ │ ├── constants.h
│ │ ├── debug.h
│ │ ├── formatters.h
│ │ ├── shader_debug.h
│ │ └── vectorlog.h
│ ├── profiler/
│ │ ├── CMakeLists.txt
│ │ ├── gui.cpp
│ │ ├── profiler.cpp
│ │ ├── statistics.cpp
│ │ └── stopwatch.cpp
│ ├── scene/
│ │ ├── CMakeLists.txt
│ │ ├── box_extent.cpp
│ │ ├── camera.cpp
│ │ ├── json.cpp
│ │ ├── obj_importer.cpp
│ │ ├── scene.cpp
│ │ └── string_utils.cpp
│ ├── subdivision/
│ │ ├── CMakeLists.txt
│ │ ├── shape.cpp
│ │ ├── subdivision_surface.cpp
│ │ ├── topology_cache.cpp
│ │ └── topology_map.cpp
│ └── utils/
│ ├── CMakeLists.txt
│ ├── buffer.cpp
│ ├── csvdump.cpp
│ ├── debug.cpp
│ └── formatters.cpp
├── rtxmg_static_analysis.props
├── rtxmg_static_analysis.ruleset
├── shadertoolsconfig.json
└── tools/
└── set_vs_vars.ps1
SYMBOL INDEX (380 symbols across 97 files)
FILE: demo/args.cpp
function printUsageAndExit (line 45) | static void printUsageAndExit(const char* argv0,
function parseBooleanArg (line 103) | static bool parseBooleanArg(char const* token,
function Args (line 347) | Args& operator << (Args& args, const Json::Value& node)
FILE: demo/args.h
type SceneArgs (line 54) | struct SceneArgs
function SceneArgs (line 83) | struct Args : SceneArgs
FILE: demo/audio/audio.cpp
type audio (line 18) | namespace audio {
FILE: demo/audio/audio.h
function namespace (line 20) | namespace donut::vfs
function namespace (line 25) | namespace audio {
FILE: demo/audio/waveFile.cpp
function readFile (line 12) | static std::vector<uint8_t> readFile(fs::path const& m_filepath) {
type audio (line 34) | namespace audio {
type WaveFile::Chunk (line 36) | struct WaveFile::Chunk{
type WaveFile::Header (line 45) | struct WaveFile::Header {
method validate (line 49) | inline bool validate() const {
FILE: demo/audio/waveFile.h
function namespace (line 13) | namespace audio {
FILE: demo/audio/xaudiofaudio.h
type FAudioBuffer (line 15) | typedef FAudioBuffer XAUDIO2_BUFFER;
type FAudioBufferWMA (line 16) | typedef FAudioBufferWMA XAUDIO2_BUFFER_WMA;
type FAudioVoiceSends (line 17) | typedef FAudioVoiceSends XAUDIO2_VOICE_SENDS;
type FAudioVoiceState (line 18) | typedef FAudioVoiceState XAUDIO2_VOICE_STATE;
type FAudioSendDescriptor (line 19) | typedef FAudioSendDescriptor XAUDIO2_SEND_DESCRIPTOR;
type FAudioEffectChain (line 20) | typedef FAudioEffectChain XAUDIO2_EFFECT_CHAIN;
type FAudioProcessor (line 21) | typedef FAudioProcessor XAUDIO2_PROCESSOR;
type FAudioWaveFormatEx (line 22) | typedef FAudioWaveFormatEx WAVEFORMATEX;
type FAudioVoiceCallback (line 23) | typedef FAudioVoiceCallback IXAudio2VoiceCallback;
type HRESULT (line 42) | typedef uint32_t HRESULT;
type BYTE (line 43) | typedef uint8_t BYTE;
function class (line 55) | class IXAudio2MasteringVoice
function class (line 75) | class IXAudio2SourceVoice
function HRESULT (line 94) | HRESULT FlushSourceBuffers() { return FAudioSourceVoice_FlushSourceBuffe...
function class (line 101) | class IXAudio2
FILE: demo/blit_params.h
type BlitParams (line 33) | struct BlitParams
FILE: demo/envmap/preprocess_envmap.h
type PreprocessEnvMapShaders (line 29) | struct PreprocessEnvMapShaders
type PreprocessEnvMapResources (line 37) | struct PreprocessEnvMapResources
FILE: demo/envmap/preprocess_envmap_params.h
type PreprocessEnvMapParams (line 26) | struct PreprocessEnvMapParams
FILE: demo/envmap/scan_system.h
type ScanSystem (line 31) | struct ScanSystem
FILE: demo/envmap/scan_system_shared.h
type PrefixScanParams (line 33) | struct PrefixScanParams
FILE: demo/gbuffer.h
type DepthFormat (line 32) | typedef float DepthFormat;
type float4 (line 33) | typedef float4 NormalFormat;
type float4 (line 34) | typedef float4 AlbedoFormat;
type float4 (line 35) | typedef float4 SpecularFormat;
type SpecularHitTFormat (line 36) | typedef float SpecularHitTFormat;
type RoughnessFormat (line 37) | typedef float RoughnessFormat;
type HitResult (line 42) | struct HitResult
function HitResult (line 51) | HitResult DefaultHitResult()
FILE: demo/gui.cpp
type Settings (line 119) | struct Settings
function ImGuiComboFromArray (line 264) | static int ImGuiComboFromArray(const char* name, E* selected, const std:...
function isFolderFiltered (line 1585) | static inline bool isFolderFiltered(fs::path const& p,
function isFormatFiltered (line 1594) | static inline bool isFormatFiltered(fs::path const& ext,
function postProcessMediaAssets (line 1603) | static void postProcessMediaAssets(MediaAssetsMap& assets)
function MediaAssetsMap (line 1619) | MediaAssetsMap
function ImFont (line 1760) | ImFont* UserInterface::AddFontFromMemoryCompressedBase85TTF(
FILE: demo/gui.h
type GLFWindow (line 43) | struct GLFWindow
function namespace (line 49) | namespace audio
type MediaAsset (line 56) | struct MediaAsset
function GrowFrameRange (line 86) | void GrowFrameRange(int frame)
type std (line 93) | typedef std::map<std::string, MediaAsset> MediaAssetsMap;
type TimeLineEditorState (line 95) | struct TimeLineEditorState
function class (line 102) | class Playback : uint8_t { Pause = 0, Play }
function SetFrame (line 121) | inline void SetFrame(float time)
function StepForward (line 125) | inline void StepForward()
function StepBackward (line 131) | inline void StepBackward()
function Rewind (line 137) | inline void Rewind()
function FastForward (line 143) | inline void FastForward()
function PlayClicked (line 150) | inline void PlayClicked()
type UIData (line 164) | struct UIData
function class (line 218) | class UserInterface : public donut::app::ImGui_Renderer
FILE: demo/korgi.cpp
type korgi (line 29) | namespace korgi
type Controller (line 43) | struct Controller
method AddHook (line 45) | void AddHook(unsigned char controlChannel, Knob* pParam)
method AddHook (line 50) | void AddHook(unsigned char controlChannel, Button* pParam)
method Init (line 56) | bool Init()
method Shutdown (line 64) | void Shutdown()
method Update (line 69) | void Update()
method Controller (line 100) | static Controller* Get()
method MidiInCallback (line 110) | static void CALLBACK MidiInCallback(HMIDIIN hMidiIn, UINT wMsg, DWOR...
method HandleMidiInput (line 122) | void HandleMidiInput(unsigned char controlChannel, unsigned char mid...
method OpenMidiDevice (line 179) | bool OpenMidiDevice()
method CloseMidiDevice (line 213) | void CloseMidiDevice()
method ClearAllLeds (line 222) | void ClearAllLeds()
method SetAllLeds (line 232) | void SetAllLeds()
method SetLedStatus (line 248) | void SetLedStatus(unsigned char controlChannel, Button* pButton)
function Init (line 284) | void Init()
function Shutdown (line 288) | void Shutdown()
function Update (line 292) | void Update()
FILE: demo/korgi.h
function Init (line 77) | static inline void Init() {}
function Shutdown (line 78) | static inline void Shutdown() {}
function Update (line 79) | static inline void Update() {}
type class (line 99) | enum class
function Control (line 108) | enum class Control : unsigned char
FILE: demo/lerp_keyframes_params.h
type LerpKeyFramesParams (line 32) | struct LerpKeyFramesParams
FILE: demo/lighting_cb.h
type LightingConstants (line 29) | struct LightingConstants
FILE: demo/maya_logger.cpp
function newLine (line 24) | inline void newLine(FILE* m_fp, uint32_t i)
function fillVectorAttr (line 30) | static void fillVectorAttr(FILE* m_fp,
function setVectorAttr (line 43) | static void setVectorAttr(FILE* m_fp,
function writeHeader (line 61) | void writeHeader(FILE* m_fp, uint32_t mayaVersion = 2023)
function writeFooter (line 70) | void writeFooter(FILE* m_fp, char const* m_filepath)
function createNode (line 75) | static void createNode(FILE* m_fp, char const* type, char const* name, c...
function createTransformNode (line 83) | static void createTransformNode(FILE* m_fp, char const* name, char const...
function createParticleNode (line 88) | static void createParticleNode(FILE* m_fp, char const* name, char const*...
function setParticleIDs (line 110) | static void setParticleIDs(FILE* m_fp, uint32_t nparticles)
function addParticleColorAttr (line 122) | static void addParticleColorAttr(FILE* m_fp,
function addParticleColorAttr (line 135) | static void addParticleColorAttr(FILE* m_fp,
function addParticlePositionAttr (line 148) | static void addParticlePositionAttr(FILE* m_fp, std::vector<float3> cons...
FILE: demo/maya_logger.h
function class (line 15) | class MayaLogger
FILE: demo/ray_payload.h
type RayPayload (line 26) | struct RayPayload
type TestPayload (line 43) | struct TestPayload
type ShadowRayPayload (line 56) | struct ShadowRayPayload
FILE: demo/render_params.h
type CameraConstants (line 40) | struct CameraConstants
type RenderParams (line 130) | struct RenderParams
type SubdInstance (line 180) | struct SubdInstance
FILE: demo/render_targets.h
function class (line 33) | class RenderTargets
FILE: demo/rtxmg_demo.cpp
function main (line 44) | int main(int argc, const char** argv)
function WinMain (line 100) | int WinMain(_In_ HINSTANCE hInstance,
FILE: demo/rtxmg_demo.h
type class (line 24) | enum class
type class (line 26) | enum class
type class (line 43) | enum class
type class (line 52) | enum class
type class (line 65) | enum class
type class (line 72) | enum class
FILE: demo/rtxmg_demo_app.cpp
function findDir (line 61) | static fs::path findDir(fs::path const& startPath, fs::path const& dirname,
function findMediaFolder (line 78) | static fs::path findMediaFolder(fs::path const& startdir, char const* di...
function RTXMGRenderer (line 277) | RTXMGRenderer& RTXMGDemoApp::GetRenderer()
FILE: demo/rtxmg_demo_app.h
function class (line 53) | class RTXMGDemoApp : public donut::app::ApplicationBase
FILE: demo/rtxmg_renderer.cpp
function VanDerCorput (line 763) | static float VanDerCorput(size_t base, size_t index)
FILE: demo/rtxmg_renderer.h
type uint16_t2 (line 56) | typedef vector<unsigned short, 2> uint16_t2;
type uint16_t4 (line 57) | typedef vector<unsigned short, 4> uint16_t4;
type Options (line 67) | struct Options
type class (line 73) | enum class
function Output (line 93) | enum class Output : uint32_t
FILE: demo/trackball.cpp
type KeyboardControls (line 39) | enum class KeyboardControls : uint8_t
type MouseButtons (line 57) | enum class MouseButtons : uint8_t { Left = 0, Middle, Right, Count }
function float3 (line 181) | float3 Trackball::GetCameraDirection() const
function float3 (line 202) | static inline float3 getUnitVector(int2 pos, int2 canvas)
FILE: demo/trackball.h
function class (line 41) | class Trackball
FILE: demo/zrender_params.h
type ZRenderParams (line 31) | struct ZRenderParams
type ZRayPayload (line 46) | struct ZRayPayload
FILE: demo/zrenderer.h
function class (line 48) | class ZRenderer
FILE: rtxmg/cluster_builder/cluster_accel_builder.cpp
function TemplateGrids (line 221) | static TemplateGrids GenerateTemplateGrids()
FILE: rtxmg/include/rtxmg/cluster_builder/cluster.h
type uint16_t2 (line 43) | typedef vector<unsigned short, 2> uint16_t2;
type uint16_t4 (line 44) | typedef vector<unsigned short, 4> uint16_t4;
function ClusterShape (line 52) | enum class ClusterShape
type Cluster (line 191) | struct Cluster
type ClusterShadingData (line 246) | struct ClusterShadingData
FILE: rtxmg/include/rtxmg/cluster_builder/cluster_accel_builder.h
type TopologyMap (line 55) | struct TopologyMap
function getYVerts (line 57) | struct TemplateGridDesc
type TemplateGrids (line 70) | struct TemplateGrids
function ShaderPermutationSurfaceType (line 84) | enum class ShaderPermutationSurfaceType : uint32_t
function class (line 163) | class FillClustersPermutation
function ShaderPermutationSurfaceType (line 189) | ShaderPermutationSurfaceType surfaceType() const
FILE: rtxmg/include/rtxmg/cluster_builder/cluster_accels.h
type ClusterAccels (line 44) | struct ClusterAccels
type ClusterStatistics (line 69) | struct ClusterStatistics
FILE: rtxmg/include/rtxmg/cluster_builder/compute_cluster_tiling_params.h
type ComputeClusterTilingParams (line 36) | struct ComputeClusterTilingParams
FILE: rtxmg/include/rtxmg/cluster_builder/copy_cluster_offset_params.h
type ClusterDispatchType (line 32) | enum ClusterDispatchType
type CopyClusterOffsetParams (line 41) | struct CopyClusterOffsetParams
FILE: rtxmg/include/rtxmg/cluster_builder/fill_blas_from_clas_args_params.h
type FillBlasFromClasArgsParams (line 36) | struct FillBlasFromClasArgsParams
FILE: rtxmg/include/rtxmg/cluster_builder/fill_clusters_params.h
type FillClustersParams (line 44) | struct FillClustersParams
FILE: rtxmg/include/rtxmg/cluster_builder/fill_instance_descs_params.h
type FillInstanceDescsParams (line 34) | struct FillInstanceDescsParams
FILE: rtxmg/include/rtxmg/cluster_builder/fill_instantiate_template_args_params.h
type FillInstantiateTemplateArgsParams (line 34) | struct FillInstantiateTemplateArgsParams
FILE: rtxmg/include/rtxmg/cluster_builder/tessellation_counters.h
type TessellationCounters (line 38) | struct TessellationCounters
FILE: rtxmg/include/rtxmg/cluster_builder/tessellator_config.h
type TessellatorConfig (line 31) | struct TessellatorConfig
function AdaptiveTessellationMode (line 55) | enum class AdaptiveTessellationMode
FILE: rtxmg/include/rtxmg/cluster_builder/tessellator_constants.h
function GetTemplateIndex (line 37) | uint32_t GetTemplateIndex(uint16_t2 clusterSize)
FILE: rtxmg/include/rtxmg/cluster_builder/tilings.h
function ClusterVertexCount (line 3) | struct ClusterTiling
function VertexCount (line 10) | inline uint32_t VertexCount() { return ClusterVertexCount() * ClusterCou...
function uint16_t2 (line 12) | inline uint16_t2 ClusterIndex2D(uint32_t rowMajorIndex)
function uint16_t2 (line 17) | inline uint16_t2 QuadOffset2D(uint32_t rowMajorIndex)
function uint2 (line 22) | inline uint2 VertexIndex2D(uint32_t rowMajorIndex)
function VertexCount (line 29) | struct SurfaceTiling
function uint16_t2 (line 58) | uint16_t2 inline ClusterOffset(uint16_t iTiling, uint32_t iCluster)
function SurfaceTiling (line 64) | inline SurfaceTiling MakeSurfaceTiling(uint16_t2 surfaceSize)
FILE: rtxmg/include/rtxmg/hiz/hiz_buffer.h
function class (line 44) | class HiZBuffer
FILE: rtxmg/include/rtxmg/hiz/hiz_buffer_display_params.h
type HiZDisplayParams (line 31) | struct HiZDisplayParams
FILE: rtxmg/include/rtxmg/hiz/hiz_buffer_reduce_params.h
type HiZReducePass1Params (line 31) | struct HiZReducePass1Params
FILE: rtxmg/include/rtxmg/hiz/zbuffer.h
function class (line 44) | class ZBuffer
FILE: rtxmg/include/rtxmg/profiler/gui.h
type ImPlotContext (line 37) | struct ImPlotContext
function class (line 42) | class ProfilerGUI
function dm (line 92) | inline dm::float2 MakeFloat2(const ImVec2& v)
function BuildUI (line 127) | void ProfilerGUI::BuildUI( ImFont *iconicFont, ImPlotContext *context, S...
FILE: rtxmg/include/rtxmg/profiler/profiler.h
type ImGuiContext (line 43) | struct ImGuiContext
function class (line 88) | class Profiler
function class (line 166) | class ScopedGPUTimer
FILE: rtxmg/include/rtxmg/profiler/sampler.h
function Print (line 70) | void Print()
FILE: rtxmg/include/rtxmg/profiler/statistics.h
function namespace (line 48) | namespace stats
type FrameSamplers (line 129) | struct FrameSamplers
type ClusterAccelSamplers (line 148) | struct ClusterAccelSamplers
type MemUsageSamplers (line 187) | struct MemUsageSamplers
FILE: rtxmg/include/rtxmg/profiler/stopwatch.h
function class (line 42) | class StopwatchCPU
function class (line 60) | class StopwatchGPU
FILE: rtxmg/include/rtxmg/scene/camera.h
function class (line 38) | class Camera
FILE: rtxmg/include/rtxmg/scene/json.h
function namespace (line 14) | namespace Json
FILE: rtxmg/include/rtxmg/scene/model.h
function GeometryType (line 31) | enum class GeometryType : uint8_t
FILE: rtxmg/include/rtxmg/scene/obj_importer.h
function namespace (line 35) | namespace donut::vfs
function namespace (line 40) | namespace donut::engine
function namespace (line 47) | namespace tf
function class (line 56) | class ObjImporter
FILE: rtxmg/include/rtxmg/scene/scene.h
type View (line 42) | struct View
type TextureType (line 50) | enum TextureType
function class (line 60) | class RTXMGScene : public Scene
FILE: rtxmg/include/rtxmg/scene/string_utils.h
function IsWhiteSpace (line 25) | inline bool IsWhiteSpace(char c)
function IsNewLine (line 30) | inline bool IsNewLine(char c) { return c == '\n'; }
function IsDigit (line 32) | inline bool IsDigit(char c) { return ((c >= '0') && (c <= '9')); }
function IsExponent (line 34) | inline bool IsExponent(char c) { return ((c == 'e') || (c == 'E')); }
FILE: rtxmg/include/rtxmg/subdivision/far.h
function Scheme (line 40) | inline Scheme
function OpenSubdiv (line 59) | inline OpenSubdiv::Sdc::SchemeType
function OpenSubdiv (line 78) | inline OpenSubdiv::Sdc::SchemeType GetSdcType(Shape const& shape)
function OpenSubdiv (line 83) | inline OpenSubdiv::Sdc::Options GetSdcOptions(Shape const& shape)
type OpenSubdiv (line 233) | typedef OpenSubdiv::Far::TopologyRefiner FarTopologyRefiner;
type OpenSubdiv (line 234) | typedef OpenSubdiv::Far::TopologyRefinerFactory<Shape>
function namespace (line 270) | namespace OpenSubdiv {
FILE: rtxmg/include/rtxmg/subdivision/osd_ports/tmr/nodeDescriptor.h
function GetType (line 30) | struct NodeDescriptor
function GetDepth (line 94) | uint32_t GetDepth() { return unpack(field0, 4, 3); }
function GetU (line 98) | uint32_t GetU() { return unpack(field0, 10, 12); }
function GetV (line 102) | uint32_t GetV() { return unpack(field0, 10, 22); }
function GetBoundaryMask (line 127) | uint32_t GetBoundaryMask() { return unpack(field0, 5, 7); }
function GetEvIndex (line 135) | uint32_t GetEvIndex() { return unpack(field0, 4, 8); }
function HasEndcap (line 140) | bool HasEndcap() { return unpack(field0, 1, 2) != 0; }
function HasSharpness (line 144) | bool HasSharpness() { return unpack(field0, 1, 2) != 0; }
function NodeDescriptor (line 149) | inline NodeDescriptor MakeNodeDescriptor(uint32_t value)
function SetRegular (line 156) | inline void NodeDescriptor::SetRegular(bool singleCrease, uint16_t depth...
function SetEnd (line 165) | inline void NodeDescriptor::SetEnd(uint16_t depth, uint16_t boundary, ui...
function SetRecursive (line 174) | inline void NodeDescriptor::SetRecursive(uint16_t depth, uint16_t u, uin...
function SetTerminal (line 183) | inline void NodeDescriptor::SetTerminal(uint16_t depth, uint16_t evIndex...
function GetBoundaryCount (line 194) | inline uint32_t NodeDescriptor::GetBoundaryCount()
function GetParamFraction (line 199) | inline float NodeDescriptor::GetParamFraction(bool regularFace)
function MapCoarseToRefined (line 205) | inline void NodeDescriptor::MapCoarseToRefined(inout float u, inout floa...
function MapRefinedToCoarse (line 214) | inline void NodeDescriptor::MapRefinedToCoarse(inout float u, inout floa...
FILE: rtxmg/include/rtxmg/subdivision/osd_ports/tmr/subdivisionNode.h
function catmarkRegularPatchSize (line 35) | struct SubdivisionNode
function catmarkTerminalPatchSize (line 47) | static int catmarkTerminalPatchSize() { return 25; }
function loopRegularPatchSize (line 48) | static int loopRegularPatchSize() { return 12; }
function regularNodeSize (line 51) | static int regularNodeSize(bool singleCrease) { return singleCrease ? 3 ...
function endCapNodeSize (line 52) | static int endCapNodeSize() { return 2; }
function terminalNodeSize (line 53) | static int terminalNodeSize() { return 3; }
function recursiveNodeSize (line 54) | static int recursiveNodeSize() { return 6; }
function getNumChildren (line 56) | static int getNumChildren(NodeType type)
function rootNodeOffset (line 66) | static int rootNodeOffset() { return 14; }
function descriptorOffset (line 69) | int descriptorOffset() { return m_nodeOffset; }
function sharpnessOffset (line 70) | int sharpnessOffset() { return m_nodeOffset + 2; }
function patchPointsOffset (line 71) | int patchPointsOffset() { return m_nodeOffset + 1; }
function childOffset (line 72) | int childOffset(int childIndex) { return m_nodeOffset + 2 + childIndex; }
function GetSharpness (line 74) | float GetSharpness()
function SubdivisionNode (line 79) | SubdivisionNode GetChild(int childIndex)
function NodeDescriptor (line 90) | NodeDescriptor GetDesc()
function GetPatchPointBase (line 95) | int GetPatchPointBase()
function Index (line 100) | Index GetPatchPoint(
FILE: rtxmg/include/rtxmg/subdivision/osd_ports/tmr/surfaceDescriptor.h
function Domain (line 28) | enum class Domain : uint16_t
function Set (line 72) | inline void LinearSurfaceDescriptor::Set(
function Index (line 80) | inline Index LinearSurfaceDescriptor::GetPatchPoint(int pointIndex, uint...
function Index (line 106) | inline Index LinearSurfaceDescriptor::GetPatchPoint(int pointIndex)
function Domain (line 111) | inline Domain LinearSurfaceDescriptor::getDomain(uint16_t faceSize, Loca...
type SurfaceDescriptor (line 155) | struct SurfaceDescriptor
function HasLimit (line 161) | bool HasLimit() { return unpack(field0, 1, 0); }
function GetParametricRotation (line 165) | uint16_t GetParametricRotation() { return (uint16_t)unpack(field0, 2, 1); }
function GetEdgeAdjacencyBits (line 167) | uint16_t GetEdgeAdjacencyBits() { return (uint16_t)unpack(field0, 4, 3); }
function GetEdgeAdjacencyBit (line 168) | bool GetEdgeAdjacencyBit(uint16_t edgeIndex) { uint16_t edgebits = (uint...
function GetTopologyMapIndex (line 170) | unsigned int GetTopologyMapIndex() { return unpack(field0, 5, 7); }
function GetSubdivisionPlanIndex (line 171) | unsigned int GetSubdivisionPlanIndex() { return unpack(field0, 20, 12); }
function Set (line 177) | inline void SurfaceDescriptor::Set(
FILE: rtxmg/include/rtxmg/subdivision/osd_ports/tmr/treeDescriptor.h
type TreeDescriptorHLSL (line 34) | struct TreeDescriptorHLSL
FILE: rtxmg/include/rtxmg/subdivision/osd_ports/tmr/types.h
function quantize (line 35) | inline float quantize(float a, uint32_t nbits)
function float3 (line 42) | inline float3 quantize(float3 v, uint32_t nbits)
type Index (line 51) | typedef int Index;
type LocalIndex (line 52) | typedef uint16_t LocalIndex;
function pack (line 59) | inline uint32_t pack(uint32_t value, uint32_t width, uint32_t offset)
function unpack (line 64) | inline uint32_t unpack(uint32_t value, uint32_t width, uint32_t offset)
type SchemeType (line 70) | enum SchemeType
type EndCapType (line 77) | enum EndCapType
type NodeType (line 85) | enum NodeType
type PatchDescriptorType (line 93) | enum PatchDescriptorType
FILE: rtxmg/include/rtxmg/subdivision/patch_param.h
function GetFaceId (line 148) | struct PatchParam
function GetU (line 178) | uint16_t GetU() { return (uint16_t)unpack(field1, 10, 22); }
function GetV (line 182) | uint16_t GetV() { return (uint16_t)unpack(field1, 10, 12); }
function GetTransition (line 185) | uint16_t GetTransition() { return (uint16_t)unpack(field0, 4, 28); }
function GetBoundary (line 188) | uint16_t GetBoundary() { return (uint16_t)unpack(field1, 5, 7); }
function NonQuadRoot (line 191) | bool NonQuadRoot() { return (unpack(field1, 1, 4) != 0); }
function GetDepth (line 194) | uint16_t GetDepth() { return (uint16_t)unpack(field1, 4, 0); }
function IsRegular (line 221) | bool IsRegular() { return (unpack(field1, 1, 5) != 0); }
function pack (line 226) | unsigned int pack(unsigned int value, int width, int offset)
function unpack (line 231) | unsigned int unpack(unsigned int value, int width, int offset)
function Set (line 237) | void PatchParam::Set(Index faceid, uint16_t u, uint16_t v,
function GetParamFraction (line 253) | float PatchParam::GetParamFraction()
function Normalize (line 258) | void PatchParam::Normalize(inout float u, inout float v)
function Unnormalize (line 267) | void PatchParam::Unnormalize(inout float u, inout float v)
function IsTriangleRotated (line 275) | bool PatchParam::IsTriangleRotated()
function NormalizeTriangle (line 280) | void PatchParam::NormalizeTriangle(inout float u, inout float v)
function UnnormalizeTriangle (line 296) | void PatchParam::UnnormalizeTriangle(inout float u, inout float v)
FILE: rtxmg/include/rtxmg/subdivision/segmented_vector.h
function Append (line 49) | void Append(const T* a_elements, uint32_t n_elements)
function Reserve (line 56) | void Reserve(size_t n)
function T (line 62) | T* Data() { return elements.data(); }
function Size (line 63) | size_t Size() { return elements.size(); }
FILE: rtxmg/include/rtxmg/subdivision/shape.h
type Scheme (line 35) | enum Scheme { kBilinear = 0, kCatmark, kLoop }
type Shape (line 37) | struct Shape
FILE: rtxmg/include/rtxmg/subdivision/subdivision_plan_hlsl.h
function SingleCreaseDynamicIsolation (line 39) | enum class SingleCreaseDynamicIsolation : uint16_t { SHARP = 0, SMOOTH =...
function GetEndCap (line 572) | struct SubdivisionPlanHLSL
function computeSingleCreaseSharpness (line 605) | float
function IsBSplinePatch (line 630) | struct SubdivisionPlanContext
function SubdivisionNode (line 651) | SubdivisionNode GetRootNode()
function SubdivisionNode (line 662) | SubdivisionNode GetNode(float2 uv, inout uint16_t quadrant, uint16_t level)
function SubdivisionNode (line 700) | SubdivisionNode EvaluateBasis(float2 st, out float wP[16], out float wDs...
function CubicBSplineWeight (line 767) | inline float CubicBSplineWeight(float t, uint32_t index)
function CubicBSplineDerivativeWeight (line 790) | inline float CubicBSplineDerivativeWeight(float t, uint32_t index)
FILE: rtxmg/include/rtxmg/subdivision/subdivision_surface.h
type Shape (line 33) | struct Shape
type TopologyMap (line 35) | struct TopologyMap
function class (line 37) | class SubdivisionSurface
FILE: rtxmg/include/rtxmg/subdivision/topology_cache.h
function class (line 52) | class TopologyCache
FILE: rtxmg/include/rtxmg/subdivision/topology_map.h
function namespace (line 40) | namespace OpenSubdiv::OPENSUBDIV_VERSION::Tmr
function namespace (line 44) | namespace stats
type TopologyMap (line 49) | struct TopologyMap
FILE: rtxmg/include/rtxmg/subdivision/vertex.h
function AddWithWeight (line 36) | struct LimitFrame
function AddWithWeight (line 59) | struct TexCoordLimitFrame
FILE: rtxmg/include/rtxmg/utils/box3.h
function Init (line 32) | struct Box3
function Include (line 53) | void Include(float3 p)
function float3 (line 59) | float3 Extent()
function Valid (line 64) | bool Valid()
FILE: rtxmg/include/rtxmg/utils/buffer.h
function nvrhi (line 36) | inline nvrhi::BufferHandle CreateBuffer(const nvrhi::BufferDesc& desc, n...
type T (line 92) | typedef T ElementType;
function operator (line 95) | operator nvrhi::IBuffer*() { return m_buffer.Get(); }
function Upload (line 127) | void Upload(const std::vector<T>& data, nvrhi::ICommandList* commandList...
function UploadElement (line 135) | void UploadElement(const T& data, uint32_t index, nvrhi::ICommandList* c...
FILE: rtxmg/include/rtxmg/utils/shader_debug.h
type ShaderDebugElement (line 34) | struct ShaderDebugElement
function _ShaderDebug (line 101) | struct ShaderDebugger
function _ShaderDebug (line 130) | void _ShaderDebug(uint4 value, uint lineNumber, uint payloadType, bool c...
function InitShaderDebugger (line 197) | static void InitShaderDebugger(RWStructuredBuffer<ShaderDebugElement> ou...
function InitShaderDebugger (line 204) | static void InitShaderDebugger(RWStructuredBuffer<ShaderDebugElement> ou...
function InitShaderDebugger (line 209) | static void InitShaderDebugger(RWStructuredBuffer<ShaderDebugElement> ou...
FILE: rtxmg/include/rtxmg/utils/vectorlog.h
function namespace (line 53) | namespace vectorlog
FILE: rtxmg/profiler/gui.cpp
function ImVec4 (line 51) | static ImVec4 heatmapColor( float value )
FILE: rtxmg/profiler/profiler.cpp
function Profiler (line 43) | Profiler& Profiler::Get()
function CPUTimer (line 59) | CPUTimer& Profiler::Timer<StopwatchCPU>::Resolve()
function GPUTimer (line 66) | GPUTimer& Profiler::Timer<StopwatchGPU>::Resolve()
function CPUTimer (line 74) | CPUTimer& Profiler::Timer<StopwatchCPU>::Profile()
function GPUTimer (line 84) | GPUTimer& Profiler::Timer<StopwatchGPU>::Profile()
FILE: rtxmg/profiler/statistics.cpp
type stats (line 45) | namespace stats {
type GraphMode (line 63) | enum class GraphMode : int {
FILE: rtxmg/scene/box_extent.cpp
function MaxBoxExtent (line 34) | float MaxBoxExtent(const box3& aabb)
FILE: rtxmg/scene/camera.cpp
function float4x4 (line 199) | float4x4 Camera::GetViewMatrix() const
function float4x4 (line 229) | float4x4 Camera::GetProjectionMatrix() const
function float4x4 (line 258) | float4x4 Camera::GetViewProjectionMatrix() const
FILE: rtxmg/scene/json.cpp
function readFile (line 11) | Json::Value readFile(const fs::path& m_filepath)
function int2 (line 89) | int2 read<int2>(const Json::Value& node, const int2& defaultValue)
function int3 (line 97) | int3 read<int3>(const Json::Value& node, const int3& defaultValue)
function int4 (line 105) | int4 read<int4>(const Json::Value& node, const int4& defaultValue)
function uint2 (line 136) | uint2 read<uint2>(const Json::Value& node, const uint2& defaultValue)
function uint3 (line 144) | uint3 read<uint3>(const Json::Value& node, const uint3& defaultValue)
function uint4 (line 152) | uint4 read<uint4>(const Json::Value& node, const uint4& defaultValue)
function float2 (line 168) | float2 read<float2>(const Json::Value& node, const float2& defaultValue)
function float3 (line 178) | float3 read<float3>(const Json::Value& node, const float3& defaultValue)
function float4 (line 188) | float4 read<float4>(const Json::Value& node, const float4& defaultValue)
function double2 (line 205) | double2 read<double2>(const Json::Value& node, const double2& defaultValue)
function double3 (line 215) | double3 read<double3>(const Json::Value& node, const double3& defaultValue)
function double4 (line 225) | double4 read<double4>(const Json::Value& node, const double4& defaultValue)
FILE: rtxmg/scene/obj_importer.cpp
function getSequenceRange (line 43) | static std::optional<int2> getSequenceRange(const std::string& str)
function getSequenceFormat (line 63) | static std::string getSequenceFormat(const std::string& str, int2 frameR...
FILE: rtxmg/scene/scene.cpp
function Instance (line 124) | static Instance& operator << (Instance& instance, const Json::Value& node)
function View (line 156) | static View& operator << (View& view, const Json::Value& node)
FILE: rtxmg/scene/string_utils.cpp
function ReadBigFile (line 113) | std::unique_ptr<uint8_t[]> ReadBigFile(fs::path const& m_filepath,
function ReadASCIIFile (line 158) | std::string ReadASCIIFile(char const* m_filepath)
FILE: rtxmg/subdivision/shape.cpp
function parseMtllib (line 53) | static std::vector<std::unique_ptr<Shape::material>>
function parseObj (line 316) | std::unique_ptr<Shape> parseObj(char const* m_filepath, Scheme shapescheme,
function udimPath (line 789) | static std::string udimPath(std::string const& filename, char const* udi...
function materialMaps (line 799) | constexpr auto materialMaps(Shape::material& m)
function materialMaps (line 804) | constexpr auto materialMaps(Shape::material const& m)
function hasUdims (line 808) | static bool hasUdims(Shape::material const& mtl)
function hasUdims (line 828) | static bool hasUdims(Shape const& shape)
function findUdims (line 836) | static std::vector<uint32_t> findUdims(fs::path const& basepath, Shape::...
function resolveUdim (line 873) | static std::unique_ptr<Shape::material> resolveUdim(fs::path const& base...
function resolveUdims (line 895) | static void resolveUdims(Shape& shape)
FILE: rtxmg/subdivision/subdivision_surface.cpp
function initSubdLinearDeviceData (line 56) | void initSubdLinearDeviceData(const Tmr::LinearSurfaceTable& surfaceTable,
function gatherStatistics (line 92) | static void gatherStatistics(Shape const& shape,
function quadrangulateFaceToSubshape (line 300) | static std::vector<uint16_t> quadrangulateFaceToSubshape(
function box3 (line 629) | static inline box3 lerpAabb(const box3& a, const box3& b, float t)
FILE: rtxmg/subdivision/topology_cache.cpp
function TopologyMap (line 50) | TopologyMap& TopologyCache::get(uint8_t traits)
FILE: rtxmg/utils/buffer.cpp
function GetGenericDesc (line 25) | nvrhi::BufferDesc GetGenericDesc(size_t nElements, uint32_t elementSize,...
function GetReadbackDesc (line 40) | nvrhi::BufferDesc GetReadbackDesc(const nvrhi::BufferDesc& desc)
function DownloadBuffer (line 53) | void DownloadBuffer(nvrhi::IBuffer* src, void* dest, nvrhi::IBuffer* sta...
FILE: rtxmg/utils/csvdump.cpp
function WriteTexToCSV (line 28) | void WriteTexToCSV(nvrhi::ICommandList* commandList, nvrhi::ITexture* te...
function WriteBufferToCSV (line 60) | void WriteBufferToCSV(nvrhi::ICommandList* commandList, RTXMGBuffer<floa...
FILE: rtxmg/utils/debug.cpp
function GetUniqueFileIndex (line 31) | int GetUniqueFileIndex(const char* baseName, const char* extension)
FILE: rtxmg/utils/formatters.cpp
function HumanFormatter (line 30) | int HumanFormatter(double value, char* buff, int bufsize, void*)
function MetricFormatter (line 48) | int MetricFormatter(double value, char* buff, int bufsize, void* data)
function MegabytesFormatter (line 67) | int MegabytesFormatter(double value, char* buff, int bufsize, void*)
function MemoryFormatter (line 73) | int MemoryFormatter(double value, char* buff, int bufsize, void*)
Condensed preview — 171 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,610K chars).
[
{
"path": ".editorconfig",
"chars": 3383,
"preview": "# Visual Studio generated .editorconfig file with C++ settings.\nroot = true\n\n[*.{c++,cc,cpp,cppm,cu,cuh,cxx,fx,h,h++,hh,"
},
{
"path": ".gitattributes",
"chars": 142,
"preview": "# Default behavior in case core.autocrlf set\n* text=auto\n\n*.dll filter=lfs diff=lfs merge=lfs -text\n*.pdb filter=lfs dif"
},
{
"path": ".gitignore",
"chars": 51,
"preview": "*.*~\nscenes\nbin/\n_build/\n_install/\nbuild/\n.vscode/\n"
},
{
"path": ".gitlab-ci.yml",
"chars": 688,
"preview": "stages:\r\n - build\r\n\r\nvariables:\r\n GIT_SUBMODULE_STRATEGY: recursive\r\n\r\nbuild-windows:\r\n stage: build\r\n tags:\r\n - "
},
{
"path": ".gitmodules",
"chars": 296,
"preview": "[submodule \"extern/donut\"]\n\tpath = extern/donut\n\turl = https://github.com/NVIDIA-RTX/Donut.git\n[submodule \"assets\"]\n\tpat"
},
{
"path": "CHANGELOG.md",
"chars": 3340,
"preview": "# RTX Mega Geometry SDK Change Log\n\n## 1.0.1\n\nImprovements\n* Add smooth vertex normal support which allows for lower tes"
},
{
"path": "CMake/FetchDXC.cmake",
"chars": 2139,
"preview": "#\n# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.\n#\n# Redistribution and use in source and binary forms, "
},
{
"path": "CMake/FetchImplot.cmake",
"chars": 2425,
"preview": "#\n# Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.\n#\n# Redistribution and use in source and binary forms, "
},
{
"path": "CMake/FetchNVAPI.cmake",
"chars": 2228,
"preview": "#\n# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.\n#\n# Redistribution and use in source and binary forms, "
},
{
"path": "CMakeLists.txt",
"chars": 4266,
"preview": "cmake_minimum_required(VERSION 3.10)\n\nproject(rtxmg LANGUAGES C CXX VERSION 1.0.1)\n\nset(CMAKE_CONFIGURATION_TYPES \"Debug"
},
{
"path": "LICENSE.txt",
"chars": 27028,
"preview": "NVIDIA RTX SDKs LICENSE\n\nThis license is a legal agreement between you and NVIDIA Corporation (\"NVIDIA\") and governs the"
},
{
"path": "README.md",
"chars": 5415,
"preview": "# RTX Mega Geometry\n\n\n\n<br/>\n<div align=\"center\">\n·\n<a href=\"CHANGELOG.md\">Change Log "
},
{
"path": "demo/CMakeLists.txt",
"chars": 4255,
"preview": "# include (\"private.cmake\" OPTIONAL)\n\ninclude (\"${DONUT_DIR}/compileshaders.cmake\")\n\nadd_subdirectory(audio)\n\n\nfile(GLOB"
},
{
"path": "demo/args.cpp",
"chars": 16850,
"preview": "//\n// Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "demo/args.h",
"chars": 4985,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "demo/audio/CMakeLists.txt",
"chars": 1734,
"preview": "\noption(ENABLE_AUDIO_ENGINE \"Enable audio playback\" ON)\n\nif (ENABLE_AUDIO_ENGINE)\n\n set(_audio_src_files\n audi"
},
{
"path": "demo/audio/audio.cpp",
"chars": 4841,
"preview": "// clang-format off\n#include \"./audio.h\"\n#include \"./waveFile.h\"\n\n#include <cstring>\n\n// clang-format on\n\n#ifndef SAFE_R"
},
{
"path": "demo/audio/audio.h",
"chars": 2216,
"preview": "#pragma once\n\n// clang-format off\n\n#if defined(AUDIO_ENGINE_WITH_XAUDIO)\n #include <xaudio2.h>\n #include <XAudio2"
},
{
"path": "demo/audio/waveFile.cpp",
"chars": 6010,
"preview": "// clang-format off\n\n#include \"./waveFile.h\"\n\n#include <cassert>\n#include <cmath>\n#include <cstring>\n#include <fstream>\n"
},
{
"path": "demo/audio/waveFile.h",
"chars": 1575,
"preview": "#pragma once\n\n// clang-format off\n\n#include <cstdint>\n#include <memory>\n#include <limits>\n#include <filesystem>\n#include"
},
{
"path": "demo/audio/xaudiofaudio.h",
"chars": 6087,
"preview": "#pragma once\n\n#include <cstring>\n#include <stdarg.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\n#inclu"
},
{
"path": "demo/blit_params.h",
"chars": 1925,
"preview": "/*\n * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free of charge, t"
},
{
"path": "demo/envmap/CMakeLists.txt",
"chars": 900,
"preview": "set(lib envmap)\nset(folder \"Demo\")\ninclude (\"${DONUT_DIR}/compileshaders.cmake\")\n\nfile(GLOB shaders \"shaders/*\")\nfile(GL"
},
{
"path": "demo/envmap/preprocess_envmap.h",
"chars": 1687,
"preview": "/*\n * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free of charge, t"
},
{
"path": "demo/envmap/preprocess_envmap_params.h",
"chars": 1449,
"preview": "/*\n * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free of charge, t"
},
{
"path": "demo/envmap/scan_system.cpp",
"chars": 3439,
"preview": "/*\n * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free of charge, t"
},
{
"path": "demo/envmap/scan_system.h",
"chars": 1757,
"preview": "/*\n * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free of charge, t"
},
{
"path": "demo/envmap/scan_system_shared.h",
"chars": 1836,
"preview": "/*\n * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free of charge, t"
},
{
"path": "demo/envmap/shaders/compute_conditional.hlsl",
"chars": 2424,
"preview": "/*\n * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free of charge, t"
},
{
"path": "demo/envmap/shaders/compute_marginal.hlsl",
"chars": 1893,
"preview": "/*\n * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free of charge, t"
},
{
"path": "demo/envmap/shaders/envmap.hlsli",
"chars": 6387,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "demo/envmap/shaders/prefix_scan.hlsl",
"chars": 2334,
"preview": "/*\n * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free of charge, t"
},
{
"path": "demo/envmap/shaders.cfg",
"chars": 106,
"preview": "shaders/prefix_scan.hlsl -T cs\nshaders/compute_conditional.hlsl -T cs\nshaders/compute_marginal.hlsl -T cs\n"
},
{
"path": "demo/gbuffer.h",
"chars": 2432,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "demo/gui.cpp",
"chars": 74635,
"preview": "/*\n * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free of charge, t"
},
{
"path": "demo/gui.h",
"chars": 8804,
"preview": "/*\n * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free of charge, t"
},
{
"path": "demo/gui_fonts.cpp",
"chars": 363967,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "demo/korgi.cpp",
"chars": 11645,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// NVIDIA CORPORATION and its licensors retain all"
},
{
"path": "demo/korgi.h",
"chars": 8084,
"preview": "#pragma once\n//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// NVIDIA CORPORATION and its licenso"
},
{
"path": "demo/lerp_keyframes_params.h",
"chars": 1847,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "demo/lighting_cb.h",
"chars": 1511,
"preview": "/*\n * Copyright (c) 2014-2021, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free of char"
},
{
"path": "demo/maya_logger.cpp",
"chars": 6085,
"preview": "\n#include \"./maya_logger.h\"\n\n#include <array>\n\nconstexpr float3 const blue = { 0.f, 0.f, 1.f };\nconstexpr float3 const g"
},
{
"path": "demo/maya_logger.h",
"chars": 789,
"preview": "\n#pragma once\n\n#include <cstdint>\n#include <cstdio>\n#include <memory>\n#include <string>\n#include <vector>\n#include <cass"
},
{
"path": "demo/motion_vectors_params.h",
"chars": 1780,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "demo/ray_payload.h",
"chars": 1937,
"preview": "/*\n * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free of charge, t"
},
{
"path": "demo/render_params.h",
"chars": 6365,
"preview": "/*\n * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free of charge, t"
},
{
"path": "demo/render_targets.cpp",
"chars": 3498,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "demo/render_targets.h",
"chars": 2271,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "demo/rtxmg_demo.cpp",
"chars": 3530,
"preview": "/*\n * Copyright (c) 2014-2021, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free of char"
},
{
"path": "demo/rtxmg_demo.h",
"chars": 3095,
"preview": "/*\n * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free of charge, t"
},
{
"path": "demo/rtxmg_demo_app.cpp",
"chars": 43180,
"preview": "\n/*\n * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free of charge, "
},
{
"path": "demo/rtxmg_demo_app.h",
"chars": 11928,
"preview": "#pragma once\n\n/*\n * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, fre"
},
{
"path": "demo/rtxmg_renderer.cpp",
"chars": 52500,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "demo/rtxmg_renderer.h",
"chars": 15826,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "demo/shaders/blit.hlsl",
"chars": 6809,
"preview": "/*\n* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n*\n* Permission is hereby granted, free of charge, to a"
},
{
"path": "demo/shaders/brdf.hlsli",
"chars": 19450,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "demo/shaders/color.hlsli",
"chars": 3309,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "demo/shaders/lerp_keyframes.hlsl",
"chars": 1696,
"preview": "/*\n* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n*\n* Permission is hereby granted, free of charge, to a"
},
{
"path": "demo/shaders/motion_vectors.hlsl",
"chars": 8021,
"preview": "/*\n* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n*\n* Permission is hereby granted, free of charge, to a"
},
{
"path": "demo/shaders/rtxmg_demo_path_tracer.hlsl",
"chars": 44745,
"preview": "/*\n * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free of charge, t"
},
{
"path": "demo/shaders/self_intersection_avoidance.hlsli",
"chars": 5497,
"preview": "//\n// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n// SPDX-License-"
},
{
"path": "demo/shaders/utils.hlsli",
"chars": 12906,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "demo/shaders/zrender.hlsl",
"chars": 3118,
"preview": "/*\n * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free of charge, t"
},
{
"path": "demo/shaders.cfg",
"chars": 381,
"preview": "shaders/blit.hlsl -T cs\nshaders/lerp_keyframes.hlsl -T cs\nshaders/motion_vectors.hlsl -T cs --compilerOptionsSPIRV \"-fvk"
},
{
"path": "demo/trackball.cpp",
"chars": 9977,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "demo/trackball.h",
"chars": 5374,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "demo/zrender_params.h",
"chars": 1613,
"preview": "/*\n * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free of charge, t"
},
{
"path": "demo/zrenderer.cpp",
"chars": 5558,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "demo/zrenderer.h",
"chars": 2725,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "docs/QuickStart.md",
"chars": 11476,
"preview": "# Quick Start Guide\n\nSee [README](../README.md) for cloning & build steps.\n\n## Path-tracer sample\n\nThis sample uses NVAP"
},
{
"path": "extern/CMakeLists.txt",
"chars": 1731,
"preview": "#\n# Copyright (c) 2023, NVIDIA CORPORATION. All rights reserved.\n# \n# NVIDIA CORPORATION and its licensors retain all in"
},
{
"path": "extern/nrd.cfg",
"chars": 41173,
"preview": "RayTracingDenoiser/Shaders/Source/Clear_Float.cs.hlsl -T cs -E main -D NRD_COMPILER_DXC=1 -D NRD_NORMAL_ENCODING=2 -D NR"
},
{
"path": "notice.txt",
"chars": 823,
"preview": "\n\n RTX MegaGeometry (RTXMG)\n Copyright (C) 2019, NVIDIA CORPORATION\n All rights reserved.\n\n https://github.com/NVIDI"
},
{
"path": "rtxmg/CMakeLists.txt",
"chars": 416,
"preview": "add_library(rtxmg)\ntarget_include_directories(rtxmg PUBLIC\n \"${CMAKE_CURRENT_SOURCE_DIR}/include\"\n)\n\nadd_subdirectory"
},
{
"path": "rtxmg/cluster_builder/CMakeLists.txt",
"chars": 982,
"preview": "set(lib cluster_builder)\nset(folder RTXMG)\n\ninclude (\"${DONUT_DIR}/compileshaders.cmake\")\n\nfile(GLOB shaders \"shaders/*\""
},
{
"path": "rtxmg/cluster_builder/cluster_accel_builder.cpp",
"chars": 69015,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/cluster_builder/shaders/compute_cluster_tiling.hlsl",
"chars": 31326,
"preview": "/*\n* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n*\n* Permission is hereby granted, free of charge, to a"
},
{
"path": "rtxmg/cluster_builder/shaders/copy_cluster_offset.hlsl",
"chars": 4723,
"preview": "/*\n* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n*\n* Permission is hereby granted, free of charge, to a"
},
{
"path": "rtxmg/cluster_builder/shaders/fill_blas_from_clas_args.hlsl",
"chars": 2147,
"preview": "/*\n* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n*\n* Permission is hereby granted, free of charge, to a"
},
{
"path": "rtxmg/cluster_builder/shaders/fill_clusters.hlsl",
"chars": 11753,
"preview": "/*\n* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n*\n* Permission is hereby granted, free of charge, to a"
},
{
"path": "rtxmg/cluster_builder/shaders/fill_instance_descs.hlsl",
"chars": 1945,
"preview": "/*\n* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n*\n* Permission is hereby granted, free of charge, to a"
},
{
"path": "rtxmg/cluster_builder/shaders/fill_instantiate_template_args.hlsl",
"chars": 2123,
"preview": "/*\n* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n*\n* Permission is hereby granted, free of charge, to a"
},
{
"path": "rtxmg/cluster_builder/shaders.cfg",
"chars": 969,
"preview": "shaders/fill_clusters.hlsl -E \"FillClustersMain\" -T cs --compilerOptionsSPIRV \"-fvk-bind-resource-heap 0 1\" -D DISPLACEM"
},
{
"path": "rtxmg/hiz/CMakeLists.txt",
"chars": 929,
"preview": "set(lib hiz)\nset(folder RTXMG)\ninclude (\"${DONUT_DIR}/compileshaders.cmake\")\n\nfile(GLOB shaders \"shaders/*\")\nfile(GLOB s"
},
{
"path": "rtxmg/hiz/hiz_buffer.cpp",
"chars": 11852,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/hiz/shaders/hiz_display.hlsl",
"chars": 2181,
"preview": "/*\n* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n*\n* Permission is hereby granted, free of charge, to a"
},
{
"path": "rtxmg/hiz/shaders/hiz_pass1.hlsl",
"chars": 3954,
"preview": "/*\n* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n*\n* Permission is hereby granted, free of charge, to a"
},
{
"path": "rtxmg/hiz/shaders/hiz_pass2.hlsl",
"chars": 4577,
"preview": "/*\n* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n*\n* Permission is hereby granted, free of charge, to a"
},
{
"path": "rtxmg/hiz/shaders/zbuffer_display.hlsl",
"chars": 1901,
"preview": "/*\n* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n*\n* Permission is hereby granted, free of charge, to a"
},
{
"path": "rtxmg/hiz/shaders/zbuffer_minmax.hlsl",
"chars": 2223,
"preview": "/*\n* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n*\n* Permission is hereby granted, free of charge, to a"
},
{
"path": "rtxmg/hiz/shaders.cfg",
"chars": 158,
"preview": "shaders/hiz_display.hlsl -T cs\nshaders/hiz_pass1.hlsl -T cs\nshaders/hiz_pass2.hlsl -T cs\nshaders/zbuffer_display.hlsl -T"
},
{
"path": "rtxmg/hiz/zbuffer.cpp",
"chars": 6519,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/include/rtxmg/cluster_builder/cluster.h",
"chars": 7709,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/include/rtxmg/cluster_builder/cluster_accel_builder.h",
"chars": 13127,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/include/rtxmg/cluster_builder/cluster_accels.h",
"chars": 3246,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/include/rtxmg/cluster_builder/compute_cluster_tiling_params.h",
"chars": 2736,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/include/rtxmg/cluster_builder/copy_cluster_offset_params.h",
"chars": 1833,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/include/rtxmg/cluster_builder/displacement.hlsli",
"chars": 3555,
"preview": "/*\n* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n*\n* Permission is hereby granted, free of charge, to a"
},
{
"path": "rtxmg/include/rtxmg/cluster_builder/fill_blas_from_clas_args_params.h",
"chars": 1836,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/include/rtxmg/cluster_builder/fill_clusters_params.h",
"chars": 2573,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/include/rtxmg/cluster_builder/fill_instance_descs_params.h",
"chars": 1746,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/include/rtxmg/cluster_builder/fill_instantiate_template_args_params.h",
"chars": 1762,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/include/rtxmg/cluster_builder/tessellation_counters.h",
"chars": 2227,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/include/rtxmg/cluster_builder/tessellator_config.h",
"chars": 4197,
"preview": "/*\n * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free of charge, t"
},
{
"path": "rtxmg/include/rtxmg/cluster_builder/tessellator_constants.h",
"chars": 2074,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/include/rtxmg/cluster_builder/tilings.h",
"chars": 4006,
"preview": "#pragma once\n\nstruct ClusterTiling\n{\n uint16_t2 tilingSize; // number of tiles in x and y direction\n uint16_t2 "
},
{
"path": "rtxmg/include/rtxmg/hiz/hiz_buffer.h",
"chars": 3701,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/include/rtxmg/hiz/hiz_buffer_constants.h",
"chars": 1885,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/include/rtxmg/hiz/hiz_buffer_display_params.h",
"chars": 1690,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/include/rtxmg/hiz/hiz_buffer_reduce_params.h",
"chars": 1655,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/include/rtxmg/hiz/zbuffer.h",
"chars": 3470,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/include/rtxmg/profiler/gui.h",
"chars": 5807,
"preview": "//\n// Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/include/rtxmg/profiler/profiler.h",
"chars": 6072,
"preview": "//\n// Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/include/rtxmg/profiler/sampler.h",
"chars": 3688,
"preview": "//\n// Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/include/rtxmg/profiler/statistics.h",
"chars": 7228,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/include/rtxmg/profiler/stopwatch.h",
"chars": 3003,
"preview": "//\n// Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/include/rtxmg/scene/box_extent.h",
"chars": 1666,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/include/rtxmg/scene/camera.h",
"chars": 3510,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/include/rtxmg/scene/json.h",
"chars": 2419,
"preview": "\n#pragma once\n\n// clang-format off\n\n#include <cassert>\n#include <filesystem>\n#include <string>\n\n#include <donut/core/mat"
},
{
"path": "rtxmg/include/rtxmg/scene/model.h",
"chars": 2448,
"preview": "#pragma once\n/*\n * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free"
},
{
"path": "rtxmg/include/rtxmg/scene/obj_importer.h",
"chars": 2607,
"preview": "/*\n * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free of charge, t"
},
{
"path": "rtxmg/include/rtxmg/scene/scene.h",
"chars": 4484,
"preview": "/*\n * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free of charge, t"
},
{
"path": "rtxmg/include/rtxmg/scene/string_utils.h",
"chars": 2413,
"preview": "//\n// Copyright (c) 2012-2016, NVIDIA CORPORATION. All rights reserved.\n//\n// NVIDIA CORPORATION and its licensors retai"
},
{
"path": "rtxmg/include/rtxmg/subdivision/far.h",
"chars": 13969,
"preview": "//\n// Copyright 2013 Pixar\n//\n// Licensed under the Apache License, Version 2.0 (the \"Apache License\")\n// with the"
},
{
"path": "rtxmg/include/rtxmg/subdivision/osd_ports/tmr/nodeDescriptor.h",
"chars": 8638,
"preview": "//\n// Copyright 2016 Nvidia\n//\n// Licensed under the Apache License, Version 2.0 (the \"Apache License\")\n// with th"
},
{
"path": "rtxmg/include/rtxmg/subdivision/osd_ports/tmr/subdivisionNode.h",
"chars": 4619,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/include/rtxmg/subdivision/osd_ports/tmr/surfaceDescriptor.h",
"chars": 6839,
"preview": "/*\n* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n*\n* Permission is hereby granted, free of charge, to a"
},
{
"path": "rtxmg/include/rtxmg/subdivision/osd_ports/tmr/treeDescriptor.h",
"chars": 2456,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/include/rtxmg/subdivision/osd_ports/tmr/types.h",
"chars": 3250,
"preview": "/*\n* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n*\n* Permission is hereby granted, free of charge, to a"
},
{
"path": "rtxmg/include/rtxmg/subdivision/patch_param.h",
"chars": 11951,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/include/rtxmg/subdivision/segmented_vector.h",
"chars": 2583,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/include/rtxmg/subdivision/shape.h",
"chars": 5184,
"preview": "/*\n * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free of charge, t"
},
{
"path": "rtxmg/include/rtxmg/subdivision/subdivision_eval.hlsli",
"chars": 25165,
"preview": "/*\n* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n*\n* Permission is hereby granted, free of charge, to a"
},
{
"path": "rtxmg/include/rtxmg/subdivision/subdivision_plan_hlsl.h",
"chars": 23604,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/include/rtxmg/subdivision/subdivision_surface.h",
"chars": 4581,
"preview": "/*\n * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free of charge, t"
},
{
"path": "rtxmg/include/rtxmg/subdivision/topology_cache.h",
"chars": 3159,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/include/rtxmg/subdivision/topology_map.h",
"chars": 3472,
"preview": "//\n// Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binar"
},
{
"path": "rtxmg/include/rtxmg/subdivision/vertex.h",
"chars": 2196,
"preview": "//\n// Copyright 2024 Nvidia\n//\n// Licensed under the Apache License, Version 2.0 (the \"Apache License\")\n// with th"
},
{
"path": "rtxmg/include/rtxmg/utils/box3.h",
"chars": 2799,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/include/rtxmg/utils/buffer.h",
"chars": 7069,
"preview": "/*\n * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free of charge, t"
},
{
"path": "rtxmg/include/rtxmg/utils/constants.h",
"chars": 2219,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/include/rtxmg/utils/debug.h",
"chars": 2231,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/include/rtxmg/utils/formatters.h",
"chars": 2213,
"preview": "/*\n * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free of charge, t"
},
{
"path": "rtxmg/include/rtxmg/utils/shader_debug.h",
"chars": 8706,
"preview": "/*\n * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free of charge, t"
},
{
"path": "rtxmg/include/rtxmg/utils/vectorlog.h",
"chars": 5707,
"preview": "/*\n * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free of charge, t"
},
{
"path": "rtxmg/profiler/CMakeLists.txt",
"chars": 330,
"preview": "set(lib profiler)\n\nfile(GLOB sources \"*.cpp\" \"../include/rtxmg/${lib}/*.h\")\n\nadd_library(${lib} OBJECT ${sources})\ntarge"
},
{
"path": "rtxmg/profiler/gui.cpp",
"chars": 5107,
"preview": "//\n// Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/profiler/profiler.cpp",
"chars": 3607,
"preview": "//\n// Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/profiler/statistics.cpp",
"chars": 38192,
"preview": "//\n// Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/profiler/stopwatch.cpp",
"chars": 5198,
"preview": "//\n// Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/scene/CMakeLists.txt",
"chars": 321,
"preview": "set(lib scene)\n\nfile(GLOB sources \"*.cpp\" \"../include/rtxmg/${lib}/*.h\")\n\nadd_library(${lib} OBJECT ${sources})\ntarget_i"
},
{
"path": "rtxmg/scene/box_extent.cpp",
"chars": 1770,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/scene/camera.cpp",
"chars": 6369,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/scene/json.cpp",
"chars": 6148,
"preview": "// clang-format off\n#include \"rtxmg/scene/json.h\"\n\n#include <json/json.h>\n\n#include <fstream>\n\n// clang-format on\nnamesp"
},
{
"path": "rtxmg/scene/obj_importer.cpp",
"chars": 7773,
"preview": "/*\n * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free of charge, t"
},
{
"path": "rtxmg/scene/scene.cpp",
"chars": 19185,
"preview": "/*\n * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free of charge, t"
},
{
"path": "rtxmg/scene/string_utils.cpp",
"chars": 5099,
"preview": "//\n// Copyright (c) 2012-2016, NVIDIA CORPORATION. All rights reserved.\n//\n// NVIDIA CORPORATION and its licensors retai"
},
{
"path": "rtxmg/subdivision/CMakeLists.txt",
"chars": 441,
"preview": "set(lib subdivision)\nset(folder RTXMG)\n\nfile(GLOB sources \"*.cpp\" \"../include/rtxmg/${lib}/*.h\" \"../include/rtxmg/${lib}"
},
{
"path": "rtxmg/subdivision/shape.cpp",
"chars": 31069,
"preview": "/*\n * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free of charge, t"
},
{
"path": "rtxmg/subdivision/subdivision_surface.cpp",
"chars": 24955,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/subdivision/topology_cache.cpp",
"chars": 3424,
"preview": "//\n// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binary for"
},
{
"path": "rtxmg/subdivision/topology_map.cpp",
"chars": 9063,
"preview": "//\n// Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved.\n//\n// Redistribution and use in source and binar"
},
{
"path": "rtxmg/utils/CMakeLists.txt",
"chars": 303,
"preview": "set(lib rtxmg_utils)\n\nfile(GLOB sources \"*.cpp\" \"../include/rtxmg/utils/*.h\")\n\nadd_library(${lib} OBJECT ${sources})\ntar"
},
{
"path": "rtxmg/utils/buffer.cpp",
"chars": 2871,
"preview": "/*\n * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free of charge, t"
},
{
"path": "rtxmg/utils/csvdump.cpp",
"chars": 2875,
"preview": "/*\n * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free of charge, t"
},
{
"path": "rtxmg/utils/debug.cpp",
"chars": 2006,
"preview": "/*\n * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free of charge, t"
},
{
"path": "rtxmg/utils/formatters.cpp",
"chars": 3039,
"preview": "/*\n * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.\n *\n * Permission is hereby granted, free of charge, t"
},
{
"path": "rtxmg_static_analysis.props",
"chars": 190,
"preview": "<Project>\n <PropertyGroup>\n <RunCodeAnalysis>true</RunCodeAnalysis>\n <CodeAnalysisRuleset>dxcb_static_a"
},
{
"path": "rtxmg_static_analysis.ruleset",
"chars": 5061,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RuleSet Name=\"DXClusterBench static analysis \" Description=\"These rules focus o"
},
{
"path": "shadertoolsconfig.json",
"chars": 81,
"preview": "{\n\t\"hlsl.additionalIncludeDirectories\": [\n\t\t\"c:\\\\work\\\\dxclusterbench\\\\src\"\n\t]\n}\n"
},
{
"path": "tools/set_vs_vars.ps1",
"chars": 1499,
"preview": "#\r\n# Find vswhere (installed with recent Visual Studio versions).\r\n#\r\nIf ($vsWhere = Get-Command \"vswhere.exe\" -ErrorAct"
}
]
About this extraction
This page contains the full source code of the NVIDIA-RTX/RTXMG GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 171 files (1.5 MB), approximately 536.3k tokens, and a symbol index with 380 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.