mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-03-14 06:34:10 +00:00
Merge branch 'master' into nvrhi-rebase-040224
This commit is contained in:
commit
7911f5252d
61 changed files with 3186 additions and 611 deletions
|
@ -510,7 +510,7 @@ Recommended in this case is `cmake-vs2022-win64-no-ffmpeg.bat`
|
|||
|
||||
Xcode release and universal builds now automatically package the executable into a macOS app bundle, defining an Info.plist file and copying the base directory and custom icon into the application bundle's Contents/Resources folder. This is controlled by adding -DMACOSX_BUNDLE=ON to the CMake options.
|
||||
|
||||
Depending on which package manager you install (Homebrew or MacPorts) you may need to change the openal-soft library and include paths specified in the cmake shell scripts. For single architecture builds (debug, release, retail) the default openal-soft paths are set for Homebrew on x86, while for universal builds the default paths are set for MacPorts on x86 or Apple Silicon. If you want to build using the single architecture shell scripts (debug, release, retail) on Apple Silicon, you will need to change the openal-soft paths from `/usr/local/...` to either `/opt/homebrew/...` (Homebrew) or `/opt/local/...` (MacPorts).
|
||||
For single architecture builds (debug, release, retail) the default openal-soft paths are set for Homebrew, while for universal builds the default paths are set for MacPorts. The single architecture build scripts are now portable and automatically detect Homebrew's openal-soft path prefix for x86 and Apple Silicon. The universal build script remains portable since MacPorts uses the same openal-soft installation path on x86 and Apple Silicon.
|
||||
|
||||
4. Compile RBDOOM-3-BFG targets:
|
||||
|
||||
|
@ -639,8 +639,10 @@ r_graphicsAPI | Default DX12, can be either DX12 or Vul
|
|||
r_antiAliasing | Different Anti-Aliasing modes
|
||||
r_exposure [0 .. 1] | Default 0.5, controls brightness and affects HDR -> sRGB Rec. 709 exposure key. This is what you change in the video brightness options
|
||||
r_useSSAO [0 .. 1] | Use Screen Space Ambient Occlusion to darken the corners in the scene and give it more depth
|
||||
r_useFilmicPostProcessing [0, 1] | Apply several post process effects to mimic a filmic look
|
||||
r_forceAmbient | Default 0.5, controls additional brightness by Global Illumination
|
||||
r_useFilmicPostFX [0, 1] | Apply several post process effects to mimic a filmic look
|
||||
r_useCRTPostFX [0, 1] | CRT monitor/TV filter
|
||||
r_renderMode [0 .. 5] | Default 0 = Doom 3, 1 = Commodore 64, 2 = Commodore 64 Highres, 3 = Sega Genesis, 4 = Sega Genesis Highres, 5 = Sony PSX
|
||||
|
||||
## Modding Support
|
||||
Name | Description
|
||||
|
|
|
@ -19,6 +19,70 @@ TBD - RBDOOM-3-BFG 1.6.0
|
|||
_______________________________
|
||||
|
||||
|
||||
## .plan - January 20, 2024
|
||||
|
||||
Cudos to Stephen Saunders for this build and to reeFridge for finding the issue.
|
||||
This fixes a number of multiplayer issues. Create Private Match with clients now works reliably. The missing functionality of the online game browser and leaderboards hasn't been fixed.
|
||||
|
||||
Changelog:
|
||||
|
||||
* Fixes regression Multiplayer: Accessing memory after it has been freed #846 caused by an earlier, but broken memory leak fix on my part. The fix is almost identical to PR Free idLobby memory inside destructor #847
|
||||
|
||||
* Fixes a critical issue with mis-reading network snapshot data on the client side, which caused no end of problems with mis-rendering, slowdowns, unstable connections, etc. The client was ignoring the entity network-synced flag which tells it whether it should read entity class-specific data. It was trying to read it all the time and sometimes coming up with null data which caused tons of problems with rendering and physics calculations (e.g. operations on NaN numbers). Simple fix was to respect the entity's network-synced flag on the client side but it makes all the difference.
|
||||
|
||||
* Fixes an incorrect assert on multiplayer VoiceChat shutdown
|
||||
|
||||
* Allows r_useScissor and r_useParallelAdd cvars to be changed in multiplayer mode for use in bake* operations on multiplayer maps
|
||||
|
||||
* Fixed a couple of uninitialized variables that showed up in valgrind when in multiplayer mode
|
||||
|
||||
* Added Amstrad CPC 6128 Retro rendering mode
|
||||
|
||||
|
||||
## .plan - January 03, 2024
|
||||
|
||||
This is a preview build of the new Retro 8-bit/16-bit/PSX rendering modes.
|
||||
|
||||
The new rendering modes can be set in the menu options but it's controlled mainly r_renderMode.
|
||||
The values are 0 = Doom, 1 = Commodore 64, 2 = Commodore 64 Highres, 3 = Sega Genesis, 4 = Sega Genesis Highres, 5 = Sony PSX
|
||||
|
||||
The Commodore 64 mode regulates all colors down to the original 16 color palette.
|
||||
The Sega mode mimics 9 bit color HW which means 3 bit per color channel resulting in a total of 512 colors.
|
||||
The PSX mode only turns off linear filtering for the textures and applies a screen space dithering effect.
|
||||
|
||||
All retro rendering modes try to mimic the 320x240 resolution but it is extended to 16:9 so it is 480 x 270.
|
||||
Highres modes only apply a higher resolution dithering on the pixelated output.
|
||||
|
||||
The PSX mode has no additional artifacts yet like wiggling vertices or textures.
|
||||
|
||||
There are also 2 new CRT filters that are drawn on top of everything else (even the console) for more arcade vibes.
|
||||
|
||||
Changelog:
|
||||
|
||||
* Fixed scissor clipping issues of regular surfaces like light flares #651
|
||||
|
||||
* Duplicating lights with Ctrl+D works now
|
||||
|
||||
* Merged script interpreter improvements from Dhewm3, especially that fixes https://github.com/dhewm/dhewm3/issues/303
|
||||
|
||||
* Doubled MAX_GLOBALS for the Runners 2.6 mod
|
||||
|
||||
* Crash fix between level switching and loading of new textures for D3HDP and other mods
|
||||
|
||||
* Fixed many small memory leaks (thanks to Steve Saunders)
|
||||
|
||||
* Reduced console spam and got rid of the depth-stencil is read-only warnings
|
||||
|
||||
* Added image_pixelLook to disable texture filtering on most textures regardless of the render mode
|
||||
|
||||
* Changed devtools.cfg so you can easily switch between the new render modes with F7 and F8
|
||||
|
||||
|
||||
Changelog TrenchBroomBFG:
|
||||
|
||||
* Added Show patches option to View Options
|
||||
|
||||
|
||||
## .plan - October 27, 2023
|
||||
|
||||
This is a preview build of the new WIP ingame Light Editor with some important bugfixes in the convertMapToValve220 command.
|
||||
|
|
|
@ -3,14 +3,14 @@ bind "I" "toggle r_showSurfaceInfo"
|
|||
bind "N" "noclip"
|
||||
bind "M" "spawn moveable_macbethchart"
|
||||
|
||||
bind "F1" "toggle r_showViewEnvprobes 1 2 3 0"
|
||||
bind "F2" "toggle r_showTris 1 2 3 0"
|
||||
bind "F1" "toggle editLights"
|
||||
bind "F2" "toggle r_showTris 1 2 0"
|
||||
bind "F3" "toggle r_forceAmbient 0.5 1.0 0"
|
||||
bind "F4" "toggle r_skipInteractions"
|
||||
bind "F5" "savegame quick"
|
||||
bind "F6" "toggle r_showLightGrid 1 3 4 0"
|
||||
bind "F7" "toggle r_useSSAO"
|
||||
bind "F8" "toggle r_useFilmicPostProcessing"
|
||||
bind "F7" "toggle r_renderMode 0 1 2 3 4 5 6 7"
|
||||
bind "F8" "toggle r_useCRTPostFX 0 1 2"
|
||||
bind "F9" "loadgame quick"
|
||||
bind "F10" "toggle com_fixedTic"
|
||||
bind "F11" "toggle r_pbrDebug"
|
||||
//bind "F10" "toggle com_fixedTic"
|
||||
bind "F11" "toggle r_useFilmicPostFX"
|
||||
|
|
|
@ -429,6 +429,8 @@ if(USE_VULKAN)
|
|||
if(USE_VMA)
|
||||
add_definitions(-DUSE_AMD_ALLOCATOR)
|
||||
include_directories("libs/vma/include")
|
||||
file(GLOB VMA_INCLUDES libs/vma/include/*.h)
|
||||
source_group("libs\\vma" FILES ${VMA_INCLUDES})
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
@ -1308,6 +1310,7 @@ set(RBDOOM3_INCLUDES
|
|||
#${FREETYPE_SOURCES}
|
||||
${SOUND_INCLUDES}
|
||||
${OGGVORBIS_INCLUDES}
|
||||
${VMA_INCLUDES}
|
||||
${OPTICK_INCLUDES}
|
||||
${UI_INCLUDES}
|
||||
${SWF_INCLUDES}
|
||||
|
@ -1780,7 +1783,8 @@ else()
|
|||
# delete precompiled header file after executable is compiled: IDE build case (e.g. Xcode)
|
||||
else()
|
||||
add_custom_command(TARGET RBDoom3BFG POST_BUILD
|
||||
COMMAND ${remove_command} "idlib/precompiled.h.gch"
|
||||
# SRS - added wildcards to remove tmp files from cmake ZERO_CHECK regeneration
|
||||
COMMAND ${remove_command} "idlib/precompiled.h*.gch*"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMENT "remove idlib/precompiled.h.gch"
|
||||
)
|
||||
|
|
|
@ -2,5 +2,16 @@ cd ..
|
|||
rm -rf build
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
# asemarafa/SRS - Determine the Homebrew path prefix for openal-soft
|
||||
if [ -z "$OPENAL_PREFIX" ]; then
|
||||
OPENAL_PREFIX=$(brew --prefix openal-soft 2>/dev/null)
|
||||
if [ -z "$OPENAL_PREFIX" ]; then
|
||||
echo "Error: openal-soft is not installed via Homebrew."
|
||||
echo "Either install it using 'brew install openal-soft' or define the path prefix via OPENAL_PREFIX."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# change or remove -DCMAKE_OSX_DEPLOYMENT_TARGET=<version> to match supported runtime targets
|
||||
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS_RELEASE="-DNDEBUG" -DCMAKE_OSX_DEPLOYMENT_TARGET=12.1 -DFFMPEG=OFF -DBINKDEC=ON -DUSE_MoltenVK=ON -DOPENAL_LIBRARY=/usr/local/opt/openal-soft/lib/libopenal.dylib -DOPENAL_INCLUDE_DIR=/usr/local/opt/openal-soft/include ../neo -Wno-dev
|
||||
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS_RELEASE="-DNDEBUG" -DCMAKE_OSX_DEPLOYMENT_TARGET=12.1 -DFFMPEG=OFF -DBINKDEC=ON -DUSE_MoltenVK=ON -DOPENAL_LIBRARY=$OPENAL_PREFIX/lib/libopenal.dylib -DOPENAL_INCLUDE_DIR=$OPENAL_PREFIX/include ../neo -Wno-dev
|
||||
|
|
|
@ -2,5 +2,16 @@ cd ..
|
|||
rm -rf build
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
# asemarafa/SRS - Determine the Homebrew path prefix for openal-soft
|
||||
if [ -z "$OPENAL_PREFIX" ]; then
|
||||
OPENAL_PREFIX=$(brew --prefix openal-soft 2>/dev/null)
|
||||
if [ -z "$OPENAL_PREFIX" ]; then
|
||||
echo "Error: openal-soft is not installed via Homebrew."
|
||||
echo "Either install it using 'brew install openal-soft' or define the path prefix via OPENAL_PREFIX."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# change or remove -DCMAKE_OSX_DEPLOYMENT_TARGET=<version> to match supported runtime targets
|
||||
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS_RELEASE="-DNDEBUG -DID_RETAIL" -DCMAKE_OSX_DEPLOYMENT_TARGET=12.1 -DFFMPEG=OFF -DBINKDEC=ON -DUSE_MoltenVK=ON -DOPENAL_LIBRARY=/usr/local/opt/openal-soft/lib/libopenal.dylib -DOPENAL_INCLUDE_DIR=/usr/local/opt/openal-soft/include ../neo -Wno-dev
|
||||
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS_RELEASE="-DNDEBUG -DID_RETAIL" -DCMAKE_OSX_DEPLOYMENT_TARGET=12.1 -DFFMPEG=OFF -DBINKDEC=ON -DUSE_MoltenVK=ON -DOPENAL_LIBRARY=$OPENAL_PREFIX/lib/libopenal.dylib -DOPENAL_INCLUDE_DIR=$OPENAL_PREFIX/include ../neo -Wno-dev
|
||||
|
|
6
neo/cmake-vs2019-win64-no-vulkan.bat
Normal file
6
neo/cmake-vs2019-win64-no-vulkan.bat
Normal file
|
@ -0,0 +1,6 @@
|
|||
cd ..
|
||||
del /s /q build
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -G "Visual Studio 16" -A x64 -DFFMPEG=OFF -DBINKDEC=ON -DUSE_VULKAN=OFF ../neo
|
||||
pause
|
6
neo/cmake-vs2022-win64-standalone.bat
Normal file
6
neo/cmake-vs2022-win64-standalone.bat
Normal file
|
@ -0,0 +1,6 @@
|
|||
cd ..
|
||||
del /s /q build
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -G "Visual Studio 17" -A x64 -DFFMPEG=OFF -DBINKDEC=ON -DSTANDALONE=ON ../neo
|
||||
pause
|
|
@ -2,10 +2,22 @@ cd ..
|
|||
rm -rf xcode-debug
|
||||
mkdir xcode-debug
|
||||
cd xcode-debug
|
||||
|
||||
# asemarafa/SRS - Determine the Homebrew path prefix for openal-soft
|
||||
if [ -z "$OPENAL_PREFIX" ]; then
|
||||
OPENAL_PREFIX=$(brew --prefix openal-soft 2>/dev/null)
|
||||
if [ -z "$OPENAL_PREFIX" ]; then
|
||||
echo "Error: openal-soft is not installed via Homebrew."
|
||||
echo "Either install it using 'brew install openal-soft' or define the path prefix via OPENAL_PREFIX."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# note 1: remove or set -DCMAKE_SUPPRESS_REGENERATION=OFF to reenable ZERO_CHECK target which checks for CMakeLists.txt changes and re-runs CMake before builds
|
||||
# however, if ZERO_CHECK is reenabled **must** add VULKAN_SDK location to Xcode Custom Paths (under Prefs/Locations) otherwise build failures may occur
|
||||
# note 2: policy CMAKE_POLICY_DEFAULT_CMP0142=NEW suppresses non-existant per-config suffixes on Xcode library search paths, works for cmake version 3.25 and later
|
||||
# note 3: env variable MVK_CONFIG_FULL_IMAGE_VIEW_SWIZZLE=1 enables MoltenVK's image view swizzle which may be required on older macOS versions or hardware (see vulkaninfo)
|
||||
# note 4: env variable MVK_CONFIG_SYNCHRONOUS_QUEUE_SUBMITS=0 disables synchronous queue submits which is optimal for the synchronization method used by the game
|
||||
# note 5: env variable MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS=2 enables MoltenVK's use of Metal argument buffers only if VK_EXT_descriptor_indexing is enabled
|
||||
cmake -G Xcode -DCMAKE_BUILD_TYPE=Debug -DCMAKE_XCODE_GENERATE_SCHEME=ON -DCMAKE_XCODE_SCHEME_ENVIRONMENT="MVK_CONFIG_FULL_IMAGE_VIEW_SWIZZLE=1;MVK_CONFIG_SYNCHRONOUS_QUEUE_SUBMITS=0;MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS=2" -DCMAKE_XCODE_SCHEME_ENABLE_GPU_API_VALIDATION=OFF -DCMAKE_SUPPRESS_REGENERATION=ON -DOPENAL_LIBRARY=/usr/local/opt/openal-soft/lib/libopenal.dylib -DOPENAL_INCLUDE_DIR=/usr/local/opt/openal-soft/include ../neo -DCMAKE_POLICY_DEFAULT_CMP0142=NEW -Wno-dev
|
||||
# note 3: env variable MVK_CONFIG_FULL_IMAGE_VIEW_SWIZZLE=1 enables MoltenVK's image view swizzle which may be required on older macOS versions or hardware (see vulkaninfo) - only used for VulkanSDK < 1.3.275
|
||||
# note 4: env variable MVK_CONFIG_SYNCHRONOUS_QUEUE_SUBMITS=0 disables synchronous queue submits which is optimal for the synchronization method used by the game - only used for VulkanSDK < 1.3.275
|
||||
# note 5: env variable MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS=2 enables MoltenVK's use of Metal argument buffers only if VK_EXT_descriptor_indexing is enabled - only used for VulkanSDK < 1.3.275
|
||||
# note 6: env variable MVK_CONFIG_TIMESTAMP_PERIOD_LOWPASS_ALPHA=1.0 disables MoltenVK's timestampPeriod lowpass filter for non-Apple GPUs - only used for VulkanSDK < 1.3.275
|
||||
cmake -G Xcode -DCMAKE_BUILD_TYPE=Debug -DCMAKE_XCODE_GENERATE_SCHEME=ON -DCMAKE_XCODE_SCHEME_ENVIRONMENT="MVK_CONFIG_FULL_IMAGE_VIEW_SWIZZLE=1;MVK_CONFIG_SYNCHRONOUS_QUEUE_SUBMITS=0;MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS=2;MVK_CONFIG_TIMESTAMP_PERIOD_LOWPASS_ALPHA=1.0" -DCMAKE_XCODE_SCHEME_ENABLE_GPU_API_VALIDATION=OFF -DCMAKE_SUPPRESS_REGENERATION=ON -DOPENAL_LIBRARY=$OPENAL_PREFIX/lib/libopenal.dylib -DOPENAL_INCLUDE_DIR=$OPENAL_PREFIX/include ../neo -DCMAKE_POLICY_DEFAULT_CMP0142=NEW -Wno-dev
|
||||
|
|
|
@ -2,7 +2,18 @@ cd ..
|
|||
rm -rf xcode-release
|
||||
mkdir xcode-release
|
||||
cd xcode-release
|
||||
|
||||
# asemarafa/SRS - Determine the Homebrew path prefix for openal-soft
|
||||
if [ -z "$OPENAL_PREFIX" ]; then
|
||||
OPENAL_PREFIX=$(brew --prefix openal-soft 2>/dev/null)
|
||||
if [ -z "$OPENAL_PREFIX" ]; then
|
||||
echo "Error: openal-soft is not installed via Homebrew."
|
||||
echo "Either install it using 'brew install openal-soft' or define the path prefix via OPENAL_PREFIX."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# note 1: remove or set -DCMAKE_SUPPRESS_REGENERATION=OFF to reenable ZERO_CHECK target which checks for CMakeLists.txt changes and re-runs CMake before builds
|
||||
# however, if ZERO_CHECK is reenabled **must** add VULKAN_SDK location to Xcode Custom Paths (under Prefs/Locations) otherwise build failures may occur
|
||||
# note 2: policy CMAKE_POLICY_DEFAULT_CMP0142=NEW suppresses non-existant per-config suffixes on Xcode library search paths, works for cmake version 3.25 and later
|
||||
cmake -G Xcode -DCMAKE_BUILD_TYPE=Release -DCMAKE_CONFIGURATION_TYPES="Release;MinSizeRel;RelWithDebInfo" -DMACOSX_BUNDLE=ON -DFFMPEG=OFF -DBINKDEC=ON -DUSE_MoltenVK=ON -DCMAKE_XCODE_GENERATE_SCHEME=ON -DCMAKE_XCODE_SCHEME_ENABLE_GPU_API_VALIDATION=OFF -DCMAKE_SUPPRESS_REGENERATION=ON -DOPENAL_LIBRARY=/usr/local/opt/openal-soft/lib/libopenal.dylib -DOPENAL_INCLUDE_DIR=/usr/local/opt/openal-soft/include ../neo -DCMAKE_POLICY_DEFAULT_CMP0142=NEW -Wno-dev
|
||||
cmake -G Xcode -DCMAKE_BUILD_TYPE=Release -DCMAKE_CONFIGURATION_TYPES="Release;MinSizeRel;RelWithDebInfo" -DMACOSX_BUNDLE=ON -DFFMPEG=OFF -DBINKDEC=ON -DUSE_MoltenVK=ON -DCMAKE_XCODE_GENERATE_SCHEME=ON -DCMAKE_XCODE_SCHEME_ENABLE_GPU_API_VALIDATION=OFF -DCMAKE_SUPPRESS_REGENERATION=ON -DOPENAL_LIBRARY=$OPENAL_PREFIX/lib/libopenal.dylib -DOPENAL_INCLUDE_DIR=$OPENAL_PREFIX/include ../neo -DCMAKE_POLICY_DEFAULT_CMP0142=NEW -Wno-dev
|
||||
|
|
|
@ -2,6 +2,15 @@ cd ..
|
|||
rm -rf xcode-universal
|
||||
mkdir xcode-universal
|
||||
cd xcode-universal
|
||||
|
||||
# SRS - Determine if openal-soft universal variant is installed via MacPorts
|
||||
OPENAL_VARIANTS=$(port info --variants openal-soft 2>/dev/null)
|
||||
if [[ $OPENAL_VARIANTS != *universal* ]]; then
|
||||
echo "Error: openal-soft universal variant is not installed via MacPorts."
|
||||
echo "Please install it using 'sudo port install openal-soft +universal'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# note 1: remove or set -DCMAKE_SUPPRESS_REGENERATION=OFF to reenable ZERO_CHECK target which checks for CMakeLists.txt changes and re-runs CMake before builds
|
||||
# however, if ZERO_CHECK is reenabled **must** add VULKAN_SDK location to Xcode Custom Paths (under Prefs/Locations) otherwise build failures may occur
|
||||
# note 2: policy CMAKE_POLICY_DEFAULT_CMP0142=NEW suppresses non-existant per-config suffixes on Xcode library search paths, works for cmake version 3.25 and later
|
||||
|
|
|
@ -429,7 +429,6 @@ idPlayerView::SingleView
|
|||
*/
|
||||
void idPlayerView::SingleView( const renderView_t* view, idMenuHandler_HUD* hudManager )
|
||||
{
|
||||
|
||||
// normal rendering
|
||||
if( !view )
|
||||
{
|
||||
|
|
|
@ -1368,9 +1368,11 @@ public:
|
|||
SYSTEM_FIELD_VSYNC,
|
||||
SYSTEM_FIELD_ANTIALIASING,
|
||||
// RB begin
|
||||
SYSTEM_FIELD_POSTFX,
|
||||
SYSTEM_FIELD_SSAO,
|
||||
SYSTEM_FIELD_RENDERMODE,
|
||||
SYSTEM_FIELD_AMBIENT_BRIGHTNESS,
|
||||
SYSTEM_FIELD_SSAO,
|
||||
SYSTEM_FIELD_FILMIC_POSTFX,
|
||||
SYSTEM_FIELD_CRT_POSTFX,
|
||||
// RB end
|
||||
SYSTEM_FIELD_BRIGHTNESS,
|
||||
SYSTEM_FIELD_VOLUME,
|
||||
|
|
|
@ -34,7 +34,7 @@ const static int NUM_SYSTEM_OPTIONS_OPTIONS = 8;
|
|||
|
||||
extern idCVar r_graphicsAPI;
|
||||
extern idCVar r_antiAliasing;
|
||||
extern idCVar r_useFilmicPostProcessing;
|
||||
extern idCVar r_useFilmicPostFX;
|
||||
extern idCVar r_swapInterval;
|
||||
extern idCVar s_volume_dB;
|
||||
extern idCVar r_exposure; // RB: use this to control HDR exposure or brightness in LDR mode
|
||||
|
@ -119,10 +119,19 @@ void idMenuScreen_Shell_SystemOptions::Initialize( idMenuHandler* data )
|
|||
// RB begin
|
||||
control = new( TAG_SWF ) idMenuWidget_ControlButton();
|
||||
control->SetOptionType( OPTION_SLIDER_TEXT );
|
||||
control->SetLabel( "Filmic VFX" );
|
||||
control->SetDataSource( &systemData, idMenuDataSource_SystemSettings::SYSTEM_FIELD_POSTFX );
|
||||
control->SetLabel( "Render Mode" );
|
||||
control->SetDataSource( &systemData, idMenuDataSource_SystemSettings::SYSTEM_FIELD_RENDERMODE );
|
||||
control->SetupEvents( DEFAULT_REPEAT_TIME, options->GetChildren().Num() );
|
||||
control->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_COMMAND, idMenuDataSource_SystemSettings::SYSTEM_FIELD_POSTFX );
|
||||
control->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_COMMAND, idMenuDataSource_SystemSettings::SYSTEM_FIELD_RENDERMODE );
|
||||
options->AddChild( control );
|
||||
|
||||
control = new( TAG_SWF ) idMenuWidget_ControlButton();
|
||||
control->SetOptionType( OPTION_SLIDER_BAR );
|
||||
control->SetLabel( "Ambient Lighting" );
|
||||
control->SetDescription( "Sets the amount of indirect lighting. Needed for modern PBR reflections" );
|
||||
control->SetDataSource( &systemData, idMenuDataSource_SystemSettings::SYSTEM_FIELD_AMBIENT_BRIGHTNESS );
|
||||
control->SetupEvents( 2, options->GetChildren().Num() );
|
||||
control->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_COMMAND, idMenuDataSource_SystemSettings::SYSTEM_FIELD_AMBIENT_BRIGHTNESS );
|
||||
options->AddChild( control );
|
||||
|
||||
control = new( TAG_SWF ) idMenuWidget_ControlButton();
|
||||
|
@ -142,12 +151,19 @@ void idMenuScreen_Shell_SystemOptions::Initialize( idMenuHandler* data )
|
|||
options->AddChild( control );*/
|
||||
|
||||
control = new( TAG_SWF ) idMenuWidget_ControlButton();
|
||||
control->SetOptionType( OPTION_SLIDER_BAR );
|
||||
control->SetLabel( "Ambient Lighting" );
|
||||
control->SetDescription( "Sets the amount of indirect lighting. Needed for modern PBR reflections" );
|
||||
control->SetDataSource( &systemData, idMenuDataSource_SystemSettings::SYSTEM_FIELD_AMBIENT_BRIGHTNESS );
|
||||
control->SetupEvents( 2, options->GetChildren().Num() );
|
||||
control->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_COMMAND, idMenuDataSource_SystemSettings::SYSTEM_FIELD_SSAO );
|
||||
control->SetOptionType( OPTION_SLIDER_TEXT );
|
||||
control->SetLabel( "Filmic Post FX" );
|
||||
control->SetDataSource( &systemData, idMenuDataSource_SystemSettings::SYSTEM_FIELD_FILMIC_POSTFX );
|
||||
control->SetupEvents( DEFAULT_REPEAT_TIME, options->GetChildren().Num() );
|
||||
control->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_COMMAND, idMenuDataSource_SystemSettings::SYSTEM_FIELD_FILMIC_POSTFX );
|
||||
options->AddChild( control );
|
||||
|
||||
control = new( TAG_SWF ) idMenuWidget_ControlButton();
|
||||
control->SetOptionType( OPTION_SLIDER_TEXT );
|
||||
control->SetLabel( "CRT Filter" );
|
||||
control->SetDataSource( &systemData, idMenuDataSource_SystemSettings::SYSTEM_FIELD_CRT_POSTFX );
|
||||
control->SetupEvents( DEFAULT_REPEAT_TIME, options->GetChildren().Num() );
|
||||
control->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_COMMAND, idMenuDataSource_SystemSettings::SYSTEM_FIELD_CRT_POSTFX );
|
||||
options->AddChild( control );
|
||||
// RB end
|
||||
|
||||
|
@ -421,7 +437,7 @@ void idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings::LoadData
|
|||
//originalShadowMapping = r_useShadowMapping.GetInteger();
|
||||
originalSSAO = r_useSSAO.GetInteger();
|
||||
originalAmbientBrightness = r_forceAmbient.GetFloat();
|
||||
originalPostProcessing = r_useFilmicPostProcessing.GetInteger();
|
||||
originalPostProcessing = r_useFilmicPostFX.GetInteger();
|
||||
// RB end
|
||||
|
||||
const int fullscreen = r_fullscreen.GetInteger();
|
||||
|
@ -593,11 +609,25 @@ void idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings::AdjustFi
|
|||
break;
|
||||
}
|
||||
// RB begin
|
||||
case SYSTEM_FIELD_POSTFX:
|
||||
case SYSTEM_FIELD_RENDERMODE:
|
||||
{
|
||||
static const int numValues = 8;
|
||||
static const int values[numValues] = { 0, 1, 2, 3, 4, 5, 6, 7 };
|
||||
r_renderMode.SetInteger( AdjustOption( r_renderMode.GetInteger(), values, numValues, adjustAmount ) );
|
||||
break;
|
||||
}
|
||||
case SYSTEM_FIELD_FILMIC_POSTFX:
|
||||
{
|
||||
static const int numValues = 2;
|
||||
static const int values[numValues] = { 0, 1 };
|
||||
r_useFilmicPostProcessing.SetInteger( AdjustOption( r_useFilmicPostProcessing.GetInteger(), values, numValues, adjustAmount ) );
|
||||
r_useFilmicPostFX.SetInteger( AdjustOption( r_useFilmicPostFX.GetInteger(), values, numValues, adjustAmount ) );
|
||||
break;
|
||||
}
|
||||
case SYSTEM_FIELD_CRT_POSTFX:
|
||||
{
|
||||
static const int numValues = 3;
|
||||
static const int values[numValues] = { 0, 1, 2 };
|
||||
r_useCRTPostFX.SetInteger( AdjustOption( r_useCRTPostFX.GetInteger(), values, numValues, adjustAmount ) );
|
||||
break;
|
||||
}
|
||||
/*
|
||||
|
@ -759,21 +789,27 @@ idSWFScriptVar idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings
|
|||
|
||||
return values[ r_antiAliasing.GetInteger() ];
|
||||
}
|
||||
case SYSTEM_FIELD_POSTFX:
|
||||
if( r_useFilmicPostProcessing.GetInteger() > 0 )
|
||||
case SYSTEM_FIELD_RENDERMODE:
|
||||
{
|
||||
static const int numValues = 8;
|
||||
static const char* values[numValues] =
|
||||
{
|
||||
return "#str_swf_enabled";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "#str_swf_disabled";
|
||||
}
|
||||
//return va( "%dx", idMath::IPow( 2, r_motionBlur.GetInteger() ) );
|
||||
// RB begin
|
||||
"Doom 3",
|
||||
"Commodore 64",
|
||||
"Commodore 64 Hi",
|
||||
"Amstrad CPC 6128",
|
||||
"Amstrad CPC 6128 Hi",
|
||||
"Sega Genesis",
|
||||
"Sega Genesis Highres",
|
||||
"Sony PSX",
|
||||
};
|
||||
|
||||
/*
|
||||
case SYSTEM_FIELD_SHADOWMAPPING:
|
||||
if( r_useShadowMapping.GetInteger() == 1 )
|
||||
compile_time_assert( numValues == ( RENDERMODE_PSX + 1 ) );
|
||||
|
||||
return values[ r_renderMode.GetInteger() ];
|
||||
}
|
||||
case SYSTEM_FIELD_FILMIC_POSTFX:
|
||||
if( r_useFilmicPostFX.GetInteger() > 0 )
|
||||
{
|
||||
return "#str_swf_enabled";
|
||||
}
|
||||
|
@ -781,7 +817,19 @@ idSWFScriptVar idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings
|
|||
{
|
||||
return "#str_swf_disabled";
|
||||
}
|
||||
*/
|
||||
|
||||
case SYSTEM_FIELD_CRT_POSTFX:
|
||||
{
|
||||
static const int numValues = 3;
|
||||
static const char* values[numValues] =
|
||||
{
|
||||
"#str_swf_disabled",
|
||||
"Mattias CRT",
|
||||
"Newpixie CRT",
|
||||
};
|
||||
|
||||
return values[ r_useCRTPostFX.GetInteger() ];
|
||||
}
|
||||
|
||||
//case SYSTEM_FIELD_LODBIAS:
|
||||
// return LinearAdjust( r_lodBias.GetFloat(), -1.0f, 1.0f, 0.0f, 100.0f );
|
||||
|
@ -798,7 +846,6 @@ idSWFScriptVar idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings
|
|||
|
||||
case SYSTEM_FIELD_AMBIENT_BRIGHTNESS:
|
||||
return LinearAdjust( r_forceAmbient.GetFloat(), 0.0f, 1.0f, 0.0f, 100.0f );
|
||||
// RB end
|
||||
|
||||
case SYSTEM_FIELD_BRIGHTNESS:
|
||||
return LinearAdjust( r_exposure.GetFloat(), 0.0f, 1.0f, 0.0f, 100.0f );
|
||||
|
@ -848,7 +895,7 @@ bool idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings::IsDataCh
|
|||
return true;
|
||||
}
|
||||
|
||||
if( originalPostProcessing != r_useFilmicPostProcessing.GetInteger() )
|
||||
if( originalPostProcessing != r_useFilmicPostFX.GetInteger() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -315,6 +315,7 @@ void idCommonLocal::TimeRenderDemo( const char* demoName, bool twice, bool quit
|
|||
while( readDemo )
|
||||
{
|
||||
BusyWait(); // SRS - BusyWait() calls UpdateScreen() which draws and renders out-of-sequence but still supports frame timing
|
||||
commonLocal.frameTiming.finishSyncTime_EndFrame = Sys_Microseconds();
|
||||
commonLocal.mainFrameTiming = commonLocal.frameTiming;
|
||||
// ** End of current logical frame **
|
||||
|
||||
|
|
|
@ -380,14 +380,26 @@ public:
|
|||
// RB end
|
||||
|
||||
// SRS start
|
||||
uint64 GetRendererStartFrameSyncMicroseconds() const
|
||||
void SetRendererMvkEncodeMicroseconds( uint64 mvkEncodeMicroSeconds )
|
||||
{
|
||||
return mainFrameTiming.finishSyncTime - mainFrameTiming.startSyncTime;
|
||||
metal_encode = mvkEncodeMicroSeconds;
|
||||
return;
|
||||
}
|
||||
|
||||
uint64 GetRendererEndFrameSyncMicroseconds() const
|
||||
uint64 GetRendererMvkEncodeMicroseconds() const
|
||||
{
|
||||
return mainFrameTiming.finishSyncTime_EndFrame - mainFrameTiming.startRenderTime;
|
||||
return metal_encode;
|
||||
}
|
||||
|
||||
void SetRendererGpuMemoryMB( int gpuMemoryMB )
|
||||
{
|
||||
gpu_memory = gpuMemoryMB;
|
||||
return;
|
||||
}
|
||||
|
||||
int GetRendererGpuMemoryMB() const
|
||||
{
|
||||
return gpu_memory;
|
||||
}
|
||||
// SRS end
|
||||
|
||||
|
@ -604,6 +616,11 @@ private:
|
|||
backEndCounters_t stats_backend;
|
||||
performanceCounters_t stats_frontend;
|
||||
|
||||
// SRS - MoltenVK's Vulkan to Metal command buffer encoding time, set default to 0 for non-macOS platforms (Windows and Linux)
|
||||
uint64 metal_encode = 0;
|
||||
// SRS - Cross-platform GPU Memory usage counter, set default to 0 in case platform or graphics API does not support queries
|
||||
int gpu_memory = 0;
|
||||
|
||||
// Used during loading screens
|
||||
int lastPacifierSessionTime;
|
||||
int lastPacifierGuiTime;
|
||||
|
|
|
@ -225,8 +225,10 @@ float idConsoleLocal::DrawFPS( float y )
|
|||
extern idCVar r_swapInterval;
|
||||
|
||||
static float previousTimes[FPS_FRAMES];
|
||||
static float previousCpuUsage[FPS_FRAMES] = {};
|
||||
static float previousGpuUsage[FPS_FRAMES] = {};
|
||||
static float previousTimesNormalized[FPS_FRAMES_HISTORY];
|
||||
static int index;
|
||||
static int index = 0;
|
||||
static int previous;
|
||||
static int valuesOffset = 0;
|
||||
|
||||
|
@ -239,6 +241,8 @@ float idConsoleLocal::DrawFPS( float y )
|
|||
previous = t;
|
||||
|
||||
int fps = 0;
|
||||
float cpuUsage = 0.0;
|
||||
float gpuUsage = 0.0;
|
||||
|
||||
const float milliSecondsPerFrame = 1000.0f / com_engineHz_latched;
|
||||
|
||||
|
@ -253,6 +257,8 @@ float idConsoleLocal::DrawFPS( float y )
|
|||
for( int i = 0 ; i < FPS_FRAMES ; i++ )
|
||||
{
|
||||
total += previousTimes[i];
|
||||
cpuUsage += previousCpuUsage[i];
|
||||
gpuUsage += previousGpuUsage[i];
|
||||
}
|
||||
if( !total )
|
||||
{
|
||||
|
@ -260,6 +266,8 @@ float idConsoleLocal::DrawFPS( float y )
|
|||
}
|
||||
fps = 1000000 * FPS_FRAMES / total;
|
||||
fps = ( fps + 500 ) / 1000;
|
||||
cpuUsage /= FPS_FRAMES;
|
||||
gpuUsage /= FPS_FRAMES;
|
||||
|
||||
const char* s = va( "%ifps", fps );
|
||||
int w = strlen( s ) * BIGCHAR_WIDTH;
|
||||
|
@ -309,12 +317,26 @@ float idConsoleLocal::DrawFPS( float y )
|
|||
const int64 frameIdleTime = int64( commonLocal.mainFrameTiming.startGameTime ) - int64( commonLocal.mainFrameTiming.finishSyncTime );
|
||||
const int64 frameBusyTime = int64( commonLocal.frameTiming.finishSyncTime ) - int64( commonLocal.mainFrameTiming.startGameTime );
|
||||
|
||||
// SRS - Frame sync time represents swap buffer synchronization + game thread wait + other time spent outside of rendering
|
||||
const int64 frameSyncTime = int64( commonLocal.frameTiming.finishSyncTime ) - int64( commonLocal.mainFrameTiming.startRenderTime ) - int64( rendererBackEndTime );
|
||||
// SRS - Frame sync time represents swap buffer synchronization + other frame time spent outside of game thread and renderer backend
|
||||
const int64 gameThreadWaitTime = int64( commonLocal.mainFrameTiming.finishSyncTime_EndFrame ) - int64( commonLocal.mainFrameTiming.finishRenderTime );
|
||||
const int64 frameSyncTime = int64( commonLocal.frameTiming.finishSyncTime ) - int64( commonLocal.mainFrameTiming.startRenderTime + rendererBackEndTime ) - gameThreadWaitTime;
|
||||
|
||||
// SRS - GPU idle time is simply the difference between measured frame-over-frame time and GPU busy time (directly from GPU timers)
|
||||
const int64 rendererGPUIdleTime = frameBusyTime + frameIdleTime - rendererGPUTime;
|
||||
|
||||
// SRS - Estimate CPU busy time measured from start of game thread until completion of game thread and renderer backend (including excess MoltenVK encoding time if applicable)
|
||||
#if defined(__APPLE__) && defined( USE_MoltenVK )
|
||||
const int64 rendererMvkEncodeTime = commonLocal.GetRendererMvkEncodeMicroseconds();
|
||||
const int64 rendererQueueSubmitTime = int64( commonLocal.mainFrameTiming.finishRenderTime - commonLocal.mainFrameTiming.startRenderTime ) - int64( rendererBackEndTime );
|
||||
const int64 rendererCPUBusyTime = int64( commonLocal.mainFrameTiming.finishSyncTime_EndFrame - commonLocal.mainFrameTiming.startGameTime ) + Min( Max( int64( 0 ), rendererMvkEncodeTime - rendererQueueSubmitTime - gameThreadWaitTime ), frameSyncTime - rendererQueueSubmitTime );
|
||||
#else
|
||||
const int64 rendererCPUBusyTime = int64( commonLocal.mainFrameTiming.finishSyncTime_EndFrame - commonLocal.mainFrameTiming.startGameTime );
|
||||
#endif
|
||||
|
||||
// SRS - Save current CPU and GPU usage factors in ring buffer to calculate smoothed averages for future frames
|
||||
previousCpuUsage[( index - 1 ) % FPS_FRAMES] = float( rendererCPUBusyTime ) / float( frameBusyTime + frameIdleTime ) * 100.0;
|
||||
previousGpuUsage[( index - 1 ) % FPS_FRAMES] = float( rendererGPUTime ) / float( rendererGPUTime + rendererGPUIdleTime ) * 100.0;
|
||||
|
||||
#if 1
|
||||
|
||||
// RB: use ImGui to show more detailed stats about the scene loads
|
||||
|
@ -427,7 +449,7 @@ float idConsoleLocal::DrawFPS( float y )
|
|||
|
||||
ImGui::TextColored( colorCyan, "API: %s, AA[%i, %i]: %s, %s", API, width, height, aaMode, resolutionText.c_str() );
|
||||
|
||||
ImGui::TextColored( colorGold, "Device: %s", deviceManager->GetRendererString() );
|
||||
ImGui::TextColored( colorGold, "Device: %s, Memory: %i MB", deviceManager->GetRendererString(), commonLocal.GetRendererGpuMemoryMB() );
|
||||
|
||||
ImGui::TextColored( colorLtGrey, "GENERAL: views:%i draws:%i tris:%i",
|
||||
commonLocal.stats_frontend.c_numViews,
|
||||
|
@ -477,7 +499,7 @@ float idConsoleLocal::DrawFPS( float y )
|
|||
|
||||
if( com_showFPS.GetInteger() > 2 )
|
||||
{
|
||||
const char* overlay = va( "Average FPS %i", fps );
|
||||
const char* overlay = va( "Average FPS %-4i", fps );
|
||||
|
||||
ImGui::PlotLines( "Relative\nFrametime ms", previousTimesNormalized, FPS_FRAMES_HISTORY, valuesOffset, overlay, -10.0f, 10.0f, ImVec2( 0, 50 ) );
|
||||
}
|
||||
|
@ -494,12 +516,20 @@ float idConsoleLocal::DrawFPS( float y )
|
|||
ImGui::TextColored( gameThreadRenderTime > maxTime ? colorRed : colorWhite, "RF: %5llu us SSR: %5llu us", gameThreadRenderTime, rendererGPU_SSRTime );
|
||||
ImGui::TextColored( rendererBackEndTime > maxTime ? colorRed : colorWhite, "RB: %5llu us Ambient Pass: %5llu us", rendererBackEndTime, rendererGPUAmbientPassTime );
|
||||
ImGui::TextColored( rendererGPUShadowAtlasTime > maxTime ? colorRed : colorWhite, "Shadows: %5llu us Shadow Atlas: %5llu us", rendererShadowsTime, rendererGPUShadowAtlasTime );
|
||||
#if defined(__APPLE__) && defined( USE_MoltenVK )
|
||||
// SRS - For more recent versions of MoltenVK with enhanced performance statistics (v1.2.6 and later), display the Vulkan to Metal encoding thread time on macOS
|
||||
ImGui::TextColored( rendererMvkEncodeTime > maxTime || rendererGPUInteractionsTime > maxTime ? colorRed : colorWhite, "Encode: %5lld us Interactions: %5llu us", rendererMvkEncodeTime, rendererGPUInteractionsTime );
|
||||
ImGui::TextColored( rendererGPUShaderPassesTime > maxTime ? colorRed : colorWhite, "Sync: %5lld us Shader Pass: %5llu us", frameSyncTime, rendererGPUShaderPassesTime );
|
||||
#else
|
||||
ImGui::TextColored( rendererGPUInteractionsTime > maxTime ? colorRed : colorWhite, "Sync: %5lld us Interactions: %5llu us", frameSyncTime, rendererGPUInteractionsTime );
|
||||
ImGui::TextColored( rendererGPUShaderPassesTime > maxTime ? colorRed : colorWhite, " Shader Pass: %5llu us", rendererGPUShaderPassesTime );
|
||||
#endif
|
||||
ImGui::TextColored( rendererGPU_TAATime > maxTime ? colorRed : colorWhite, " TAA: %5llu us", rendererGPU_TAATime );
|
||||
ImGui::TextColored( rendererGPUPostProcessingTime > maxTime ? colorRed : colorWhite, " PostFX: %5llu us", rendererGPUPostProcessingTime );
|
||||
ImGui::TextColored( frameBusyTime > maxTime || rendererGPUTime > maxTime ? colorRed : colorWhite, "Total: %5lld us Total: %5lld us", frameBusyTime, rendererGPUTime );
|
||||
ImGui::TextColored( colorWhite, "Idle: %5lld us Idle: %5lld us", frameIdleTime, rendererGPUIdleTime );
|
||||
// SRS - Show CPU and GPU overall usage statistics
|
||||
//ImGui::TextColored( colorWhite, "Usage: %3.0f %% Usage: %3.0f %%", cpuUsage, gpuUsage );
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
|
|
@ -398,6 +398,8 @@ void idCommonLocal::Draw()
|
|||
|
||||
// draw the half console / notify console on top of everything
|
||||
console->Draw( false );
|
||||
|
||||
renderSystem->DrawCRTPostFX();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -880,13 +882,13 @@ void idCommonLocal::Frame()
|
|||
}
|
||||
frameTiming.finishRenderTime = Sys_Microseconds();
|
||||
|
||||
// SRS - Use finishSyncTime_EndFrame to record timing just before gameThread.WaitForThread() for com_smp = 1
|
||||
frameTiming.finishSyncTime_EndFrame = Sys_Microseconds();
|
||||
|
||||
// make sure the game / draw thread has completed
|
||||
// This may block if the game is taking longer than the render back end
|
||||
gameThread.WaitForThread();
|
||||
|
||||
// SRS - Use finishSyncTime_EndFrame to record timing just after gameThread.WaitForThread()
|
||||
frameTiming.finishSyncTime_EndFrame = Sys_Microseconds();
|
||||
|
||||
// Send local usermds to the server.
|
||||
// This happens after the game frame has run so that prediction data is up to date.
|
||||
SendUsercmds( Game()->GetLocalClientNum() );
|
||||
|
|
|
@ -70,5 +70,11 @@
|
|||
#else
|
||||
#define OPTICK_ENABLE_GPU_VULKAN (OPTICK_ENABLE_GPU /*&& 0*/)
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Vulkan Functions
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(OPTICK_STATIC_VULKAN_FUNCTIONS)
|
||||
#define OPTICK_STATIC_VULKAN_FUNCTIONS (0 /*1*/)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
|
|
@ -96,6 +96,7 @@
|
|||
|
||||
// Vulkan Forward Declarations
|
||||
#define OPTICK_DEFINE_HANDLE(object) typedef struct object##_T *object;
|
||||
OPTICK_DEFINE_HANDLE(VkInstance);
|
||||
OPTICK_DEFINE_HANDLE(VkDevice);
|
||||
OPTICK_DEFINE_HANDLE(VkPhysicalDevice);
|
||||
OPTICK_DEFINE_HANDLE(VkQueue);
|
||||
|
@ -125,6 +126,7 @@ struct VkCommandBufferBeginInfo;
|
|||
#endif
|
||||
#endif
|
||||
|
||||
typedef void* (VKAPI_PTR *PFN_vkGetInstanceProcAddr_)(VkInstance instance, const char* pName);
|
||||
typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceProperties_)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties* pProperties);
|
||||
typedef int32_t (VKAPI_PTR *PFN_vkCreateQueryPool_)(VkDevice device, const VkQueryPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkQueryPool* pQueryPool);
|
||||
typedef int32_t (VKAPI_PTR *PFN_vkCreateCommandPool_)(VkDevice device, const VkCommandPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkCommandPool* pCommandPool);
|
||||
|
@ -165,6 +167,7 @@ namespace Optick
|
|||
{
|
||||
struct OPTICK_API VulkanFunctions
|
||||
{
|
||||
PFN_vkGetInstanceProcAddr_ vkGetInstanceProcAddr;
|
||||
PFN_vkGetPhysicalDeviceProperties_ vkGetPhysicalDeviceProperties;
|
||||
PFN_vkCreateQueryPool_ vkCreateQueryPool;
|
||||
PFN_vkCreateCommandPool_ vkCreateCommandPool;
|
||||
|
@ -778,7 +781,7 @@ struct OPTICK_API GPUContext
|
|||
};
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
OPTICK_API void InitGpuD3D12(ID3D12Device* device, ID3D12CommandQueue** cmdQueues, uint32_t numQueues);
|
||||
OPTICK_API void InitGpuVulkan(VkDevice* vkDevices, VkPhysicalDevice* vkPhysicalDevices, VkQueue* vkQueues, uint32_t* cmdQueuesFamily, uint32_t numQueues, const VulkanFunctions* functions);
|
||||
OPTICK_API void InitGpuVulkan(VkInstance vkInstance, VkDevice* vkDevices, VkPhysicalDevice* vkPhysicalDevices, VkQueue* vkQueues, uint32_t* cmdQueuesFamily, uint32_t numQueues, const VulkanFunctions* functions);
|
||||
OPTICK_API void GpuFlip(void* swapChain, uint32_t frameID = 0);
|
||||
OPTICK_API GPUContext SetGpuContext(GPUContext context);
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1046,7 +1049,7 @@ struct OptickApp
|
|||
|
||||
// GPU events
|
||||
#define OPTICK_GPU_INIT_D3D12(DEVICE, CMD_QUEUES, NUM_CMD_QUEUS) ::Optick::InitGpuD3D12(DEVICE, CMD_QUEUES, NUM_CMD_QUEUS);
|
||||
#define OPTICK_GPU_INIT_VULKAN(DEVICES, PHYSICAL_DEVICES, CMD_QUEUES, CMD_QUEUES_FAMILY, NUM_CMD_QUEUS, FUNCTIONS) ::Optick::InitGpuVulkan(DEVICES, PHYSICAL_DEVICES, CMD_QUEUES, CMD_QUEUES_FAMILY, NUM_CMD_QUEUS, FUNCTIONS);
|
||||
#define OPTICK_GPU_INIT_VULKAN(INSTANCE, DEVICES, PHYSICAL_DEVICES, CMD_QUEUES, CMD_QUEUES_FAMILY, NUM_CMD_QUEUS, FUNCTIONS) ::Optick::InitGpuVulkan(INSTANCE, DEVICES, PHYSICAL_DEVICES, CMD_QUEUES, CMD_QUEUES_FAMILY, NUM_CMD_QUEUS, FUNCTIONS);
|
||||
|
||||
// Setup GPU context:
|
||||
// Params:
|
||||
|
@ -1121,7 +1124,7 @@ struct OptickApp
|
|||
#define OPTICK_SET_MEMORY_ALLOCATOR(ALLOCATE_FUNCTION, DEALLOCATE_FUNCTION, INIT_THREAD_CALLBACK)
|
||||
#define OPTICK_SHUTDOWN()
|
||||
#define OPTICK_GPU_INIT_D3D12(DEVICE, CMD_QUEUES, NUM_CMD_QUEUS)
|
||||
#define OPTICK_GPU_INIT_VULKAN(DEVICES, PHYSICAL_DEVICES, CMD_QUEUES, CMD_QUEUES_FAMILY, NUM_CMD_QUEUS, FUNCTIONS)
|
||||
#define OPTICK_GPU_INIT_VULKAN(INSTANCE, DEVICES, PHYSICAL_DEVICES, CMD_QUEUES, CMD_QUEUES_FAMILY, NUM_CMD_QUEUS, FUNCTIONS)
|
||||
#define OPTICK_GPU_CONTEXT(...)
|
||||
#define OPTICK_GPU_EVENT(NAME)
|
||||
#define OPTICK_GPU_FLIP(...)
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdexcept>
|
||||
|
||||
#if defined(OPTICK_MSVC)
|
||||
|
||||
|
@ -143,11 +144,12 @@ static const ProcessID INVALID_PROCESS_ID = (ProcessID)-1;
|
|||
#ifdef _DEBUG
|
||||
#define OPTICK_ASSERT(arg, description) if (!(arg)) { OPTICK_DEBUG_BREAK; }
|
||||
#define OPTICK_FAILED(description) { OPTICK_DEBUG_BREAK; }
|
||||
#define OPTICK_VERIFY(arg, description, operation) if (!(arg)) { OPTICK_DEBUG_BREAK; operation; }
|
||||
#else
|
||||
#define OPTICK_ASSERT(arg, description)
|
||||
#define OPTICK_FAILED(description)
|
||||
#define OPTICK_FAILED(description) { throw std::runtime_error(description); }
|
||||
#define OPTICK_VERIFY(arg, description, operation) if (!(arg)) { OPTICK_FAILED(description); operation; }
|
||||
#endif
|
||||
#define OPTICK_VERIFY(arg, description, operation) if (!(arg)) { OPTICK_DEBUG_BREAK; operation; }
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -71,7 +71,7 @@ namespace Optick
|
|||
GPUProfilerVulkan();
|
||||
~GPUProfilerVulkan();
|
||||
|
||||
void InitDevice(VkDevice* devices, VkPhysicalDevice* physicalDevices, VkQueue* cmdQueues, uint32_t* cmdQueuesFamily, uint32_t nodeCount, const VulkanFunctions* functions);
|
||||
void InitDevice(VkInstance instance, VkDevice* devices, VkPhysicalDevice* physicalDevices, VkQueue* cmdQueues, uint32_t* cmdQueuesFamily, uint32_t nodeCount, const VulkanFunctions* functions);
|
||||
void QueryTimestamp(VkCommandBuffer commandBuffer, int64_t* outCpuTimestamp);
|
||||
void Flip(VkSwapchainKHR swapChain);
|
||||
|
||||
|
@ -94,10 +94,10 @@ namespace Optick
|
|||
}
|
||||
};
|
||||
|
||||
void InitGpuVulkan(VkDevice* vkDevices, VkPhysicalDevice* vkPhysicalDevices, VkQueue* vkQueues, uint32_t* cmdQueuesFamily, uint32_t numQueues, const VulkanFunctions* functions)
|
||||
void InitGpuVulkan(VkInstance vkInstance, VkDevice* vkDevices, VkPhysicalDevice* vkPhysicalDevices, VkQueue* vkQueues, uint32_t* cmdQueuesFamily, uint32_t numQueues, const VulkanFunctions* functions)
|
||||
{
|
||||
GPUProfilerVulkan* gpuProfiler = Memory::New<GPUProfilerVulkan>();
|
||||
gpuProfiler->InitDevice(vkDevices, vkPhysicalDevices, vkQueues, cmdQueuesFamily, numQueues, functions);
|
||||
gpuProfiler->InitDevice(vkInstance, vkDevices, vkPhysicalDevices, vkQueues, cmdQueuesFamily, numQueues, functions);
|
||||
Core::Get().InitGPUProfiler(gpuProfiler);
|
||||
}
|
||||
|
||||
|
@ -107,15 +107,17 @@ namespace Optick
|
|||
prevPresentID = 0;
|
||||
}
|
||||
|
||||
void GPUProfilerVulkan::InitDevice(VkDevice* devices, VkPhysicalDevice* physicalDevices, VkQueue* cmdQueues, uint32_t* cmdQueuesFamily, uint32_t nodeCount, const VulkanFunctions* functions)
|
||||
void GPUProfilerVulkan::InitDevice(VkInstance instance, VkDevice* devices, VkPhysicalDevice* physicalDevices, VkQueue* cmdQueues, uint32_t* cmdQueuesFamily, uint32_t nodeCount, const VulkanFunctions* functions)
|
||||
{
|
||||
if (functions != nullptr)
|
||||
{
|
||||
vulkanFunctions = *functions;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
#if OPTICK_STATIC_VULKAN_FUNCTIONS
|
||||
vulkanFunctions = {
|
||||
nullptr, // don't define vkGetInstanceProcAddr if vulkan functions are static
|
||||
vkGetPhysicalDeviceProperties,
|
||||
(PFN_vkCreateQueryPool_)vkCreateQueryPool,
|
||||
(PFN_vkCreateCommandPool_)vkCreateCommandPool,
|
||||
|
@ -142,6 +144,23 @@ namespace Optick
|
|||
vkFreeCommandBuffers,
|
||||
nullptr, // dynamically define vkGetPastPresentationTimingGOOGLE if VK_GOOGLE_display_timing extension available
|
||||
};
|
||||
#else
|
||||
OPTICK_FAILED("Either set OPTICK_STATIC_VULKAN_FUNCTIONS = 1 or VulkanFunctions must be defined! Can't initialize GPU Profiler!");
|
||||
#endif
|
||||
}
|
||||
|
||||
PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr_ = nullptr;
|
||||
if (vulkanFunctions.vkGetInstanceProcAddr)
|
||||
{
|
||||
if (instance)
|
||||
{
|
||||
vkGetDeviceProcAddr_ = (PFN_vkGetDeviceProcAddr)(*vulkanFunctions.vkGetInstanceProcAddr)(instance, "vkGetDeviceProcAddr");
|
||||
vulkanFunctions.vkGetPhysicalDeviceProperties = (PFN_vkGetPhysicalDeviceProperties_)(*vulkanFunctions.vkGetInstanceProcAddr)(instance, "vkGetPhysicalDeviceProperties");
|
||||
}
|
||||
else
|
||||
{
|
||||
OPTICK_FAILED("VkInstance must be defined if VulkanFunctions::vkGetInstanceProcAddr is defined! Can't initialize GPU Profiler!");
|
||||
}
|
||||
}
|
||||
|
||||
VkQueryPoolCreateInfo queryPoolCreateInfo;
|
||||
|
@ -168,6 +187,40 @@ namespace Optick
|
|||
VkResult r;
|
||||
for (uint32_t i = 0; i < nodeCount; ++i)
|
||||
{
|
||||
if (vkGetDeviceProcAddr_)
|
||||
{
|
||||
vulkanFunctions.vkCreateQueryPool = (PFN_vkCreateQueryPool_)vkGetDeviceProcAddr_(devices[i], "vkCreateQueryPool");
|
||||
vulkanFunctions.vkCreateCommandPool = (PFN_vkCreateCommandPool_)vkGetDeviceProcAddr_(devices[i], "vkCreateCommandPool");
|
||||
vulkanFunctions.vkCreateEvent = (PFN_vkCreateEvent_)vkGetDeviceProcAddr_(devices[i], "vkCreateEvent");
|
||||
vulkanFunctions.vkAllocateCommandBuffers = (PFN_vkAllocateCommandBuffers_)vkGetDeviceProcAddr_(devices[i], "vkAllocateCommandBuffers");
|
||||
vulkanFunctions.vkCreateFence = (PFN_vkCreateFence_)vkGetDeviceProcAddr_(devices[i], "vkCreateFence");
|
||||
vulkanFunctions.vkCmdResetQueryPool = (PFN_vkCmdResetQueryPool_)vkGetDeviceProcAddr_(devices[i], "vkCmdResetQueryPool");
|
||||
vulkanFunctions.vkResetQueryPool = (PFN_vkResetQueryPool_)vkGetDeviceProcAddr_(devices[i], "vkResetQueryPool");
|
||||
vulkanFunctions.vkCmdWaitEvents = (PFN_vkCmdWaitEvents_)vkGetDeviceProcAddr_(devices[i], "vkCmdWaitEvents");
|
||||
vulkanFunctions.vkResetEvent = (PFN_vkResetEvent_)vkGetDeviceProcAddr_(devices[i], "vkResetEvent");
|
||||
vulkanFunctions.vkSetEvent = (PFN_vkSetEvent_)vkGetDeviceProcAddr_(devices[i], "vkSetEvent");
|
||||
vulkanFunctions.vkQueueSubmit = (PFN_vkQueueSubmit_)vkGetDeviceProcAddr_(devices[i], "vkQueueSubmit");
|
||||
vulkanFunctions.vkWaitForFences = (PFN_vkWaitForFences_)vkGetDeviceProcAddr_(devices[i], "vkWaitForFences");
|
||||
vulkanFunctions.vkResetCommandBuffer = (PFN_vkResetCommandBuffer_)vkGetDeviceProcAddr_(devices[i], "vkResetCommandBuffer");
|
||||
vulkanFunctions.vkCmdWriteTimestamp = (PFN_vkCmdWriteTimestamp_)vkGetDeviceProcAddr_(devices[i], "vkCmdWriteTimestamp");
|
||||
vulkanFunctions.vkGetQueryPoolResults = (PFN_vkGetQueryPoolResults_)vkGetDeviceProcAddr_(devices[i], "vkGetQueryPoolResults");
|
||||
vulkanFunctions.vkBeginCommandBuffer = (PFN_vkBeginCommandBuffer_)vkGetDeviceProcAddr_(devices[i], "vkBeginCommandBuffer");
|
||||
vulkanFunctions.vkEndCommandBuffer = (PFN_vkEndCommandBuffer_)vkGetDeviceProcAddr_(devices[i], "vkEndCommandBuffer");
|
||||
vulkanFunctions.vkResetFences = (PFN_vkResetFences_)vkGetDeviceProcAddr_(devices[i], "vkResetFences");
|
||||
vulkanFunctions.vkDestroyCommandPool = (PFN_vkDestroyCommandPool_)vkGetDeviceProcAddr_(devices[i], "vkDestroyCommandPool");
|
||||
vulkanFunctions.vkDestroyQueryPool = (PFN_vkDestroyQueryPool_)vkGetDeviceProcAddr_(devices[i], "vkDestroyQueryPool");
|
||||
vulkanFunctions.vkDestroyEvent = (PFN_vkDestroyEvent_)vkGetDeviceProcAddr_(devices[i], "vkDestroyEvent");
|
||||
vulkanFunctions.vkDestroyFence = (PFN_vkDestroyFence_)vkGetDeviceProcAddr_(devices[i], "vkDestroyFence");
|
||||
vulkanFunctions.vkFreeCommandBuffers = (PFN_vkFreeCommandBuffers_)vkGetDeviceProcAddr_(devices[i], "vkFreeCommandBuffers");
|
||||
vulkanFunctions.vkGetPastPresentationTimingGOOGLE = (PFN_vkGetPastPresentationTimingGOOGLE_)vkGetDeviceProcAddr_(devices[i], "vkGetPastPresentationTimingGOOGLE");
|
||||
}
|
||||
#if OPTICK_STATIC_VULKAN_FUNCTIONS
|
||||
else if (!vulkanFunctions.vkGetPastPresentationTimingGOOGLE)
|
||||
{
|
||||
vulkanFunctions.vkGetPastPresentationTimingGOOGLE = (PFN_vkGetPastPresentationTimingGOOGLE_)vkGetDeviceProcAddr(devices[i], "vkGetPastPresentationTimingGOOGLE");
|
||||
}
|
||||
#endif
|
||||
|
||||
VkPhysicalDeviceProperties properties = { 0 };
|
||||
(*vulkanFunctions.vkGetPhysicalDeviceProperties)(physicalDevices[i], &properties);
|
||||
GPUProfiler::InitNode(properties.deviceName, i);
|
||||
|
@ -175,7 +228,6 @@ namespace Optick
|
|||
NodePayload* nodePayload = Memory::New<NodePayload>();
|
||||
nodePayloads[i] = nodePayload;
|
||||
nodePayload->vulkanFunctions = &vulkanFunctions;
|
||||
nodePayload->vulkanFunctions->vkGetPastPresentationTimingGOOGLE = (PFN_vkGetPastPresentationTimingGOOGLE_)vkGetDeviceProcAddr(devices[i], "vkGetPastPresentationTimingGOOGLE");
|
||||
nodePayload->device = devices[i];
|
||||
nodePayload->physicalDevice = physicalDevices[i];
|
||||
nodePayload->queue = cmdQueues[i];
|
||||
|
@ -498,7 +550,7 @@ namespace Optick
|
|||
#include "optick_common.h"
|
||||
namespace Optick
|
||||
{
|
||||
void InitGpuVulkan(VkDevice* /*vkDevices*/, VkPhysicalDevice* /*vkPhysicalDevices*/, VkQueue* /*vkQueues*/, uint32_t* /*cmdQueuesFamily*/, uint32_t /*numQueues*/, const VulkanFunctions* /*functions*/)
|
||||
void InitGpuVulkan(VkInstance /*vkInstance*/, VkDevice* /*vkDevices*/, VkPhysicalDevice* /*vkPhysicalDevices*/, VkQueue* /*vkQueues*/, uint32_t* /*cmdQueuesFamily*/, uint32_t /*numQueues*/, const VulkanFunctions* /*functions*/)
|
||||
{
|
||||
OPTICK_FAILED("OPTICK_ENABLE_GPU_VULKAN is disabled! Can't initialize GPU Profiler!");
|
||||
}
|
||||
|
|
|
@ -289,7 +289,7 @@ Server::Server(short port) : socket(Memory::New<Socket>()), saveCb(nullptr)
|
|||
{
|
||||
if (!socket->Bind(port, 4))
|
||||
{
|
||||
OPTICK_FAILED("Failed to bind a socket! Most probably the port is blocked by anti-virus! Change the port and verify that your game has enough permissions to communicate over the TCP\IP.");
|
||||
OPTICK_FAILED("Failed to bind a socket! Most probably the port is blocked by anti-virus! Change the port and verify that your game has enough permissions to communicate over the TCP/IP.");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -499,4 +499,4 @@ Server & Server::Get()
|
|||
|
||||
}
|
||||
|
||||
#endif //USE_OPTICK
|
||||
#endif //USE_OPTICK
|
||||
|
|
|
@ -46,7 +46,6 @@ If you have questions concerning this license or the applicable additional terms
|
|||
#include "../libs/mesa/format_r11g11b10f.h"
|
||||
|
||||
idCVar image_highQualityCompression( "image_highQualityCompression", "0", CVAR_BOOL, "Use high quality (slow) compression" );
|
||||
idCVar r_useHighQualitySky( "r_useHighQualitySky", "1", CVAR_BOOL | CVAR_ARCHIVE, "Use high quality skyboxes" );
|
||||
|
||||
/*
|
||||
========================
|
||||
|
|
|
@ -459,15 +459,7 @@ public:
|
|||
return ( void* )texture.Get();
|
||||
}
|
||||
|
||||
void* GetSampler( SamplerCache& samplerCache )
|
||||
{
|
||||
if( !sampler )
|
||||
{
|
||||
sampler = samplerCache.GetOrCreateSampler( samplerDesc );
|
||||
}
|
||||
|
||||
return ( void* )sampler.Get();
|
||||
}
|
||||
void* GetSampler( SamplerCache& samplerCache );
|
||||
|
||||
void* GetSampler( nvrhi::IDevice* device )
|
||||
{
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
Copyright (C) 2013-2021 Robert Beckebans
|
||||
Copyright (C) 2013-2024 Robert Beckebans
|
||||
Copyright (C) 2022 Stephen Pridham
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
@ -1148,3 +1148,209 @@ void idImageManager::CreateIntrinsicImages()
|
|||
release_assert( loadingIconImage->referencedOutsideLevelLoad );
|
||||
release_assert( hellLoadingIconImage->referencedOutsideLevelLoad );
|
||||
}
|
||||
|
||||
|
||||
CONSOLE_COMMAND( makeImageHeader, "load an image and turn it into a .h file", NULL )
|
||||
{
|
||||
byte* buffer;
|
||||
int width = 0, height = 0;
|
||||
|
||||
if( args.Argc() < 2 )
|
||||
{
|
||||
common->Printf( "USAGE: makeImageHeader filename [exportname]\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
idStr filename = args.Argv( 1 );
|
||||
|
||||
R_LoadImage( filename, &buffer, &width, &height, NULL, true, NULL );
|
||||
if( !buffer )
|
||||
{
|
||||
common->Printf( "loading %s failed.\n", filename.c_str() );
|
||||
return;
|
||||
}
|
||||
|
||||
filename.StripFileExtension();
|
||||
|
||||
idStr exportname;
|
||||
|
||||
if( args.Argc() == 3 )
|
||||
{
|
||||
exportname.Format( "Image_%s.h", args.Argv( 2 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
exportname.Format( "Image_%s.h", filename.c_str() );
|
||||
}
|
||||
|
||||
for( int i = 0; i < exportname.Length(); i++ )
|
||||
{
|
||||
if( exportname[ i ] == '/' )
|
||||
{
|
||||
exportname[ i ] = '_';
|
||||
}
|
||||
}
|
||||
|
||||
idFileLocal headerFile( fileSystem->OpenFileWrite( exportname, "fs_basepath" ) );
|
||||
|
||||
idStr uppername = exportname;
|
||||
uppername.ToUpper();
|
||||
|
||||
for( int i = 0; i < uppername.Length(); i++ )
|
||||
{
|
||||
if( uppername[ i ] == '.' )
|
||||
{
|
||||
uppername[ i ] = '_';
|
||||
}
|
||||
}
|
||||
|
||||
headerFile->Printf( "#ifndef %s_TEX_H\n", uppername.c_str() );
|
||||
headerFile->Printf( "#define %s_TEX_H\n\n", uppername.c_str() );
|
||||
|
||||
headerFile->Printf( "#define %s_TEX_WIDTH %i\n", uppername.c_str(), width );
|
||||
headerFile->Printf( "#define %s_TEX_HEIGHT %i\n\n", uppername.c_str(), height );
|
||||
|
||||
headerFile->Printf( "static const unsigned char %s_Bytes[] = {\n", uppername.c_str() );
|
||||
|
||||
int bufferSize = width * height * 4;
|
||||
|
||||
for( int i = 0; i < bufferSize; i++ )
|
||||
{
|
||||
byte b = buffer[i];
|
||||
|
||||
if( i < ( bufferSize - 1 ) )
|
||||
{
|
||||
headerFile->Printf( "0x%02hhx, ", b );
|
||||
}
|
||||
else
|
||||
{
|
||||
headerFile->Printf( "0x%02hhx", b );
|
||||
}
|
||||
|
||||
if( i % 12 == 0 )
|
||||
{
|
||||
headerFile->Printf( "\n" );
|
||||
}
|
||||
}
|
||||
headerFile->Printf( "\n};\n#endif\n" );
|
||||
|
||||
Mem_Free( buffer );
|
||||
}
|
||||
|
||||
CONSOLE_COMMAND( makePaletteHeader, "load a .pal palette, build an image from it and turn it into a .h file", NULL )
|
||||
{
|
||||
if( args.Argc() < 2 )
|
||||
{
|
||||
common->Printf( "USAGE: makePaletteHeader filename [exportname]\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
idStr filename = args.Argv( 1 );
|
||||
filename.DefaultFileExtension( ".pal" );
|
||||
|
||||
ID_TIME_T timeStamp;
|
||||
char* palBuffer;
|
||||
int palBufferLen = fileSystem->ReadFile( filename, ( void** )&palBuffer, &timeStamp );
|
||||
if( palBufferLen <= 0 || palBuffer == nullptr )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// parse JASC-PAL file
|
||||
idLexer src;
|
||||
idToken token, token2;
|
||||
|
||||
src.LoadMemory( palBuffer, palBufferLen, filename, 0 );
|
||||
|
||||
src.ExpectTokenString( "JASC" );
|
||||
src.ExpectTokenString( "-" );
|
||||
src.ExpectTokenString( "PAL" );
|
||||
int palVersion = src.ParseInt();
|
||||
|
||||
int numColors = src.ParseInt();
|
||||
|
||||
//idList<id
|
||||
byte rgb[3];
|
||||
for( int i = 0; i < numColors; i++ )
|
||||
{
|
||||
rgb[0] = src.ParseInt();
|
||||
rgb[1] = src.ParseInt();
|
||||
rgb[2] = src.ParseInt();
|
||||
|
||||
idLib::Printf( "RGB( %d, %d, %d ),\n", rgb[0], rgb[1], rgb[2] );
|
||||
}
|
||||
|
||||
fileSystem->FreeFile( palBuffer );
|
||||
|
||||
filename.StripFileExtension();
|
||||
|
||||
// TODO build image and convert to header
|
||||
//byte* buffer;
|
||||
//int width = 0, height = 0;
|
||||
|
||||
/*
|
||||
idStr exportname;
|
||||
|
||||
if( args.Argc() == 3 )
|
||||
{
|
||||
exportname.Format( "Image_%s.h", args.Argv( 2 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
exportname.Format( "Image_%s.h", filename.c_str() );
|
||||
}
|
||||
|
||||
for( int i = 0; i < exportname.Length(); i++ )
|
||||
{
|
||||
if( exportname[ i ] == '/' )
|
||||
{
|
||||
exportname[ i ] = '_';
|
||||
}
|
||||
}
|
||||
|
||||
idFileLocal headerFile( fileSystem->OpenFileWrite( exportname, "fs_basepath" ) );
|
||||
|
||||
idStr uppername = exportname;
|
||||
uppername.ToUpper();
|
||||
|
||||
for( int i = 0; i < uppername.Length(); i++ )
|
||||
{
|
||||
if( uppername[ i ] == '.' )
|
||||
{
|
||||
uppername[ i ] = '_';
|
||||
}
|
||||
}
|
||||
|
||||
headerFile->Printf( "#ifndef %s_TEX_H\n", uppername.c_str() );
|
||||
headerFile->Printf( "#define %s_TEX_H\n\n", uppername.c_str() );
|
||||
|
||||
headerFile->Printf( "#define %s_TEX_WIDTH %i\n", uppername.c_str(), width );
|
||||
headerFile->Printf( "#define %s_TEX_HEIGHT %i\n\n", uppername.c_str(), height );
|
||||
|
||||
headerFile->Printf( "static const unsigned char %s_Bytes[] = {\n", uppername.c_str() );
|
||||
|
||||
int bufferSize = width * height * 4;
|
||||
|
||||
for( int i = 0; i < bufferSize; i++ )
|
||||
{
|
||||
byte b = buffer[i];
|
||||
|
||||
if( i < ( bufferSize - 1 ) )
|
||||
{
|
||||
headerFile->Printf( "0x%02hhx, ", b );
|
||||
}
|
||||
else
|
||||
{
|
||||
headerFile->Printf( "0x%02hhx", b );
|
||||
}
|
||||
|
||||
if( i % 12 == 0 )
|
||||
{
|
||||
headerFile->Printf( "\n" );
|
||||
}
|
||||
}
|
||||
headerFile->Printf( "\n};\n#endif\n" );
|
||||
|
||||
Mem_Free( buffer );
|
||||
*/
|
||||
}
|
|
@ -73,8 +73,6 @@ typedef struct mtrParsingData_s
|
|||
bool forceOverlays;
|
||||
} mtrParsingData_t;
|
||||
|
||||
extern idCVar r_useHighQualitySky;
|
||||
|
||||
idCVar r_forceSoundOpAmplitude( "r_forceSoundOpAmplitude", "0", CVAR_FLOAT, "Don't call into the sound system for amplitudes" );
|
||||
|
||||
/*
|
||||
|
@ -1870,14 +1868,7 @@ void idMaterial::ParseStage( idLexer& src, const textureRepeat_t trpDefault )
|
|||
}
|
||||
if( !token.Icmp( "uncompressedCubeMap" ) )
|
||||
{
|
||||
if( r_useHighQualitySky.GetBool() )
|
||||
{
|
||||
td = TD_HIGHQUALITY_CUBE; // motorsep 05-17-2015; token to mark cubemap/skybox to be uncompressed texture
|
||||
}
|
||||
else
|
||||
{
|
||||
td = TD_LOWQUALITY_CUBE;
|
||||
}
|
||||
td = TD_HIGHQUALITY_CUBE; // motorsep 05-17-2015; token to mark cubemap/skybox to be uncompressed texture
|
||||
continue;
|
||||
}
|
||||
if( !token.Icmp( "nopicmip" ) )
|
||||
|
|
|
@ -44,7 +44,7 @@ static const char* MD5_SnapshotName = "_MD5_Snapshot_";
|
|||
static const byte MD5B_VERSION = 106;
|
||||
static const unsigned int MD5B_MAGIC = ( '5' << 24 ) | ( 'D' << 16 ) | ( 'M' << 8 ) | MD5B_VERSION;
|
||||
|
||||
idCVar r_useGPUSkinning( "r_useGPUSkinning", "1", CVAR_INTEGER, "animate normals and tangents instead of deriving" );
|
||||
idCVar r_useGPUSkinning( "r_useGPUSkinning", "1", CVAR_INTEGER | CVAR_NOCHEAT, "animate normals and tangents instead of deriving" );
|
||||
|
||||
/***********************************************************************
|
||||
|
||||
|
|
|
@ -729,9 +729,13 @@ bool idUniformBuffer::AllocBufferObject( const void* data, int allocSize, buffer
|
|||
// This buffer is a shader resource as opposed to a constant buffer due to
|
||||
// constant buffers not being able to be sub-ranged.
|
||||
nvrhi::BufferDesc bufferDesc;
|
||||
//bufferDesc.initialState = nvrhi::ResourceStates::ConstantBuffer; // SRS - shouldn't this be initialized to CopyDest?
|
||||
bufferDesc.initialState = nvrhi::ResourceStates::CopyDest;
|
||||
bufferDesc.canHaveTypedViews = true;
|
||||
bufferDesc.canHaveRawViews = true;
|
||||
bufferDesc.byteSize = numBytes;
|
||||
bufferDesc.structStride = sizeof( idVec4 ); // SRS - this defines a structured storage buffer vs. a constant buffer
|
||||
bufferDesc.initialState = nvrhi::ResourceStates::Common;
|
||||
bufferDesc.structStride = sizeof( idVec4 );
|
||||
bufferDesc.isConstantBuffer = true;
|
||||
|
||||
if( usage == BU_DYNAMIC )
|
||||
{
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
Copyright (C) 2013-2022 Robert Beckebans
|
||||
Copyright (C) 2013-2023 Robert Beckebans
|
||||
Copyright (C) 2022 Stephen Pridham
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
@ -30,11 +30,7 @@ If you have questions concerning this license or the applicable additional terms
|
|||
#include "precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
/*
|
||||
================================================================================================
|
||||
Contains the Image implementation for OpenGL.
|
||||
================================================================================================
|
||||
*/
|
||||
idCVar image_pixelLook( "image_pixelLook", "0", CVAR_BOOL | CVAR_ARCHIVE, "Turn off linear filtering on most textures to achieve the 90s software renderer look" );
|
||||
|
||||
#include "../RenderCommon.h"
|
||||
|
||||
|
@ -296,6 +292,36 @@ void idImage::SetTexParameters()
|
|||
{
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idImage::GetSampler
|
||||
========================
|
||||
*/
|
||||
void* idImage::GetSampler( SamplerCache& samplerCache )
|
||||
{
|
||||
if( R_UsePixelatedLook() )
|
||||
{
|
||||
if( !sampler )
|
||||
{
|
||||
nvrhi::SamplerDesc sampDesc = samplerDesc;
|
||||
|
||||
// turn off linear filtering
|
||||
sampDesc.setAllFilters( false );
|
||||
|
||||
sampler = samplerCache.GetOrCreateSampler( samplerDesc );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !sampler )
|
||||
{
|
||||
sampler = samplerCache.GetOrCreateSampler( samplerDesc );
|
||||
}
|
||||
}
|
||||
|
||||
return ( void* )sampler.Get();
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idImage::AllocImage
|
||||
|
|
|
@ -733,18 +733,37 @@ void idRenderBackend::GetCurrentBindingLayout( int type )
|
|||
desc[2].bindings[5].resourceHandle = ( nvrhi::ITexture* )GetImageAt( 10 )->GetTextureID();
|
||||
}
|
||||
|
||||
if( desc[3].bindings.empty() )
|
||||
if( R_UsePixelatedLook() )
|
||||
{
|
||||
desc[3].bindings =
|
||||
if( desc[3].bindings.empty() )
|
||||
{
|
||||
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_AnisotropicWrapSampler ),
|
||||
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearClampSampler )
|
||||
};
|
||||
desc[3].bindings =
|
||||
{
|
||||
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_PointWrapSampler ),
|
||||
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearClampSampler )
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
desc[3].bindings[0].resourceHandle = commonPasses.m_PointWrapSampler;
|
||||
desc[3].bindings[1].resourceHandle = commonPasses.m_LinearClampSampler;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
desc[3].bindings[0].resourceHandle = commonPasses.m_AnisotropicWrapSampler;
|
||||
desc[3].bindings[1].resourceHandle = commonPasses.m_LinearClampSampler;
|
||||
if( desc[3].bindings.empty() )
|
||||
{
|
||||
desc[3].bindings =
|
||||
{
|
||||
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_AnisotropicWrapSampler ),
|
||||
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearClampSampler )
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
desc[3].bindings[0].resourceHandle = commonPasses.m_AnisotropicWrapSampler;
|
||||
desc[3].bindings[1].resourceHandle = commonPasses.m_LinearClampSampler;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( type == BINDING_LAYOUT_AMBIENT_LIGHTING_IBL_SKINNED )
|
||||
|
@ -804,18 +823,37 @@ void idRenderBackend::GetCurrentBindingLayout( int type )
|
|||
desc[2].bindings[5].resourceHandle = ( nvrhi::ITexture* )GetImageAt( 10 )->GetTextureID();
|
||||
}
|
||||
|
||||
if( desc[3].bindings.empty() )
|
||||
if( R_UsePixelatedLook() )
|
||||
{
|
||||
desc[3].bindings =
|
||||
if( desc[3].bindings.empty() )
|
||||
{
|
||||
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_AnisotropicWrapSampler ),
|
||||
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearClampSampler )
|
||||
};
|
||||
desc[3].bindings =
|
||||
{
|
||||
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_PointWrapSampler ),
|
||||
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearClampSampler )
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
desc[3].bindings[0].resourceHandle = commonPasses.m_PointWrapSampler;
|
||||
desc[3].bindings[1].resourceHandle = commonPasses.m_LinearClampSampler;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
desc[3].bindings[0].resourceHandle = commonPasses.m_AnisotropicWrapSampler;
|
||||
desc[3].bindings[1].resourceHandle = commonPasses.m_LinearClampSampler;
|
||||
if( desc[3].bindings.empty() )
|
||||
{
|
||||
desc[3].bindings =
|
||||
{
|
||||
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_AnisotropicWrapSampler ),
|
||||
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearClampSampler )
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
desc[3].bindings[0].resourceHandle = commonPasses.m_AnisotropicWrapSampler;
|
||||
desc[3].bindings[1].resourceHandle = commonPasses.m_LinearClampSampler;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( type == BINDING_LAYOUT_DRAW_AO )
|
||||
|
@ -900,18 +938,37 @@ void idRenderBackend::GetCurrentBindingLayout( int type )
|
|||
}
|
||||
|
||||
// samplers: 3
|
||||
if( desc[3].bindings.empty() )
|
||||
if( R_UsePixelatedLook() )
|
||||
{
|
||||
desc[3].bindings =
|
||||
if( desc[3].bindings.empty() )
|
||||
{
|
||||
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_AnisotropicWrapSampler ),
|
||||
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearBorderSampler )
|
||||
};
|
||||
desc[3].bindings =
|
||||
{
|
||||
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_PointWrapSampler ),
|
||||
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearBorderSampler )
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
desc[3].bindings[0].resourceHandle = commonPasses.m_PointWrapSampler;
|
||||
desc[3].bindings[1].resourceHandle = commonPasses.m_LinearBorderSampler;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
desc[3].bindings[0].resourceHandle = commonPasses.m_AnisotropicWrapSampler;
|
||||
desc[3].bindings[1].resourceHandle = commonPasses.m_LinearBorderSampler;
|
||||
if( desc[3].bindings.empty() )
|
||||
{
|
||||
desc[3].bindings =
|
||||
{
|
||||
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_AnisotropicWrapSampler ),
|
||||
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearBorderSampler )
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
desc[3].bindings[0].resourceHandle = commonPasses.m_AnisotropicWrapSampler;
|
||||
desc[3].bindings[1].resourceHandle = commonPasses.m_LinearBorderSampler;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( type == BINDING_LAYOUT_DRAW_INTERACTION_SKINNED )
|
||||
|
@ -967,18 +1024,37 @@ void idRenderBackend::GetCurrentBindingLayout( int type )
|
|||
}
|
||||
|
||||
// samplers: 3
|
||||
if( desc[3].bindings.empty() )
|
||||
if( R_UsePixelatedLook() )
|
||||
{
|
||||
desc[3].bindings =
|
||||
if( desc[3].bindings.empty() )
|
||||
{
|
||||
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_AnisotropicWrapSampler ),
|
||||
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearBorderSampler )
|
||||
};
|
||||
desc[3].bindings =
|
||||
{
|
||||
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_PointWrapSampler ),
|
||||
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearBorderSampler )
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
desc[3].bindings[0].resourceHandle = commonPasses.m_PointWrapSampler;
|
||||
desc[3].bindings[1].resourceHandle = commonPasses.m_LinearBorderSampler;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
desc[3].bindings[0].resourceHandle = commonPasses.m_AnisotropicWrapSampler;
|
||||
desc[3].bindings[1].resourceHandle = commonPasses.m_LinearBorderSampler;
|
||||
if( desc[3].bindings.empty() )
|
||||
{
|
||||
desc[3].bindings =
|
||||
{
|
||||
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_AnisotropicWrapSampler ),
|
||||
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearBorderSampler )
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
desc[3].bindings[0].resourceHandle = commonPasses.m_AnisotropicWrapSampler;
|
||||
desc[3].bindings[1].resourceHandle = commonPasses.m_LinearBorderSampler;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( type == BINDING_LAYOUT_DRAW_INTERACTION_SM )
|
||||
|
@ -1037,24 +1113,49 @@ void idRenderBackend::GetCurrentBindingLayout( int type )
|
|||
}
|
||||
|
||||
// samplers: 3
|
||||
if( desc[3].bindings.empty() )
|
||||
if( R_UsePixelatedLook() )
|
||||
{
|
||||
auto& bindings = desc[3].bindings;
|
||||
bindings =
|
||||
if( desc[3].bindings.empty() )
|
||||
{
|
||||
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_AnisotropicWrapSampler ),
|
||||
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearBorderSampler ),
|
||||
nvrhi::BindingSetItem::Sampler( 2, commonPasses.m_LinearClampCompareSampler ),
|
||||
nvrhi::BindingSetItem::Sampler( 3, commonPasses.m_PointWrapSampler ) // blue noise
|
||||
};
|
||||
auto& bindings = desc[3].bindings;
|
||||
bindings =
|
||||
{
|
||||
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_PointWrapSampler ),
|
||||
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearBorderSampler ),
|
||||
nvrhi::BindingSetItem::Sampler( 2, commonPasses.m_LinearClampCompareSampler ),
|
||||
nvrhi::BindingSetItem::Sampler( 3, commonPasses.m_PointWrapSampler ) // blue noise
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
auto& bindings = desc[3].bindings;
|
||||
bindings[0].resourceHandle = commonPasses.m_PointWrapSampler;
|
||||
bindings[1].resourceHandle = commonPasses.m_LinearBorderSampler;
|
||||
bindings[2].resourceHandle = commonPasses.m_LinearClampCompareSampler;
|
||||
bindings[3].resourceHandle = commonPasses.m_PointWrapSampler;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto& bindings = desc[3].bindings;
|
||||
bindings[0].resourceHandle = commonPasses.m_AnisotropicWrapSampler;
|
||||
bindings[1].resourceHandle = commonPasses.m_LinearBorderSampler;
|
||||
bindings[2].resourceHandle = commonPasses.m_LinearClampCompareSampler;
|
||||
bindings[3].resourceHandle = commonPasses.m_PointWrapSampler;
|
||||
if( desc[3].bindings.empty() )
|
||||
{
|
||||
auto& bindings = desc[3].bindings;
|
||||
bindings =
|
||||
{
|
||||
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_AnisotropicWrapSampler ),
|
||||
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearBorderSampler ),
|
||||
nvrhi::BindingSetItem::Sampler( 2, commonPasses.m_LinearClampCompareSampler ),
|
||||
nvrhi::BindingSetItem::Sampler( 3, commonPasses.m_PointWrapSampler ) // blue noise
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
auto& bindings = desc[3].bindings;
|
||||
bindings[0].resourceHandle = commonPasses.m_AnisotropicWrapSampler;
|
||||
bindings[1].resourceHandle = commonPasses.m_LinearBorderSampler;
|
||||
bindings[2].resourceHandle = commonPasses.m_LinearClampCompareSampler;
|
||||
bindings[3].resourceHandle = commonPasses.m_PointWrapSampler;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( type == BINDING_LAYOUT_DRAW_INTERACTION_SM_SKINNED )
|
||||
|
@ -1117,24 +1218,49 @@ void idRenderBackend::GetCurrentBindingLayout( int type )
|
|||
}
|
||||
|
||||
// samplers: 3
|
||||
if( desc[3].bindings.empty() )
|
||||
if( R_UsePixelatedLook() )
|
||||
{
|
||||
auto& bindings = desc[3].bindings;
|
||||
bindings =
|
||||
if( desc[3].bindings.empty() )
|
||||
{
|
||||
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_AnisotropicWrapSampler ),
|
||||
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearBorderSampler ),
|
||||
nvrhi::BindingSetItem::Sampler( 2, commonPasses.m_LinearClampCompareSampler ),
|
||||
nvrhi::BindingSetItem::Sampler( 3, commonPasses.m_PointWrapSampler ) // blue noise
|
||||
};
|
||||
auto& bindings = desc[3].bindings;
|
||||
bindings =
|
||||
{
|
||||
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_PointWrapSampler ),
|
||||
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearBorderSampler ),
|
||||
nvrhi::BindingSetItem::Sampler( 2, commonPasses.m_LinearClampCompareSampler ),
|
||||
nvrhi::BindingSetItem::Sampler( 3, commonPasses.m_PointWrapSampler ) // blue noise
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
auto& bindings = desc[3].bindings;
|
||||
bindings[0].resourceHandle = commonPasses.m_PointWrapSampler;
|
||||
bindings[1].resourceHandle = commonPasses.m_LinearBorderSampler;
|
||||
bindings[2].resourceHandle = commonPasses.m_LinearClampCompareSampler;
|
||||
bindings[3].resourceHandle = commonPasses.m_PointWrapSampler;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto& bindings = desc[3].bindings;
|
||||
bindings[0].resourceHandle = commonPasses.m_AnisotropicWrapSampler;
|
||||
bindings[1].resourceHandle = commonPasses.m_LinearBorderSampler;
|
||||
bindings[2].resourceHandle = commonPasses.m_LinearClampCompareSampler;
|
||||
bindings[3].resourceHandle = commonPasses.m_PointWrapSampler;
|
||||
if( desc[3].bindings.empty() )
|
||||
{
|
||||
auto& bindings = desc[3].bindings;
|
||||
bindings =
|
||||
{
|
||||
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_AnisotropicWrapSampler ),
|
||||
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearBorderSampler ),
|
||||
nvrhi::BindingSetItem::Sampler( 2, commonPasses.m_LinearClampCompareSampler ),
|
||||
nvrhi::BindingSetItem::Sampler( 3, commonPasses.m_PointWrapSampler ) // blue noise
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
auto& bindings = desc[3].bindings;
|
||||
bindings[0].resourceHandle = commonPasses.m_AnisotropicWrapSampler;
|
||||
bindings[1].resourceHandle = commonPasses.m_LinearBorderSampler;
|
||||
bindings[2].resourceHandle = commonPasses.m_LinearClampCompareSampler;
|
||||
bindings[3].resourceHandle = commonPasses.m_PointWrapSampler;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( type == BINDING_LAYOUT_FOG )
|
||||
|
@ -1340,16 +1466,33 @@ void idRenderBackend::GetCurrentBindingLayout( int type )
|
|||
desc[0].bindings[3].resourceHandle = ( nvrhi::ITexture* )GetImageAt( 2 )->GetTextureID();
|
||||
}
|
||||
|
||||
if( desc[1].bindings.empty() )
|
||||
if( R_UsePixelatedLook() )
|
||||
{
|
||||
desc[1].bindings =
|
||||
if( desc[1].bindings.empty() )
|
||||
{
|
||||
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_LinearClampSampler )
|
||||
};
|
||||
desc[1].bindings =
|
||||
{
|
||||
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_PointClampSampler )
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
desc[1].bindings[0].resourceHandle = commonPasses.m_PointClampSampler;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
desc[1].bindings[0].resourceHandle = commonPasses.m_LinearClampSampler;
|
||||
if( desc[1].bindings.empty() )
|
||||
{
|
||||
desc[1].bindings =
|
||||
{
|
||||
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_LinearClampSampler )
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
desc[1].bindings[0].resourceHandle = commonPasses.m_LinearClampSampler;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( type == BINDING_LAYOUT_POST_PROCESS_FINAL )
|
||||
|
@ -1415,16 +1558,33 @@ void idRenderBackend::GetCurrentBindingLayout( int type )
|
|||
bindings[1].resourceHandle = ( nvrhi::ITexture* )GetImageAt( 1 )->GetTextureID();
|
||||
}
|
||||
|
||||
if( desc[2].bindings.empty() )
|
||||
if( R_UsePixelatedLook() )
|
||||
{
|
||||
desc[2].bindings =
|
||||
if( desc[2].bindings.empty() )
|
||||
{
|
||||
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_LinearWrapSampler )
|
||||
};
|
||||
desc[2].bindings =
|
||||
{
|
||||
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_PointWrapSampler )
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
desc[2].bindings[0].resourceHandle = commonPasses.m_PointWrapSampler;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
desc[2].bindings[0].resourceHandle = commonPasses.m_LinearWrapSampler;
|
||||
if( desc[2].bindings.empty() )
|
||||
{
|
||||
desc[2].bindings =
|
||||
{
|
||||
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_LinearWrapSampler )
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
desc[2].bindings[0].resourceHandle = commonPasses.m_LinearWrapSampler;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( type == BINDING_LAYOUT_NORMAL_CUBE_SKINNED )
|
||||
|
@ -1462,16 +1622,33 @@ void idRenderBackend::GetCurrentBindingLayout( int type )
|
|||
bindings[1].resourceHandle = ( nvrhi::ITexture* )GetImageAt( 1 )->GetTextureID();
|
||||
}
|
||||
|
||||
if( desc[2].bindings.empty() )
|
||||
if( R_UsePixelatedLook() )
|
||||
{
|
||||
desc[2].bindings =
|
||||
if( desc[2].bindings.empty() )
|
||||
{
|
||||
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_LinearWrapSampler )
|
||||
};
|
||||
desc[2].bindings =
|
||||
{
|
||||
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_PointWrapSampler )
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
desc[2].bindings[0].resourceHandle = commonPasses.m_PointWrapSampler;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
desc[2].bindings[0].resourceHandle = commonPasses.m_LinearWrapSampler;
|
||||
if( desc[2].bindings.empty() )
|
||||
{
|
||||
desc[2].bindings =
|
||||
{
|
||||
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_LinearWrapSampler )
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
desc[2].bindings[0].resourceHandle = commonPasses.m_LinearWrapSampler;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( type == BINDING_LAYOUT_BINK_VIDEO )
|
||||
|
@ -1495,16 +1672,33 @@ void idRenderBackend::GetCurrentBindingLayout( int type )
|
|||
desc[0].bindings[3].resourceHandle = ( nvrhi::ITexture* )GetImageAt( 2 )->GetTextureID();
|
||||
}
|
||||
|
||||
if( desc[1].bindings.empty() )
|
||||
if( R_UsePixelatedLook() )
|
||||
{
|
||||
desc[1].bindings =
|
||||
if( desc[1].bindings.empty() )
|
||||
{
|
||||
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_LinearWrapSampler )
|
||||
};
|
||||
desc[1].bindings =
|
||||
{
|
||||
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_PointWrapSampler )
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
desc[1].bindings[0].resourceHandle = commonPasses.m_PointWrapSampler;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
desc[1].bindings[0].resourceHandle = commonPasses.m_LinearWrapSampler;
|
||||
if( desc[1].bindings.empty() )
|
||||
{
|
||||
desc[1].bindings =
|
||||
{
|
||||
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_LinearWrapSampler )
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
desc[1].bindings[0].resourceHandle = commonPasses.m_LinearWrapSampler;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( type == BINDING_LAYOUT_TAA_MOTION_VECTORS )
|
||||
|
@ -1597,11 +1791,12 @@ void idRenderBackend::GL_EndFrame()
|
|||
|
||||
commandList->close();
|
||||
|
||||
deviceManager->GetDevice()->executeCommandList( commandList );
|
||||
|
||||
// required for Vulkan: transition our swap image to present
|
||||
deviceManager->EndFrame();
|
||||
|
||||
// SRS - execute after EndFrame() to avoid need for barrier command list on Vulkan
|
||||
deviceManager->GetDevice()->executeCommandList( commandList );
|
||||
|
||||
// update jitter for perspective matrix
|
||||
taaPass->AdvanceFrame();
|
||||
}
|
||||
|
@ -1830,7 +2025,7 @@ See if some cvars that we watch have changed
|
|||
*/
|
||||
void idRenderBackend::CheckCVars()
|
||||
{
|
||||
// gamma stuff
|
||||
// TODO remove, gamma stuff doesn't work and isn't used using the latest Nvidia drivers
|
||||
if( r_gamma.IsModified() || r_brightness.IsModified() )
|
||||
{
|
||||
r_gamma.ClearModified();
|
||||
|
@ -1845,56 +2040,14 @@ void idRenderBackend::CheckCVars()
|
|||
deviceManager->SetVsyncEnabled( r_swapInterval.GetInteger() );
|
||||
}
|
||||
|
||||
// filtering
|
||||
/*if( r_maxAnisotropicFiltering.IsModified() || r_useTrilinearFiltering.IsModified() || r_lodBias.IsModified() )
|
||||
// retro rendering
|
||||
if( r_renderMode.IsModified() )
|
||||
{
|
||||
idLib::Printf( "Updating texture filter parameters.\n" );
|
||||
r_maxAnisotropicFiltering.ClearModified();
|
||||
r_useTrilinearFiltering.ClearModified();
|
||||
r_lodBias.ClearModified();
|
||||
r_renderMode.ClearModified();
|
||||
|
||||
for( int i = 0; i < globalImages->images.Num(); i++ )
|
||||
{
|
||||
if( globalImages->images[i] )
|
||||
{
|
||||
globalImages->images[i]->Bind();
|
||||
globalImages->images[i]->SetTexParameters();
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
#if 0
|
||||
if( r_antiAliasing.IsModified() )
|
||||
{
|
||||
switch( r_antiAliasing.GetInteger() )
|
||||
{
|
||||
case ANTI_ALIASING_MSAA_2X:
|
||||
case ANTI_ALIASING_MSAA_4X:
|
||||
if( r_antiAliasing.GetInteger() > 0 )
|
||||
{
|
||||
//glEnable( GL_MULTISAMPLE );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
//glDisable( GL_MULTISAMPLE );
|
||||
break;
|
||||
}
|
||||
|
||||
if( tr.IsInitialized() )
|
||||
{
|
||||
Framebuffer::ResizeFramebuffers();
|
||||
}
|
||||
|
||||
if( taaPass )
|
||||
{
|
||||
delete taaPass;
|
||||
taaPass = NULL;
|
||||
}
|
||||
|
||||
r_antiAliasing.ClearModified();
|
||||
// clear caches because PSX rendering will use nearest texture filtering instead of linear
|
||||
ClearCaches();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -362,7 +362,7 @@ bool idRenderProgManager::CommitConstantBuffer( nvrhi::ICommandList* commandList
|
|||
// The vkDoom3 backend even didn't bother with this and always fired the uniforms for each draw call.
|
||||
if( uniformsChanged || bindingLayoutTypeChanged )
|
||||
{
|
||||
commandList->writeBuffer( constantBuffer[BindingLayoutType()], uniforms.Ptr(), uniforms.Allocated() );
|
||||
commandList->writeBuffer( constantBuffer /*[BindingLayoutType()]*/, uniforms.Ptr(), uniforms.Allocated() );
|
||||
|
||||
uniformsChanged = false;
|
||||
|
||||
|
|
|
@ -254,8 +254,8 @@ void SsaoPass::Render(
|
|||
quarterResExtent.maxY = ( quarterResExtent.maxY + 3 ) / 4;
|
||||
|
||||
// TODO required and remove this by fixing the shaders
|
||||
// because they include #include <global_inc.hlsl>
|
||||
renderProgManager.BindShader_TextureVertexColor();
|
||||
|
||||
renderProgManager.CommitConstantBuffer( commandList, true );
|
||||
|
||||
SsaoConstants ssaoConstants = {};
|
||||
|
|
|
@ -2172,11 +2172,11 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr
|
|||
specularColor = lightColor;// * 0.5f;
|
||||
|
||||
float ambientBoost = 1.0f;
|
||||
if( !r_usePBR.GetBool() )
|
||||
{
|
||||
ambientBoost += r_useSSAO.GetBool() ? 0.2f : 0.0f;
|
||||
ambientBoost *= 1.1f;
|
||||
}
|
||||
//if( !r_usePBR.GetBool() )
|
||||
//{
|
||||
// ambientBoost += r_useSSAO.GetBool() ? 0.2f : 0.0f;
|
||||
// ambientBoost *= 1.1f;
|
||||
//}
|
||||
|
||||
ambientColor.x = r_forceAmbient.GetFloat() * ambientBoost;
|
||||
ambientColor.y = r_forceAmbient.GetFloat() * ambientBoost;
|
||||
|
@ -2186,7 +2186,7 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr
|
|||
|
||||
renderProgManager.SetRenderParm( RENDERPARM_AMBIENT_COLOR, ambientColor.ToFloatPtr() );
|
||||
|
||||
bool useIBL = r_usePBR.GetBool() && !fillGbuffer;
|
||||
bool useIBL = !fillGbuffer;
|
||||
|
||||
// setup renderparms assuming we will be drawing trivial surfaces first
|
||||
RB_SetupForFastPathInteractions( diffuseColor, specularColor );
|
||||
|
@ -5374,6 +5374,10 @@ void idRenderBackend::ExecuteBackEndCommands( const emptyCommand_t* cmds )
|
|||
break;
|
||||
}
|
||||
|
||||
case RC_CRT_POST_PROCESS:
|
||||
CRTPostProcess();
|
||||
break;
|
||||
|
||||
default:
|
||||
common->Error( "RB_ExecuteBackEndCommands: bad commandId" );
|
||||
break;
|
||||
|
@ -5382,12 +5386,13 @@ void idRenderBackend::ExecuteBackEndCommands( const emptyCommand_t* cmds )
|
|||
|
||||
DrawFlickerBox();
|
||||
|
||||
GL_EndFrame();
|
||||
|
||||
// stop rendering on this thread
|
||||
uint64 backEndFinishTime = Sys_Microseconds();
|
||||
pc.cpuTotalMicroSec = backEndFinishTime - backEndStartTime;
|
||||
|
||||
// SRS - capture backend timing before GL_EndFrame() since it can block when r_mvkSynchronousQueueSubmits is enabled on macOS/MoltenVK
|
||||
GL_EndFrame();
|
||||
|
||||
if( r_debugRenderToTexture.GetInteger() == 1 )
|
||||
{
|
||||
common->Printf( "3d: %i, 2d: %i, SetBuf: %i, CpyRenders: %i, CpyFrameBuf: %i\n", c_draw3d, c_draw2d, c_setBuffers, c_copyRenders, pc.c_copyFrameBuffer );
|
||||
|
@ -5976,15 +5981,6 @@ idRenderBackend::PostProcess
|
|||
extern idCVar rs_enable;
|
||||
void idRenderBackend::PostProcess( const void* data )
|
||||
{
|
||||
// only do the post process step if resolution scaling is enabled. Prevents the unnecessary copying of the framebuffer and
|
||||
// corresponding full screen quad pass.
|
||||
/*
|
||||
if( rs_enable.GetInteger() == 0 && !r_useFilmicPostProcessing.GetBool() && r_antiAliasing.GetInteger() == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
if( viewDef->renderView.rdflags & RDF_IRRADIANCE )
|
||||
{
|
||||
#if defined( USE_NVRHI )
|
||||
|
@ -6102,7 +6098,7 @@ void idRenderBackend::PostProcess( const void* data )
|
|||
}
|
||||
#endif
|
||||
|
||||
if( r_useFilmicPostProcessing.GetBool() )
|
||||
if( r_useFilmicPostFX.GetBool() || r_renderMode.GetInteger() > 0 )
|
||||
{
|
||||
BlitParameters blitParms;
|
||||
blitParms.sourceTexture = ( nvrhi::ITexture* )globalImages->ldrImage->GetTextureID();
|
||||
|
@ -6119,7 +6115,37 @@ void idRenderBackend::PostProcess( const void* data )
|
|||
GL_SelectTexture( 1 );
|
||||
globalImages->blueNoiseImage256->Bind();
|
||||
|
||||
renderProgManager.BindShader_PostProcess();
|
||||
float jitterTexScale[4] = {};
|
||||
|
||||
if( r_renderMode.GetInteger() == RENDERMODE_C64 || r_renderMode.GetInteger() == RENDERMODE_C64_HIGHRES )
|
||||
{
|
||||
jitterTexScale[0] = r_renderMode.GetInteger() == RENDERMODE_C64_HIGHRES ? 2.0 : 1.0;
|
||||
|
||||
renderProgManager.BindShader_PostProcess_RetroC64();
|
||||
}
|
||||
else if( r_renderMode.GetInteger() == RENDERMODE_CPC || r_renderMode.GetInteger() == RENDERMODE_CPC_HIGHRES )
|
||||
{
|
||||
jitterTexScale[0] = r_renderMode.GetInteger() == RENDERMODE_CPC_HIGHRES ? 2.0 : 1.0;
|
||||
|
||||
renderProgManager.BindShader_PostProcess_RetroCPC();
|
||||
}
|
||||
else if( r_renderMode.GetInteger() == RENDERMODE_GENESIS || r_renderMode.GetInteger() == RENDERMODE_GENESIS_HIGHRES )
|
||||
{
|
||||
jitterTexScale[0] = r_renderMode.GetInteger() == RENDERMODE_GENESIS_HIGHRES ? 2.0 : 1.0;
|
||||
|
||||
renderProgManager.BindShader_PostProcess_RetroGenesis();
|
||||
}
|
||||
else if( r_renderMode.GetInteger() == RENDERMODE_PSX )
|
||||
{
|
||||
renderProgManager.BindShader_PostProcess_RetroPSX();
|
||||
}
|
||||
else
|
||||
{
|
||||
renderProgManager.BindShader_PostProcess();
|
||||
}
|
||||
|
||||
jitterTexScale[1] = r_retroDitherScale.GetFloat();
|
||||
SetFragmentParm( RENDERPARM_JITTERTEXSCALE, jitterTexScale ); // rpJitterTexScale
|
||||
|
||||
float jitterTexOffset[4];
|
||||
jitterTexOffset[0] = 1.0f / globalImages->blueNoiseImage256->GetUploadWidth();
|
||||
|
@ -6164,3 +6190,90 @@ void idRenderBackend::PostProcess( const void* data )
|
|||
renderLog.CloseBlock();
|
||||
renderLog.CloseMainBlock();
|
||||
}
|
||||
|
||||
void idRenderBackend::CRTPostProcess()
|
||||
{
|
||||
#if 1
|
||||
//renderLog.OpenMainBlock( MRB_POSTPROCESS );
|
||||
renderLog.OpenBlock( "Render_CRTPostFX", colorBlue );
|
||||
|
||||
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO | GLS_DEPTHMASK | GLS_DEPTHFUNC_ALWAYS | GLS_CULL_TWOSIDED );
|
||||
|
||||
int screenWidth = renderSystem->GetWidth();
|
||||
int screenHeight = renderSystem->GetHeight();
|
||||
|
||||
// set the window clipping
|
||||
GL_Viewport( 0, 0, screenWidth, screenHeight );
|
||||
GL_Scissor( 0, 0, screenWidth, screenHeight );
|
||||
|
||||
if( r_useCRTPostFX.GetInteger() > 0 )
|
||||
{
|
||||
BlitParameters blitParms;
|
||||
blitParms.sourceTexture = ( nvrhi::ITexture* )globalImages->ldrImage->GetTextureID();
|
||||
blitParms.targetFramebuffer = globalFramebuffers.smaaBlendFBO->GetApiObject();
|
||||
|
||||
blitParms.targetViewport = nvrhi::Viewport( renderSystem->GetWidth(), renderSystem->GetHeight() );
|
||||
commonPasses.BlitTexture( commandList, blitParms, &bindingCache );
|
||||
|
||||
GL_SelectTexture( 0 );
|
||||
globalImages->smaaBlendImage->Bind();
|
||||
|
||||
globalFramebuffers.ldrFBO->Bind();
|
||||
|
||||
GL_SelectTexture( 1 );
|
||||
globalImages->blueNoiseImage256->Bind();
|
||||
|
||||
if( r_useCRTPostFX.GetInteger() == 1 )
|
||||
{
|
||||
renderProgManager.BindShader_CrtMattias();
|
||||
}
|
||||
else
|
||||
{
|
||||
renderProgManager.BindShader_CrtNewPixie();
|
||||
}
|
||||
|
||||
float windowCoordParm[4];
|
||||
windowCoordParm[0] = r_crtCurvature.GetFloat();
|
||||
windowCoordParm[1] = r_crtVignette.GetFloat();
|
||||
windowCoordParm[2] = screenWidth;
|
||||
windowCoordParm[3] = screenHeight;
|
||||
SetFragmentParm( RENDERPARM_WINDOWCOORD, windowCoordParm ); // rpWindowCoord
|
||||
|
||||
float jitterTexOffset[4];
|
||||
jitterTexOffset[0] = 1.0f / globalImages->blueNoiseImage256->GetUploadWidth();
|
||||
jitterTexOffset[1] = 1.0f / globalImages->blueNoiseImage256->GetUploadHeight();
|
||||
|
||||
if( r_shadowMapRandomizeJitter.GetBool() )
|
||||
{
|
||||
jitterTexOffset[2] = Sys_Milliseconds() / 1000.0f;
|
||||
jitterTexOffset[3] = tr.frameCount % 64;
|
||||
}
|
||||
else
|
||||
{
|
||||
jitterTexOffset[2] = 0.0f;
|
||||
jitterTexOffset[3] = 0.0f;
|
||||
}
|
||||
|
||||
SetFragmentParm( RENDERPARM_JITTERTEXOFFSET, jitterTexOffset ); // rpJitterTexOffset
|
||||
|
||||
// Draw
|
||||
DrawElementsWithCounters( &unitSquareSurface );
|
||||
}
|
||||
|
||||
//GL_SelectTexture( 0 );
|
||||
//renderProgManager.Unbind();
|
||||
|
||||
// copy LDR result to DX12 / Vulkan swapchain image
|
||||
BlitParameters blitParms;
|
||||
blitParms.sourceTexture = ( nvrhi::ITexture* )globalImages->ldrImage->GetTextureID();
|
||||
blitParms.targetFramebuffer = deviceManager->GetCurrentFramebuffer();
|
||||
blitParms.targetViewport = nvrhi::Viewport( renderSystem->GetWidth(), renderSystem->GetHeight() );
|
||||
commonPasses.BlitTexture( commandList, blitParms, &bindingCache );
|
||||
|
||||
GL_SelectTexture( 0 );
|
||||
globalImages->currentRenderImage->Bind();
|
||||
|
||||
renderLog.CloseBlock();
|
||||
//renderLog.CloseMainBlock();
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -208,7 +208,9 @@ private:
|
|||
|
||||
// Experimental feature
|
||||
void MotionBlur();
|
||||
|
||||
void PostProcess( const void* data );
|
||||
void CRTPostProcess();
|
||||
|
||||
private:
|
||||
void GL_StartFrame();
|
||||
|
|
|
@ -699,11 +699,12 @@ TR_CMDS
|
|||
enum renderCommand_t
|
||||
{
|
||||
RC_NOP,
|
||||
RC_DRAW_VIEW_3D, // may be at a reduced resolution, will be upsampled before 2D GUIs
|
||||
RC_DRAW_VIEW_GUI, // not resolution scaled
|
||||
RC_DRAW_VIEW_3D, // may be at a reduced resolution, will be upsampled before 2D GUIs
|
||||
RC_DRAW_VIEW_GUI, // not resolution scaled
|
||||
RC_SET_BUFFER,
|
||||
RC_COPY_RENDER,
|
||||
RC_POST_PROCESS,
|
||||
RC_POST_PROCESS, // postfx after scene rendering is done but before GUI rendering
|
||||
RC_CRT_POST_PROCESS, // CRT simulation after everything has been rendered on the final swapchain image
|
||||
};
|
||||
|
||||
struct emptyCommand_t
|
||||
|
@ -746,6 +747,13 @@ struct postProcessCommand_t
|
|||
viewDef_t* viewDef;
|
||||
};
|
||||
|
||||
struct crtPostProcessCommand_t
|
||||
{
|
||||
renderCommand_t commandId;
|
||||
renderCommand_t* next;
|
||||
int padding;
|
||||
};
|
||||
|
||||
//=======================================================================
|
||||
|
||||
// this is the inital allocation for max number of drawsurfs
|
||||
|
@ -932,6 +940,8 @@ public:
|
|||
virtual void DrawBigChar( int x, int y, int ch );
|
||||
virtual void DrawBigStringExt( int x, int y, const char* string, const idVec4& setColor, bool forceColor );
|
||||
|
||||
virtual void DrawCRTPostFX(); // RB
|
||||
|
||||
virtual void WriteDemoPics();
|
||||
virtual void WriteEndFrame();
|
||||
virtual void DrawDemoPics();
|
||||
|
@ -950,7 +960,6 @@ public:
|
|||
virtual void CropRenderSize( int width, int height );
|
||||
virtual void CropRenderSize( int x, int y, int width, int height, bool topLeftAncor );
|
||||
virtual void CaptureRenderToImage( const char* imageName, bool clearColorAfterCopy = false );
|
||||
virtual void CaptureRenderToFile( const char* fileName, bool fixAlpha );
|
||||
virtual void UnCrop();
|
||||
virtual bool UploadImage( const char* imageName, const byte* data, int width, int height );
|
||||
|
||||
|
@ -1259,7 +1268,6 @@ extern idCVar r_hdrDebug;
|
|||
extern idCVar r_ldrContrastThreshold;
|
||||
extern idCVar r_ldrContrastOffset;
|
||||
|
||||
extern idCVar r_useFilmicPostProcessing;
|
||||
extern idCVar r_forceAmbient;
|
||||
|
||||
extern idCVar r_useSSAO;
|
||||
|
@ -1267,7 +1275,6 @@ extern idCVar r_ssaoDebug;
|
|||
extern idCVar r_ssaoFiltering;
|
||||
extern idCVar r_useHierarchicalDepthBuffer;
|
||||
|
||||
extern idCVar r_usePBR;
|
||||
extern idCVar r_pbrDebug;
|
||||
extern idCVar r_showViewEnvprobes;
|
||||
extern idCVar r_showLightGrid; // show Quake 3 style light grid points
|
||||
|
@ -1283,6 +1290,28 @@ extern idCVar r_taaClampingFactor;
|
|||
extern idCVar r_taaNewFrameWeight;
|
||||
extern idCVar r_taaMaxRadiance;
|
||||
extern idCVar r_taaMotionVectors;
|
||||
|
||||
extern idCVar r_useFilmicPostFX;
|
||||
extern idCVar r_useCRTPostFX;
|
||||
extern idCVar r_crtCurvature;
|
||||
extern idCVar r_crtVignette;
|
||||
|
||||
enum RenderMode
|
||||
{
|
||||
RENDERMODE_DOOM,
|
||||
RENDERMODE_C64,
|
||||
RENDERMODE_C64_HIGHRES,
|
||||
RENDERMODE_CPC,
|
||||
RENDERMODE_CPC_HIGHRES,
|
||||
RENDERMODE_GENESIS,
|
||||
RENDERMODE_GENESIS_HIGHRES,
|
||||
RENDERMODE_PSX,
|
||||
};
|
||||
|
||||
extern idCVar r_retroDitherScale;
|
||||
|
||||
extern idCVar r_renderMode;
|
||||
extern idCVar image_pixelLook;
|
||||
// RB end
|
||||
|
||||
/*
|
||||
|
@ -1293,6 +1322,8 @@ INITIALIZATION
|
|||
====================================================================
|
||||
*/
|
||||
|
||||
bool R_UsePixelatedLook();
|
||||
|
||||
bool R_UseTemporalAA();
|
||||
|
||||
uint R_GetMSAASamples();
|
||||
|
|
|
@ -88,10 +88,10 @@ void idRenderProgManager::Init( nvrhi::IDevice* device )
|
|||
uniforms.SetNum( RENDERPARM_TOTAL, vec4_zero );
|
||||
uniformsChanged = false;
|
||||
|
||||
for( int i = 0; i < NUM_BINDING_LAYOUTS; i++ )
|
||||
//for( int i = 0; i < NUM_BINDING_LAYOUTS; i++ )
|
||||
{
|
||||
auto constantBufferDesc = nvrhi::utils::CreateVolatileConstantBufferDesc( uniforms.Allocated(), va( "RenderParams_%d", i ), 16384 );
|
||||
constantBuffer[i] = device->createBuffer( constantBufferDesc );
|
||||
auto constantBufferDesc = nvrhi::utils::CreateVolatileConstantBufferDesc( uniforms.Allocated(), va( "RenderParams_%d", 1 ), 16384 );
|
||||
constantBuffer = device->createBuffer( constantBufferDesc );
|
||||
}
|
||||
|
||||
// === Main draw vertex layout ===
|
||||
|
@ -521,6 +521,12 @@ void idRenderProgManager::Init( nvrhi::IDevice* device )
|
|||
{ BUILTIN_SKYBOX, "builtin/legacy/skybox", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
|
||||
{ BUILTIN_WOBBLESKY, "builtin/legacy/wobblesky", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
|
||||
{ BUILTIN_POSTPROCESS, "builtin/post/postprocess", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_POST_PROCESS_FINAL },
|
||||
{ BUILTIN_POSTPROCESS_RETRO_C64, "builtin/post/retro_c64", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_POST_PROCESS_FINAL },
|
||||
{ BUILTIN_POSTPROCESS_RETRO_CPC, "builtin/post/retro_cpc", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_POST_PROCESS_FINAL },
|
||||
{ BUILTIN_POSTPROCESS_RETRO_GENESIS, "builtin/post/retro_genesis", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_POST_PROCESS_FINAL },
|
||||
{ BUILTIN_POSTPROCESS_RETRO_PSX, "builtin/post/retro_ps1", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_POST_PROCESS_FINAL },
|
||||
{ BUILTIN_CRT_MATTIAS, "builtin/post/crt_mattias", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_POST_PROCESS_FINAL },
|
||||
{ BUILTIN_CRT_NUPIXIE, "builtin/post/crt_newpixie", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_POST_PROCESS_FINAL },
|
||||
|
||||
{ BUILTIN_SCREEN, "builtin/post/screen", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
|
||||
{ BUILTIN_TONEMAP, "builtin/post/tonemap", "", { { "BRIGHTPASS", "0" }, { "HDR_DEBUG", "0"} }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
|
||||
|
@ -618,7 +624,6 @@ void idRenderProgManager::Init( nvrhi::IDevice* device )
|
|||
}
|
||||
}
|
||||
|
||||
r_usePBR.ClearModified();
|
||||
r_pbrDebug.ClearModified();
|
||||
|
||||
uniforms.SetNum( RENDERPARM_TOTAL, vec4_zero );
|
||||
|
@ -720,9 +725,9 @@ void idRenderProgManager::Shutdown()
|
|||
}
|
||||
|
||||
// SRS - Unmap buffer memory using overloaded = operator
|
||||
for( int i = 0; i < constantBuffer.Num(); i++ )
|
||||
//for( int i = 0; i < constantBuffer.Num(); i++ )
|
||||
{
|
||||
constantBuffer[i] = nullptr;
|
||||
constantBuffer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -366,6 +366,12 @@ enum
|
|||
BUILTIN_WOBBLESKY,
|
||||
BUILTIN_POSTPROCESS,
|
||||
// RB begin
|
||||
BUILTIN_POSTPROCESS_RETRO_C64, // Commodore 64
|
||||
BUILTIN_POSTPROCESS_RETRO_CPC, // Amstrad 6128
|
||||
BUILTIN_POSTPROCESS_RETRO_GENESIS, // Sega Genesis / Megadrive
|
||||
BUILTIN_POSTPROCESS_RETRO_PSX, // Sony Playstation 1
|
||||
BUILTIN_CRT_MATTIAS,
|
||||
BUILTIN_CRT_NUPIXIE,
|
||||
BUILTIN_SCREEN,
|
||||
BUILTIN_TONEMAP,
|
||||
BUILTIN_BRIGHTPASS,
|
||||
|
@ -817,6 +823,36 @@ public:
|
|||
BindShader_Builtin( BUILTIN_POSTPROCESS );
|
||||
}
|
||||
|
||||
void BindShader_PostProcess_RetroC64()
|
||||
{
|
||||
BindShader_Builtin( BUILTIN_POSTPROCESS_RETRO_C64 );
|
||||
}
|
||||
|
||||
void BindShader_PostProcess_RetroCPC()
|
||||
{
|
||||
BindShader_Builtin( BUILTIN_POSTPROCESS_RETRO_CPC );
|
||||
}
|
||||
|
||||
void BindShader_PostProcess_RetroGenesis()
|
||||
{
|
||||
BindShader_Builtin( BUILTIN_POSTPROCESS_RETRO_GENESIS );
|
||||
}
|
||||
|
||||
void BindShader_PostProcess_RetroPSX()
|
||||
{
|
||||
BindShader_Builtin( BUILTIN_POSTPROCESS_RETRO_PSX );
|
||||
}
|
||||
|
||||
void BindShader_CrtMattias()
|
||||
{
|
||||
BindShader_Builtin( BUILTIN_CRT_MATTIAS );
|
||||
}
|
||||
|
||||
void BindShader_CrtNewPixie()
|
||||
{
|
||||
BindShader_Builtin( BUILTIN_CRT_NUPIXIE );
|
||||
}
|
||||
|
||||
void BindShader_Screen()
|
||||
{
|
||||
BindShader_Builtin( BUILTIN_SCREEN );
|
||||
|
@ -964,7 +1000,7 @@ public:
|
|||
|
||||
ID_INLINE nvrhi::IBuffer* ConstantBuffer()
|
||||
{
|
||||
return constantBuffer[BindingLayoutType()];
|
||||
return constantBuffer;//[BindingLayoutType()];
|
||||
}
|
||||
ID_INLINE idUniformBuffer& BindingParamUbo()
|
||||
{
|
||||
|
@ -1070,7 +1106,8 @@ private:
|
|||
|
||||
idStaticList< idStaticList<nvrhi::BindingLayoutHandle, nvrhi::c_MaxBindingLayouts>, NUM_BINDING_LAYOUTS > bindingLayouts;
|
||||
|
||||
idArray<nvrhi::BufferHandle, NUM_BINDING_LAYOUTS> constantBuffer;
|
||||
//idArray<nvrhi::BufferHandle, NUM_BINDING_LAYOUTS> constantBuffer;
|
||||
nvrhi::BufferHandle constantBuffer;
|
||||
};
|
||||
|
||||
extern idRenderProgManager renderProgManager;
|
||||
|
|
|
@ -782,7 +782,6 @@ const emptyCommand_t* idRenderSystemLocal::SwapCommandBuffers_FinishCommandBuffe
|
|||
// set the time for shader effects in 2D rendering
|
||||
frameShaderTime = Sys_Milliseconds() * 0.001;
|
||||
|
||||
// RB: TODO RC_SET_BUFFER is not handled in OpenGL
|
||||
setBufferCommand_t* cmd2 = ( setBufferCommand_t* )R_GetCommandBuffer( sizeof( *cmd2 ) );
|
||||
cmd2->commandId = RC_SET_BUFFER;
|
||||
cmd2->buffer = 0;
|
||||
|
@ -1038,53 +1037,6 @@ void idRenderSystemLocal::CaptureRenderToImage( const char* imageName, bool clea
|
|||
guiModel->Clear();
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
idRenderSystemLocal::CaptureRenderToFile
|
||||
==============
|
||||
*/
|
||||
void idRenderSystemLocal::CaptureRenderToFile( const char* fileName, bool fixAlpha )
|
||||
{
|
||||
if( !IsInitialized() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
idScreenRect& rc = renderCrops[currentRenderCrop];
|
||||
|
||||
guiModel->EmitFullScreen();
|
||||
guiModel->Clear();
|
||||
|
||||
RenderCommandBuffers( frameData->cmdHead );
|
||||
|
||||
// TODO implement for NVRHI
|
||||
|
||||
#if !defined( USE_VULKAN ) && !defined( USE_NVRHI )
|
||||
glReadBuffer( GL_BACK );
|
||||
|
||||
// include extra space for OpenGL padding to word boundaries
|
||||
int c = ( rc.GetWidth() + 3 ) * rc.GetHeight();
|
||||
byte* data = ( byte* )R_StaticAlloc( c * 3 );
|
||||
|
||||
glReadPixels( rc.x1, rc.y1, rc.GetWidth(), rc.GetHeight(), GL_RGB, GL_UNSIGNED_BYTE, data );
|
||||
|
||||
byte* data2 = ( byte* )R_StaticAlloc( c * 4 );
|
||||
|
||||
for( int i = 0 ; i < c ; i++ )
|
||||
{
|
||||
data2[ i * 4 ] = data[ i * 3 ];
|
||||
data2[ i * 4 + 1 ] = data[ i * 3 + 1 ];
|
||||
data2[ i * 4 + 2 ] = data[ i * 3 + 2 ];
|
||||
data2[ i * 4 + 3 ] = 0xff;
|
||||
}
|
||||
|
||||
R_WriteTGA( fileName, data2, rc.GetWidth(), rc.GetHeight(), true );
|
||||
|
||||
R_StaticFree( data );
|
||||
R_StaticFree( data2 );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
|
@ -1153,3 +1105,19 @@ bool idRenderSystemLocal::UploadImage( const char* imageName, const byte* data,
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// RB
|
||||
void idRenderSystemLocal::DrawCRTPostFX()
|
||||
{
|
||||
if( !IsInitialized() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
guiModel->EmitFullScreen();
|
||||
guiModel->Clear();
|
||||
|
||||
crtPostProcessCommand_t* cmd = ( crtPostProcessCommand_t* )R_GetCommandBuffer( sizeof( *cmd ) );
|
||||
cmd->commandId = RC_CRT_POST_PROCESS;
|
||||
}
|
|
@ -306,6 +306,8 @@ public:
|
|||
virtual void DrawBigChar( int x, int y, int ch ) = 0;
|
||||
virtual void DrawBigStringExt( int x, int y, const char* string, const idVec4& setColor, bool forceColor ) = 0;
|
||||
|
||||
virtual void DrawCRTPostFX() = 0; // RB
|
||||
|
||||
// dump all 2D drawing so far this frame to the demo file
|
||||
virtual void WriteDemoPics() = 0;
|
||||
virtual void WriteEndFrame() = 0;
|
||||
|
@ -359,9 +361,6 @@ public:
|
|||
virtual void CropRenderSize( int width, int height ) = 0;
|
||||
virtual void CropRenderSize( int x, int y, int width, int height, bool topLeftAncor ) = 0;
|
||||
virtual void CaptureRenderToImage( const char* imageName, bool clearColorAfterCopy = false ) = 0;
|
||||
// fixAlpha will set all the alpha channel values to 0xff, which allows screen captures
|
||||
// to use the default tga loading code without having dimmed down areas in many places
|
||||
virtual void CaptureRenderToFile( const char* fileName, bool fixAlpha = false ) = 0;
|
||||
virtual void UnCrop() = 0;
|
||||
|
||||
// the image has to be already loaded ( most straightforward way would be through a FindMaterial )
|
||||
|
|
|
@ -171,9 +171,6 @@ idCVar r_flareSize( "r_flareSize", "1", CVAR_RENDERER | CVAR_FLOAT, "scale the f
|
|||
idCVar r_useScissor( "r_useScissor", "1", CVAR_RENDERER | CVAR_BOOL | CVAR_NOCHEAT, "scissor clip as portals and lights are processed" );
|
||||
idCVar r_useLightDepthBounds( "r_useLightDepthBounds", "1", CVAR_RENDERER | CVAR_BOOL, "use depth bounds test on lights to reduce both shadow and interaction fill" );
|
||||
idCVar r_useShadowDepthBounds( "r_useShadowDepthBounds", "1", CVAR_RENDERER | CVAR_BOOL, "use depth bounds test on individual shadow volumes to reduce shadow fill" );
|
||||
// RB begin
|
||||
idCVar r_useHalfLambertLighting( "r_useHalfLambertLighting", "0", CVAR_RENDERER | CVAR_BOOL | CVAR_ARCHIVE, "use Half-Lambert lighting instead of classic Lambert, requires reloadShaders" );
|
||||
// RB end
|
||||
|
||||
idCVar r_screenFraction( "r_screenFraction", "100", CVAR_RENDERER | CVAR_INTEGER, "for testing fill rate, the resolution of the entire screen can be changed" );
|
||||
idCVar r_usePortals( "r_usePortals", "1", CVAR_RENDERER | CVAR_BOOL, " 1 = use portals to perform area culling, otherwise draw everything" );
|
||||
|
@ -276,7 +273,7 @@ idCVar r_hdrDebug( "r_hdrDebug", "0", CVAR_RENDERER | CVAR_FLOAT, "show scene lu
|
|||
idCVar r_ldrContrastThreshold( "r_ldrContrastThreshold", "1.1", CVAR_RENDERER | CVAR_FLOAT, "" );
|
||||
idCVar r_ldrContrastOffset( "r_ldrContrastOffset", "3", CVAR_RENDERER | CVAR_FLOAT, "" );
|
||||
|
||||
idCVar r_useFilmicPostProcessing( "r_useFilmicPostProcessing", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL, "apply several post process effects to mimic a filmic look" );
|
||||
idCVar r_useFilmicPostFX( "r_useFilmicPostFX", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL, "filmic look with chromatic abberation and film grain" );
|
||||
|
||||
idCVar r_forceAmbient( "r_forceAmbient", "0.5", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_FLOAT, "render additional ambient pass to make the game less dark", 0.0f, 1.0f );
|
||||
|
||||
|
@ -285,8 +282,6 @@ idCVar r_ssaoDebug( "r_ssaoDebug", "0", CVAR_RENDERER | CVAR_INTEGER, "" );
|
|||
idCVar r_ssaoFiltering( "r_ssaoFiltering", "0", CVAR_RENDERER | CVAR_BOOL, "" );
|
||||
idCVar r_useHierarchicalDepthBuffer( "r_useHierarchicalDepthBuffer", "1", CVAR_RENDERER | CVAR_BOOL, "" );
|
||||
|
||||
// RB: only change r_usePBR if you are a developer
|
||||
idCVar r_usePBR( "r_usePBR", "1", CVAR_RENDERER | CVAR_ROM | CVAR_STATIC | CVAR_BOOL, "use PBR and Image Based Lighting instead of old Quake 4 style ambient lighting" );
|
||||
idCVar r_pbrDebug( "r_pbrDebug", "0", CVAR_RENDERER | CVAR_INTEGER, "show which materials have PBR support (green = PBR, red = oldschool D3)" );
|
||||
idCVar r_showViewEnvprobes( "r_showViewEnvprobes", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = displays the bounding boxes of all view environment probes, 2 = show irradiance" );
|
||||
idCVar r_showLightGrid( "r_showLightGrid", "0", CVAR_RENDERER | CVAR_INTEGER, "show Quake 3 style light grid points" );
|
||||
|
@ -302,6 +297,14 @@ idCVar r_taaClampingFactor( "r_taaClampingFactor", "1.0", CVAR_RENDERER | CVAR_F
|
|||
idCVar r_taaNewFrameWeight( "r_taaNewFrameWeight", "0.1", CVAR_RENDERER | CVAR_FLOAT, "" );
|
||||
idCVar r_taaMaxRadiance( "r_taaMaxRadiance", "10000", CVAR_RENDERER | CVAR_FLOAT, "" );
|
||||
idCVar r_taaMotionVectors( "r_taaMotionVectors", "1", CVAR_RENDERER | CVAR_BOOL, "" );
|
||||
|
||||
idCVar r_useCRTPostFX( "r_useCRTPostFX", "0", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "RetroArch CRT shader: 1 = Matthias CRT, 1 = New Pixie", 0, 2 );
|
||||
idCVar r_crtCurvature( "r_crtCurvature", "2", CVAR_RENDERER | CVAR_FLOAT, "rounded borders" );
|
||||
idCVar r_crtVignette( "r_crtVignette", "0.8", CVAR_RENDERER | CVAR_FLOAT, "fading into the borders" );
|
||||
|
||||
idCVar r_retroDitherScale( "r_retroDitherScale", "0.3", CVAR_RENDERER | CVAR_FLOAT, "" );
|
||||
|
||||
idCVar r_renderMode( "r_renderMode", "0", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "0 = Doom, 1 = Commodore 64, 2 = Commodore 64 Highres, 3 = Amstrad CPC 6128, 4 = Amstrad CPC 6128 Highres, 5 = Sega Genesis, 6 = Sega Genesis Highres, 7 = Sony PSX", 0, 7 );
|
||||
// RB end
|
||||
|
||||
const char* fileExten[4] = { "tga", "png", "jpg", "exr" };
|
||||
|
@ -311,6 +314,11 @@ const char* skyDirection[6] = { "_forward", "_back", "_left", "_right", "_up", "
|
|||
DeviceManager* deviceManager = NULL;
|
||||
|
||||
|
||||
bool R_UsePixelatedLook()
|
||||
{
|
||||
return ( r_renderMode.GetInteger() == RENDERMODE_PSX ) || image_pixelLook.GetBool();
|
||||
}
|
||||
|
||||
bool R_UseTemporalAA()
|
||||
{
|
||||
if( !r_useTemporalAA.GetBool() )
|
||||
|
@ -2203,10 +2211,12 @@ void idRenderSystemLocal::Shutdown()
|
|||
|
||||
// SRS - wait for fence to hit before freeing any resources the GPU may be using, otherwise get Vulkan validation layer errors on shutdown
|
||||
// SRS - skip this step if we are in a Doom Classic game
|
||||
#if defined(USE_DOOMCLASSIC)
|
||||
if( common->GetCurrentGame() == DOOM3_BFG )
|
||||
{
|
||||
backend.GL_BlockingSwapBuffers();
|
||||
}
|
||||
#endif
|
||||
|
||||
// free the vertex cache, which should have nothing allocated now
|
||||
vertexCache.Shutdown();
|
||||
|
|
|
@ -1264,89 +1264,4 @@ static const unsigned char brfLutTexBytes[] =
|
|||
Mem_Free( hdrBuffer );
|
||||
}
|
||||
|
||||
CONSOLE_COMMAND( makeImageHeader, "load an image and turn it into a .h file", NULL )
|
||||
{
|
||||
byte* buffer;
|
||||
int width = 0, height = 0;
|
||||
|
||||
if( args.Argc() < 2 )
|
||||
{
|
||||
common->Printf( "USAGE: makeImageHeader filename [exportname]\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
idStr filename = args.Argv( 1 );
|
||||
|
||||
R_LoadImage( filename, &buffer, &width, &height, NULL, true, NULL );
|
||||
if( !buffer )
|
||||
{
|
||||
common->Printf( "loading %s failed.\n", filename.c_str() );
|
||||
return;
|
||||
}
|
||||
|
||||
filename.StripFileExtension();
|
||||
|
||||
idStr exportname;
|
||||
|
||||
if( args.Argc() == 3 )
|
||||
{
|
||||
exportname.Format( "Image_%s.h", args.Argv( 2 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
exportname.Format( "Image_%s.h", filename.c_str() );
|
||||
}
|
||||
|
||||
for( int i = 0; i < exportname.Length(); i++ )
|
||||
{
|
||||
if( exportname[ i ] == '/' )
|
||||
{
|
||||
exportname[ i ] = '_';
|
||||
}
|
||||
}
|
||||
|
||||
idFileLocal headerFile( fileSystem->OpenFileWrite( exportname, "fs_basepath" ) );
|
||||
|
||||
idStr uppername = exportname;
|
||||
uppername.ToUpper();
|
||||
|
||||
for( int i = 0; i < uppername.Length(); i++ )
|
||||
{
|
||||
if( uppername[ i ] == '.' )
|
||||
{
|
||||
uppername[ i ] = '_';
|
||||
}
|
||||
}
|
||||
|
||||
headerFile->Printf( "#ifndef %s_TEX_H\n", uppername.c_str() );
|
||||
headerFile->Printf( "#define %s_TEX_H\n\n", uppername.c_str() );
|
||||
|
||||
headerFile->Printf( "#define %s_TEX_WIDTH %i\n", uppername.c_str(), width );
|
||||
headerFile->Printf( "#define %s_TEX_HEIGHT %i\n\n", uppername.c_str(), height );
|
||||
|
||||
headerFile->Printf( "static const unsigned char %s_Bytes[] = {\n", uppername.c_str() );
|
||||
|
||||
int bufferSize = width * height * 4;
|
||||
|
||||
for( int i = 0; i < bufferSize; i++ )
|
||||
{
|
||||
byte b = buffer[i];
|
||||
|
||||
if( i < ( bufferSize - 1 ) )
|
||||
{
|
||||
headerFile->Printf( "0x%02hhx, ", b );
|
||||
}
|
||||
else
|
||||
{
|
||||
headerFile->Printf( "0x%02hhx", b );
|
||||
}
|
||||
|
||||
if( i % 12 == 0 )
|
||||
{
|
||||
headerFile->Printf( "\n" );
|
||||
}
|
||||
}
|
||||
headerFile->Printf( "\n};\n#endif\n" );
|
||||
|
||||
Mem_Free( buffer );
|
||||
}
|
||||
|
|
|
@ -31,10 +31,20 @@ source_group("global" FILES ${globalshaders})
|
|||
|
||||
source_group("user" FILES ${usershaders})
|
||||
|
||||
compile_shaders_all_platforms(
|
||||
TARGET Shaders
|
||||
CONFIG ${CMAKE_CURRENT_SOURCE_DIR}/shaders.cfg
|
||||
OUTPUT_BASE ${CMAKE_CURRENT_SOURCE_DIR}/../../base/renderprogs2 # This path scheme is a bit odd.
|
||||
SHADER_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
SOURCES ${shaders}
|
||||
)
|
||||
if(STANDALONE)
|
||||
compile_shaders_all_platforms(
|
||||
TARGET Shaders
|
||||
CONFIG ${CMAKE_CURRENT_SOURCE_DIR}/shaders.cfg
|
||||
OUTPUT_BASE ${CMAKE_CURRENT_SOURCE_DIR}/../../content/renderprogs2
|
||||
SHADER_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
SOURCES ${shaders}
|
||||
)
|
||||
else()
|
||||
compile_shaders_all_platforms(
|
||||
TARGET Shaders
|
||||
CONFIG ${CMAKE_CURRENT_SOURCE_DIR}/shaders.cfg
|
||||
OUTPUT_BASE ${CMAKE_CURRENT_SOURCE_DIR}/../../base/renderprogs2 # This path scheme is a bit odd.
|
||||
SHADER_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
SOURCES ${shaders}
|
||||
)
|
||||
endif()
|
127
neo/shaders/builtin/post/crt_mattias.ps.hlsl
Normal file
127
neo/shaders/builtin/post/crt_mattias.ps.hlsl
Normal file
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
newpixie CRT
|
||||
|
||||
Copyright (c) 2016 Mattias Gustavsson
|
||||
Copyright (c) 2023 Robert Beckebans
|
||||
|
||||
MIT License
|
||||
|
||||
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 <global_inc.hlsl>
|
||||
|
||||
|
||||
// *INDENT-OFF*
|
||||
Texture2D t_CurrentRender : register( t0 VK_DESCRIPTOR_SET( 0 ) );
|
||||
Texture2D t_BlueNoise : register( t1 VK_DESCRIPTOR_SET( 0 ) );
|
||||
|
||||
SamplerState LinearSampler : register(s0 VK_DESCRIPTOR_SET( 1 ) );
|
||||
SamplerState samp1 : register(s1 VK_DESCRIPTOR_SET( 1 ) ); // blue noise 256
|
||||
|
||||
struct PS_IN
|
||||
{
|
||||
float4 position : SV_Position;
|
||||
float2 texcoord0 : TEXCOORD0_centroid;
|
||||
};
|
||||
|
||||
struct PS_OUT
|
||||
{
|
||||
float4 color : SV_Target0;
|
||||
};
|
||||
// *INDENT-ON*
|
||||
|
||||
|
||||
float2 curve( float2 uv, float curvature )
|
||||
{
|
||||
uv = ( uv - 0.5 ) * 2.0;
|
||||
uv *= 1.1;
|
||||
uv.x *= 1.0 + pow( ( abs( uv.y ) / 5.0 ), 2.0 );
|
||||
uv.y *= 1.0 + pow( ( abs( uv.x ) / 4.0 ), 2.0 );
|
||||
uv = ( uv / curvature ) + 0.5;
|
||||
uv = uv * 0.92 + 0.04;
|
||||
return uv;
|
||||
}
|
||||
|
||||
void main( PS_IN fragment, out PS_OUT result )
|
||||
{
|
||||
float2 iResolution = rpWindowCoord.zw;
|
||||
float iTime = rpJitterTexOffset.x;
|
||||
|
||||
float2 q = fragment.texcoord0.xy;
|
||||
q = saturate( q );
|
||||
|
||||
float2 uv = q;
|
||||
if( rpWindowCoord.x > 0.0 )
|
||||
{
|
||||
uv = curve( uv, 2.0 );
|
||||
}
|
||||
|
||||
// wiggle
|
||||
float x = 0.0; //sin( 0.3 * iTime + uv.y * 21.0 ) * sin( 0.7 * iTime + uv.y * 29.0 ) * sin( 0.3 + 0.33 * iTime + uv.y * 31.0 ) * 0.0017;
|
||||
|
||||
float3 col;
|
||||
col.r = t_CurrentRender.Sample( LinearSampler, float2( x + uv.x + 0.001, uv.y + 0.001 ) ).x + 0.05;
|
||||
col.g = t_CurrentRender.Sample( LinearSampler, float2( x + uv.x + 0.000, uv.y - 0.002 ) ).y + 0.05;
|
||||
col.b = t_CurrentRender.Sample( LinearSampler, float2( x + uv.x - 0.002, uv.y + 0.000 ) ).z + 0.05;
|
||||
|
||||
/* Ghosting */
|
||||
#if 1
|
||||
col.r += 0.08 * t_CurrentRender.Sample( LinearSampler, 0.75 * float2( x + 0.025, -0.027 ) + float2( uv.x + 0.001, uv.y + 0.001 ) ).x;
|
||||
col.g += 0.05 * t_CurrentRender.Sample( LinearSampler, 0.75 * float2( x + -0.022, -0.02 ) + float2( uv.x + 0.000, uv.y - 0.002 ) ).y;
|
||||
col.b += 0.08 * t_CurrentRender.Sample( LinearSampler, 0.75 * float2( x + -0.02, -0.018 ) + float2( uv.x - 0.002, uv.y + 0.000 ) ).z;
|
||||
#endif
|
||||
|
||||
/* Level adjustment (curves) */
|
||||
col = clamp( col * 0.6 + 0.4 * col * col * 1.0, 0.0, 1.0 );
|
||||
|
||||
/* Vignette */
|
||||
float vig = ( 0.0 + 1.0 * 16.0 * uv.x * uv.y * ( 1.0 - uv.x ) * ( 1.0 - uv.y ) );
|
||||
col *= _float3( pow( vig, 0.3 ) );
|
||||
|
||||
col *= float3( 0.95, 1.05, 0.95 );
|
||||
col *= 2.8;
|
||||
|
||||
/* Scanlines */
|
||||
float scans = clamp( 0.35 + 0.35 * sin( 3.5 * iTime + uv.y * iResolution.y * 1.5 ), 0.0, 1.0 );
|
||||
|
||||
float s = pow( scans, 1.7 );
|
||||
col = col * _float3( 0.4 + 0.7 * s ) ;
|
||||
|
||||
col *= 1.0 + 0.01 * sin( 110.0 * iTime );
|
||||
if( uv.x < 0.0 || uv.x > 1.0 )
|
||||
{
|
||||
col *= 0.0;
|
||||
}
|
||||
if( uv.y < 0.0 || uv.y > 1.0 )
|
||||
{
|
||||
col *= 0.0;
|
||||
}
|
||||
|
||||
col *= 1.0 - 0.65 * _float3( clamp( ( fmod( fragment.texcoord0.x, 2.0 ) - 1.0 ) * 2.0, 0.0, 1.0 ) );
|
||||
|
||||
float comp = smoothstep( 0.1, 0.9, sin( iTime ) );
|
||||
|
||||
// Remove the next line to stop cross-fade between original and postprocess
|
||||
//col = mix( col, oricol, comp );
|
||||
|
||||
result.color = float4( col.x, col.y, col.z, 1.0 );
|
||||
}
|
55
neo/shaders/builtin/post/crt_mattias.vs.hlsl
Normal file
55
neo/shaders/builtin/post/crt_mattias.vs.hlsl
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "global_inc.hlsl"
|
||||
|
||||
|
||||
// *INDENT-OFF*
|
||||
struct VS_IN
|
||||
{
|
||||
float4 position : POSITION;
|
||||
float2 texcoord : TEXCOORD0;
|
||||
float4 normal : NORMAL;
|
||||
float4 tangent : TANGENT;
|
||||
float4 color : COLOR0;
|
||||
float4 color2 : COLOR1;
|
||||
};
|
||||
|
||||
struct VS_OUT {
|
||||
float4 position : SV_Position;
|
||||
float2 texcoord0 : TEXCOORD0_centroid;
|
||||
};
|
||||
// *INDENT-ON*
|
||||
|
||||
void main( VS_IN vertex, out VS_OUT result )
|
||||
{
|
||||
result.position = vertex.position;
|
||||
result.position.y = -result.position.y;
|
||||
|
||||
result.texcoord0 = vertex.texcoord;
|
||||
}
|
254
neo/shaders/builtin/post/crt_newpixie.ps.hlsl
Normal file
254
neo/shaders/builtin/post/crt_newpixie.ps.hlsl
Normal file
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
newpixie CRT
|
||||
|
||||
Copyright (c) 2016 Mattias Gustavsson
|
||||
Copyright (c) 2023 Robert Beckebans
|
||||
|
||||
MIT License
|
||||
|
||||
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 <global_inc.hlsl>
|
||||
|
||||
|
||||
// *INDENT-OFF*
|
||||
Texture2D t_CurrentRender : register( t0 VK_DESCRIPTOR_SET( 0 ) );
|
||||
Texture2D t_BlueNoise : register( t1 VK_DESCRIPTOR_SET( 0 ) );
|
||||
|
||||
SamplerState LinearSampler : register(s0 VK_DESCRIPTOR_SET( 1 ) );
|
||||
SamplerState samp1 : register(s1 VK_DESCRIPTOR_SET( 1 ) ); // blue noise 256
|
||||
|
||||
struct PS_IN
|
||||
{
|
||||
float4 position : SV_Position;
|
||||
float2 texcoord0 : TEXCOORD0_centroid;
|
||||
};
|
||||
|
||||
struct PS_OUT
|
||||
{
|
||||
float4 color : SV_Target0;
|
||||
};
|
||||
// *INDENT-ON*
|
||||
|
||||
|
||||
float3 tsample( Texture2D tex, vec2 tc, float offs, vec2 resolution )
|
||||
{
|
||||
#if 1
|
||||
//tc = tc * vec2( 1.025, 0.92 ) + vec2( -0.0125, 0.04 );
|
||||
float3 s = pow( abs( tex.Sample( LinearSampler, vec2( tc.x, 1.0 - tc.y ) ).rgb ), _float3( 2.2 ) );
|
||||
return s * _float3( 1.25 );
|
||||
#else
|
||||
float3 s = tex.Sample( LinearSampler, vec2( tc.x, 1.0 - tc.y ) ).rgb;
|
||||
return s;
|
||||
#endif
|
||||
}
|
||||
|
||||
float3 filmic( float3 LinearColor )
|
||||
{
|
||||
float3 x = max( _float3( 0.0 ), LinearColor - _float3( 0.004 ) );
|
||||
return ( x * ( 6.2 * x + 0.5 ) ) / ( x * ( 6.2 * x + 1.7 ) + 0.06 );
|
||||
}
|
||||
|
||||
float2 curve( float2 uv, float curvature )
|
||||
{
|
||||
uv = ( uv - 0.5 ) * 2.0;
|
||||
uv *= 1.1;
|
||||
uv.x *= 1.0 + pow( ( abs( uv.y ) / 5.0 ), 2.0 );
|
||||
uv.y *= 1.0 + pow( ( abs( uv.x ) / 4.0 ), 2.0 );
|
||||
uv = ( uv / curvature ) + 0.5;
|
||||
uv = uv * 0.92 + 0.04;
|
||||
return uv;
|
||||
}
|
||||
|
||||
float2 curve2( float2 uv, float curvature )
|
||||
{
|
||||
uv = ( uv - 0.5 ) * 2.0;
|
||||
uv *= 1.1;
|
||||
uv.x *= 1.0 + pow( ( abs( uv.y ) / 4.0 ), 2.0 );
|
||||
uv.y *= 1.0 + pow( ( abs( uv.x ) / 3.0 ), 2.0 );
|
||||
uv = ( uv / curvature ) + 0.5;
|
||||
uv = uv * 0.92 + 0.04;
|
||||
return uv;
|
||||
}
|
||||
|
||||
void main( PS_IN fragment, out PS_OUT result )
|
||||
{
|
||||
// revised version from RetroArch
|
||||
|
||||
struct Params
|
||||
{
|
||||
float curvature;
|
||||
float ghosting;
|
||||
float scanroll;
|
||||
float vignette;
|
||||
float wiggle_toggle;
|
||||
int FrameCount;
|
||||
};
|
||||
|
||||
Params params;
|
||||
params.curvature = rpWindowCoord.x;
|
||||
params.ghosting = 0.0;
|
||||
params.scanroll = 1.0;
|
||||
params.wiggle_toggle = 0.0;
|
||||
params.vignette = rpWindowCoord.y;
|
||||
params.FrameCount = int( rpJitterTexOffset.w );
|
||||
|
||||
// stop time variable so the screen doesn't wiggle
|
||||
float time = params.FrameCount % 849 * 36.0;
|
||||
float2 uv = fragment.texcoord0.xy;
|
||||
uv.y = 1.0 - uv.y;
|
||||
uv = saturate( uv );
|
||||
|
||||
/* Curve */
|
||||
//float2 curved_uv = lerp( curve2( uv, params.curvature ), uv, 0.4 );
|
||||
//float scale = -0.101;
|
||||
//float2 scuv = curved_uv * ( 1.0 - scale ) + scale / 2.0 + float2( 0.003, -0.001 );
|
||||
|
||||
//uv = scuv;
|
||||
|
||||
float2 curved_uv = uv;
|
||||
|
||||
if( params.curvature > 0.0 )
|
||||
{
|
||||
curved_uv = curve( uv, 2.0 );
|
||||
}
|
||||
float2 scuv = curved_uv;
|
||||
|
||||
float2 resolution = rpWindowCoord.zw;
|
||||
|
||||
/* Main color, Bleed */
|
||||
float3 col;
|
||||
float x = params.wiggle_toggle * sin( 0.1 * time + curved_uv.y * 13.0 ) * sin( 0.23 * time + curved_uv.y * 19.0 ) * sin( 0.3 + 0.11 * time + curved_uv.y * 23.0 ) * 0.0012;
|
||||
|
||||
// make time do something again
|
||||
time = float( params.FrameCount % 640 * 1 );
|
||||
|
||||
Texture2D backbuffer = t_CurrentRender;
|
||||
#if 1
|
||||
col.r = tsample( backbuffer, vec2( x + scuv.x + 0.0009, scuv.y + 0.0009 ), resolution.y / 800.0, resolution ).x + 0.02;
|
||||
col.g = tsample( backbuffer, vec2( x + scuv.x + 0.0000, scuv.y - 0.0011 ), resolution.y / 800.0, resolution ).y + 0.02;
|
||||
col.b = tsample( backbuffer, vec2( x + scuv.x - 0.0015, scuv.y + 0.0000 ), resolution.y / 800.0, resolution ).z + 0.02;
|
||||
#else
|
||||
col.r = t_CurrentRender.Sample( LinearSampler, float2( x + uv.x + 0.001, uv.y + 0.001 ) ).x + 0.05;
|
||||
col.g = t_CurrentRender.Sample( LinearSampler, float2( x + uv.x + 0.000, uv.y - 0.002 ) ).y + 0.05;
|
||||
col.b = t_CurrentRender.Sample( LinearSampler, float2( x + uv.x - 0.002, uv.y + 0.000 ) ).z + 0.05;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Ghosting */
|
||||
#if 1
|
||||
{
|
||||
float o = sin( -fragment.position.y * 1.5 ) / resolution.x;
|
||||
x += o * 0.25;
|
||||
|
||||
float ghs = 0.15 * params.ghosting;
|
||||
Texture2D blurbuffer = t_CurrentRender; // FIXME
|
||||
float3 r = tsample( blurbuffer, float2( x - 0.014 * 1.0, -0.027 ) * 0.85 + 0.007 * float2( 0.35 * sin( 1.0 / 7.0 + 15.0 * curved_uv.y + 0.9 * time ),
|
||||
0.35 * sin( 2.0 / 7.0 + 10.0 * curved_uv.y + 1.37 * time ) ) + float2( scuv.x + 0.001, scuv.y + 0.001 ),
|
||||
5.5 + 1.3 * sin( 3.0 / 9.0 + 31.0 * curved_uv.x + 1.70 * time ), resolution ).xyz * float3( 0.5, 0.25, 0.25 );
|
||||
float3 g = tsample( blurbuffer, float2( x - 0.019 * 1.0, -0.020 ) * 0.85 + 0.007 * float2( 0.35 * cos( 1.0 / 9.0 + 15.0 * curved_uv.y + 0.5 * time ),
|
||||
0.35 * sin( 2.0 / 9.0 + 10.0 * curved_uv.y + 1.50 * time ) ) + float2( scuv.x + 0.000, scuv.y - 0.002 ),
|
||||
5.4 + 1.3 * sin( 3.0 / 3.0 + 71.0 * curved_uv.x + 1.90 * time ), resolution ).xyz * float3( 0.25, 0.5, 0.25 );
|
||||
float3 b = tsample( blurbuffer, float2( x - 0.017 * 1.0, -0.003 ) * 0.85 + 0.007 * float2( 0.35 * sin( 2.0 / 3.0 + 15.0 * curved_uv.y + 0.7 * time ),
|
||||
0.35 * cos( 2.0 / 3.0 + 10.0 * curved_uv.y + 1.63 * time ) ) + float2( scuv.x - 0.002, scuv.y + 0.000 ),
|
||||
5.3 + 1.3 * sin( 3.0 / 7.0 + 91.0 * curved_uv.x + 1.65 * time ), resolution ).xyz * float3( 0.25, 0.25, 0.5 );
|
||||
|
||||
float i = clamp( col.r * 0.299 + col.g * 0.587 + col.b * 0.114, 0.0, 1.0 );
|
||||
i = pow( 1.0 - pow( i, 2.0 ), 1.0 );
|
||||
i = ( 1.0 - i ) * 0.85 + 0.15;
|
||||
|
||||
col += _float3( ghs * ( 1.0 - 0.299 ) ) * pow( clamp( _float3( 3.0 ) * r, _float3( 0.0 ), _float3( 1.0 ) ), _float3( 2.0 ) ) * _float3( i );
|
||||
col += _float3( ghs * ( 1.0 - 0.587 ) ) * pow( clamp( _float3( 3.0 ) * g, _float3( 0.0 ), _float3( 1.0 ) ), _float3( 2.0 ) ) * _float3( i );
|
||||
col += _float3( ghs * ( 1.0 - 0.114 ) ) * pow( clamp( _float3( 3.0 ) * b, _float3( 0.0 ), _float3( 1.0 ) ), _float3( 2.0 ) ) * _float3( i );
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Level adjustment (curves) */
|
||||
#if 1
|
||||
col *= float3( 0.95, 1.05, 0.95 );
|
||||
col = clamp( col * 1.3 + 0.75 * col * col + 1.25 * col * col * col * col * col, _float3( 0.0 ), _float3( 10.0 ) );
|
||||
#endif
|
||||
|
||||
/* Vignette */
|
||||
#if 1
|
||||
float vig = ( ( 1.0 - 0.99 * params.vignette ) + 1.0 * 16.0 * curved_uv.x * curved_uv.y * ( 1.0 - curved_uv.x ) * ( 1.0 - curved_uv.y ) );
|
||||
vig = 1.3 * pow( vig, 0.5 );
|
||||
col *= vig;
|
||||
#endif
|
||||
|
||||
time *= params.scanroll;
|
||||
|
||||
/* Scanlines */
|
||||
float scans = clamp( 0.35 + 0.18 * sin( 6.0 * time - curved_uv.y * resolution.y * 1.5 ), 0.0, 1.0 );
|
||||
float s = pow( scans, 0.9 );
|
||||
col = col * _float3( s );
|
||||
|
||||
/* Vertical lines (shadow mask) */
|
||||
col *= 1.0 - 0.23 * ( clamp( ( fragment.position.xy.x % 3.0 ) / 2.0, 0.0, 1.0 ) );
|
||||
|
||||
/* Tone map */
|
||||
col = filmic( col );
|
||||
|
||||
/* Noise */
|
||||
#if 1
|
||||
/*float2 seed = floor(curved_uv*resolution.xy*float2(0.5))/resolution.xy;*/
|
||||
float2 seed = curved_uv * resolution.xy;
|
||||
/* seed = curved_uv; */
|
||||
col -= 0.015 * pow( float3( rand( seed + time ), rand( seed + time * 2.0 ), rand( seed + time * 3.0 ) ), _float3( 1.5 ) );
|
||||
#endif
|
||||
|
||||
/* Flicker */
|
||||
col *= ( 1.0 - 0.004 * ( sin( 50.0 * time + curved_uv.y * 2.0 ) * 0.5 + 0.5 ) );
|
||||
|
||||
/* Clamp */
|
||||
#if 1
|
||||
if( curved_uv.x < 0.0 || curved_uv.x > 1.0 )
|
||||
{
|
||||
col *= 0.0;
|
||||
}
|
||||
if( curved_uv.y < 0.0 || curved_uv.y > 1.0 )
|
||||
{
|
||||
col *= 0.0;
|
||||
}
|
||||
#endif
|
||||
|
||||
uv = curved_uv;
|
||||
|
||||
#if 1
|
||||
/* Frame */
|
||||
float2 fscale = float2( 0.026, -0.018 ); //float2( -0.018, -0.013 );
|
||||
//uv = float2( uv.x, 1.0 - uv.y );
|
||||
|
||||
//float4 f = texture( frametexture, vTexCoord.xy ); //*((1.0)+2.0*fscale)-fscale-float2(-0.0, 0.005));
|
||||
//f.xyz = mix( f.xyz, float3( 0.5, 0.5, 0.5 ), 0.5 );
|
||||
float4 f = _float4( 0.5 );
|
||||
float fvig = clamp( -0.00 + 512.0 * uv.x * uv.y * ( 1.0 - uv.x ) * ( 1.0 - uv.y ), 0.2, 0.8 );
|
||||
//col = lerp( col, lerp( max( col, 0.0 ), pow( abs( f.xyz ), _float3( 1.4 ) ) * fvig, f.w * f.w ), _float3( use_frame ) );
|
||||
//col = lerp( col, lerp( max( col, 0.0 ), pow( abs( f.xyz ), _float3( 1.4 ) ) * fvig, f.w * f.w ), _float3( 1.0 ) );
|
||||
|
||||
// Gamma correction since we are not rendering to an sRGB render target.
|
||||
col = pow( col, _float3( 1.0 / 1.1 ) );
|
||||
#endif
|
||||
|
||||
result.color = float4( col, 1.0 );
|
||||
}
|
55
neo/shaders/builtin/post/crt_newpixie.vs.hlsl
Normal file
55
neo/shaders/builtin/post/crt_newpixie.vs.hlsl
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "global_inc.hlsl"
|
||||
|
||||
|
||||
// *INDENT-OFF*
|
||||
struct VS_IN
|
||||
{
|
||||
float4 position : POSITION;
|
||||
float2 texcoord : TEXCOORD0;
|
||||
float4 normal : NORMAL;
|
||||
float4 tangent : TANGENT;
|
||||
float4 color : COLOR0;
|
||||
float4 color2 : COLOR1;
|
||||
};
|
||||
|
||||
struct VS_OUT {
|
||||
float4 position : SV_Position;
|
||||
float2 texcoord0 : TEXCOORD0_centroid;
|
||||
};
|
||||
// *INDENT-ON*
|
||||
|
||||
void main( VS_IN vertex, out VS_OUT result )
|
||||
{
|
||||
result.position = vertex.position;
|
||||
result.position.y = -result.position.y;
|
||||
|
||||
result.texcoord0 = vertex.texcoord;
|
||||
}
|
|
@ -72,8 +72,6 @@ struct PS_OUT
|
|||
#define Dithering_QuantizationSteps 16.0 // 8.0 = 2 ^ 3 quantization bits
|
||||
#define Dithering_NoiseBoost 1.0
|
||||
#define Dithering_Wide 1.0
|
||||
#define DITHER_IN_LINEAR_SPACE 0
|
||||
#define DITHER_GENERATE_NOISE 0
|
||||
|
||||
float3 overlay( float3 a, float3 b )
|
||||
{
|
||||
|
@ -284,70 +282,9 @@ float3 BlueNoise3( float2 n, float x )
|
|||
}
|
||||
|
||||
|
||||
float Noise( float2 n, float x )
|
||||
{
|
||||
n += x;
|
||||
|
||||
#if 1
|
||||
return frac( sin( dot( n.xy, float2( 12.9898, 78.233 ) ) ) * 43758.5453 ) * 2.0 - 1.0;
|
||||
#else
|
||||
//return BlueNoise( n, 55.0 );
|
||||
return BlueNoise( n, 1.0 );
|
||||
|
||||
//return InterleavedGradientNoise( n ) * 2.0 - 1.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Step 1 in generation of the dither source texture.
|
||||
float Step1( float2 uv, float n )
|
||||
{
|
||||
float a = 1.0, b = 2.0, c = -12.0, t = 1.0;
|
||||
|
||||
return ( 1.0 / ( a * 4.0 + b * 4.0 - c ) ) * (
|
||||
Noise( uv + float2( -1.0, -1.0 ) * t, n ) * a +
|
||||
Noise( uv + float2( 0.0, -1.0 ) * t, n ) * b +
|
||||
Noise( uv + float2( 1.0, -1.0 ) * t, n ) * a +
|
||||
Noise( uv + float2( -1.0, 0.0 ) * t, n ) * b +
|
||||
Noise( uv + float2( 0.0, 0.0 ) * t, n ) * c +
|
||||
Noise( uv + float2( 1.0, 0.0 ) * t, n ) * b +
|
||||
Noise( uv + float2( -1.0, 1.0 ) * t, n ) * a +
|
||||
Noise( uv + float2( 0.0, 1.0 ) * t, n ) * b +
|
||||
Noise( uv + float2( 1.0, 1.0 ) * t, n ) * a +
|
||||
0.0 );
|
||||
}
|
||||
|
||||
// Step 2 in generation of the dither source texture.
|
||||
float Step2( float2 uv, float n )
|
||||
{
|
||||
float a = 1.0, b = 2.0, c = -2.0, t = 1.0;
|
||||
|
||||
#if DITHER_IN_LINEAR_SPACE
|
||||
return ( 1.0 / ( a * 4.0 + b * 4.0 - c ) ) * (
|
||||
#else
|
||||
return ( 4.0 / ( a * 4.0 + b * 4.0 - c ) ) * (
|
||||
#endif
|
||||
Step1( uv + float2( -1.0, -1.0 ) * t, n ) * a +
|
||||
Step1( uv + float2( 0.0, -1.0 ) * t, n ) * b +
|
||||
Step1( uv + float2( 1.0, -1.0 ) * t, n ) * a +
|
||||
Step1( uv + float2( -1.0, 0.0 ) * t, n ) * b +
|
||||
Step1( uv + float2( 0.0, 0.0 ) * t, n ) * c +
|
||||
Step1( uv + float2( 1.0, 0.0 ) * t, n ) * b +
|
||||
Step1( uv + float2( -1.0, 1.0 ) * t, n ) * a +
|
||||
Step1( uv + float2( 0.0, 1.0 ) * t, n ) * b +
|
||||
Step1( uv + float2( 1.0, 1.0 ) * t, n ) * a +
|
||||
0.0 );
|
||||
}
|
||||
|
||||
// Used for stills.
|
||||
float3 Step3( float2 uv )
|
||||
{
|
||||
#if DITHER_GENERATE_NOISE
|
||||
float a = Step2( uv, 0.07 );
|
||||
float b = Step2( uv, 0.11 );
|
||||
float c = Step2( uv, 0.13 );
|
||||
|
||||
return float3( a, b, c );
|
||||
#else
|
||||
float3 noise = BlueNoise3( uv, 0.0 );
|
||||
|
||||
#if 1
|
||||
|
@ -359,19 +296,11 @@ float3 Step3( float2 uv )
|
|||
#endif
|
||||
|
||||
return noise;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Used for temporal dither.
|
||||
float3 Step3T( float2 uv )
|
||||
{
|
||||
#if DITHER_GENERATE_NOISE
|
||||
float a = Step2( uv, 0.07 * fract( rpJitterTexOffset.z ) );
|
||||
float b = Step2( uv, 0.11 * fract( rpJitterTexOffset.z ) );
|
||||
float c = Step2( uv, 0.13 * fract( rpJitterTexOffset.z ) );
|
||||
|
||||
return float3( a, b, c );
|
||||
#else
|
||||
float3 noise = BlueNoise3( uv, 1.0 );
|
||||
|
||||
#if 1
|
||||
|
@ -383,7 +312,6 @@ float3 Step3T( float2 uv )
|
|||
#endif
|
||||
|
||||
return noise;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -395,86 +323,32 @@ void DitheringPass( inout float4 fragColor, PS_IN fragment )
|
|||
float3 color = fragColor.rgb;
|
||||
|
||||
#if 0
|
||||
// BOTTOM: Show bands.
|
||||
if( uv2.y >= 0.975 )
|
||||
{
|
||||
// quantized signal
|
||||
color = float3( uv2.x );
|
||||
// BOTTOM: Show bands.
|
||||
color = _float3( uv2.x );
|
||||
|
||||
// dithered still
|
||||
//color = floor( color * Dithering_QuantizationSteps + Step3( uv ) * Dithering_NoiseBoost ) * ( 1.0 / ( Dithering_QuantizationSteps - 1.0 ) );
|
||||
}
|
||||
else if( uv2.y >= 0.95 )
|
||||
{
|
||||
// quantized signal
|
||||
color = float3( uv2.x );
|
||||
color = _float3( uv2.x );
|
||||
color = floor( color * Dithering_QuantizationSteps ) * ( 1.0 / ( Dithering_QuantizationSteps - 1.0 ) );
|
||||
}
|
||||
else if( uv2.y >= 0.925 )
|
||||
{
|
||||
// quantized signal dithered temporally
|
||||
color = float3( uv2.x );
|
||||
color = _float3( uv2.x );
|
||||
color = floor( color * Dithering_QuantizationSteps + Step3( uv ) * Dithering_NoiseBoost ) * ( 1.0 / ( Dithering_QuantizationSteps - 1.0 ) );
|
||||
}
|
||||
// TOP: Show dither texture.
|
||||
else if( uv2.y >= 0.9 )
|
||||
{
|
||||
// TOP: Show dither texture.
|
||||
color = Step3( uv ) * ( 0.25 * Dithering_NoiseBoost ) + 0.5;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
|
||||
#if DITHER_IN_LINEAR_SPACE
|
||||
|
||||
color = Linear3( color );
|
||||
|
||||
// Add grain in linear space.
|
||||
#if 0
|
||||
// Slow more correct solutions.
|
||||
#if 1
|
||||
// Too expensive.
|
||||
// Helps understand the fast solutions.
|
||||
float3 amount = Linear3( Srgb3( color ) + ( Dithering_NoiseBoost / Dithering_QuantizationSteps ) ) - color;
|
||||
#else
|
||||
// Less too expensive.
|
||||
float luma = PhotoLuma( color );
|
||||
|
||||
// Implement this as a texture lookup table.
|
||||
float amount = Linear1( Srgb1( luma ) + ( Dithering_NoiseBoost / Dithering_QuantizationSteps ) ) - luma;
|
||||
#endif
|
||||
|
||||
#else
|
||||
// Fast solutions.
|
||||
#if 1
|
||||
// Hack 1 (fastest).
|
||||
// For HDR need saturate() around luma.
|
||||
float luma = PhotoLuma( color );
|
||||
float amount = mix(
|
||||
Linear1( Dithering_NoiseBoost / Dithering_QuantizationSteps ),
|
||||
Linear1( ( Dithering_NoiseBoost / Dithering_QuantizationSteps ) + 1.0 ) - 1.0,
|
||||
luma );
|
||||
#else
|
||||
// Hack 2 (slower?).
|
||||
// For HDR need saturate() around color in mix().
|
||||
float3 amount = mix(
|
||||
float3( Linear1( Dithering_NoiseBoost / Dithering_QuantizationSteps ) ),
|
||||
float3( Linear1( ( Dithering_NoiseBoost / Dithering_QuantizationSteps ) + 1.0 ) - 1.0 ),
|
||||
color );
|
||||
#endif
|
||||
|
||||
#endif
|
||||
color += Step3T( uv ) * amount;// * Dithering_NoiseBoost;
|
||||
|
||||
// The following represents hardware linear->sRGB xform
|
||||
// which happens on sRGB formatted render targets,
|
||||
// except using a lot less bits/pixel.
|
||||
color = max( float3( 0.0 ), color );
|
||||
color = Srgb3( color );
|
||||
color = floor( color * Dithering_QuantizationSteps ) * ( 1.0 / ( Dithering_QuantizationSteps - 1.0 ) );
|
||||
|
||||
#else
|
||||
|
||||
#if 0
|
||||
if( uv2.x <= 0.5 )
|
||||
{
|
||||
|
@ -486,8 +360,6 @@ void DitheringPass( inout float4 fragColor, PS_IN fragment )
|
|||
{
|
||||
color = floor( 0.5 + color * ( Dithering_QuantizationSteps + Dithering_Wide - 1.0 ) + ( -Dithering_Wide * 0.5 ) + Step3T( uv ) * ( Dithering_Wide ) ) * ( 1.0 / ( Dithering_QuantizationSteps - 1.0 ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
fragColor.rgb = color;
|
||||
|
|
283
neo/shaders/builtin/post/retro_c64.ps.hlsl
Normal file
283
neo/shaders/builtin/post/retro_c64.ps.hlsl
Normal file
|
@ -0,0 +1,283 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
Copyright (C) 2024 Robert Beckebans
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "global_inc.hlsl"
|
||||
|
||||
|
||||
// *INDENT-OFF*
|
||||
Texture2D t_BaseColor : register( t0 VK_DESCRIPTOR_SET( 0 ) );
|
||||
Texture2D t_BlueNoise : register( t1 VK_DESCRIPTOR_SET( 0 ) );
|
||||
|
||||
SamplerState samp0 : register(s0 VK_DESCRIPTOR_SET( 1 ) );
|
||||
SamplerState samp1 : register(s1 VK_DESCRIPTOR_SET( 1 ) ); // blue noise 256
|
||||
|
||||
struct PS_IN
|
||||
{
|
||||
float4 position : SV_Position;
|
||||
float2 texcoord0 : TEXCOORD0_centroid;
|
||||
};
|
||||
|
||||
struct PS_OUT
|
||||
{
|
||||
float4 color : SV_Target0;
|
||||
};
|
||||
// *INDENT-ON*
|
||||
|
||||
|
||||
#define RESOLUTION_DIVISOR 4.0
|
||||
#define NUM_COLORS 16
|
||||
|
||||
|
||||
float3 Average( float3 pal[NUM_COLORS] )
|
||||
{
|
||||
float3 sum = _float3( 0 );
|
||||
|
||||
for( int i = 0; i < NUM_COLORS; i++ )
|
||||
{
|
||||
sum += pal[i];
|
||||
}
|
||||
|
||||
return sum / float( NUM_COLORS );
|
||||
}
|
||||
|
||||
float3 Deviation( float3 pal[NUM_COLORS] )
|
||||
{
|
||||
float3 sum = _float3( 0 );
|
||||
float3 avg = Average( pal );
|
||||
|
||||
for( int i = 0; i < NUM_COLORS; i++ )
|
||||
{
|
||||
sum += abs( pal[i] - avg );
|
||||
}
|
||||
|
||||
return sum / float( NUM_COLORS );
|
||||
}
|
||||
|
||||
// squared distance to avoid the sqrt of distance function
|
||||
float ColorCompare( float3 a, float3 b )
|
||||
{
|
||||
float3 diff = b - a;
|
||||
return dot( diff, diff );
|
||||
}
|
||||
|
||||
// find nearest palette color using Euclidean distance
|
||||
float3 LinearSearch( float3 c, float3 pal[NUM_COLORS] )
|
||||
{
|
||||
int index = 0;
|
||||
float minDist = ColorCompare( c, pal[0] );
|
||||
|
||||
for( int i = 1; i < NUM_COLORS; i++ )
|
||||
{
|
||||
float dist = ColorCompare( c, pal[i] );
|
||||
|
||||
if( dist < minDist )
|
||||
{
|
||||
minDist = dist;
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
|
||||
return pal[index];
|
||||
}
|
||||
|
||||
/*
|
||||
float3 GetClosest( float3 val1, float3 val2, float3 target )
|
||||
{
|
||||
if( distance( target, val1 ) >= distance( val2, target ) )
|
||||
{
|
||||
return val2;
|
||||
}
|
||||
else
|
||||
{
|
||||
return val1;
|
||||
}
|
||||
}
|
||||
|
||||
// find nearest palette color using Euclidean disntance and binary search
|
||||
// this requires an already sorted palette as input
|
||||
float3 BinarySearch( float3 target, float3 pal[NUM_COLORS] )
|
||||
{
|
||||
float targetY = PhotoLuma( target );
|
||||
|
||||
// left-side case
|
||||
if( targetY <= PhotoLuma( pal[0] ) )
|
||||
{
|
||||
return pal[0];
|
||||
}
|
||||
|
||||
// right-side case
|
||||
if( targetY >= PhotoLuma( pal[NUM_COLORS - 1] ) )
|
||||
{
|
||||
return pal[NUM_COLORS - 1];
|
||||
}
|
||||
|
||||
int i = 0, j = NUM_COLORS, mid = 0;
|
||||
while( i < j )
|
||||
{
|
||||
mid = ( i + j ) / 2;
|
||||
|
||||
if( distance( pal[mid], target ) < 0.01 )
|
||||
{
|
||||
return pal[mid];
|
||||
}
|
||||
|
||||
// if target is less than array element, then search in left
|
||||
if( targetY < PhotoLuma( pal[mid] ) )
|
||||
{
|
||||
// if target is greater than previous
|
||||
// to mid, return closest of two
|
||||
if( mid > 0 && targetY > PhotoLuma( pal[mid - 1] ) )
|
||||
{
|
||||
return GetClosest( pal[mid - 1], pal[mid], target );
|
||||
}
|
||||
j = mid;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( mid < ( NUM_COLORS - 1 ) && targetY < PhotoLuma( pal[mid + 1] ) )
|
||||
{
|
||||
return GetClosest( pal[mid], pal[mid + 1], target );
|
||||
}
|
||||
i = mid + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// only single element left after search
|
||||
return pal[mid];
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
#define RGB(r, g, b) float3(float(r)/255.0, float(g)/255.0, float(b)/255.0)
|
||||
|
||||
void main( PS_IN fragment, out PS_OUT result )
|
||||
{
|
||||
// C64 colors http://unusedino.de/ec64/technical/misc/vic656x/colors/
|
||||
#if 0
|
||||
const float3 palette[NUM_COLORS] =
|
||||
{
|
||||
RGB( 0, 0, 0 ),
|
||||
RGB( 255, 255, 255 ),
|
||||
RGB( 116, 67, 53 ),
|
||||
RGB( 124, 172, 186 ),
|
||||
RGB( 123, 72, 144 ),
|
||||
RGB( 100, 151, 79 ),
|
||||
RGB( 64, 50, 133 ),
|
||||
RGB( 191, 205, 122 ),
|
||||
RGB( 123, 91, 47 ),
|
||||
RGB( 79, 69, 0 ),
|
||||
RGB( 163, 114, 101 ),
|
||||
RGB( 80, 80, 80 ),
|
||||
RGB( 120, 120, 120 ),
|
||||
RGB( 164, 215, 142 ),
|
||||
RGB( 120, 106, 189 ),
|
||||
RGB( 159, 159, 150 ),
|
||||
};
|
||||
#else
|
||||
// gamma corrected version
|
||||
const float3 palette[NUM_COLORS] =
|
||||
{
|
||||
RGB( 0, 0, 0 ), // black
|
||||
RGB( 255, 255, 255 ), // white
|
||||
RGB( 104, 55, 43 ), // red
|
||||
RGB( 112, 164, 178 ), // cyan
|
||||
RGB( 111, 61, 134 ), // purple
|
||||
RGB( 88, 141, 67 ), // green
|
||||
RGB( 53, 40, 121 ), // blue
|
||||
RGB( 184, 199, 111 ), // yellow
|
||||
RGB( 111, 79, 37 ), // orange
|
||||
RGB( 67, 57, 0 ), // brown
|
||||
RGB( 154, 103, 89 ), // light red
|
||||
RGB( 68, 68, 68 ), // dark grey
|
||||
RGB( 108, 108, 108 ), // grey
|
||||
RGB( 154, 210, 132 ), // light green
|
||||
RGB( 108, 94, 181 ), // light blue
|
||||
RGB( 149, 149, 149 ), // light grey
|
||||
};
|
||||
#endif
|
||||
|
||||
float2 uv = ( fragment.texcoord0 );
|
||||
float2 uvPixelated = floor( fragment.position.xy / RESOLUTION_DIVISOR ) * RESOLUTION_DIVISOR;
|
||||
|
||||
float3 quantizationPeriod = _float3( 1.0 / NUM_COLORS );
|
||||
|
||||
// get pixellated base color
|
||||
float3 color = t_BaseColor.Sample( samp0, uvPixelated * rpWindowCoord.xy ).rgb;
|
||||
|
||||
float2 uvDither = uvPixelated;
|
||||
//if( rpJitterTexScale.x > 1.0 )
|
||||
{
|
||||
uvDither = fragment.position.xy / ( RESOLUTION_DIVISOR / rpJitterTexScale.x );
|
||||
}
|
||||
float dither = DitherArray8x8( uvDither ) - 0.5;
|
||||
|
||||
#if 0
|
||||
if( uv.y < 0.0625 )
|
||||
{
|
||||
color = HSVToRGB( float3( uv.x, 1.0, uv.y * 16.0 ) );
|
||||
|
||||
result.color = float4( color, 1.0 );
|
||||
return;
|
||||
}
|
||||
else if( uv.y < 0.125 )
|
||||
{
|
||||
// quantized
|
||||
color = HSVToRGB( float3( uv.x, 1.0, ( uv.y - 0.0625 ) * 16.0 ) );
|
||||
color = LinearSearch( color, palette );
|
||||
|
||||
result.color = float4( color, 1.0 );
|
||||
return;
|
||||
}
|
||||
else if( uv.y < 0.1875 )
|
||||
{
|
||||
// dithered quantized
|
||||
color = HSVToRGB( float3( uv.x, 1.0, ( uv.y - 0.125 ) * 16.0 ) );
|
||||
|
||||
color.rgb += float3( dither, dither, dither ) * quantizationPeriod;
|
||||
color = LinearSearch( color, palette );
|
||||
|
||||
result.color = float4( color, 1.0 );
|
||||
return;
|
||||
}
|
||||
else if( uv.y < 0.25 )
|
||||
{
|
||||
color = _float3( uv.x );
|
||||
color = floor( color * NUM_COLORS ) * ( 1.0 / ( NUM_COLORS - 1.0 ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
//color.rgb += float3( dither, dither, dither ) * quantizationPeriod;
|
||||
color.rgb += float3( dither, dither, dither ) * Deviation( palette ) * rpJitterTexScale.y;
|
||||
|
||||
// find closest color match from C64 color palette
|
||||
color = LinearSearch( color.rgb, palette );
|
||||
//color = float4( BinarySearch( color.rgb, palette ), 1.0 );
|
||||
|
||||
result.color = float4( color, 1.0 );
|
||||
}
|
55
neo/shaders/builtin/post/retro_c64.vs.hlsl
Normal file
55
neo/shaders/builtin/post/retro_c64.vs.hlsl
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "global_inc.hlsl"
|
||||
|
||||
|
||||
// *INDENT-OFF*
|
||||
struct VS_IN
|
||||
{
|
||||
float4 position : POSITION;
|
||||
float2 texcoord : TEXCOORD0;
|
||||
float4 normal : NORMAL;
|
||||
float4 tangent : TANGENT;
|
||||
float4 color : COLOR0;
|
||||
float4 color2 : COLOR1;
|
||||
};
|
||||
|
||||
struct VS_OUT {
|
||||
float4 position : SV_Position;
|
||||
float2 texcoord0 : TEXCOORD0_centroid;
|
||||
};
|
||||
// *INDENT-ON*
|
||||
|
||||
void main( VS_IN vertex, out VS_OUT result )
|
||||
{
|
||||
result.position = vertex.position;
|
||||
result.position.y = -result.position.y;
|
||||
|
||||
result.texcoord0 = vertex.texcoord;
|
||||
}
|
393
neo/shaders/builtin/post/retro_cpc.ps.hlsl
Normal file
393
neo/shaders/builtin/post/retro_cpc.ps.hlsl
Normal file
|
@ -0,0 +1,393 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
Copyright (C) 2024 Robert Beckebans
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "global_inc.hlsl"
|
||||
|
||||
|
||||
// *INDENT-OFF*
|
||||
Texture2D t_BaseColor : register( t0 VK_DESCRIPTOR_SET( 0 ) );
|
||||
Texture2D t_BlueNoise : register( t1 VK_DESCRIPTOR_SET( 0 ) );
|
||||
|
||||
SamplerState samp0 : register(s0 VK_DESCRIPTOR_SET( 1 ) );
|
||||
SamplerState samp1 : register(s1 VK_DESCRIPTOR_SET( 1 ) ); // blue noise 256
|
||||
|
||||
struct PS_IN
|
||||
{
|
||||
float4 position : SV_Position;
|
||||
float2 texcoord0 : TEXCOORD0_centroid;
|
||||
};
|
||||
|
||||
struct PS_OUT
|
||||
{
|
||||
float4 color : SV_Target0;
|
||||
};
|
||||
// *INDENT-ON*
|
||||
|
||||
|
||||
#define RESOLUTION_DIVISOR 4.0
|
||||
#define NUM_COLORS 32 // original 27
|
||||
|
||||
/*
|
||||
float LinearTweak1( float c )
|
||||
{
|
||||
return ( c <= 0.04045 ) ? c / 12.92 : pow( ( c + 0.055 ) / 1.055, 1.4 );
|
||||
}
|
||||
|
||||
float3 LinearTweak3( float3 c )
|
||||
{
|
||||
return float3( Linear1( c.r ), Linear1( c.g ), Linear1( c.b ) );
|
||||
}
|
||||
*/
|
||||
|
||||
float3 Average( float3 pal[NUM_COLORS] )
|
||||
{
|
||||
float3 sum = _float3( 0 );
|
||||
|
||||
for( int i = 0; i < NUM_COLORS; i++ )
|
||||
{
|
||||
sum += pal[i];
|
||||
}
|
||||
|
||||
return sum / float( NUM_COLORS );
|
||||
}
|
||||
|
||||
float3 Deviation( float3 pal[NUM_COLORS] )
|
||||
{
|
||||
float3 sum = _float3( 0 );
|
||||
float3 avg = Average( pal );
|
||||
|
||||
for( int i = 0; i < NUM_COLORS; i++ )
|
||||
{
|
||||
sum += abs( pal[i] - avg );
|
||||
}
|
||||
|
||||
return sum / float( NUM_COLORS );
|
||||
}
|
||||
|
||||
// squared distance to avoid the sqrt of distance function
|
||||
float ColorCompare( float3 a, float3 b )
|
||||
{
|
||||
float3 diff = b - a;
|
||||
return dot( diff, diff );
|
||||
}
|
||||
|
||||
// find nearest palette color using Euclidean distance
|
||||
float3 LinearSearch( float3 c, float3 pal[NUM_COLORS] )
|
||||
{
|
||||
int index = 0;
|
||||
float minDist = ColorCompare( c, pal[0] );
|
||||
|
||||
for( int i = 1; i < NUM_COLORS; i++ )
|
||||
{
|
||||
float dist = ColorCompare( c, pal[i] );
|
||||
|
||||
if( dist < minDist )
|
||||
{
|
||||
minDist = dist;
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
|
||||
return pal[index];
|
||||
}
|
||||
|
||||
#define RGB(r, g, b) float3(float(r)/255.0, float(g)/255.0, float(b)/255.0)
|
||||
|
||||
|
||||
|
||||
void main( PS_IN fragment, out PS_OUT result )
|
||||
{
|
||||
#if 0
|
||||
// Amstrad CPC colors https://www.cpcwiki.eu/index.php/CPC_Palette
|
||||
const float3 palette[NUM_COLORS] =
|
||||
{
|
||||
RGB( 0, 0, 0 ), // black
|
||||
RGB( 0, 0, 128 ), // blue
|
||||
RGB( 0, 0, 255 ), // bright blue
|
||||
RGB( 128, 0, 0 ), // red
|
||||
RGB( 128, 0, 128 ), // magenta
|
||||
RGB( 128, 0, 255 ), // mauve
|
||||
RGB( 255, 0, 0 ), // bright red
|
||||
RGB( 255, 0, 128 ), // purple
|
||||
RGB( 255, 0, 255 ), // bright magenta
|
||||
RGB( 0, 128, 0 ), // green
|
||||
RGB( 0, 128, 128 ), // cyan
|
||||
RGB( 0, 128, 255 ), // sky blue
|
||||
RGB( 128, 128, 0 ), // yellow
|
||||
RGB( 128, 128, 128 ), // white
|
||||
RGB( 128, 128, 255 ), // pastel blue
|
||||
RGB( 255, 128, 0 ), // orange
|
||||
RGB( 255, 128, 128 ), // pink
|
||||
RGB( 255, 128, 255 ), // pastel magenta
|
||||
RGB( 0, 255, 0 ), // bright green
|
||||
RGB( 0, 255, 128 ), // sea green
|
||||
RGB( 0, 255, 255 ), // bright cyan
|
||||
RGB( 128, 255, 0 ), // lime
|
||||
RGB( 128, 255, 128 ), // pastel green
|
||||
RGB( 128, 255, 255 ), // pastel cyan
|
||||
RGB( 255, 255, 0 ), // bright yellow
|
||||
RGB( 255, 255, 128 ), // pastel yellow
|
||||
RGB( 255, 255, 255 ), // bright white
|
||||
|
||||
#if 1
|
||||
RGB( 16, 16, 16 ), // black
|
||||
RGB( 0, 28, 28 ), // dark cyan
|
||||
RGB( 112, 164, 178 ) * 1.3, // cyan
|
||||
#endif
|
||||
};
|
||||
|
||||
#elif 1
|
||||
// Tweaked LOSPEC CPC BOY PALETTE which is less saturated by Arne Niklas Jansson
|
||||
// https://lospec.com/palette-list/cpc-boy
|
||||
|
||||
const float3 palette[NUM_COLORS] = // 32
|
||||
{
|
||||
RGB( 0, 0, 0 ),
|
||||
RGB( 27, 27, 101 ),
|
||||
RGB( 53, 53, 201 ),
|
||||
RGB( 102, 30, 37 ),
|
||||
RGB( 85, 51, 97 ),
|
||||
RGB( 127, 53, 201 ),
|
||||
RGB( 188, 53, 53 ),
|
||||
RGB( 192, 70, 110 ),
|
||||
RGB( 223, 109, 155 ),
|
||||
RGB( 27, 101, 27 ),
|
||||
RGB( 27, 110, 131 ),
|
||||
RGB( 30, 121, 229 ),
|
||||
RGB( 121, 95, 27 ),
|
||||
RGB( 128, 128, 128 ),
|
||||
RGB( 145, 148, 223 ),
|
||||
RGB( 201, 127, 53 ),
|
||||
RGB( 227, 155, 141 ),
|
||||
RGB( 248, 120, 248 ),
|
||||
RGB( 53, 175, 53 ),
|
||||
RGB( 53, 183, 143 ),
|
||||
RGB( 53, 193, 215 ),
|
||||
RGB( 127, 201, 53 ),
|
||||
RGB( 173, 200, 170 ),
|
||||
RGB( 141, 225, 199 ),
|
||||
RGB( 225, 198, 67 ),
|
||||
RGB( 228, 221, 154 ),
|
||||
RGB( 255, 255, 255 ),
|
||||
RGB( 238, 234, 224 ),
|
||||
RGB( 172, 181, 107 ),
|
||||
RGB( 118, 132, 72 ),
|
||||
RGB( 63, 80, 63 ),
|
||||
RGB( 36, 49, 55 ),
|
||||
};
|
||||
|
||||
#elif 0
|
||||
|
||||
// NES 1
|
||||
// https://lospec.com/palette-list/nintendo-entertainment-system
|
||||
|
||||
const float3 palette[NUM_COLORS] = // 55
|
||||
{
|
||||
RGB( 0, 0, 0 ),
|
||||
RGB( 252, 252, 252 ),
|
||||
RGB( 248, 248, 248 ),
|
||||
RGB( 188, 188, 188 ),
|
||||
RGB( 124, 124, 124 ),
|
||||
RGB( 164, 228, 252 ),
|
||||
RGB( 60, 188, 252 ),
|
||||
RGB( 0, 120, 248 ),
|
||||
RGB( 0, 0, 252 ),
|
||||
RGB( 184, 184, 248 ),
|
||||
RGB( 104, 136, 252 ),
|
||||
RGB( 0, 88, 248 ),
|
||||
RGB( 0, 0, 188 ),
|
||||
RGB( 216, 184, 248 ),
|
||||
RGB( 152, 120, 248 ),
|
||||
RGB( 104, 68, 252 ),
|
||||
RGB( 68, 40, 188 ),
|
||||
RGB( 248, 184, 248 ),
|
||||
RGB( 248, 120, 248 ),
|
||||
RGB( 216, 0, 204 ),
|
||||
RGB( 148, 0, 132 ),
|
||||
RGB( 248, 164, 192 ),
|
||||
RGB( 248, 88, 152 ),
|
||||
RGB( 228, 0, 88 ),
|
||||
RGB( 168, 0, 32 ),
|
||||
RGB( 240, 208, 176 ),
|
||||
RGB( 248, 120, 88 ),
|
||||
RGB( 248, 56, 0 ),
|
||||
RGB( 168, 16, 0 ),
|
||||
RGB( 252, 224, 168 ),
|
||||
RGB( 252, 160, 68 ),
|
||||
RGB( 228, 92, 16 ),
|
||||
RGB( 136, 20, 0 ),
|
||||
RGB( 248, 216, 120 ),
|
||||
RGB( 248, 184, 0 ),
|
||||
RGB( 172, 124, 0 ),
|
||||
RGB( 80, 48, 0 ),
|
||||
RGB( 216, 248, 120 ),
|
||||
RGB( 184, 248, 24 ),
|
||||
RGB( 0, 184, 0 ),
|
||||
RGB( 0, 120, 0 ),
|
||||
RGB( 184, 248, 184 ),
|
||||
RGB( 88, 216, 84 ),
|
||||
RGB( 0, 168, 0 ),
|
||||
RGB( 0, 104, 0 ),
|
||||
RGB( 184, 248, 216 ),
|
||||
RGB( 88, 248, 152 ),
|
||||
RGB( 0, 168, 68 ),
|
||||
RGB( 0, 88, 0 ),
|
||||
RGB( 0, 252, 252 ),
|
||||
RGB( 0, 232, 216 ),
|
||||
RGB( 0, 136, 136 ),
|
||||
RGB( 0, 64, 88 ),
|
||||
RGB( 248, 216, 248 ),
|
||||
RGB( 120, 120, 120 ),
|
||||
};
|
||||
|
||||
#elif 0
|
||||
|
||||
const float3 palette[NUM_COLORS] = // 32
|
||||
{
|
||||
RGB( 0, 0, 0 ),
|
||||
RGB( 192, 64, 80 ),
|
||||
RGB( 240, 240, 240 ),
|
||||
RGB( 192, 192, 176 ),
|
||||
RGB( 128, 144, 144 ),
|
||||
RGB( 96, 96, 112 ),
|
||||
RGB( 96, 64, 64 ),
|
||||
RGB( 64, 48, 32 ),
|
||||
RGB( 112, 80, 48 ),
|
||||
RGB( 176, 112, 64 ),
|
||||
RGB( 224, 160, 80 ),
|
||||
RGB( 224, 192, 128 ),
|
||||
RGB( 240, 224, 96 ),
|
||||
RGB( 224, 128, 48 ),
|
||||
RGB( 208, 80, 32 ),
|
||||
RGB( 144, 48, 32 ),
|
||||
RGB( 96, 48, 112 ),
|
||||
RGB( 176, 96, 160 ),
|
||||
RGB( 224, 128, 192 ),
|
||||
RGB( 192, 160, 208 ),
|
||||
RGB( 112, 112, 192 ),
|
||||
RGB( 48, 64, 144 ),
|
||||
RGB( 32, 32, 64 ),
|
||||
RGB( 32, 96, 208 ),
|
||||
RGB( 64, 160, 224 ),
|
||||
RGB( 128, 208, 224 ),
|
||||
RGB( 160, 240, 144 ),
|
||||
RGB( 48, 160, 96 ),
|
||||
RGB( 48, 64, 48 ),
|
||||
RGB( 48, 112, 32 ),
|
||||
RGB( 112, 160, 48 ),
|
||||
RGB( 160, 208, 80 ),
|
||||
};
|
||||
|
||||
#elif 0
|
||||
|
||||
// Gameboy
|
||||
const float3 palette[NUM_COLORS] = // 4
|
||||
{
|
||||
RGB( 27, 42, 9 ),
|
||||
RGB( 14, 69, 11 ),
|
||||
RGB( 73, 107, 34 ),
|
||||
RGB( 154, 158, 63 ),
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
// https://lospec.com/palette-list/existential-demo
|
||||
const float3 palette[NUM_COLORS] = // 8
|
||||
{
|
||||
RGB( 248, 243, 253 ),
|
||||
RGB( 250, 198, 180 ),
|
||||
RGB( 154, 218, 231 ),
|
||||
RGB( 151, 203, 29 ),
|
||||
RGB( 93, 162, 202 ),
|
||||
RGB( 218, 41, 142 ),
|
||||
RGB( 11, 134, 51 ),
|
||||
RGB( 46, 43, 18 ),
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
float2 uv = ( fragment.texcoord0 );
|
||||
float2 uvPixelated = floor( fragment.position.xy / RESOLUTION_DIVISOR ) * RESOLUTION_DIVISOR;
|
||||
|
||||
float3 quantizationPeriod = _float3( 1.0 / NUM_COLORS );
|
||||
float3 quantDeviation = Deviation( palette );
|
||||
|
||||
// get pixellated base color
|
||||
float3 color = t_BaseColor.Sample( samp0, uvPixelated * rpWindowCoord.xy ).rgb;
|
||||
|
||||
float2 uvDither = uvPixelated;
|
||||
//if( rpJitterTexScale.x > 1.0 )
|
||||
{
|
||||
uvDither = fragment.position.xy / ( RESOLUTION_DIVISOR / rpJitterTexScale.x );
|
||||
}
|
||||
float dither = DitherArray8x8( uvDither ) - 0.5;
|
||||
|
||||
#if 0
|
||||
if( uv.y < 0.0625 )
|
||||
{
|
||||
color = HSVToRGB( float3( uv.x, 1.0, uv.y * 16.0 ) );
|
||||
|
||||
result.color = float4( color, 1.0 );
|
||||
return;
|
||||
}
|
||||
else if( uv.y < 0.125 )
|
||||
{
|
||||
// quantized
|
||||
color = HSVToRGB( float3( uv.x, 1.0, ( uv.y - 0.0625 ) * 16.0 ) );
|
||||
color = LinearSearch( color, palette );
|
||||
|
||||
result.color = float4( color, 1.0 );
|
||||
return;
|
||||
}
|
||||
else if( uv.y < 0.1875 )
|
||||
{
|
||||
// dithered quantized
|
||||
color = HSVToRGB( float3( uv.x, 1.0, ( uv.y - 0.125 ) * 16.0 ) );
|
||||
|
||||
color.rgb += float3( dither, dither, dither ) * quantDeviation * rpJitterTexScale.y;
|
||||
color = LinearSearch( color, palette );
|
||||
|
||||
result.color = float4( color, 1.0 );
|
||||
return;
|
||||
}
|
||||
else if( uv.y < 0.25 )
|
||||
{
|
||||
color = _float3( uv.x );
|
||||
color = floor( color * NUM_COLORS ) * ( 1.0 / ( NUM_COLORS - 1.0 ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
//color.rgb += float3( dither, dither, dither ) * quantizationPeriod;
|
||||
color.rgb += float3( dither, dither, dither ) * quantDeviation * rpJitterTexScale.y;
|
||||
|
||||
// find closest color match from CPC color palette
|
||||
color = LinearSearch( color.rgb, palette );
|
||||
|
||||
result.color = float4( color, 1.0 );
|
||||
}
|
55
neo/shaders/builtin/post/retro_cpc.vs.hlsl
Normal file
55
neo/shaders/builtin/post/retro_cpc.vs.hlsl
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "global_inc.hlsl"
|
||||
|
||||
|
||||
// *INDENT-OFF*
|
||||
struct VS_IN
|
||||
{
|
||||
float4 position : POSITION;
|
||||
float2 texcoord : TEXCOORD0;
|
||||
float4 normal : NORMAL;
|
||||
float4 tangent : TANGENT;
|
||||
float4 color : COLOR0;
|
||||
float4 color2 : COLOR1;
|
||||
};
|
||||
|
||||
struct VS_OUT {
|
||||
float4 position : SV_Position;
|
||||
float2 texcoord0 : TEXCOORD0_centroid;
|
||||
};
|
||||
// *INDENT-ON*
|
||||
|
||||
void main( VS_IN vertex, out VS_OUT result )
|
||||
{
|
||||
result.position = vertex.position;
|
||||
result.position.y = -result.position.y;
|
||||
|
||||
result.texcoord0 = vertex.texcoord;
|
||||
}
|
148
neo/shaders/builtin/post/retro_genesis.ps.hlsl
Normal file
148
neo/shaders/builtin/post/retro_genesis.ps.hlsl
Normal file
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
Copyright (C) 2023 Robert Beckebans
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "global_inc.hlsl"
|
||||
|
||||
|
||||
// *INDENT-OFF*
|
||||
Texture2D t_BaseColor : register( t0 VK_DESCRIPTOR_SET( 0 ) );
|
||||
Texture2D t_BlueNoise : register( t1 VK_DESCRIPTOR_SET( 0 ) );
|
||||
|
||||
SamplerState samp0 : register(s0 VK_DESCRIPTOR_SET( 1 ) );
|
||||
SamplerState samp1 : register(s1 VK_DESCRIPTOR_SET( 1 ) ); // blue noise 256
|
||||
|
||||
struct PS_IN
|
||||
{
|
||||
float4 position : SV_Position;
|
||||
float2 texcoord0 : TEXCOORD0_centroid;
|
||||
};
|
||||
|
||||
struct PS_OUT
|
||||
{
|
||||
float4 color : SV_Target0;
|
||||
};
|
||||
// *INDENT-ON*
|
||||
|
||||
|
||||
#define RESOLUTION_DIVISOR 4.0
|
||||
#define Dithering_QuantizationSteps 8.0 // 8.0 = 2 ^ 3 quantization bits
|
||||
|
||||
float3 Quantize( float3 color, float3 period )
|
||||
{
|
||||
return floor( color * Dithering_QuantizationSteps ) * ( 1.0 / ( Dithering_QuantizationSteps - 1.0 ) );
|
||||
|
||||
//return floor( ( color + period / 2.0 ) / period ) * period;
|
||||
}
|
||||
|
||||
|
||||
float3 BlueNoise3( float2 n, float x )
|
||||
{
|
||||
float2 uv = n.xy * rpJitterTexOffset.xy;
|
||||
|
||||
float3 noise = t_BlueNoise.Sample( samp1, uv ).rgb;
|
||||
|
||||
noise = frac( noise + c_goldenRatioConjugate * rpJitterTexOffset.w * x );
|
||||
|
||||
noise.x = RemapNoiseTriErp( noise.x );
|
||||
noise.y = RemapNoiseTriErp( noise.y );
|
||||
noise.z = RemapNoiseTriErp( noise.z );
|
||||
|
||||
noise = noise * 2.0 - 1.0;
|
||||
|
||||
return noise;
|
||||
}
|
||||
|
||||
#define RGB(r, g, b) float3(float(r)/255.0, float(g)/255.0, float(b)/255.0)
|
||||
|
||||
void main( PS_IN fragment, out PS_OUT result )
|
||||
{
|
||||
float2 uv = ( fragment.texcoord0 );
|
||||
float2 uvPixelated = floor( fragment.position.xy / RESOLUTION_DIVISOR ) * RESOLUTION_DIVISOR;
|
||||
|
||||
// the Sega Mega Drive has a 9 bit HW palette making a total of 512 available colors
|
||||
// that is 3 bit per RGB channel
|
||||
// 2^3 = 8
|
||||
// 8 * 8 * 8 = 512 colors
|
||||
// although only 61 colors were available on the screen at the same time but we ignore this for now
|
||||
|
||||
const int quantizationSteps = Dithering_QuantizationSteps;
|
||||
float3 quantizationPeriod = _float3( 1.0 / ( quantizationSteps - 1 ) );
|
||||
|
||||
// get pixellated base color
|
||||
float3 color = t_BaseColor.Sample( samp0, uvPixelated * rpWindowCoord.xy ).rgb;
|
||||
|
||||
float2 uvDither = uvPixelated;
|
||||
//if( rpJitterTexScale.x > 1.0 )
|
||||
{
|
||||
uvDither = fragment.position.xy / ( RESOLUTION_DIVISOR / rpJitterTexScale.x );
|
||||
}
|
||||
float dither = DitherArray8x8( uvDither ) - 0.5;
|
||||
|
||||
#if 0
|
||||
if( uv.y < 0.0625 )
|
||||
{
|
||||
color = HSVToRGB( float3( uv.x, 1.0, uv.y * 16.0 ) );
|
||||
|
||||
result.color = float4( color, 1.0 );
|
||||
return;
|
||||
}
|
||||
else if( uv.y < 0.125 )
|
||||
{
|
||||
// quantized
|
||||
color = HSVToRGB( float3( uv.x, 1.0, ( uv.y - 0.0625 ) * 16.0 ) );
|
||||
color = Quantize( color, quantizationPeriod );
|
||||
|
||||
result.color = float4( color, 1.0 );
|
||||
return;
|
||||
}
|
||||
else if( uv.y < 0.1875 )
|
||||
{
|
||||
// dithered quantized
|
||||
color = HSVToRGB( float3( uv.x, 1.0, ( uv.y - 0.125 ) * 16.0 ) );
|
||||
|
||||
color.rgb += float3( dither, dither, dither ) * quantizationPeriod;
|
||||
color = Quantize( color, quantizationPeriod );
|
||||
|
||||
result.color = float4( color, 1.0 );
|
||||
return;
|
||||
}
|
||||
else if( uv.y < 0.25 )
|
||||
{
|
||||
color = _float3( uv.x );
|
||||
color = Quantize( color, quantizationPeriod );
|
||||
}
|
||||
#endif
|
||||
|
||||
color.rgb += float3( dither, dither, dither ) * quantizationPeriod;// * rpJitterTexScale.y;
|
||||
|
||||
// find closest color match from Sega Mega Drive color palette
|
||||
color = Quantize( color, quantizationPeriod );
|
||||
|
||||
result.color = float4( color, 1.0 );
|
||||
}
|
55
neo/shaders/builtin/post/retro_genesis.vs.hlsl
Normal file
55
neo/shaders/builtin/post/retro_genesis.vs.hlsl
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "global_inc.hlsl"
|
||||
|
||||
|
||||
// *INDENT-OFF*
|
||||
struct VS_IN
|
||||
{
|
||||
float4 position : POSITION;
|
||||
float2 texcoord : TEXCOORD0;
|
||||
float4 normal : NORMAL;
|
||||
float4 tangent : TANGENT;
|
||||
float4 color : COLOR0;
|
||||
float4 color2 : COLOR1;
|
||||
};
|
||||
|
||||
struct VS_OUT {
|
||||
float4 position : SV_Position;
|
||||
float2 texcoord0 : TEXCOORD0_centroid;
|
||||
};
|
||||
// *INDENT-ON*
|
||||
|
||||
void main( VS_IN vertex, out VS_OUT result )
|
||||
{
|
||||
result.position = vertex.position;
|
||||
result.position.y = -result.position.y;
|
||||
|
||||
result.texcoord0 = vertex.texcoord;
|
||||
}
|
129
neo/shaders/builtin/post/retro_ps1.ps.hlsl
Normal file
129
neo/shaders/builtin/post/retro_ps1.ps.hlsl
Normal file
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
Copyright (C) 2023 Robert Beckebans
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "global_inc.hlsl"
|
||||
|
||||
|
||||
// *INDENT-OFF*
|
||||
Texture2D t_BaseColor : register( t0 VK_DESCRIPTOR_SET( 0 ) );
|
||||
Texture2D t_BlueNoise : register( t1 VK_DESCRIPTOR_SET( 0 ) );
|
||||
|
||||
SamplerState samp0 : register(s0 VK_DESCRIPTOR_SET( 1 ) );
|
||||
SamplerState samp1 : register(s1 VK_DESCRIPTOR_SET( 1 ) ); // blue noise 256
|
||||
|
||||
struct PS_IN
|
||||
{
|
||||
float4 position : SV_Position;
|
||||
float2 texcoord0 : TEXCOORD0_centroid;
|
||||
};
|
||||
|
||||
struct PS_OUT
|
||||
{
|
||||
float4 color : SV_Target0;
|
||||
};
|
||||
// *INDENT-ON*
|
||||
|
||||
|
||||
#define RESOLUTION_DIVISOR 4.0
|
||||
#define Dithering_QuantizationSteps 32.0 // 8.0 = 2 ^ 3 quantization bits
|
||||
|
||||
float3 Quantize( float3 color, float3 period )
|
||||
{
|
||||
return floor( color * Dithering_QuantizationSteps ) * ( 1.0 / ( Dithering_QuantizationSteps - 1.0 ) );
|
||||
|
||||
//return floor( ( color + period / 2.0 ) / period ) * period;
|
||||
}
|
||||
|
||||
|
||||
void main( PS_IN fragment, out PS_OUT result )
|
||||
{
|
||||
float2 uv = ( fragment.texcoord0 );
|
||||
float2 uvPixelated = floor( fragment.position.xy / RESOLUTION_DIVISOR ) * RESOLUTION_DIVISOR;
|
||||
|
||||
// most Sony Playstation 1 titles used 5 bit per RGB channel
|
||||
// 2^5 = 32
|
||||
// 32 * 32 * 32 = 32768 colors
|
||||
|
||||
const int quantizationSteps = Dithering_QuantizationSteps;
|
||||
float3 quantizationPeriod = _float3( 1.0 / ( quantizationSteps - 1 ) );
|
||||
|
||||
// get pixellated base color
|
||||
float3 color = t_BaseColor.Sample( samp0, uvPixelated * rpWindowCoord.xy ).rgb;
|
||||
|
||||
// add Bayer 8x8 dithering
|
||||
float2 uvDither = fragment.position.xy / RESOLUTION_DIVISOR;
|
||||
|
||||
float dither = DitherArray8x8( uvDither ) - 0.5;
|
||||
|
||||
#if 0
|
||||
if( uv.y < 0.0625 )
|
||||
{
|
||||
color = HSVToRGB( float3( uv.x, 1.0, uv.y * 16.0 ) );
|
||||
|
||||
result.color = float4( color, 1.0 );
|
||||
return;
|
||||
}
|
||||
else if( uv.y < 0.125 )
|
||||
{
|
||||
// quantized
|
||||
color = HSVToRGB( float3( uv.x, 1.0, ( uv.y - 0.0625 ) * 16.0 ) );
|
||||
color = Quantize( color, quantizationPeriod );
|
||||
|
||||
result.color = float4( color, 1.0 );
|
||||
return;
|
||||
}
|
||||
else if( uv.y < 0.1875 )
|
||||
{
|
||||
// dithered quantized
|
||||
color = HSVToRGB( float3( uv.x, 1.0, ( uv.y - 0.125 ) * 16.0 ) );
|
||||
|
||||
color.rgb += float3( dither, dither, dither ) * quantizationPeriod;
|
||||
color = Quantize( color, quantizationPeriod );
|
||||
|
||||
result.color = float4( color, 1.0 );
|
||||
return;
|
||||
}
|
||||
else if( uv.y < 0.25 )
|
||||
{
|
||||
color = _float3( uv.x );
|
||||
color = Quantize( color, quantizationPeriod );
|
||||
}
|
||||
#endif
|
||||
|
||||
color.rgb += float3( dither, dither, dither ) * quantizationPeriod;
|
||||
|
||||
// PSX color quantization with 15-bit
|
||||
color = Quantize( color, quantizationPeriod );
|
||||
|
||||
|
||||
|
||||
//color = t_BaseColor.Sample( samp0, uv ).rgb;
|
||||
|
||||
result.color = float4( color, 1.0 );
|
||||
}
|
55
neo/shaders/builtin/post/retro_ps1.vs.hlsl
Normal file
55
neo/shaders/builtin/post/retro_ps1.vs.hlsl
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "global_inc.hlsl"
|
||||
|
||||
|
||||
// *INDENT-OFF*
|
||||
struct VS_IN
|
||||
{
|
||||
float4 position : POSITION;
|
||||
float2 texcoord : TEXCOORD0;
|
||||
float4 normal : NORMAL;
|
||||
float4 tangent : TANGENT;
|
||||
float4 color : COLOR0;
|
||||
float4 color2 : COLOR1;
|
||||
};
|
||||
|
||||
struct VS_OUT {
|
||||
float4 position : SV_Position;
|
||||
float2 texcoord0 : TEXCOORD0_centroid;
|
||||
};
|
||||
// *INDENT-ON*
|
||||
|
||||
void main( VS_IN vertex, out VS_OUT result )
|
||||
{
|
||||
result.position = vertex.position;
|
||||
result.position.y = -result.position.y;
|
||||
|
||||
result.texcoord0 = vertex.texcoord;
|
||||
}
|
|
@ -244,6 +244,43 @@ float4 LinearRGBToSRGB( float4 c )
|
|||
#endif
|
||||
}
|
||||
|
||||
float3 HSVToRGB( float3 HSV )
|
||||
{
|
||||
float3 RGB = HSV.z;
|
||||
|
||||
float var_h = HSV.x * 6;
|
||||
float var_i = floor( var_h ); // Or ... var_i = floor( var_h )
|
||||
float var_1 = HSV.z * ( 1.0 - HSV.y );
|
||||
float var_2 = HSV.z * ( 1.0 - HSV.y * ( var_h - var_i ) );
|
||||
float var_3 = HSV.z * ( 1.0 - HSV.y * ( 1 - ( var_h - var_i ) ) );
|
||||
if( var_i == 0 )
|
||||
{
|
||||
RGB = float3( HSV.z, var_3, var_1 );
|
||||
}
|
||||
else if( var_i == 1 )
|
||||
{
|
||||
RGB = float3( var_2, HSV.z, var_1 );
|
||||
}
|
||||
else if( var_i == 2 )
|
||||
{
|
||||
RGB = float3( var_1, HSV.z, var_3 );
|
||||
}
|
||||
else if( var_i == 3 )
|
||||
{
|
||||
RGB = float3( var_1, var_2, HSV.z );
|
||||
}
|
||||
else if( var_i == 4 )
|
||||
{
|
||||
RGB = float3( var_3, var_1, HSV.z );
|
||||
}
|
||||
else
|
||||
{
|
||||
RGB = float3( HSV.z, var_1, var_2 );
|
||||
}
|
||||
|
||||
return ( RGB );
|
||||
}
|
||||
|
||||
/** Efficient GPU implementation of the octahedral unit vector encoding from
|
||||
|
||||
Cigolle, Donow, Evangelakos, Mara, McGuire, Meyer,
|
||||
|
@ -366,6 +403,7 @@ float rand( float2 co )
|
|||
#define _float3( x ) float3( x, x, x )
|
||||
#define _float4( x ) float4( x, x, x, x )
|
||||
#define _int2( x ) int2( x, x )
|
||||
#define _int3( x ) int3( x, x, x )
|
||||
#define vec2 float2
|
||||
#define vec3 float3
|
||||
#define vec4 float4
|
||||
|
@ -488,14 +526,44 @@ float InterleavedGradientNoiseAnim( float2 uv, float frameIndex )
|
|||
return rnd;
|
||||
}
|
||||
|
||||
// RB: very efficient white noise without sine https://www.shadertoy.com/view/4djSRW
|
||||
#define HASHSCALE3 float3(443.897, 441.423, 437.195)
|
||||
|
||||
float3 Hash33( float3 p3 )
|
||||
float R2Noise( float2 uv )
|
||||
{
|
||||
p3 = frac( p3 * HASHSCALE3 );
|
||||
p3 += dot( p3, p3.yxz + 19.19 );
|
||||
return frac( ( p3.xxy + p3.yxx ) * p3.zyx );
|
||||
const float a1 = 0.75487766624669276;
|
||||
const float a2 = 0.569840290998;
|
||||
|
||||
return frac( a1 * float( uv.x ) + a2 * float( uv.y ) );
|
||||
}
|
||||
|
||||
// array/table version from http://www.anisopteragames.com/how-to-fix-color-banding-with-dithering/
|
||||
static const uint ArrayDitherArray8x8[] =
|
||||
{
|
||||
0, 32, 8, 40, 2, 34, 10, 42, /* 8x8 Bayer ordered dithering */
|
||||
48, 16, 56, 24, 50, 18, 58, 26, /* pattern. Each input pixel */
|
||||
12, 44, 4, 36, 14, 46, 6, 38, /* is scaled to the 0..63 range */
|
||||
60, 28, 52, 20, 62, 30, 54, 22, /* before looking in this table */
|
||||
3, 35, 11, 43, 1, 33, 9, 41, /* to determine the action. */
|
||||
51, 19, 59, 27, 49, 17, 57, 25,
|
||||
15, 47, 7, 39, 13, 45, 5, 37,
|
||||
63, 31, 55, 23, 61, 29, 53, 21
|
||||
};
|
||||
|
||||
float DitherArray8x8( float2 pos )
|
||||
{
|
||||
uint stippleOffset = ( ( uint )pos.y % 8 ) * 8 + ( ( uint )pos.x % 8 );
|
||||
uint byte = ArrayDitherArray8x8[stippleOffset];
|
||||
float stippleThreshold = byte / 64.0f;
|
||||
return stippleThreshold;
|
||||
}
|
||||
|
||||
float DitherArray8x8Anim( float2 pos, int frameIndexMod4 )
|
||||
{
|
||||
pos += int2( frameIndexMod4 % 2, frameIndexMod4 / 2 ) * uint2( 5, 5 );
|
||||
|
||||
uint stippleOffset = ( ( uint )pos.y % 8 ) * 8 + ( ( uint )pos.x % 8 );
|
||||
uint byte = ArrayDitherArray8x8[stippleOffset];
|
||||
float stippleThreshold = byte / 64.0f;
|
||||
return stippleThreshold;
|
||||
}
|
||||
|
||||
|
||||
#define SMAA_RT_METRICS float4(1.0 / 1280.0, 1.0 / 720.0, 1280.0, 720.0)
|
|
@ -52,6 +52,18 @@ builtin/lighting/interactionSM.ps.hlsl -T ps -D USE_GPU_SKINNING={0,1} -D LIGHT_
|
|||
|
||||
builtin/post/postprocess.vs.hlsl -T vs
|
||||
builtin/post/postprocess.ps.hlsl -T ps
|
||||
builtin/post/retro_c64.vs.hlsl -T vs
|
||||
builtin/post/retro_c64.ps.hlsl -T ps
|
||||
builtin/post/retro_cpc.vs.hlsl -T vs
|
||||
builtin/post/retro_cpc.ps.hlsl -T ps
|
||||
builtin/post/retro_genesis.vs.hlsl -T vs
|
||||
builtin/post/retro_genesis.ps.hlsl -T ps
|
||||
builtin/post/retro_ps1.vs.hlsl -T vs
|
||||
builtin/post/retro_ps1.ps.hlsl -T ps
|
||||
builtin/post/crt_mattias.vs.hlsl -T vs
|
||||
builtin/post/crt_mattias.ps.hlsl -T ps
|
||||
builtin/post/crt_newpixie.vs.hlsl -T vs
|
||||
builtin/post/crt_newpixie.ps.hlsl -T ps
|
||||
builtin/post/screen.vs.hlsl -T vs
|
||||
builtin/post/screen.ps.hlsl -T ps
|
||||
builtin/post/tonemap.vs.hlsl -T vs -D BRIGHTPASS={0,1} -D HDR_DEBUG={0,1}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include "renderer/RenderCommon.h"
|
||||
#include "renderer/RenderSystem.h"
|
||||
#include "framework/Common_local.h"
|
||||
#include <sys/DeviceManager.h>
|
||||
|
||||
#include <Windows.h>
|
||||
|
@ -57,7 +58,7 @@ class DeviceManager_DX12 : public DeviceManager
|
|||
RefCountPtr<IDXGISwapChain3> m_SwapChain;
|
||||
DXGI_SWAP_CHAIN_DESC1 m_SwapChainDesc{};
|
||||
DXGI_SWAP_CHAIN_FULLSCREEN_DESC m_FullScreenDesc{};
|
||||
RefCountPtr<IDXGIAdapter> m_DxgiAdapter;
|
||||
RefCountPtr<IDXGIAdapter3> m_DxgiAdapter;
|
||||
bool m_TearingSupported = false;
|
||||
|
||||
std::vector<RefCountPtr<ID3D12Resource>> m_SwapChainBuffers;
|
||||
|
@ -388,7 +389,7 @@ bool DeviceManager_DX12::CreateDeviceAndSwapChain()
|
|||
}
|
||||
}
|
||||
|
||||
m_DxgiAdapter = targetAdapter;
|
||||
targetAdapter->QueryInterface( IID_PPV_ARGS( &m_DxgiAdapter ) );
|
||||
|
||||
D3D12_COMMAND_QUEUE_DESC queueDesc;
|
||||
ZeroMemory( &queueDesc, sizeof( queueDesc ) );
|
||||
|
@ -566,6 +567,12 @@ void DeviceManager_DX12::ResizeSwapChain()
|
|||
void DeviceManager_DX12::BeginFrame()
|
||||
{
|
||||
OPTICK_CATEGORY( "DX12_BeginFrame", Optick::Category::Wait );
|
||||
|
||||
// SRS - get DXGI GPU memory usage for display in statistics overlay HUD
|
||||
DXGI_QUERY_VIDEO_MEMORY_INFO memoryInfoLocal = {}, memoryInfoNonLocal = {};
|
||||
m_DxgiAdapter->QueryVideoMemoryInfo( 0, DXGI_MEMORY_SEGMENT_GROUP_LOCAL, &memoryInfoLocal );
|
||||
m_DxgiAdapter->QueryVideoMemoryInfo( 0, DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL, &memoryInfoNonLocal );
|
||||
commonLocal.SetRendererGpuMemoryMB( int( ( memoryInfoLocal.CurrentUsage + memoryInfoNonLocal.CurrentUsage ) / 1024 / 1024 ) );
|
||||
}
|
||||
|
||||
nvrhi::ITexture* DeviceManager_DX12::GetCurrentBackBuffer()
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <unordered_set>
|
||||
|
||||
#include "renderer/RenderCommon.h"
|
||||
#include "framework/Common_local.h"
|
||||
#include <sys/DeviceManager.h>
|
||||
|
||||
#include <nvrhi/vulkan.h>
|
||||
|
@ -39,12 +40,22 @@
|
|||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
// SRS - optionally needed for MoltenVK runtime config visibility
|
||||
#if defined(__APPLE__) && defined( USE_MoltenVK )
|
||||
#include <MoltenVK/vk_mvk_moltenvk.h>
|
||||
|
||||
idCVar r_mvkSynchronousQueueSubmits( "r_mvkSynchronousQueueSubmits", "0", CVAR_BOOL | CVAR_INIT, "Use MoltenVK's synchronous queue submit option." );
|
||||
#if defined(__APPLE__)
|
||||
#if defined( USE_MoltenVK )
|
||||
#if 0
|
||||
#include <MoltenVK/mvk_vulkan.h>
|
||||
#include <MoltenVK/mvk_config.h> // SRS - will eventually move to these mvk include files for MoltenVK >= 1.2.7 / SDK >= 1.3.275.0
|
||||
#else
|
||||
#include <MoltenVK/vk_mvk_moltenvk.h> // SRS - now deprecated, but provides backwards compatibility for MoltenVK < 1.2.7 / SDK < 1.3.275.0
|
||||
#endif
|
||||
#endif
|
||||
#if defined( VK_EXT_layer_settings ) || defined( USE_MoltenVK )
|
||||
idCVar r_mvkSynchronousQueueSubmits( "r_mvkSynchronousQueueSubmits", "0", CVAR_BOOL | CVAR_INIT, "Use MoltenVK's synchronous queue submit option." );
|
||||
idCVar r_mvkUseMetalArgumentBuffers( "r_mvkUseMetalArgumentBuffers", "2", CVAR_INTEGER | CVAR_INIT, "Use MoltenVK's Metal argument buffers option (0=Off, 1=Always On, 2=On when VK_EXT_descriptor_indexing enabled)", 0, 2 );
|
||||
#endif
|
||||
#endif
|
||||
#include <nvrhi/validation.h>
|
||||
#include <libs/optick/optick.h>
|
||||
|
||||
#if defined( USE_AMD_ALLOCATOR )
|
||||
#define VMA_IMPLEMENTATION
|
||||
|
@ -204,20 +215,21 @@ private:
|
|||
{
|
||||
// instance
|
||||
{
|
||||
#if defined(__APPLE__) && defined( VK_KHR_portability_enumeration )
|
||||
#if defined(__APPLE__)
|
||||
#if defined( VK_KHR_portability_enumeration )
|
||||
// SRS - This is optional since it only became manadatory with Vulkan SDK 1.3.216.0 or later
|
||||
VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME,
|
||||
#endif
|
||||
#if defined( VK_EXT_layer_settings )
|
||||
// SRS - This is optional since implemented only for MoltenVK 1.2.7 / SDK 1.3.275.0 or later
|
||||
VK_EXT_LAYER_SETTINGS_EXTENSION_NAME,
|
||||
#endif
|
||||
#endif
|
||||
VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME,
|
||||
VK_EXT_DEBUG_UTILS_EXTENSION_NAME
|
||||
},
|
||||
// layers
|
||||
{
|
||||
#if defined(__APPLE__)
|
||||
// SRS - synchronization2 not supported natively on MoltenVK, use layer implementation instead
|
||||
"VK_LAYER_KHRONOS_synchronization2"
|
||||
#endif
|
||||
},
|
||||
{ },
|
||||
// device
|
||||
{
|
||||
VK_EXT_DEBUG_MARKER_EXTENSION_NAME,
|
||||
|
@ -228,7 +240,11 @@ private:
|
|||
#if USE_OPTICK
|
||||
VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME,
|
||||
#endif
|
||||
VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME
|
||||
#if defined( VK_KHR_format_feature_flags2 )
|
||||
VK_KHR_FORMAT_FEATURE_FLAGS_2_EXTENSION_NAME,
|
||||
#endif
|
||||
VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME,
|
||||
VK_EXT_MEMORY_BUDGET_EXTENSION_NAME
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -275,7 +291,7 @@ private:
|
|||
nvrhi::vulkan::DeviceHandle m_NvrhiDevice;
|
||||
nvrhi::DeviceHandle m_ValidationLayer;
|
||||
|
||||
nvrhi::CommandListHandle m_BarrierCommandList;
|
||||
//nvrhi::CommandListHandle m_BarrierCommandList; // SRS - no longer needed
|
||||
std::queue<vk::Semaphore> m_PresentSemaphoreQueue;
|
||||
vk::Semaphore m_PresentSemaphore;
|
||||
|
||||
|
@ -289,6 +305,19 @@ private:
|
|||
// SRS - flag indicating support for presentation timing via VK_GOOGLE_display_timing extension
|
||||
bool displayTimingEnabled = false;
|
||||
|
||||
// SRS - slot for Vulkan device API version at runtime (initialize to Vulkan build version)
|
||||
uint32_t m_DeviceApiVersion = VK_HEADER_VERSION_COMPLETE;
|
||||
|
||||
// SRS - function pointer for initing Vulkan DynamicLoader, VMA, Optick, and MoltenVK functions
|
||||
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = nullptr;
|
||||
|
||||
#if defined(__APPLE__) && defined( USE_MoltenVK )
|
||||
#if MVK_VERSION >= MVK_MAKE_VERSION( 1, 2, 6 )
|
||||
// SRS - function pointer for retrieving MoltenVK advanced performance statistics
|
||||
PFN_vkGetPerformanceStatisticsMVK vkGetPerformanceStatisticsMVK = nullptr;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
private:
|
||||
static VKAPI_ATTR VkBool32 VKAPI_CALL vulkanDebugCallback(
|
||||
VkDebugReportFlagsEXT flags,
|
||||
|
@ -429,6 +458,7 @@ bool DeviceManager_VK::createInstance()
|
|||
|
||||
std::unordered_set<std::string> requiredLayers = enabledExtensions.layers;
|
||||
|
||||
auto instanceVersion = vk::enumerateInstanceVersion();
|
||||
for( const auto& layer : vk::enumerateInstanceLayerProperties() )
|
||||
{
|
||||
const std::string name = layer.layerName;
|
||||
|
@ -436,6 +466,13 @@ bool DeviceManager_VK::createInstance()
|
|||
{
|
||||
enabledExtensions.layers.insert( name );
|
||||
}
|
||||
#if defined(__APPLE__) && !defined( USE_MoltenVK )
|
||||
// SRS - Vulkan SDK < 1.3.268.1 does not have native VK_KHR_synchronization2 support on macOS, add Khronos layer to emulate
|
||||
else if( name == "VK_LAYER_KHRONOS_synchronization2" && instanceVersion < VK_MAKE_API_VERSION( 0, 1, 3, 268 ) )
|
||||
{
|
||||
enabledExtensions.layers.insert( name );
|
||||
}
|
||||
#endif
|
||||
|
||||
requiredLayers.erase( name );
|
||||
}
|
||||
|
@ -473,11 +510,68 @@ bool DeviceManager_VK::createInstance()
|
|||
.setPpEnabledExtensionNames( instanceExtVec.data() )
|
||||
.setPApplicationInfo( &applicationInfo );
|
||||
|
||||
#if defined(__APPLE__) && defined( VK_KHR_portability_enumeration )
|
||||
#if defined(__APPLE__)
|
||||
#if defined( VK_KHR_portability_enumeration )
|
||||
if( enabledExtensions.instance.find( VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME ) != enabledExtensions.instance.end() )
|
||||
{
|
||||
info.setFlags( vk::InstanceCreateFlagBits( VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR ) );
|
||||
}
|
||||
#endif
|
||||
#if defined( VK_EXT_layer_settings )
|
||||
// SRS - set MoltenVK runtime configuration parameters on macOS via standardized VK_EXT_layer_settings extension
|
||||
std::vector<vk::LayerSettingEXT> layerSettings;
|
||||
vk::LayerSettingsCreateInfoEXT layerSettingsCreateInfo;
|
||||
|
||||
const vk::Bool32 valueTrue = vk::True, valueFalse = vk::False;
|
||||
const int32_t useMetalArgumentBuffers = r_mvkUseMetalArgumentBuffers.GetInteger();
|
||||
const float timestampPeriodLowPassAlpha = 1.0;
|
||||
|
||||
if( enabledExtensions.instance.find( VK_EXT_LAYER_SETTINGS_EXTENSION_NAME ) != enabledExtensions.instance.end() )
|
||||
{
|
||||
// SRS - use MoltenVK layer for configuration via VK_EXT_layer_settings extension
|
||||
vk::LayerSettingEXT layerSetting = { "MoltenVK", "", vk::LayerSettingTypeEXT( 0 ), 1, nullptr };
|
||||
|
||||
// SRS - Set MoltenVK's synchronous queue submit option for vkQueueSubmit() & vkQueuePresentKHR()
|
||||
layerSetting.pSettingName = "MVK_CONFIG_SYNCHRONOUS_QUEUE_SUBMITS";
|
||||
layerSetting.type = vk::LayerSettingTypeEXT::eBool32;
|
||||
layerSetting.pValues = r_mvkSynchronousQueueSubmits.GetBool() ? &valueTrue : &valueFalse;
|
||||
layerSettings.push_back( layerSetting );
|
||||
|
||||
// SRS - Enable MoltenVK's image view swizzle feature in case we don't have native image view swizzle
|
||||
layerSetting.pSettingName = "MVK_CONFIG_FULL_IMAGE_VIEW_SWIZZLE";
|
||||
layerSetting.type = vk::LayerSettingTypeEXT::eBool32;
|
||||
layerSetting.pValues = &valueTrue;
|
||||
layerSettings.push_back( layerSetting );
|
||||
|
||||
// SRS - Turn MoltenVK's Metal argument buffer feature on for descriptor indexing only
|
||||
layerSetting.pSettingName = "MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS";
|
||||
layerSetting.type = vk::LayerSettingTypeEXT::eInt32;
|
||||
layerSetting.pValues = &useMetalArgumentBuffers;
|
||||
layerSettings.push_back( layerSetting );
|
||||
|
||||
// SRS - Disable MoltenVK's timestampPeriod filter for HUD / Optick profiler timing calibration
|
||||
layerSetting.pSettingName = "MVK_CONFIG_TIMESTAMP_PERIOD_LOWPASS_ALPHA";
|
||||
layerSetting.type = vk::LayerSettingTypeEXT::eFloat32;
|
||||
layerSetting.pValues = ×tampPeriodLowPassAlpha;
|
||||
layerSettings.push_back( layerSetting );
|
||||
|
||||
// SRS - Only enable MoltenVK performance tracking if using API and available based on version
|
||||
#if defined( USE_MoltenVK )
|
||||
#if MVK_VERSION >= MVK_MAKE_VERSION( 1, 2, 6 )
|
||||
// SRS - Enable MoltenVK's performance tracking for display of Metal encoding timer on macOS
|
||||
layerSetting.pSettingName = "MVK_CONFIG_PERFORMANCE_TRACKING";
|
||||
layerSetting.type = vk::LayerSettingTypeEXT::eBool32;
|
||||
layerSetting.pValues = &valueTrue;
|
||||
layerSettings.push_back( layerSetting );
|
||||
#endif
|
||||
#endif
|
||||
|
||||
layerSettingsCreateInfo.settingCount = uint32_t( layerSettings.size() );
|
||||
layerSettingsCreateInfo.pSettings = layerSettings.data();
|
||||
|
||||
info.setPNext( &layerSettingsCreateInfo );
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
const vk::Result res = vk::createInstance( &info, nullptr, &m_VulkanInstance );
|
||||
|
@ -823,10 +917,17 @@ bool DeviceManager_VK::createDevice()
|
|||
auto meshletFeatures = vk::PhysicalDeviceMeshShaderFeaturesNV()
|
||||
.setTaskShader( true )
|
||||
.setMeshShader( true );
|
||||
|
||||
// SRS - get/set shading rate features which are detected individually by nvrhi (not just at extension level)
|
||||
vk::PhysicalDeviceFeatures2 actualDeviceFeatures2;
|
||||
vk::PhysicalDeviceFragmentShadingRateFeaturesKHR fragmentShadingRateFeatures;
|
||||
actualDeviceFeatures2.pNext = &fragmentShadingRateFeatures;
|
||||
m_VulkanPhysicalDevice.getFeatures2( &actualDeviceFeatures2 );
|
||||
|
||||
auto vrsFeatures = vk::PhysicalDeviceFragmentShadingRateFeaturesKHR()
|
||||
.setPipelineFragmentShadingRate( true )
|
||||
.setPrimitiveFragmentShadingRate( true )
|
||||
.setAttachmentFragmentShadingRate( true );
|
||||
.setPipelineFragmentShadingRate( fragmentShadingRateFeatures.pipelineFragmentShadingRate )
|
||||
.setPrimitiveFragmentShadingRate( fragmentShadingRateFeatures.primitiveFragmentShadingRate )
|
||||
.setAttachmentFragmentShadingRate( fragmentShadingRateFeatures.attachmentFragmentShadingRate );
|
||||
|
||||
auto sync2Features = vk::PhysicalDeviceSynchronization2FeaturesKHR()
|
||||
.setSynchronization2( true );
|
||||
|
@ -854,7 +955,7 @@ bool DeviceManager_VK::createDevice()
|
|||
|
||||
auto deviceFeatures = vk::PhysicalDeviceFeatures()
|
||||
.setShaderImageGatherExtended( true )
|
||||
.setShaderStorageImageReadWithoutFormat( true )
|
||||
.setShaderStorageImageReadWithoutFormat( actualDeviceFeatures2.features.shaderStorageImageReadWithoutFormat )
|
||||
.setSamplerAnisotropy( true )
|
||||
.setTessellationShader( true )
|
||||
.setTextureCompressionBC( true )
|
||||
|
@ -927,15 +1028,16 @@ bool DeviceManager_VK::createDevice()
|
|||
enablePModeImmediate = find( surfacePModes.begin(), surfacePModes.end(), vk::PresentModeKHR::eImmediate ) != surfacePModes.end();
|
||||
enablePModeFifoRelaxed = find( surfacePModes.begin(), surfacePModes.end(), vk::PresentModeKHR::eFifoRelaxed ) != surfacePModes.end();
|
||||
|
||||
// stash the renderer string
|
||||
// stash the device renderer string and api version
|
||||
auto prop = m_VulkanPhysicalDevice.getProperties();
|
||||
m_RendererString = std::string( prop.deviceName.data() );
|
||||
m_DeviceApiVersion = prop.apiVersion;
|
||||
|
||||
#if defined( USE_AMD_ALLOCATOR )
|
||||
// SRS - initialize the vma allocator
|
||||
VmaVulkanFunctions vulkanFunctions = {};
|
||||
vulkanFunctions.vkGetInstanceProcAddr = &vkGetInstanceProcAddr;
|
||||
vulkanFunctions.vkGetDeviceProcAddr = &vkGetDeviceProcAddr;
|
||||
vulkanFunctions.vkGetInstanceProcAddr = vkGetInstanceProcAddr;
|
||||
vulkanFunctions.vkGetDeviceProcAddr = ( PFN_vkGetDeviceProcAddr )vkGetInstanceProcAddr( m_VulkanInstance, "vkGetDeviceProcAddr" );
|
||||
|
||||
VmaAllocatorCreateInfo allocatorCreateInfo = {};
|
||||
allocatorCreateInfo.vulkanApiVersion = VK_API_VERSION_1_2;
|
||||
|
@ -1105,7 +1207,6 @@ bool DeviceManager_VK::CreateDeviceAndSwapChain()
|
|||
{
|
||||
enabledExtensions.instance.insert( VK_EXT_DEBUG_REPORT_EXTENSION_NAME );
|
||||
#if defined(__APPLE__) && defined( USE_MoltenVK )
|
||||
enabledExtensions.layers.insert( "MoltenVK" );
|
||||
}
|
||||
|
||||
// SRS - when USE_MoltenVK defined, load libMoltenVK vs. the default libvulkan
|
||||
|
@ -1117,8 +1218,7 @@ bool DeviceManager_VK::CreateDeviceAndSwapChain()
|
|||
// SRS - make static so ~DynamicLoader() does not prematurely unload vulkan dynamic lib
|
||||
static const vk::DynamicLoader dl;
|
||||
#endif
|
||||
const PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = // NOLINT(misc-misplaced-const)
|
||||
dl.getProcAddress<PFN_vkGetInstanceProcAddr>( "vkGetInstanceProcAddr" );
|
||||
vkGetInstanceProcAddr = dl.getProcAddress<PFN_vkGetInstanceProcAddr>( "vkGetInstanceProcAddr" );
|
||||
VULKAN_HPP_DEFAULT_DISPATCHER.init( vkGetInstanceProcAddr );
|
||||
|
||||
#define CHECK(a) if (!(a)) { return false; }
|
||||
|
@ -1153,37 +1253,70 @@ bool DeviceManager_VK::CreateDeviceAndSwapChain()
|
|||
CHECK( pickPhysicalDevice() );
|
||||
CHECK( findQueueFamilies( m_VulkanPhysicalDevice, m_WindowSurface ) );
|
||||
|
||||
// SRS - when USE_MoltenVK defined, set MoltenVK runtime configuration parameters on macOS
|
||||
// SRS - when USE_MoltenVK defined, set MoltenVK runtime configuration parameters on macOS (deprecated version)
|
||||
#if defined(__APPLE__) && defined( USE_MoltenVK )
|
||||
vk::PhysicalDeviceFeatures2 deviceFeatures2;
|
||||
vk::PhysicalDevicePortabilitySubsetFeaturesKHR portabilityFeatures;
|
||||
deviceFeatures2.setPNext( &portabilityFeatures );
|
||||
m_VulkanPhysicalDevice.getFeatures2( &deviceFeatures2 );
|
||||
|
||||
MVKConfiguration pConfig;
|
||||
size_t pConfigSize = sizeof( pConfig );
|
||||
|
||||
vkGetMoltenVKConfigurationMVK( m_VulkanInstance, &pConfig, &pConfigSize );
|
||||
|
||||
// SRS - Set MoltenVK's synchronous queue submit option for vkQueueSubmit() & vkQueuePresentKHR()
|
||||
pConfig.synchronousQueueSubmits = r_mvkSynchronousQueueSubmits.GetBool() ? VK_TRUE : VK_FALSE;
|
||||
vkSetMoltenVKConfigurationMVK( m_VulkanInstance, &pConfig, &pConfigSize );
|
||||
|
||||
// SRS - If we don't have native image view swizzle, enable MoltenVK's image view swizzle feature
|
||||
if( portabilityFeatures.imageViewFormatSwizzle == VK_FALSE )
|
||||
#if defined( VK_EXT_layer_settings )
|
||||
// SRS - for backwards compatibility at runtime: execute only if we can't find the VK_EXT_layer_settings extension
|
||||
if( enabledExtensions.instance.find( VK_EXT_LAYER_SETTINGS_EXTENSION_NAME ) == enabledExtensions.instance.end() )
|
||||
#endif
|
||||
{
|
||||
idLib::Printf( "Enabling MoltenVK's image view swizzle...\n" );
|
||||
pConfig.fullImageViewSwizzle = VK_TRUE;
|
||||
vkSetMoltenVKConfigurationMVK( m_VulkanInstance, &pConfig, &pConfigSize );
|
||||
// SRS - vkSetMoltenVKConfigurationMVK() now deprecated, but retained for MoltenVK < 1.2.7 / SDK < 1.3.275.0
|
||||
const PFN_vkGetMoltenVKConfigurationMVK vkGetMoltenVKConfigurationMVK = // NOLINT(misc-misplaced-const)
|
||||
( PFN_vkGetMoltenVKConfigurationMVK )vkGetInstanceProcAddr( m_VulkanInstance, "vkGetMoltenVKConfigurationMVK" );
|
||||
const PFN_vkSetMoltenVKConfigurationMVK vkSetMoltenVKConfigurationMVK = // NOLINT(misc-misplaced-const)
|
||||
( PFN_vkSetMoltenVKConfigurationMVK )vkGetInstanceProcAddr( m_VulkanInstance, "vkSetMoltenVKConfigurationMVK" );
|
||||
|
||||
vk::PhysicalDeviceFeatures2 deviceFeatures2;
|
||||
vk::PhysicalDevicePortabilitySubsetFeaturesKHR portabilityFeatures;
|
||||
deviceFeatures2.setPNext( &portabilityFeatures );
|
||||
m_VulkanPhysicalDevice.getFeatures2( &deviceFeatures2 );
|
||||
|
||||
MVKConfiguration mvkConfig;
|
||||
size_t mvkConfigSize = sizeof( mvkConfig );
|
||||
|
||||
vkGetMoltenVKConfigurationMVK( m_VulkanInstance, &mvkConfig, &mvkConfigSize );
|
||||
|
||||
// SRS - Set MoltenVK's synchronous queue submit option for vkQueueSubmit() & vkQueuePresentKHR()
|
||||
if( mvkConfig.synchronousQueueSubmits == VK_TRUE && !r_mvkSynchronousQueueSubmits.GetBool() )
|
||||
{
|
||||
idLib::Printf( "Disabled MoltenVK's synchronous queue submits...\n" );
|
||||
mvkConfig.synchronousQueueSubmits = VK_FALSE;
|
||||
}
|
||||
|
||||
// SRS - If we don't have native image view swizzle, enable MoltenVK's image view swizzle feature
|
||||
if( portabilityFeatures.imageViewFormatSwizzle == VK_FALSE )
|
||||
{
|
||||
idLib::Printf( "Enabled MoltenVK's image view swizzle...\n" );
|
||||
mvkConfig.fullImageViewSwizzle = VK_TRUE;
|
||||
}
|
||||
|
||||
// SRS - Set MoltenVK's Metal argument buffer option for descriptor resource scaling
|
||||
// - Also needed for Vulkan SDK 1.3.268.1 to work around SPIRV-Cross issue for Metal conversion.
|
||||
// - See https://github.com/KhronosGroup/MoltenVK/issues/2016 and https://github.com/goki/vgpu/issues/9
|
||||
// - Issue solved in Vulkan SDK >= 1.3.275.0, but config uses VK_EXT_layer_settings instead of this code.
|
||||
if( mvkConfig.useMetalArgumentBuffers == MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS_NEVER && r_mvkUseMetalArgumentBuffers.GetInteger() )
|
||||
{
|
||||
idLib::Printf( "Enabled MoltenVK's Metal argument buffers...\n" );
|
||||
mvkConfig.useMetalArgumentBuffers = MVKUseMetalArgumentBuffers( r_mvkUseMetalArgumentBuffers.GetInteger() );
|
||||
}
|
||||
|
||||
#if MVK_VERSION >= MVK_MAKE_VERSION( 1, 2, 6 )
|
||||
if( mvkConfig.apiVersionToAdvertise >= VK_MAKE_API_VERSION( 0, 1, 2, 268 ) )
|
||||
{
|
||||
// SRS - Disable MoltenVK's timestampPeriod filter for HUD / Optick profiler timing calibration
|
||||
mvkConfig.timestampPeriodLowPassAlpha = 1.0;
|
||||
// SRS - Enable MoltenVK's performance tracking for display of Metal encoding timer on macOS
|
||||
mvkConfig.performanceTracking = VK_TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
vkSetMoltenVKConfigurationMVK( m_VulkanInstance, &mvkConfig, &mvkConfigSize );
|
||||
}
|
||||
|
||||
// SRS - Turn MoltenVK's Metal argument buffer feature on for descriptor indexing only
|
||||
if( pConfig.useMetalArgumentBuffers == MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS_NEVER )
|
||||
{
|
||||
idLib::Printf( "Enabling MoltenVK's Metal argument buffers for descriptor indexing...\n" );
|
||||
pConfig.useMetalArgumentBuffers = MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS_DESCRIPTOR_INDEXING;
|
||||
vkSetMoltenVKConfigurationMVK( m_VulkanInstance, &pConfig, &pConfigSize );
|
||||
}
|
||||
#if MVK_VERSION >= MVK_MAKE_VERSION( 1, 2, 6 )
|
||||
// SRS - Get function pointer for retrieving MoltenVK advanced performance statistics in DeviceManager_VK::BeginFrame()
|
||||
vkGetPerformanceStatisticsMVK = ( PFN_vkGetPerformanceStatisticsMVK )vkGetInstanceProcAddr( m_VulkanInstance, "vkGetPerformanceStatisticsMVK" );
|
||||
#endif
|
||||
#endif
|
||||
|
||||
CHECK( createDevice() );
|
||||
|
@ -1223,7 +1356,7 @@ bool DeviceManager_VK::CreateDeviceAndSwapChain()
|
|||
|
||||
CHECK( createSwapChain() );
|
||||
|
||||
m_BarrierCommandList = m_NvrhiDevice->createCommandList();
|
||||
//m_BarrierCommandList = m_NvrhiDevice->createCommandList(); // SRS - no longer needed
|
||||
|
||||
// SRS - Give each swapchain image its own semaphore in case of overlap (e.g. MoltenVK async queue submit)
|
||||
for( int i = 0; i < m_SwapChainImages.size(); i++ )
|
||||
|
@ -1237,7 +1370,11 @@ bool DeviceManager_VK::CreateDeviceAndSwapChain()
|
|||
|
||||
#undef CHECK
|
||||
|
||||
OPTICK_GPU_INIT_VULKAN( ( VkDevice* )&m_VulkanDevice, ( VkPhysicalDevice* )&m_VulkanPhysicalDevice, ( VkQueue* )&m_GraphicsQueue, ( uint32_t* )&m_GraphicsQueueFamily, 1, nullptr );
|
||||
#if USE_OPTICK
|
||||
const Optick::VulkanFunctions optickVulkanFunctions = { ( PFN_vkGetInstanceProcAddr_ )vkGetInstanceProcAddr };
|
||||
#endif
|
||||
|
||||
OPTICK_GPU_INIT_VULKAN( ( VkInstance )m_VulkanInstance, ( VkDevice* )&m_VulkanDevice, ( VkPhysicalDevice* )&m_VulkanPhysicalDevice, ( VkQueue* )&m_GraphicsQueue, ( uint32_t* )&m_GraphicsQueueFamily, 1, &optickVulkanFunctions );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1260,7 +1397,7 @@ void DeviceManager_VK::DestroyDeviceAndSwapChain()
|
|||
}
|
||||
m_PresentSemaphore = vk::Semaphore();
|
||||
|
||||
m_BarrierCommandList = nullptr;
|
||||
//m_BarrierCommandList = nullptr; // SRS - no longer needed
|
||||
|
||||
destroySwapChain();
|
||||
|
||||
|
@ -1308,6 +1445,45 @@ void DeviceManager_VK::DestroyDeviceAndSwapChain()
|
|||
|
||||
void DeviceManager_VK::BeginFrame()
|
||||
{
|
||||
OPTICK_CATEGORY( "Vulkan_BeginFrame", Optick::Category::Wait );
|
||||
|
||||
#if defined(__APPLE__) && defined( USE_MoltenVK )
|
||||
#if MVK_VERSION >= MVK_MAKE_VERSION( 1, 2, 6 )
|
||||
if( vkGetPerformanceStatisticsMVK && m_DeviceApiVersion >= VK_MAKE_API_VERSION( 0, 1, 2, 268 ) )
|
||||
{
|
||||
// SRS - get MoltenVK's Metal encoding time and GPU memory usage for display in statistics overlay HUD
|
||||
MVKPerformanceStatistics mvkPerfStats;
|
||||
size_t mvkPerfStatsSize = sizeof( mvkPerfStats );
|
||||
vkGetPerformanceStatisticsMVK( m_VulkanDevice, &mvkPerfStats, &mvkPerfStatsSize );
|
||||
commonLocal.SetRendererMvkEncodeMicroseconds( uint64( Max( 0.0, mvkPerfStats.queue.submitCommandBuffers.latest - mvkPerfStats.queue.retrieveCAMetalDrawable.latest ) * 1000.0 ) );
|
||||
commonLocal.SetRendererGpuMemoryMB( int( mvkPerfStats.device.gpuMemoryAllocated.latest / 1024.0 ) );
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
// SRS - get Vulkan GPU memory usage for display in statistics overlay HUD
|
||||
vk::PhysicalDeviceMemoryProperties2 memoryProperties2;
|
||||
vk::PhysicalDeviceMemoryBudgetPropertiesEXT memoryBudget;
|
||||
memoryProperties2.pNext = &memoryBudget;
|
||||
m_VulkanPhysicalDevice.getMemoryProperties2( &memoryProperties2 );
|
||||
|
||||
VkDeviceSize gpuMemoryAllocated = 0;
|
||||
for( uint32_t i = 0; i < memoryProperties2.memoryProperties.memoryHeapCount; i++ )
|
||||
{
|
||||
gpuMemoryAllocated += memoryBudget.heapUsage[i];
|
||||
|
||||
#if defined(__APPLE__)
|
||||
// SRS - macOS Vulkan API <= 1.2.268 has heap reporting defect, use heapUsage[0] only
|
||||
if( m_DeviceApiVersion <= VK_MAKE_API_VERSION( 0, 1, 2, 268 ) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
commonLocal.SetRendererGpuMemoryMB( int( gpuMemoryAllocated / 1024 / 1024 ) );
|
||||
}
|
||||
|
||||
const vk::Result res = m_VulkanDevice.acquireNextImageKHR( m_SwapChain,
|
||||
std::numeric_limits<uint64_t>::max(), // timeout
|
||||
m_PresentSemaphore,
|
||||
|
@ -1323,9 +1499,10 @@ void DeviceManager_VK::EndFrame()
|
|||
{
|
||||
m_NvrhiDevice->queueSignalSemaphore( nvrhi::CommandQueue::Graphics, m_PresentSemaphore, 0 );
|
||||
|
||||
m_BarrierCommandList->open(); // umm...
|
||||
m_BarrierCommandList->close();
|
||||
m_NvrhiDevice->executeCommandList( m_BarrierCommandList );
|
||||
// SRS - Don't need barrier commandlist if EndFrame() is called before executeCommandList() in idRenderBackend::GL_EndFrame()
|
||||
//m_BarrierCommandList->open(); // umm...
|
||||
//m_BarrierCommandList->close();
|
||||
//m_NvrhiDevice->executeCommandList( m_BarrierCommandList );
|
||||
}
|
||||
|
||||
void DeviceManager_VK::Present()
|
||||
|
|
|
@ -452,6 +452,8 @@ main
|
|||
*/
|
||||
int main( int argc, const char** argv )
|
||||
{
|
||||
extern idCVar r_useGPUSkinning;
|
||||
|
||||
// DG: needed for Sys_ReLaunch()
|
||||
cmdargc = argc;
|
||||
cmdargv = argv;
|
||||
|
@ -481,6 +483,21 @@ int main( int argc, const char** argv )
|
|||
common->Init( 0, NULL, NULL );
|
||||
}
|
||||
|
||||
// SRS - Determine the machine name, e.g. "x86_64" or "arm64"
|
||||
// Might be cleaner in posix Sys_Init(), but only needed on
|
||||
// macOS and all the required sys includes are located here.
|
||||
size_t size;
|
||||
sysctlbyname( "hw.machine", NULL, &size, NULL, 0 );
|
||||
char* machineName = ( char* )Mem_Alloc( size, TAG_SYSTEM );
|
||||
sysctlbyname( "hw.machine", machineName, &size, NULL, 0 );
|
||||
|
||||
// FIXME: On Apple Silicon disable GPU skinning to eliminate rendering artifacts
|
||||
if( strcmp( machineName, "arm64" ) == 0 )
|
||||
{
|
||||
r_useGPUSkinning.SetInteger( 0 );
|
||||
}
|
||||
Mem_Free( machineName );
|
||||
|
||||
Posix_LateInit();
|
||||
|
||||
while( 1 )
|
||||
|
|
Loading…
Reference in a new issue