diff --git a/.gitignore b/.gitignore index 9dd8b410..fa703ab8 100644 --- a/.gitignore +++ b/.gitignore @@ -14,7 +14,7 @@ # Precompiled Headers *.gch *.pch -Source/Renderer/Libs/AMDFidelityFX/CACAO/PrecompiledShadersDXIL/* +Source/Renderer/Libs/AMD/CACAO/PrecompiledShadersDXIL/* # Compiled Dynamic libraries *.so diff --git a/.gitmodules b/.gitmodules index 790f800a..1faacbb6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -19,3 +19,6 @@ [submodule "Data/Textures/PBR"] path = Data/Textures/PBR url = https://github.com/vilbeyli/PBRCollection.git +[submodule "Source/Renderer/Libs/AMD/FidelityFX-SDK"] + path = Source/Renderer/Libs/AMD/FidelityFX-SDK + url = https://github.com/GPUOpen-LibrariesAndSDKs/FidelityFX-SDK.git diff --git a/Build/GenerateProjectFiles.bat b/Build/GenerateProjectFiles.bat index 1d522cdc..05bed301 100644 --- a/Build/GenerateProjectFiles.bat +++ b/Build/GenerateProjectFiles.bat @@ -73,10 +73,12 @@ set SUBMODULE_DIR0=..\Libs\VQUtils\ set SUBMODULE_DIR1=..\Source\Renderer\Libs\D3D12MA\ set SUBMODULE_DIR2=..\Source\Renderer\Libs\D3DX12\ set SUBMODULE_DIR3=..\Libs\imgui\ +set SUBMODULE_DIR4=..\Source\Renderer\Libs\AMD\FidelityFX-SDK\ set SUBMODULE_FILE_PATH0=!SUBMODULE_DIR0!!SUBMODULE_FILE! set SUBMODULE_FILE_PATH1=!SUBMODULE_DIR1!!SUBMODULE_FILE! set SUBMODULE_FILE_PATH2=!SUBMODULE_DIR2! set SUBMODULE_FILE_PATH3=!SUBMODULE_DIR3!!SUBMODULE_FILE! +set SUBMODULE_FILE_PATH4=!SUBMODULE_DIR4!!SUBMODULE_FILE! :: walk thru submodule paths set MISSING_SUBMODULE_DIRS= @@ -97,6 +99,10 @@ if not exist !SUBMODULE_FILE_PATH3! ( set NEED_TO_INIT_SUBMODULES=1 set MISSING_SUBMODULE_DIRS=!MISSING_SUBMODULE_DIRS! !SUBMODULE_DIR3!, ) +if not exist !SUBMODULE_FILE_PATH4! ( + set NEED_TO_INIT_SUBMODULES=1 + set MISSING_SUBMODULE_DIRS=!MISSING_SUBMODULE_DIRS! !SUBMODULE_DIR4!, +) :: init submodules if necessary if !NEED_TO_INIT_SUBMODULES! neq 0 ( @@ -111,6 +117,7 @@ if !NEED_TO_INIT_SUBMODULES! neq 0 ( git submodule update --init Libs/imgui git submodule update --init Libs/cgltf git submodule update --init Source/Renderer/Libs/D3DX12 + git submodule update --init Source/Renderer/Libs/AMD/FidelityFX-SDK cd Build :: check if submodule initialized properly @@ -119,6 +126,7 @@ if !NEED_TO_INIT_SUBMODULES! neq 0 ( if not exist !SUBMODULE_FILE_PATH1! ( set NEED_TO_INIT_SUBMODULES=1 ) if not exist !SUBMODULE_FILE_PATH2! ( set NEED_TO_INIT_SUBMODULES=1 ) if not exist !SUBMODULE_FILE_PATH3! ( set NEED_TO_INIT_SUBMODULES=1 ) + if not exist !SUBMODULE_FILE_PATH4! ( set NEED_TO_INIT_SUBMODULES=1 ) if !NEED_TO_INIT_SUBMODULES! neq 0 ( echo. echo [VQBuild] Could not initialize submodule. Make sure all the submodules are initialized and updated. diff --git a/CMakeLists.txt b/CMakeLists.txt index bc997c1b..344e306d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -112,11 +112,6 @@ set (SceneFiles "Source/Engine/Scene/Quaternion.cpp" ) -set (PostProcessFiles - "Source/Engine/PostProcess/PostProcess.h" - "Source/Engine/PostProcess/PostProcess.cpp" -) - set (UIFiles "Source/Engine/UI/VQUI.cpp" "Source/Engine/UI/VQUI.h" @@ -177,7 +172,6 @@ source_group("Source\\Importer" FILES ${ImporterFiles}) source_group("Source\\Core" FILES ${CoreFiles}) source_group("Source\\Scene" FILES ${SceneFiles}) source_group("Source\\UI" FILES ${UIFiles}) -source_group("Source\\PostProcess" FILES ${PostProcessFiles}) source_group("Source" FILES ${SourceVQE}) set_source_files_properties(${Config} PROPERTIES VS_TOOL_OVERRIDE "Text") @@ -187,6 +181,7 @@ set_source_files_properties(${Materials} PROPERTIES VS_TOOL_OVERRIDE "Text") link_directories(${CMAKE_CURRENT_SOURCE_DIR}/Libs/VQUtils/Bin/) link_directories(${CMAKE_CURRENT_SOURCE_DIR}/Libs/WinPixEventRuntime/bin/x64) +link_directories(${CMAKE_CURRENT_SOURCE_DIR}/Source/Renderer/Libs/AMD/FidelityFX-SDK/PrebuiltSignedDLL) # Create a library with the project name that is build with the Headers and Source files add_executable( ${PROJECT_NAME} @@ -227,7 +222,8 @@ set_target_properties(ImGUI PROPERTIES FOLDER Libs) target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${Includes}) target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${LibsIncl}) -target_link_libraries(${PROJECT_NAME} PRIVATE VQUtils VQRenderer WinPixEventRuntime ImGUI) +target_link_libraries(${PROJECT_NAME} PRIVATE VQUtils VQRenderer WinPixEventRuntime ImGUI amd_fidelityfx_dx12) + add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different diff --git a/Data/EngineSettings.ini b/Data/EngineSettings.ini index a48ffc43..e1d91837 100644 --- a/Data/EngineSettings.ini +++ b/Data/EngineSettings.ini @@ -2,7 +2,7 @@ [Graphics] VSync=false -RenderScale=1.0 +RenderResolutionScale=1.0 TripleBuffer=true AntiAliasing=true Reflections=1 diff --git a/Data/Resources/VQE.rc b/Data/Resources/VQE.rc index 714ea8b5..7ea89a58 100644 --- a/Data/Resources/VQE.rc +++ b/Data/Resources/VQE.rc @@ -79,11 +79,11 @@ BEGIN BEGIN VALUE "CompanyName", "Volkan Ilbeyli @vilbeyli - GitHub/VQE" VALUE "FileDescription", "VQEngine Renderer Application" - VALUE "FileVersion", "0.11.0.0" + VALUE "FileVersion", "0.12.0.0" VALUE "InternalName", "VQE.exe" VALUE "OriginalFilename", "VQE.exe" VALUE "ProductName", "VQEngine" - VALUE "ProductVersion", "0.11.0.0" + VALUE "ProductVersion", "0.12.0.0" END END BLOCK "VarFileInfo" diff --git a/README.md b/README.md index 5536071b..4fe9d5c5 100644 --- a/README.md +++ b/README.md @@ -262,7 +262,7 @@ VQE supports the following command line parameters: - [D3D12MA](https://github.com/GPUOpen-LibrariesAndSDKs/D3D12MemoryAllocator) - [stb](https://github.com/nothings/stb) - [tinyxml2](https://github.com/leethomason/tinyxml2) -- [cgltf][https://github.com/jkuhlmann/cgltf] +- [cgltf](https://github.com/jkuhlmann/cgltf) - [WinPixEventRuntime](https://devblogs.microsoft.com/pix/winpixeventruntime/) - [Khronos glTF Sample Models](https://github.com/KhronosGroup/glTF-Sample-Models) - [cgbookcase PBR Textures](https://www.cgbookcase.com/) diff --git a/Shaders/AMDFidelityFX/CACAO/ffx_cacao.hlsl b/Shaders/AMD/CACAO/ffx_cacao.hlsl similarity index 100% rename from Shaders/AMDFidelityFX/CACAO/ffx_cacao.hlsl rename to Shaders/AMD/CACAO/ffx_cacao.hlsl diff --git a/Shaders/AMDFidelityFX/CAS/ffx_a.h b/Shaders/AMD/CAS/ffx_a.h similarity index 100% rename from Shaders/AMDFidelityFX/CAS/ffx_a.h rename to Shaders/AMD/CAS/ffx_a.h diff --git a/Shaders/AMDFidelityFX/CAS/ffx_cas.h b/Shaders/AMD/CAS/ffx_cas.h similarity index 100% rename from Shaders/AMDFidelityFX/CAS/ffx_cas.h rename to Shaders/AMD/CAS/ffx_cas.h diff --git a/Shaders/AMDFidelityFX/DNSR/LICENSE.txt b/Shaders/AMD/DNSR/LICENSE.txt similarity index 100% rename from Shaders/AMDFidelityFX/DNSR/LICENSE.txt rename to Shaders/AMD/DNSR/LICENSE.txt diff --git a/Shaders/AMDFidelityFX/DNSR/README.md b/Shaders/AMD/DNSR/README.md similarity index 100% rename from Shaders/AMDFidelityFX/DNSR/README.md rename to Shaders/AMD/DNSR/README.md diff --git a/Shaders/AMDFidelityFX/DNSR/ffx_denoiser_reflections_common.h b/Shaders/AMD/DNSR/ffx_denoiser_reflections_common.h similarity index 100% rename from Shaders/AMDFidelityFX/DNSR/ffx_denoiser_reflections_common.h rename to Shaders/AMD/DNSR/ffx_denoiser_reflections_common.h diff --git a/Shaders/AMDFidelityFX/DNSR/ffx_denoiser_reflections_config.h b/Shaders/AMD/DNSR/ffx_denoiser_reflections_config.h similarity index 100% rename from Shaders/AMDFidelityFX/DNSR/ffx_denoiser_reflections_config.h rename to Shaders/AMD/DNSR/ffx_denoiser_reflections_config.h diff --git a/Shaders/AMDFidelityFX/DNSR/ffx_denoiser_reflections_prefilter.h b/Shaders/AMD/DNSR/ffx_denoiser_reflections_prefilter.h similarity index 100% rename from Shaders/AMDFidelityFX/DNSR/ffx_denoiser_reflections_prefilter.h rename to Shaders/AMD/DNSR/ffx_denoiser_reflections_prefilter.h diff --git a/Shaders/AMDFidelityFX/DNSR/ffx_denoiser_reflections_reproject.h b/Shaders/AMD/DNSR/ffx_denoiser_reflections_reproject.h similarity index 100% rename from Shaders/AMDFidelityFX/DNSR/ffx_denoiser_reflections_reproject.h rename to Shaders/AMD/DNSR/ffx_denoiser_reflections_reproject.h diff --git a/Shaders/AMDFidelityFX/DNSR/ffx_denoiser_reflections_resolve_temporal.h b/Shaders/AMD/DNSR/ffx_denoiser_reflections_resolve_temporal.h similarity index 100% rename from Shaders/AMDFidelityFX/DNSR/ffx_denoiser_reflections_resolve_temporal.h rename to Shaders/AMD/DNSR/ffx_denoiser_reflections_resolve_temporal.h diff --git a/Shaders/AMDFidelityFX/DNSR/ffx_denoiser_shadows_filter.h b/Shaders/AMD/DNSR/ffx_denoiser_shadows_filter.h similarity index 100% rename from Shaders/AMDFidelityFX/DNSR/ffx_denoiser_shadows_filter.h rename to Shaders/AMD/DNSR/ffx_denoiser_shadows_filter.h diff --git a/Shaders/AMDFidelityFX/DNSR/ffx_denoiser_shadows_prepare.h b/Shaders/AMD/DNSR/ffx_denoiser_shadows_prepare.h similarity index 100% rename from Shaders/AMDFidelityFX/DNSR/ffx_denoiser_shadows_prepare.h rename to Shaders/AMD/DNSR/ffx_denoiser_shadows_prepare.h diff --git a/Shaders/AMDFidelityFX/DNSR/ffx_denoiser_shadows_tileclassification.h b/Shaders/AMD/DNSR/ffx_denoiser_shadows_tileclassification.h similarity index 100% rename from Shaders/AMDFidelityFX/DNSR/ffx_denoiser_shadows_tileclassification.h rename to Shaders/AMD/DNSR/ffx_denoiser_shadows_tileclassification.h diff --git a/Shaders/AMDFidelityFX/DNSR/ffx_denoiser_shadows_util.h b/Shaders/AMD/DNSR/ffx_denoiser_shadows_util.h similarity index 100% rename from Shaders/AMDFidelityFX/DNSR/ffx_denoiser_shadows_util.h rename to Shaders/AMD/DNSR/ffx_denoiser_shadows_util.h diff --git a/Shaders/AMDFidelityFX/FSR1.0/ffx_a.h b/Shaders/AMD/FSR1.0/ffx_a.h similarity index 100% rename from Shaders/AMDFidelityFX/FSR1.0/ffx_a.h rename to Shaders/AMD/FSR1.0/ffx_a.h diff --git a/Shaders/AMDFidelityFX/FSR1.0/ffx_fsr1.h b/Shaders/AMD/FSR1.0/ffx_fsr1.h similarity index 100% rename from Shaders/AMDFidelityFX/FSR1.0/ffx_fsr1.h rename to Shaders/AMD/FSR1.0/ffx_fsr1.h diff --git a/Shaders/AMDFidelityFX/SPD/ffx_a.h b/Shaders/AMD/SPD/ffx_a.h similarity index 100% rename from Shaders/AMDFidelityFX/SPD/ffx_a.h rename to Shaders/AMD/SPD/ffx_a.h diff --git a/Shaders/AMDFidelityFX/SPD/ffx_spd.h b/Shaders/AMD/SPD/ffx_spd.h similarity index 100% rename from Shaders/AMDFidelityFX/SPD/ffx_spd.h rename to Shaders/AMD/SPD/ffx_spd.h diff --git a/Shaders/AMDFidelityFX/SSSR/ffx_sssr.h b/Shaders/AMD/SSSR/ffx_sssr.h similarity index 100% rename from Shaders/AMDFidelityFX/SSSR/ffx_sssr.h rename to Shaders/AMD/SSSR/ffx_sssr.h diff --git a/Shaders/AMDFidelityFX.hlsl b/Shaders/AMDFidelityFX.hlsl index 0bdc3a42..8eafa416 100644 --- a/Shaders/AMDFidelityFX.hlsl +++ b/Shaders/AMDFidelityFX.hlsl @@ -57,7 +57,7 @@ // //-------------------------------------------------------------------------------------- #if FFXCAS_CS || FFXCAS_PS -#include "AMDFidelityFX/CAS/ffx_a.h" +#include "AMD/CAS/ffx_a.h" // // App-side Defines @@ -114,7 +114,7 @@ cbuffer CASConstants : register(b0) -#include "AMDFidelityFX/CAS/ffx_cas.h" +#include "AMD/CAS/ffx_cas.h" // // CAS Main @@ -183,7 +183,7 @@ void CAS_CSMain(uint3 LocalThreadId : SV_GroupThreadID, uint3 WorkGroupId : SV_G // //-------------------------------------------------------------------------------------- #if FSR_EASU_CS || FSR_EASU_PS -#include "AMDFidelityFX/FSR1.0/ffx_a.h" +#include "AMD/FSR1.0/ffx_a.h" // // App-side Defines @@ -238,7 +238,7 @@ SamplerState samLinearClamp : register(s0); -#include "AMDFidelityFX/FSR1.0/ffx_fsr1.h" +#include "AMD/FSR1.0/ffx_fsr1.h" // @@ -304,7 +304,7 @@ cbuffer RCASConstants : register(b0) uint4 RCASConst0; } -#include "AMDFidelityFX/FSR1.0/ffx_a.h" +#include "AMD/FSR1.0/ffx_a.h" // @@ -328,7 +328,7 @@ cbuffer RCASConstants : register(b0) #endif // FSR_FP16 -#include "AMDFidelityFX/FSR1.0/ffx_fsr1.h" +#include "AMD/FSR1.0/ffx_fsr1.h" // // RCAS // @@ -518,7 +518,7 @@ AH4 SpdReduce4H(AH4 v0, AH4 v1, AH4 v2, AH4 v3) } #endif // A_HALF -#include "AMDFidelityFX/SPD/ffx_spd.h" +#include "AMD/SPD/ffx_spd.h" // // SPD Main // diff --git a/Shaders/DepthPrePass.hlsl b/Shaders/DepthPrePass.hlsl index 89e83be1..e7e7d5d8 100644 --- a/Shaders/DepthPrePass.hlsl +++ b/Shaders/DepthPrePass.hlsl @@ -84,11 +84,11 @@ Texture2D texHeightmap : register(t8); #if INSTANCED_DRAW matrix GetWorldMatrix(uint instID) { return cbPerObject.matWorld[instID]; } matrix GetWorldNormalMatrix(uint instID) { return cbPerObject.matNormal[instID]; } -matrix GetWorldViewProjectionMatrix(uint instID) { return cbPerObject.matWorldViewProj[instID]; } +matrix GetWorldViewProjectionMatrix(uint instID) { return cbPerObject.matJitteredWorldViewProj[instID]; } #else matrix GetWorldMatrix() { return cbPerObject.matWorld; } matrix GetWorldNormalMatrix() { return cbPerObject.matNormal; } -matrix GetWorldViewProjectionMatrix() { return cbPerObject.matWorldViewProj; } +matrix GetWorldViewProjectionMatrix() { return cbPerObject.matJitteredWorldViewProj; } #endif float2 GetUVScale() { return cbPerObject.materialData.uvScaleOffset.xy; } float2 GetUVOffset() { return cbPerObject.materialData.uvScaleOffset.zw; } diff --git a/Shaders/DownsampleDepth.hlsl b/Shaders/DownsampleDepth.hlsl index 0b8a8fbc..acdd6473 100644 --- a/Shaders/DownsampleDepth.hlsl +++ b/Shaders/DownsampleDepth.hlsl @@ -50,7 +50,7 @@ cbuffer cbDownsampleDepth #define A_GPU #define A_HLSL -#include "AMDFidelityFX/SPD/ffx_a.h" +#include "AMD/SPD/ffx_a.h" groupshared float g_group_shared_depth_values[16][16]; groupshared uint g_group_shared_counter; @@ -71,7 +71,7 @@ AF4 SpdLoadIntermediate(AU1 x, AU1 y) { void SpdStoreIntermediate(AU1 x, AU1 y, AF4 value) { g_group_shared_depth_values[x][y] = value.x; } AF4 SpdReduce4(AF4 v0, AF4 v1, AF4 v2, AF4 v3) { return min(min(v0, v1), min(v2, v3)); } -#include "AMDFidelityFX/SPD/ffx_spd.h" +#include "AMD/SPD/ffx_spd.h" uint GetThreadgroupCount(uint2 image_size) { // Each threadgroup works on 64x64 texels diff --git a/Shaders/ForwardLighting.hlsl b/Shaders/ForwardLighting.hlsl index 420e60e5..9f9e2d2a 100644 --- a/Shaders/ForwardLighting.hlsl +++ b/Shaders/ForwardLighting.hlsl @@ -56,14 +56,27 @@ struct PSInput struct PSOutput { float4 color : SV_TARGET0; + #if PS_OUTPUT_ALBEDO_METALLIC float4 albedo_metallic : SV_TARGET1; #endif -#if PS_OUTPUT_ALBEDO_METALLIC && PS_OUTPUT_MOTION_VECTORS +#if PS_OUTPUT_MOTION_VECTORS + #if PS_OUTPUT_ALBEDO_METALLIC float2 motion_vectors : SV_TARGET2; -#elif !PS_OUTPUT_ALBEDO_METALLIC && PS_OUTPUT_MOTION_VECTORS + #else float2 motion_vectors : SV_TARGET1; + #endif +#endif + +#if PS_OUTPUT_MASK + #if PS_OUTPUT_ALBEDO_METALLIC && PS_OUTPUT_MOTION_VECTORS + float transparencyAndCompositionMask : SV_TARGET3; + #elif S_OUTPUT_ALBEDO_METALLIC || PS_OUTPUT_MOTION_VECTORS + float transparencyAndCompositionMask : SV_TARGET2; + #else + float transparencyAndCompositionMask : SV_TARGET1; + #endif #endif }; @@ -119,6 +132,7 @@ TextureCubeArray texPointLightShadowMaps : register(t22); matrix GetWorldMatrix(uint instID) { return cbPerObject.matWorld[instID]; } matrix GetWorldNormalMatrix(uint instID) { return cbPerObject.matNormal[instID]; } matrix GetWorldViewProjectionMatrix(uint instID) { return cbPerObject.matWorldViewProj[instID]; } +matrix GetJitteredWorldViewProjectionMatrix(uint instID) { return cbPerObject.matJitteredWorldViewProj[instID]; } #if PS_OUTPUT_MOTION_VECTORS matrix GetPrevWorldViewProjectionMatrix(uint instID) { return cbPerObject.matWorldViewProjPrev[instID]; } #endif @@ -126,6 +140,7 @@ matrix GetPrevWorldViewProjectionMatrix(uint instID) { return cbPerObject.matWor matrix GetWorldMatrix() { return cbPerObject.matWorld; } matrix GetWorldNormalMatrix() { return cbPerObject.matNormal; } matrix GetWorldViewProjectionMatrix() { return cbPerObject.matWorldViewProj; } +matrix GetJitteredWorldViewProjectionMatrix() { return cbPerObject.matJitteredWorldViewProj; } #if PS_OUTPUT_MOTION_VECTORS matrix GetPrevWorldViewProjectionMatrix() { return cbPerObject.matWorldViewProjPrev; } #endif @@ -155,35 +170,36 @@ PSInput TransformVertex( #if INSTANCED_DRAW matrix matW = GetWorldMatrix(InstanceID); - matrix matWVP = GetWorldViewProjectionMatrix(InstanceID); + matrix matJWVP = GetJitteredWorldViewProjectionMatrix(InstanceID); matrix matWN = GetWorldNormalMatrix(InstanceID); #if PS_OUTPUT_MOTION_VECTORS + matrix matWVP = GetWorldViewProjectionMatrix(InstanceID); matrix matPrevWVP = GetPrevWorldViewProjectionMatrix(InstanceID); #endif #else matrix matW = GetWorldMatrix(); - matrix matWVP = GetWorldViewProjectionMatrix(); + matrix matJWVP = GetJitteredWorldViewProjectionMatrix(); matrix matWN = GetWorldNormalMatrix(); #if PS_OUTPUT_MOTION_VECTORS + matrix matWVP = GetWorldViewProjectionMatrix(); matrix matPrevWVP = GetPrevWorldViewProjectionMatrix(); #endif #endif // INSTANCED_DRAW PSInput result; - result.position = mul(matWVP, vPosition); + result.position = mul(matJWVP, vPosition); result.WorldSpacePosition = mul(matW, vPosition).xyz; result.WorldSpaceNormal = mul((float4x3)matWN, Normal).xyz; result.WorldSpaceTangent = mul((float4x3)matWN, Tangent).xyz; - #if PS_OUTPUT_MOTION_VECTORS +#if PS_OUTPUT_MOTION_VECTORS result.svPositionPrev = mul(matPrevWVP, vPosition); - #endif +#endif result.uv = uv; #if PS_OUTPUT_MOTION_VECTORS - result.svPositionCurr = result.position; + result.svPositionCurr = mul(matWVP, vPosition); #endif - return result; } @@ -225,14 +241,15 @@ PSOutput PSMain(PSInput In) const float2 uv = In.uv * cbPerObject.materialData.uvScaleOffset.xy + cbPerObject.materialData.uvScaleOffset.zw; const int TEX_CFG = cbPerObject.materialData.textureConfig; + const float MipBias = OverrideGlobalMipBias(TEX_CFG) ? cbPerObject.materialData.mipMapBias : cbPerFrame.fGlobalMipBias; - float4 AlbedoAlpha = texDiffuse .Sample(AnisoSampler, uv); + float4 AlbedoAlpha = texDiffuse.SampleBias(AnisoSampler, uv, MipBias); float3 Normal = texNormals.SampleBias(AnisoSampler, uv, cbPerObject.materialData.normalMapMipBias).rgb; - float3 Emissive = texEmissive .Sample(LinearSampler, uv).rgb; - float Metalness = texMetalness.Sample(AnisoSampler, uv).r; - float Roughness = texRoughness.Sample(AnisoSampler, uv).r; - float3 OcclRghMtl = texOcclRoughMetal.Sample(AnisoSampler, uv).rgb; - float LocalAO = texLocalAO.Sample(AnisoSampler, uv).r; + float3 Emissive = texEmissive.SampleBias(LinearSampler, uv, MipBias).rgb; + float Metalness = texMetalness.SampleBias(AnisoSampler, uv, MipBias).r; + float Roughness = texRoughness.SampleBias(AnisoSampler, uv, MipBias).r; + float3 OcclRghMtl = texOcclRoughMetal.SampleBias(AnisoSampler, uv, MipBias).rgb; + float LocalAO = texLocalAO.SampleBias(AnisoSampler, uv, MipBias).r; #if ENABLE_ALPHA_MASK if (HasDiffuseMap(TEX_CFG) && AlbedoAlpha.a < 0.01f) @@ -383,9 +400,11 @@ PSOutput PSMain(PSInput In) o.albedo_metallic = float4(Surface.diffuseColor, Surface.metalness); #endif #if PS_OUTPUT_MOTION_VECTORS - //o.motion_vectors = float2(0.77777777777777, 0.8888888888888888); // debug output o.motion_vectors = float2(In.svPositionCurr.xy / In.svPositionCurr.w - In.svPositionPrev.xy / In.svPositionPrev.w); #endif + #if PS_OUTPUT_MASK + o.transparencyAndCompositionMask = 1.0f; + #endif return o; } diff --git a/Shaders/LightingConstantBufferData.h b/Shaders/LightingConstantBufferData.h index 97693dc0..5b0c0d75 100644 --- a/Shaders/LightingConstantBufferData.h +++ b/Shaders/LightingConstantBufferData.h @@ -113,15 +113,16 @@ struct SceneLighting // MATERIAL //---------------------------------------------------------- // Has*Map() encoding should match Material::GetTextureConfig() -inline int HasDiffuseMap(int textureConfig) { return ((textureConfig & (1 << 0)) > 0 ? 1 : 0); } -inline int HasNormalMap(int textureConfig) { return ((textureConfig & (1 << 1)) > 0 ? 1 : 0); } -inline int HasAmbientOcclusionMap(int textureConfig) { return ((textureConfig & (1 << 2)) > 0 ? 1 : 0); } -inline int HasAlphaMask(int textureConfig) { return ((textureConfig & (1 << 3)) > 0 ? 1 : 0); } -inline int HasRoughnessMap(int textureConfig) { return ((textureConfig & (1 << 4)) > 0 ? 1 : 0); } -inline int HasMetallicMap(int textureConfig) { return ((textureConfig & (1 << 5)) > 0 ? 1 : 0); } -inline int HasHeightMap(int textureConfig) { return ((textureConfig & (1 << 6)) > 0 ? 1 : 0); } -inline int HasEmissiveMap(int textureConfig) { return ((textureConfig & (1 << 7)) > 0 ? 1 : 0); } -inline int HasOcclusionRoughnessMetalnessMap(int textureConfig) { return ((textureConfig & (1 << 8)) > 0 ? 1 : 0); } +inline int HasDiffuseMap(int textureConfig) { return ((textureConfig & (1 << 0 )) > 0 ? 1 : 0); } +inline int HasNormalMap(int textureConfig) { return ((textureConfig & (1 << 1 )) > 0 ? 1 : 0); } +inline int HasAmbientOcclusionMap(int textureConfig) { return ((textureConfig & (1 << 2 )) > 0 ? 1 : 0); } +inline int HasAlphaMask(int textureConfig) { return ((textureConfig & (1 << 3 )) > 0 ? 1 : 0); } +inline int HasRoughnessMap(int textureConfig) { return ((textureConfig & (1 << 4 )) > 0 ? 1 : 0); } +inline int HasMetallicMap(int textureConfig) { return ((textureConfig & (1 << 5 )) > 0 ? 1 : 0); } +inline int HasHeightMap(int textureConfig) { return ((textureConfig & (1 << 6 )) > 0 ? 1 : 0); } +inline int HasEmissiveMap(int textureConfig) { return ((textureConfig & (1 << 7 )) > 0 ? 1 : 0); } +inline int HasOcclusionRoughnessMetalnessMap(int textureConfig) { return ((textureConfig & (1 << 8 )) > 0 ? 1 : 0); } +inline bool OverrideGlobalMipBias(uint textureConfig) { return ((textureConfig & (1 << 31)) > 0 ? 1 : 0); } struct ALIGNAS(16) MaterialData { @@ -136,10 +137,12 @@ struct ALIGNAS(16) MaterialData float4 uvScaleOffset; + float mipMapBias; float roughness; float metalness; float displacement; - float textureConfig; + + uint textureConfig; }; @@ -169,6 +172,7 @@ struct PerFrameData float2 f2DirectionalLightShadowMapDimensions; float fAmbientLightingFactor; float fHDRIOffsetInRadians; + float fGlobalMipBias; }; struct PerViewLightingData { @@ -188,15 +192,19 @@ struct PerViewLightingData struct ALIGNAS(64) PerObjectLightingData { #if INSTANCED_DRAW - matrix matWorldViewProj [MAX_INSTANCE_COUNT__SCENE_MESHES]; - matrix matWorld [MAX_INSTANCE_COUNT__SCENE_MESHES]; - matrix matWorldViewProjPrev[MAX_INSTANCE_COUNT__SCENE_MESHES]; - matrix matNormal [MAX_INSTANCE_COUNT__SCENE_MESHES]; // could be 4x3 - int4 ObjID [MAX_INSTANCE_COUNT__SCENE_MESHES]; // int[] causes alignment issues as each element is aligned to 16B on the GPU. use int4.x + matrix matWorldViewProj [MAX_INSTANCE_COUNT__SCENE_MESHES]; + matrix matJitteredWorldViewProj [MAX_INSTANCE_COUNT__SCENE_MESHES]; + matrix matWorld [MAX_INSTANCE_COUNT__SCENE_MESHES]; + matrix matWorldViewProjPrev [MAX_INSTANCE_COUNT__SCENE_MESHES]; + matrix matJitteredWorldViewProjPrev[MAX_INSTANCE_COUNT__SCENE_MESHES]; + matrix matNormal [MAX_INSTANCE_COUNT__SCENE_MESHES]; // could be 4x3 + int4 ObjID [MAX_INSTANCE_COUNT__SCENE_MESHES]; // int[] causes alignment issues as each element is aligned to 16B on the GPU. use int4.x #else matrix matWorldViewProj; + matrix matJitteredWorldViewProj; matrix matWorld; matrix matWorldViewProjPrev; + matrix matJitteredWorldViewProjPrev; matrix matNormal; int4 ObjID; #endif diff --git a/Shaders/ScreenSpaceReflections/ClassifyReflectionTiles.hlsl b/Shaders/ScreenSpaceReflections/ClassifyReflectionTiles.hlsl index 13217037..eea058e2 100644 --- a/Shaders/ScreenSpaceReflections/ClassifyReflectionTiles.hlsl +++ b/Shaders/ScreenSpaceReflections/ClassifyReflectionTiles.hlsl @@ -21,7 +21,7 @@ THE SOFTWARE. ********************************************************************/ #include "Common.hlsl" -#include "../AMDFidelityFX/DNSR/ffx_denoiser_reflections_common.h" +#include "../AMD/DNSR/ffx_denoiser_reflections_common.h" #include "../BRDF.hlsl" Texture2D g_roughness : register(t0); diff --git a/Shaders/ScreenSpaceReflections/Intersect.hlsl b/Shaders/ScreenSpaceReflections/Intersect.hlsl index c8022e1c..7a4bf03e 100644 --- a/Shaders/ScreenSpaceReflections/Intersect.hlsl +++ b/Shaders/ScreenSpaceReflections/Intersect.hlsl @@ -140,7 +140,7 @@ bool IsMirrorReflection(float roughness) { return roughness < 0.041; } -#include "../AMDFidelityFX/SSSR/ffx_sssr.h" +#include "../AMD/SSSR/ffx_sssr.h" [numthreads(8, 8, 1)] void CSMain(uint group_index : SV_GroupIndex, uint group_id : SV_GroupID) { diff --git a/Shaders/ScreenSpaceReflections/Prefilter.hlsl b/Shaders/ScreenSpaceReflections/Prefilter.hlsl index fc9e413d..fc0d98ad 100644 --- a/Shaders/ScreenSpaceReflections/Prefilter.hlsl +++ b/Shaders/ScreenSpaceReflections/Prefilter.hlsl @@ -70,7 +70,7 @@ void FFX_DNSR_Reflections_StorePrefilteredReflections(int2 pixel_coordinate, min g_out_variance[pixel_coordinate] = variance.x; } -#include "../AMDFidelityFX/DNSR/ffx_denoiser_reflections_prefilter.h" +#include "../AMD/DNSR/ffx_denoiser_reflections_prefilter.h" [numthreads(8, 8, 1)] void CSMain(int2 group_thread_id : SV_GroupThreadID, diff --git a/Shaders/ScreenSpaceReflections/Reproject.hlsl b/Shaders/ScreenSpaceReflections/Reproject.hlsl index 2169af28..0c4f0e75 100644 --- a/Shaders/ScreenSpaceReflections/Reproject.hlsl +++ b/Shaders/ScreenSpaceReflections/Reproject.hlsl @@ -71,7 +71,7 @@ void FFX_DNSR_Reflections_StoreRadianceReprojected(int2 pixel_coordinate, min16f void FFX_DNSR_Reflections_StoreAverageRadiance(int2 pixel_coordinate, min16float3 value) { g_out_average_radiance[pixel_coordinate] = value; } void FFX_DNSR_Reflections_StoreVariance(int2 pixel_coordinate, min16float value) { g_out_variance[pixel_coordinate] = value; } void FFX_DNSR_Reflections_StoreNumSamples(int2 pixel_coordinate, min16float value) { g_out_sample_count[pixel_coordinate] = value; } -#include "../AMDFidelityFX/DNSR/ffx_denoiser_reflections_reproject.h" +#include "../AMD/DNSR/ffx_denoiser_reflections_reproject.h" [numthreads(8, 8, 1)] void CSMain(int2 group_thread_id : SV_GroupThreadID, diff --git a/Shaders/ScreenSpaceReflections/ResolveTemporal.hlsl b/Shaders/ScreenSpaceReflections/ResolveTemporal.hlsl index 012473fc..52bf1003 100644 --- a/Shaders/ScreenSpaceReflections/ResolveTemporal.hlsl +++ b/Shaders/ScreenSpaceReflections/ResolveTemporal.hlsl @@ -50,7 +50,7 @@ void FFX_DNSR_Reflections_StoreTemporalAccumulation(int2 pixel_coordinate, min16 g_out_variance[pixel_coordinate] = variance.x; } -#include "../AMDFidelityFX/DNSR/ffx_denoiser_reflections_resolve_temporal.h" +#include "../AMD/DNSR/ffx_denoiser_reflections_resolve_temporal.h" [numthreads(8, 8, 1)] void CSMain(int2 group_thread_id : SV_GroupThreadID, diff --git a/Shaders/Skydome.hlsl b/Shaders/Skydome.hlsl index 82580b58..93f0b692 100644 --- a/Shaders/Skydome.hlsl +++ b/Shaders/Skydome.hlsl @@ -48,9 +48,26 @@ PSInput VSMain(float4 position : POSITION, float2 uv : TEXCOORD0) return result; } -float4 PSMain(PSInput input) : SV_TARGET + +struct PSOutput +{ + float4 color : SV_TARGET0; +#if PS_OUTPUT_MASK + float transparencyAndCompositionMask : SV_TARGET1; +#endif +}; + +PSOutput PSMain(PSInput input) { + PSOutput o = (PSOutput) 0; + float2 uv = DirectionToEquirectUV(normalize(input.CubemapLookDirection)); float3 ColorTex = texEquirectEnvironmentMap.SampleLevel(Sampler, uv, 0).rgb; - return float4(ColorTex, 1); + o.color = float4(ColorTex, 1); + +#if PS_OUTPUT_MASK + o.transparencyAndCompositionMask = 1.0f; +#endif + + return o; } diff --git a/Shaders/UIHDRComposite.hlsl b/Shaders/UIHDRComposite.hlsl index 65de253c..c98959d7 100644 --- a/Shaders/UIHDRComposite.hlsl +++ b/Shaders/UIHDRComposite.hlsl @@ -29,7 +29,6 @@ cbuffer CBuffer : register(b0) float Brightness; } -Texture2D SceneHDRTexture; Texture2D UITexture; PSInput VSMain(uint id : SV_VertexID) @@ -53,23 +52,10 @@ PSInput VSMain(uint id : SV_VertexID) float4 PSMain(PSInput input) : SV_TARGET { - // sample source images: UI + PostProcessed Scene float4 UITexSample = UITexture.Load(int3(input.position.xy, 0)); - float4 ColorTexSample = SceneHDRTexture.Load(int3(input.position.xy, 0)); - - // check if the pixel is completely black (= UI pass didn't write on top) - bool bIsUIPixel = dot(UITexSample.rgb, UITexSample.rgb) != 0; - + // de-gamma the SDR UI content and get to linear space float3 LinearUIColor = SRGBToLinear(UITexSample.rgb); - - float3 OutColor = OutColor = ColorTexSample.rgb; - if (bIsUIPixel) - { - // UI is currently not transparent - OutColor = LinearUIColor.rgb * Brightness /* + ColorTexSample.rgb * (1.0f - UITexSample.a)*/; - } - float OutAlpha = 1.0f; - - return float4(OutColor, OutAlpha); + + return float4(LinearUIColor * Brightness, UITexSample.a); } diff --git a/Shaders/VQPlatform.h b/Shaders/VQPlatform.h index 7ca61b4a..538cbd0e 100644 --- a/Shaders/VQPlatform.h +++ b/Shaders/VQPlatform.h @@ -31,9 +31,10 @@ #define int2 DirectX::XMINT2 #define int3 DirectX::XMINT3 #define int4 DirectX::XMINT4 -#define uint2 DirectX::XMUINT2; -#define uint3 DirectX::XMUINT3; -#define uint4 DirectX::XMUINT4; +#define uint unsigned +#define uint2 DirectX::XMUINT2 +#define uint3 DirectX::XMUINT3 +#define uint4 DirectX::XMUINT4 #define matrix DirectX::XMMATRIX #define float3x3 DirectX::XMFLOAT3X3 #define float4x3 DirectX::XMFLOAT4X3 @@ -43,7 +44,6 @@ namespace VQ_SHADER_DATA { #endif - #ifdef VQ_CPU } // namespace VQ_SHADER_DATA #endif diff --git a/Source/Engine/Core/FileParser.cpp b/Source/Engine/Core/FileParser.cpp index 27bae18a..c7309a56 100644 --- a/Source/Engine/Core/FileParser.cpp +++ b/Source/Engine/Core/FileParser.cpp @@ -101,42 +101,44 @@ void FileParser::ParseEngineSettingsFile(FStartupParameters& params) if (SettingName == "VSync") { params.bOverrideGFXSetting_bVSync = true; - params.EngineSettings.gfx.bVsync = StrUtil::ParseBool(SettingValue); + params.EngineSettings.gfx.Display.bVsync = StrUtil::ParseBool(SettingValue); } - if (SettingName == "RenderScale") + if (SettingName == "RenderResolutionScale") { params.bOverrideGFXSetting_RenderScale = true; - params.EngineSettings.gfx.RenderScale = StrUtil::ParseFloat(SettingValue); + params.EngineSettings.gfx.Rendering.RenderResolutionScale = StrUtil::ParseFloat(SettingValue); } if (SettingName == "TripleBuffer") { params.bOverrideGFXSetting_bUseTripleBuffering = true; - params.EngineSettings.gfx.bUseTripleBuffering = StrUtil::ParseBool(SettingValue); + params.EngineSettings.gfx.Display.bUseTripleBuffering = StrUtil::ParseBool(SettingValue); } +#if 0 // TODO: enable anti-alising with its enum options if (SettingName == "AntiAliasing" || SettingName == "AA") { params.bOverrideGFXSetting_bAA = true; params.EngineSettings.gfx.bAntiAliasing = StrUtil::ParseBool(SettingValue); } +#endif if (SettingName == "MaxFrameRate" || SettingName == "MaxFPS") { params.bOverrideGFXSetting_bMaxFrameRate = true; if (SettingValue == "Unlimited" || SettingValue == "0") - params.EngineSettings.gfx.MaxFrameRate = 0; + params.EngineSettings.gfx.Rendering.MaxFrameRate = 0; else if (SettingValue == "Auto" || SettingValue == "Automatic" || SettingValue == "-1") - params.EngineSettings.gfx.MaxFrameRate = -1; + params.EngineSettings.gfx.Rendering.MaxFrameRate = -1; else - params.EngineSettings.gfx.MaxFrameRate = StrUtil::ParseInt(SettingValue); + params.EngineSettings.gfx.Rendering.MaxFrameRate = StrUtil::ParseInt(SettingValue); } if (SettingName == "EnvironmentMapResolution") { - params.EngineSettings.gfx.EnvironmentMapResolution = StrUtil::ParseInt(SettingValue); + params.EngineSettings.gfx.Rendering.EnvironmentMapResolution = StrUtil::ParseInt(SettingValue); params.bOverrideGFXSetting_EnvironmentMapResolution = true; } if (SettingName == "Reflections") { params.bOverrideGFXSettings_Reflections = true; - params.EngineSettings.gfx.Reflections = static_cast(StrUtil::ParseInt(SettingValue)); + params.EngineSettings.gfx.Rendering.Reflections = static_cast(StrUtil::ParseInt(SettingValue)); } // @@ -678,7 +680,7 @@ FSceneRepresentation FileParser::ParseSceneFile(const std::string& SceneFile) { const Transform tf = fnParseTransform(pTransform); l.Position = tf._position; - l.RenderScale = tf._scale; + l.MeshScale = tf._scale; l.RotationQuaternion = tf._rotation; } diff --git a/Source/Engine/Core/Types.h b/Source/Engine/Core/Types.h index 29aac51e..c9e2c9de 100644 --- a/Source/Engine/Core/Types.h +++ b/Source/Engine/Core/Types.h @@ -34,7 +34,9 @@ using uint32 = unsigned; using uint16 = unsigned short; using uint8 = unsigned char; +#ifndef uint using uint = unsigned; +#endif using fp32 = float; diff --git a/Source/Engine/Core/VQEngine_EventHandlers.cpp b/Source/Engine/Core/VQEngine_EventHandlers.cpp index 46ad7405..ccdff223 100644 --- a/Source/Engine/Core/VQEngine_EventHandlers.cpp +++ b/Source/Engine/Core/VQEngine_EventHandlers.cpp @@ -25,7 +25,7 @@ #include "Windows.h" #include "imgui.h" -#define VERBOSE_LOGGING 0 +#define VERBOSE_LOGGING 1 // ------------------------------------------------------------------------------------------------------------------------------------------------------------ // @@ -277,35 +277,16 @@ void VQEngine::UpdateThread_HandleWindowResizeEvent(const std::shared_ptrGetWindowSwapChain(p->hwnd); const int NUM_BACK_BUFFERS = Swapchain.GetNumBackBuffers(); - if ((uWidth | uHeight) != 0 && mpScene) + if (mpScene) { // Update Camera Projection Matrices Camera& cam = mpScene->GetActiveCamera(); // TODO: all cameras? FProjectionMatrixParameters UpdatedProjectionMatrixParams = cam.GetProjectionParameters(); UpdatedProjectionMatrixParams.ViewportWidth = static_cast(uWidth); UpdatedProjectionMatrixParams.ViewportHeight = static_cast(uHeight); + const float AspectRatio = UpdatedProjectionMatrixParams.ViewportWidth / UpdatedProjectionMatrixParams.ViewportHeight; + Log::Info("Update ActiveSceneCamera Viewport Size %dx%d | aspect ratio: %.3f", (int)uWidth, (int)uHeight, AspectRatio); cam.SetProjectionMatrix(UpdatedProjectionMatrixParams); - - // Update PostProcess Data - for (int i = 0; i < NUM_BACK_BUFFERS; ++i) - { - FPostProcessParameters& PPParams = mpScene->GetPostProcessParameters(i); - -#if !DISABLE_FIDELITYFX_CAS - // Update FidelityFX constant blocks - if (PPParams.IsFFXCASEnabled()) - { - PPParams.FFXCASParams.UpdateCASConstantBlock(uWidth, uHeight, uWidth, uHeight); - } -#endif - if (PPParams.IsFSREnabled()) - { - const uint InputWidth = static_cast(PPParams.ResolutionScale * uWidth); - const uint InputHeight = static_cast(PPParams.ResolutionScale * uHeight); - PPParams.FSR_EASUParams.UpdateEASUConstantBlock(InputWidth, InputHeight, InputWidth, InputHeight, uWidth, uHeight); - PPParams.FSR_RCASParams.UpdateRCASConstantBlock(); - } - } } } } @@ -412,16 +393,17 @@ void VQEngine::RenderThread_HandleWindowResizeEvent(const std::shared_ptrOnResize(WIDTH, HEIGHT); - mpRenderer->OnWindowSizeChanged(hwnd, WIDTH, HEIGHT); // updates render context - const FPostProcessParameters& PPParams = this->mpScene->GetPostProcessParameters(0); - const bool bFSREnabled = PPParams.IsFSREnabled() && !bUseHDRRenderPath; // TODO: remove this when FSR-HDR is implemented - const bool bUpscaling = bFSREnabled || 0; // update here when other upscaling methods are added + mSettings.gfx.Display.DisplayResolutionX = WIDTH; + mSettings.gfx.Display.DisplayResolutionY = HEIGHT; - const float fResolutionScale = bUpscaling ? PPParams.ResolutionScale : 1.0f; + mpRenderer->OnWindowSizeChanged(hwnd, WIDTH, HEIGHT); // updates render context - RenderThread_UnloadWindowSizeDependentResources(hwnd); - RenderThread_LoadWindowSizeDependentResources(hwnd, WIDTH, HEIGHT, fResolutionScale); + if (hwnd == mpWinMain->GetHWND()) + { + mpRenderer->UnloadWindowSizeDependentResources(hwnd); + mpRenderer->LoadWindowSizeDependentResources(hwnd, mSettings.gfx, this->ShouldRenderHDR(hwnd)); + } } void VQEngine::RenderThread_HandleWindowCloseEvent(const IEvent* pEvent) @@ -443,7 +425,7 @@ void VQEngine::RenderThread_HandleWindowCloseEvent(const IEvent* pEvent) } mpRenderer->GetWindowSwapChain(hwnd).WaitForGPU(); - RenderThread_UnloadWindowSizeDependentResources(hwnd); + mpRenderer->UnloadWindowSizeDependentResources(hwnd); pWindowCloseEvent->Signal_WindowDependentResourcesDestroyed.NotifyAll(); } @@ -478,11 +460,10 @@ void VQEngine::RenderThread_HandleToggleFullscreenEvent(const IEvent* pEvent) Swapchain.WaitForGPU(); // make sure GPU is finished - const auto& PPParams = this->mpScene->GetPostProcessParameters(0); - const bool bFSREnabled = PPParams.IsFSREnabled(); + const bool bFSREnabled = mSettings.gfx.IsFSR1Enabled(); const bool bUpscaling = bFSREnabled || 0; // update here when other upscaling methods are added - const float fResolutionScale = bUpscaling ? PPParams.ResolutionScale : 1.0f; + const float fResolutionScale = bUpscaling ? mSettings.gfx.Rendering.RenderResolutionScale : 1.0f; // // EXCLUSIVE FULLSCREEN @@ -566,7 +547,7 @@ void VQEngine::RenderThread_HandleSetVSyncEvent(const IEvent* pEvent) Swapchain.EnsureSwapChainColorSpace(Swapchain.GetFormat() == DXGI_FORMAT_R16G16B16A16_FLOAT ? _16 : _8, false); } - mSettings.gfx.bVsync = bVsyncState; + mSettings.gfx.Display.bVsync = bVsyncState; Log::Info("Toggle VSync: %d", bVsyncState); } @@ -598,13 +579,14 @@ void VQEngine::RenderThread_HandleSetSwapchainFormatEvent(const IEvent* pEvent) const int NUM_BACK_BUFFERS = Swapchain.GetNumBackBuffers(); const int BACK_BUFFER_INDEX = Swapchain.GetCurrentBackBufferIndex(); - const EDisplayCurve OutputDisplayCurve = Swapchain.IsHDRFormat() ? EDisplayCurve::Linear : EDisplayCurve::sRGB; - for (int i = 0; i < NUM_BACK_BUFFERS; ++i) - mpScene->GetPostProcessParameters(i).TonemapperParams.OutputDisplayCurve = OutputDisplayCurve; + const EDisplayCurve OutputDisplayCurve = Swapchain.IsHDRFormat() + ? mSettings.gfx.PostProcessing.HDROutputDisplayCurve + : mSettings.gfx.PostProcessing.SDROutputDisplayCurve; + Log::Info("Set Swapchain Format: %s | OutputDisplayCurve: %s" , VQRenderer::DXGIFormatAsString(pSwapchainEvent->format).data() - , (OutputDisplayCurve == EDisplayCurve::sRGB ? "Gamma2.2" : (OutputDisplayCurve == EDisplayCurve::Linear ? "Linear" : "PQ")) + , GetDisplayCurveString(OutputDisplayCurve) ); } void VQEngine::RenderThread_HandleSetSwapchainQueueEvent(const IEvent* pEvent) @@ -643,8 +625,4 @@ void VQEngine::RenderThread_HandleSetHDRMetaDataEvent(const IEvent* pEvent) Swapchain.WaitForGPU(); Swapchain.SetHDRMetaData(pSetMetaDataEvent->payload); } - - const EDisplayCurve OutputDisplayCurve = Swapchain.IsHDRFormat() ? EDisplayCurve::Linear : EDisplayCurve::sRGB; - for (int i = 0; i < Swapchain.GetNumBackBuffers(); ++i) - mpScene->GetPostProcessParameters(i).TonemapperParams.OutputDisplayCurve = OutputDisplayCurve; } diff --git a/Source/Engine/Main.cpp b/Source/Engine/Main.cpp index 3f8ab8cd..9a3b6878 100644 --- a/Source/Engine/Main.cpp +++ b/Source/Engine/Main.cpp @@ -120,34 +120,22 @@ static void ParseCommandLineParameters(FStartupParameters& refStartupParams, PST refStartupParams.bOverrideGFXSetting_bVSync = true; if (paramValue.empty()) { - refStartupParams.EngineSettings.gfx.bVsync = true; + refStartupParams.EngineSettings.gfx.Display.bVsync = true; } else { - refStartupParams.EngineSettings.gfx.bVsync = StrUtil::ParseBool(paramValue); - } - } - if (paramName == "-AntiAliasing" || paramName == "-AA") - { - refStartupParams.bOverrideGFXSetting_bAA = true; - if (paramValue.empty()) - { - refStartupParams.EngineSettings.gfx.bAntiAliasing = true; - } - else - { - refStartupParams.EngineSettings.gfx.bAntiAliasing = StrUtil::ParseBool(paramValue); + refStartupParams.EngineSettings.gfx.Display.bVsync = StrUtil::ParseBool(paramValue); } } if (paramName == "-TripleBuffering") { refStartupParams.bOverrideGFXSetting_bUseTripleBuffering = true; - refStartupParams.EngineSettings.gfx.bUseTripleBuffering = true; + refStartupParams.EngineSettings.gfx.Display.bUseTripleBuffering = true; } if (paramName == "-DoubleBuffering") { refStartupParams.bOverrideGFXSetting_bUseTripleBuffering = true; - refStartupParams.EngineSettings.gfx.bUseTripleBuffering = false; + refStartupParams.EngineSettings.gfx.Display.bUseTripleBuffering = false; } if (paramName == "-HDR") { @@ -158,11 +146,11 @@ static void ParseCommandLineParameters(FStartupParameters& refStartupParams, PST { refStartupParams.bOverrideGFXSetting_bMaxFrameRate = true; if (paramValue == "Unlimited" || paramValue == "0") - refStartupParams.EngineSettings.gfx.MaxFrameRate = 0; + refStartupParams.EngineSettings.gfx.Rendering.MaxFrameRate = 0; else if (paramValue == "Auto" || paramValue == "Automatic" || paramValue == "-1") - refStartupParams.EngineSettings.gfx.MaxFrameRate = -1; + refStartupParams.EngineSettings.gfx.Rendering.MaxFrameRate = -1; else - refStartupParams.EngineSettings.gfx.MaxFrameRate = StrUtil::ParseInt(paramValue); + refStartupParams.EngineSettings.gfx.Rendering.MaxFrameRate = StrUtil::ParseInt(paramValue); } if (paramName == "-Scene") diff --git a/Source/Engine/PostProcess/PostProcess.cpp b/Source/Engine/PostProcess/PostProcess.cpp deleted file mode 100644 index 9f26a7fa..00000000 --- a/Source/Engine/PostProcess/PostProcess.cpp +++ /dev/null @@ -1,100 +0,0 @@ -// VQE -// Copyright(C) 2020 - Volkan Ilbeyli -// -// This program 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. -// -// This program 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 this program.If not, see . -// -// Contact: volkanilbeyli@gmail.com - -#define FFX_DEBUG_LOG 1 - -#define A_CPU 1 - -#include "PostProcess.h" - -#include "../Core/Types.h" -#if FFX_DEBUG_LOG -#include "../../VQUtils/Include/Log.h" -#endif - -#include - -//#include "Shaders/AMDFidelityFX/CAS/ffx_a.h" -#include "Shaders/AMDFidelityFX/FSR1.0/ffx_a.h" -#include "Shaders/AMDFidelityFX/CAS/ffx_cas.h" -#include "Shaders/AMDFidelityFX/FSR1.0/ffx_fsr1.h" - -float FPostProcessParameters::FFSR1_RCAS::GetLinearSharpness() const { return std::powf(0.5f, this->RCASSharpnessStops); } -void FPostProcessParameters::FFSR1_RCAS::SetLinearSharpness(float Sharpness) { this->RCASSharpnessStops = std::log10f(Sharpness) / std::log10f(0.5f); } -void FPostProcessParameters::FFSR1_RCAS::UpdateRCASConstantBlock() -{ -#if FFX_DEBUG_LOG - Log::Info("[FidelityFX][FSR-RCAS]: FsrRcasCon() called with SharpnessStops=%.2f", this->RCASSharpnessStops); -#endif - FsrRcasCon(reinterpret_cast(&this->RCASConstantBlock[0]), this->RCASSharpnessStops); -} - -void FPostProcessParameters::FFSR1_EASU::UpdateEASUConstantBlock( - uint InputWidth - , uint InputHeight - , uint InputContainerWidth - , uint InputContainerHeight - , uint OutputWidth - , uint OutputHeight) -{ -#if FFX_DEBUG_LOG - Log::Info("[FidelityFX][Super Resolution]: FsrEasuCon() called with InputResolution=%ux%u, ContainerDimensions=%ux%u, OutputResolution==%ux%u", - InputWidth - , InputHeight - , InputContainerWidth - , InputContainerHeight - , OutputWidth - , OutputHeight); -#endif - FsrEasuCon( - reinterpret_cast(&this->EASUConstantBlock[0]) - , reinterpret_cast(&this->EASUConstantBlock[4]) - , reinterpret_cast(&this->EASUConstantBlock[8]) - , reinterpret_cast(&this->EASUConstantBlock[12]) - , static_cast(InputWidth) // This the rendered image resolution being upscaled - , static_cast(InputHeight) - , static_cast(InputContainerWidth) // This is the resolution of the resource containing the input image (useful for dynamic resolution) - , static_cast(InputContainerHeight) - , static_cast(OutputWidth) // This is the display resolution which the input image gets upscaled to - , static_cast(OutputHeight) - ); -} - -#if !DISABLE_FIDELITYFX_CAS -void FPostProcessParameters::FFFXCAS::UpdateCASConstantBlock( - uint InputWidth - , uint InputHeight - , uint OutputWidth - , uint OutputHeight) -{ -#if FFX_DEBUG_LOG - Log::Info("[FidelityFX][CAS]: CasSetup() called with Sharpness=%.2f, InputResolution=%ux%u, OutputResolution==%ux%u", - this->CASSharpen - , InputWidth - , InputHeight - , OutputWidth - , OutputHeight); -#endif - CasSetup(&this->CASConstantBlock[0], &this->CASConstantBlock[4], this->CASSharpen, - static_cast(InputWidth), - static_cast(InputHeight), // input resolution - static_cast(OutputWidth), - static_cast(OutputHeight) // output resolution - ); -} -#endif \ No newline at end of file diff --git a/Source/Engine/PostProcess/PostProcess.h b/Source/Engine/PostProcess/PostProcess.h deleted file mode 100644 index fa25f5a2..00000000 --- a/Source/Engine/PostProcess/PostProcess.h +++ /dev/null @@ -1,172 +0,0 @@ -// VQE -// Copyright(C) 2020 - Volkan Ilbeyli -// -// This program 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. -// -// This program 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 this program.If not, see . -// -// Contact: volkanilbeyli@gmail.com -#pragma once - -#include "../Core/Types.h" - -#include "Renderer/Rendering/HDR.h" - -#define DISABLE_FIDELITYFX_CAS 1 // disable ffx cas but keep implementaiton around, now using fsr1 rcas - -// fwd decl -struct FUIState; - -// AMD / FidelityFX Super Resolution 1.0: -namespace AMD_FidelityFX_SuperResolution1 -{ - enum EPreset - { - ULTRA_QUALITY = 0, - QUALITY, - BALANCED, - PERFORMANCE, - CUSTOM, - - NUM_FSR1_PRESET_OPTIONS - }; - inline float GetAMDFSR1ScreenPercentage(EPreset ePreset) - { - switch (ePreset) - { - case EPreset::ULTRA_QUALITY: return 0.77f; - case EPreset::QUALITY: return 0.67f; - case EPreset::BALANCED: return 0.58f; - case EPreset::PERFORMANCE: return 0.50f; - } - return 1.0f; - } -} - -enum class EDrawMode -{ - LIT_AND_POSTPROCESSED = 0, - //WIREFRAME, // TODO: add support - //NO_MATERIALS, // TODO: add support - - DEPTH, - NORMALS, - ROUGHNESS, - METALLIC, - AO, - ALBEDO, - REFLECTIONS, - MOTION_VECTORS, - - NUM_DRAW_MODES, -}; - -// TODO: separate post process options from parameters (shader data) -struct FPostProcessParameters -{ - enum EUpscalingAlgorithm - { - NONE = 0, - FIDELITYFX_SUPER_RESOLUTION1, - - NUM_UPSCALING_ALGORITHMS - }; - - struct FTonemapper - { - EColorSpace ContentColorSpace = EColorSpace::REC_709; - EDisplayCurve OutputDisplayCurve = EDisplayCurve::sRGB; - float DisplayReferenceBrightnessLevel = 200.0f; - int ToggleGammaCorrection = 1; - float UIHDRBrightness = 1.0f; - }; - struct FBlurParams // Gaussian Blur Pass - { - int iImageSizeX; - int iImageSizeY; - }; - struct FVizualizationParams - { - int iDrawMode = 0; - int iUnpackNormals = 0; - float fInputStrength = 100.0f; - }; -#if !DISABLE_FIDELITYFX_CAS - struct FFFXCAS - { - float CASSharpen = 0.8f; - FFFXCAS() = default; - FFFXCAS(const FFFXCAS& other) : CASSharpen(other.CASSharpen) { memcpy(CASConstantBlock, other.CASConstantBlock, sizeof(CASConstantBlock)); } - void UpdateCASConstantBlock(uint InputWidth, uint InputHeight, uint OutputWidth, uint OutputHeight); - - unsigned CASConstantBlock[8]; - }; -#endif - struct FFSR1_EASU - { - void UpdateEASUConstantBlock(uint InputWidth, uint InputHeight, - uint InputContainerWidth, uint InputContainerHeight, - uint OutputWidth, uint OutputHeight); - - unsigned EASUConstantBlock[16]; - }; - struct FFSR1_RCAS - { - float GetLinearSharpness() const; - void SetLinearSharpness(float Sharpness); - void UpdateRCASConstantBlock(); - - unsigned RCASConstantBlock[4]; - float RCASSharpnessStops = 0.2f; - }; - - using AMD_FSR1_Preset = AMD_FidelityFX_SuperResolution1::EPreset; - - //------------------------------------------------------------------------------------------- - //------------------------------------------------------------------------------------------- - //------------------------------------------------------------------------------------------- -#if !DISABLE_FIDELITYFX_CAS - inline bool IsFFXCASEnabled() const { return !this->IsFSREnabled() && this->bEnableCAS; } -#else - inline bool IsFFXCASEnabled() const { return false; } -#endif - inline bool IsFSREnabled() const { return UpscalingAlgorithm == EUpscalingAlgorithm::FIDELITYFX_SUPER_RESOLUTION1; } - - int SceneRTWidth = 0; - int SceneRTHeight = 0; - int DisplayResolutionWidth = 0; - int DisplayResolutionHeight = 0; - - FTonemapper TonemapperParams = {}; - FBlurParams BlurParams = {}; - - EUpscalingAlgorithm UpscalingAlgorithm = EUpscalingAlgorithm::FIDELITYFX_SUPER_RESOLUTION1; - AMD_FSR1_Preset UpscalingQualityPresetEnum = AMD_FSR1_Preset::ULTRA_QUALITY; - FFSR1_EASU FSR_EASUParams = {}; - FFSR1_RCAS FSR_RCASParams = {}; -#if !DISABLE_FIDELITYFX_CAS - FFFXCAS FFXCASParams = {}; -#endif - float ResolutionScale = 1.0f; - float Sharpness = 0.8f; - - EDrawMode DrawModeEnum = EDrawMode::LIT_AND_POSTPROCESSED; - FVizualizationParams VizParams = {}; - -#if !DISABLE_FIDELITYFX_CAS - bool bEnableCAS = false; -#endif - bool bEnableGaussianBlur = false; - - - EUpscalingAlgorithm UpscalingAlgorithmLastValue; -}; diff --git a/Source/Engine/Scene/Camera.h b/Source/Engine/Scene/Camera.h index e4ce2ffa..f38468ae 100644 --- a/Source/Engine/Scene/Camera.h +++ b/Source/Engine/Scene/Camera.h @@ -86,6 +86,7 @@ class CameraController protected: Camera* mpCamera = nullptr; }; + class FirstPersonController : public CameraController { public: @@ -99,6 +100,7 @@ class FirstPersonController : public CameraController float AngularSpeedDeg; float MoveSpeed; }; + class OrbitController : public CameraController { public: @@ -111,6 +113,7 @@ class OrbitController : public CameraController private: DirectX::XMFLOAT3 mF3LookAt; }; + enum ECameraControllerType { FIRST_PERSON = 0, @@ -177,6 +180,7 @@ class Camera // ------------------------- DirectX::XMFLOAT4X4 mMatView; // ------------------------- + std::vector> mpControllers; size_t mControllerIndex; }; diff --git a/Source/Engine/Scene/Light.cpp b/Source/Engine/Scene/Light.cpp index 48a506f5..f78eca91 100644 --- a/Source/Engine/Scene/Light.cpp +++ b/Source/Engine/Scene/Light.cpp @@ -59,7 +59,7 @@ Light::Light() : Position(XMFLOAT3(0,0,0)) , Range(1000.0f) , RotationQuaternion(Quaternion::Identity()) - , RenderScale(XMFLOAT3(0.1f,0.1f,0.1f)) + , MeshScale(XMFLOAT3(0.1f,0.1f,0.1f)) , bEnabled(true) , bCastingShadows(false) , Mobility(EMobility::DYNAMIC) diff --git a/Source/Engine/Scene/Light.h b/Source/Engine/Scene/Light.h index e19c1ef1..8d0272e1 100644 --- a/Source/Engine/Scene/Light.h +++ b/Source/Engine/Scene/Light.h @@ -112,7 +112,7 @@ struct Light DirectX::XMFLOAT3 Position; float Range; Quaternion RotationQuaternion; - DirectX::XMFLOAT3 RenderScale; + DirectX::XMFLOAT3 MeshScale; bool bEnabled; bool bCastingShadows; EMobility Mobility; diff --git a/Source/Engine/Scene/Material.cpp b/Source/Engine/Scene/Material.cpp index ee75b6ef..d564e2db 100644 --- a/Source/Engine/Scene/Material.cpp +++ b/Source/Engine/Scene/Material.cpp @@ -20,9 +20,9 @@ #include "Scene.h" #include "Renderer/Renderer.h" -int Material::GetTextureConfig() const +uint Material::GetTextureConfig() const { - int textureConfig = 0; + uint textureConfig = 0; textureConfig |= TexDiffuseMap == -1 ? 0 : (1 << 0); textureConfig |= TexNormalMap == -1 ? 0 : (1 << 1); textureConfig |= TexAmbientOcclusionMap == -1 ? 0 : (1 << 2); @@ -32,6 +32,7 @@ int Material::GetTextureConfig() const textureConfig |= TexHeightMap == -1 ? 0 : (1 << 6); textureConfig |= TexEmissiveMap == -1 ? 0 : (1 << 7); textureConfig |= TexOcclusionRoughnessMetalnessMap == -1 ? 0 : (1 << 8); + textureConfig |= bOverrideGlobalMipBias ? (1 << 31) : 0; return textureConfig; } diff --git a/Source/Engine/Scene/Material.h b/Source/Engine/Scene/Material.h index 493f15d4..833a3729 100644 --- a/Source/Engine/Scene/Material.h +++ b/Source/Engine/Scene/Material.h @@ -43,7 +43,9 @@ enum EMaterialTextureMapBindings struct alignas(16) Material { - DirectX::XMFLOAT3 diffuse = {1, 1, 1}; // 12 Bytes + // cbuffer section + //------------------------------------------------------------ + DirectX::XMFLOAT3 diffuse = { 1, 1, 1 }; // 12 Bytes float alpha = 1.0f; // 4 Bytes DirectX::XMFLOAT3 emissiveColor = { 1, 1, 1 }; // 12 Bytes float emissiveIntensity = 0.0f; // 4 Bytes @@ -51,7 +53,7 @@ struct alignas(16) Material float normalMapMipBias = 0.0f; // 4 Bytes DirectX::XMFLOAT2 tiling = { 1, 1 }; // 8 Bytes DirectX::XMFLOAT2 uv_bias = { 0, 0 }; // 8 Bytes - // Cook-Torrence BRDF + float mipMapBias = 0.0f; // 4 Bytes float roughness = 0.8f; // 4 Bytes float metalness = 0.0f; // 4 Bytes float displacement = 0.0f; // 4 Bytes @@ -67,8 +69,8 @@ struct alignas(16) Material (((uint8)ETessellationOutputTopology::TESSELLATION_OUTPUT_TRIANGLE_CW) << 4) | (((uint8)ETessellationPartitioning::FRACTIONAL_ODD) << 6); bool bWireframe = false; - uint8 padding0 = 0xDE; - uint8 padding1 = 0xAD; + bool bOverrideGlobalMipBias = false; + uint8 padding1 = 0xDE; SRV_ID SRVMaterialMaps = INVALID_ID; SRV_ID SRVHeightMap = INVALID_ID; @@ -82,7 +84,6 @@ struct alignas(16) Material TextureID TexOcclusionRoughnessMetalnessMap = INVALID_ID; TextureID TexAmbientOcclusionMap = INVALID_ID; TextureID TexHeightMap = INVALID_ID; - TextureID padding2 = INVALID_ID; // to align TessellationData w/ a cache line VQ_SHADER_DATA::TessellationParams TessellationData; inline bool IsTessellationEnabled() const { return PackedTessellationConfig & 0x1; } @@ -123,10 +124,10 @@ struct alignas(16) Material // at the end of MaterialData for encoding the texture configuration. const size_t BytesToCopy = sizeof(VQ_SHADER_DATA::MaterialData);// -sizeof(float); memcpy(&data, this, BytesToCopy); - data.textureConfig = static_cast(GetTextureConfig()); + data.textureConfig = GetTextureConfig(); } - int GetTextureConfig() const; + uint GetTextureConfig() const; bool IsTransparent(const VQRenderer& mRenderer) const; bool IsAlphaMasked(const VQRenderer& mRenderer) const; diff --git a/Source/Engine/Scene/Scene.cpp b/Source/Engine/Scene/Scene.cpp index 7c82dca8..aba18bc9 100644 --- a/Source/Engine/Scene/Scene.cpp +++ b/Source/Engine/Scene/Scene.cpp @@ -523,7 +523,7 @@ void Scene::PreUpdate(int FRAME_DATA_INDEX, int FRAME_DATA_PREV_INDEX) for (size_t Handle : mTransformHandles) { Transform* pTF = mGameObjectTransformPool.Get(Handle); - pTF->_positionPrev = pTF->_position; + pTF->UpdateHistory(); } } } @@ -540,6 +540,7 @@ void Scene::Update(float dt, int FRAME_DATA_INDEX) Cam.Update(dt, mInput); this->HandleInput(SceneView); this->UpdateScene(dt, SceneView); + SceneView.DeltaTimeInSeconds = dt; } static void ExtractSceneView(FSceneView& SceneView, std::unordered_map& mViewProjectionMatrixHistory, const Camera& cam, std::pair cubeVBIB) @@ -565,7 +566,7 @@ static void ExtractSceneView(FSceneView& SceneView, std::unordered_mapmMeshes.at(EBuiltInMeshes::CUBE).GetIABufferIDs()); SceneView.pEnvironmentMapMesh = &mMeshes.at((MeshID)EBuiltInMeshes::CUBE); - SceneView.NumGameObjectBBRenderCmds = (uint)(SceneView.sceneRenderOptions.bDrawGameObjectBoundingBoxes ? DIV_AND_ROUND_UP(mBoundingBoxHierarchy.mGameObjectBoundingBoxes.size(), MAX_INSTANCE_COUNT__UNLIT_SHADER) : 0); - SceneView.NumMeshBBRenderCmds = (uint)(SceneView.sceneRenderOptions.bDrawMeshBoundingBoxes ? DIV_AND_ROUND_UP(mBoundingBoxHierarchy.mMeshBoundingBoxes.size() , MAX_INSTANCE_COUNT__UNLIT_SHADER) : 0); + SceneView.NumGameObjectBBRenderCmds = (uint)(SceneView.sceneRenderOptions.Debug.bDrawGameObjectBoundingBoxes ? DIV_AND_ROUND_UP(mBoundingBoxHierarchy.mGameObjectBoundingBoxes.size(), MAX_INSTANCE_COUNT__UNLIT_SHADER) : 0); + SceneView.NumMeshBBRenderCmds = (uint)(SceneView.sceneRenderOptions.Debug.bDrawMeshBoundingBoxes ? DIV_AND_ROUND_UP(mBoundingBoxHierarchy.mMeshBoundingBoxes.size() , MAX_INSTANCE_COUNT__UNLIT_SHADER) : 0); SceneView.pGameObjectBoundingBoxList = &mBoundingBoxHierarchy.mGameObjectBoundingBoxes; SceneView.pMeshBoundingBoxList = &mBoundingBoxHierarchy.mMeshBoundingBoxes; @@ -804,7 +805,13 @@ void Scene::PostUpdate(ThreadPool& UpdateWorkerThreadPool, const FUIState& UISta FSceneDrawData& DrawData = mRenderer.GetSceneDrawData(FRAME_DATA_INDEX); GatherLightMeshRenderData(SceneView); - GatherOutlineMeshRenderData(DrawData.outlineRenderParams, mSelectedObjects, this, SceneView.view, SceneView.proj, SceneView.sceneRenderOptions.OutlineColor); + GatherOutlineMeshRenderData(DrawData.outlineRenderParams, + mSelectedObjects, + this, + SceneView.view, + SceneView.proj, + XMFLOAT4(Settings.Editor.OutlineColor) + ); if (UIState.bDrawLightVolume) { @@ -820,7 +827,7 @@ void Scene::PostUpdate(ThreadPool& UpdateWorkerThreadPool, const FUIState& UISta } } - if (SceneView.sceneRenderOptions.bDrawVertexLocalAxes) + if (SceneView.sceneRenderOptions.Debug.bDrawVertexLocalAxes) { CollectDebugVertexDrawParams(DrawData, mSelectedObjects, this, mModels, mMeshes, cam); } @@ -851,22 +858,6 @@ const FSceneShadowViews& Scene::GetShadowView(int FRAME_DATA_INDEX) const return mFrameShadowViews[0]; #endif } -FPostProcessParameters& Scene::GetPostProcessParameters(int FRAME_DATA_INDEX) -{ -#if VQENGINE_MT_PIPELINED_UPDATE_AND_RENDER_THREADS - return mFrameSceneViews[FRAME_DATA_INDEX].postProcessParameters; -#else - return mFrameSceneViews[0].postProcessParameters; -#endif -} -const FPostProcessParameters& Scene::GetPostProcessParameters(int FRAME_DATA_INDEX) const -{ -#if VQENGINE_MT_PIPELINED_UPDATE_AND_RENDER_THREADS - return mFrameSceneViews[FRAME_DATA_INDEX].postProcessParameters; -#else - return mFrameSceneViews[0].postProcessParameters; -#endif -} void Scene::RenderUI(FUIState& UIState, uint32_t W, uint32_t H) @@ -897,12 +888,12 @@ void Scene::HandleInput(FSceneView& SceneView) } if (mInput.IsKeyTriggered("L")) { - ToggleBool(SceneView.sceneRenderOptions.bDrawLightBounds); + ToggleBool(SceneView.sceneRenderOptions.Debug.bDrawLightBounds); } if (mInput.IsKeyTriggered("N")) { - if(bIsShiftDown) ToggleBool(SceneView.sceneRenderOptions.bDrawGameObjectBoundingBoxes); - else ToggleBool(SceneView.sceneRenderOptions.bDrawMeshBoundingBoxes); + if(bIsShiftDown) ToggleBool(SceneView.sceneRenderOptions.Debug.bDrawGameObjectBoundingBoxes); + else ToggleBool(SceneView.sceneRenderOptions.Debug.bDrawMeshBoundingBoxes); } @@ -1171,7 +1162,7 @@ void Scene::GatherFrustumCullParameters(FSceneView& SceneView, FSceneShadowViews { mFrustumCullWorkerContext.vBoundingBoxList = BVH.mMeshBoundingBoxes; - const bool bForceLOD0_ShadowView = SceneView.sceneRenderOptions.bForceLOD0_ShadowView; + const bool bForceLOD0_ShadowView = SceneView.sceneRenderOptions.Debug.bForceLOD0_ShadowView; std::function fnShadowViewSort = [](const FVisibleMeshSortData& l, const FVisibleMeshSortData& r) { return MeshSorting::GetShadowMeshKey(l.matID, l.meshID, l.iLOD, l.bTess) > MeshSorting::GetShadowMeshKey(r.matID, r.meshID, r.iLOD, r.bTess); @@ -1216,7 +1207,7 @@ void Scene::GatherFrustumCullParameters(FSceneView& SceneView, FSceneShadowViews // main view SCOPED_CPU_MARKER(fnMark("InitWorkerContexts", vRanges[0].first, vRanges[0].second).c_str()); - const bool bForceLOD0 = SceneView.sceneRenderOptions.bForceLOD0_SceneView; + const bool bForceLOD0 = SceneView.sceneRenderOptions.Debug.bForceLOD0_SceneView; std::function fnMainViewSort = [](const FVisibleMeshSortData& l, const FVisibleMeshSortData& r) { return MeshSorting::GetLitMeshKey(l.matID, l.meshID, l.iLOD, l.bTess) > MeshSorting::GetLitMeshKey(r.matID, r.meshID, r.iLOD, r.bTess); @@ -1388,13 +1379,13 @@ void Scene::GatherLightMeshRenderData(const FSceneView& SceneView) const SceneDrawData.lightBoundsRenderParams.clear(); SceneDrawData.lightRenderParams.clear(); - if (SceneView.sceneRenderOptions.bDrawLightMeshes) + if (SceneView.sceneRenderOptions.Debug.bDrawLightMeshes) { ::GatherLightMeshRenderData(mLightsStatic , SceneDrawData.lightRenderParams, SceneView.cameraPosition, this); ::GatherLightMeshRenderData(mLightsDynamic , SceneDrawData.lightRenderParams, SceneView.cameraPosition, this); ::GatherLightMeshRenderData(mLightsStationary, SceneDrawData.lightRenderParams, SceneView.cameraPosition, this); } - if (SceneView.sceneRenderOptions.bDrawLightBounds) + if (SceneView.sceneRenderOptions.Debug.bDrawLightBounds) { ::GatherLightBoundsRenderData(mLightsStatic , SceneDrawData.lightBoundsRenderParams, SceneView.cameraPosition, this); ::GatherLightBoundsRenderData(mLightsDynamic , SceneDrawData.lightBoundsRenderParams, SceneView.cameraPosition, this); diff --git a/Source/Engine/Scene/Scene.h b/Source/Engine/Scene/Scene.h index 2b17edab..8f0d1a59 100644 --- a/Source/Engine/Scene/Scene.h +++ b/Source/Engine/Scene/Scene.h @@ -26,7 +26,6 @@ #include "../Core/Memory.h" #include "../AssetLoader.h" -#include "../PostProcess/PostProcess.h" #include @@ -127,7 +126,7 @@ class Scene private: // Derived Scenes shouldn't access these functions void PreUpdate(int FRAME_DATA_INDEX, int FRAME_DATA_PREV_INDEX); void Update(float dt, int FRAME_DATA_INDEX = 0); - void PostUpdate(ThreadPool& UpdateWorkerThreadPool, const FUIState& UIState, bool bAppInSimulationState, int FRAME_DATA_INDEX = 0); + void PostUpdate(ThreadPool& UpdateWorkerThreadPool, const FUIState& UIState, bool bAppInSimulationState, const FEngineSettings& Settings, int FRAME_DATA_INDEX = 0); void StartLoading(FSceneRepresentation& scene, ThreadPool& UpdateWorkerThreadPool); void OnLoadComplete(const BuiltinMeshArray_t& builtinMeshes); @@ -156,7 +155,6 @@ class Scene void LoadSceneMaterials(const std::vector& Materials, TaskID taskID); void LoadLights(const std::vector& SceneLights); void LoadCameras(std::vector& CameraParams); - void LoadPostProcessSettings(); void CalculateGameObjectLocalSpaceBoundingBoxes(); @@ -172,8 +170,6 @@ class Scene FSceneView& GetSceneView (int FRAME_DATA_INDEX); const FSceneView& GetSceneView (int FRAME_DATA_INDEX) const; const FSceneShadowViews& GetShadowView(int FRAME_DATA_INDEX) const; - FPostProcessParameters& GetPostProcessParameters(int FRAME_DATA_INDEX); - const FPostProcessParameters& GetPostProcessParameters(int FRAME_DATA_INDEX) const ; inline const Camera& GetActiveCamera() const { return mCameras[mIndex_SelectedCamera]; } inline Camera& GetActiveCamera() { return mCameras[mIndex_SelectedCamera]; } diff --git a/Source/Engine/Scene/SceneLoading.cpp b/Source/Engine/Scene/SceneLoading.cpp index 1de33af6..be28f70c 100644 --- a/Source/Engine/Scene/SceneLoading.cpp +++ b/Source/Engine/Scene/SceneLoading.cpp @@ -117,7 +117,6 @@ void Scene::StartLoading(FSceneRepresentation& sceneRep, ThreadPool& UpdateWorke LoadLights(sceneRep.Lights); LoadCameras(sceneRep.Cameras); - LoadPostProcessSettings(); { SCOPED_CPU_MARKER("ClearHistoryData"); @@ -417,37 +416,6 @@ void Scene::LoadCameras(std::vector& CameraParams) Log::Info("[Scene] Cameras initialized"); } -void Scene::LoadPostProcessSettings(/*TODO: scene PP settings*/) -{ - SCOPED_CPU_MARKER("Scene::LoadPostProcessSettings()"); - - const uint fWidth = this->mpWindow->GetWidth(); - const uint fHeight = this->mpWindow->GetHeight(); - - // Update PostProcess Data - for (size_t i = 0; i < mFrameSceneViews.size(); ++i) - { - FPostProcessParameters& PPParams = this->GetPostProcessParameters(static_cast(i)); - - // Update FidelityFX constant blocks -#if !DISABLE_FIDELITYFX_CAS - PPParams.bEnableCAS = true; // TODO: read from scene PP settings - if (PPParams.IsFFXCASEnabled()) - { - PPParams.FFXCASParams.UpdateCASConstantBlock(fWidth, fHeight, fWidth, fHeight); - } -#endif - - if (PPParams.IsFSREnabled()) - { - const uint InputWidth = static_cast (PPParams.ResolutionScale * fWidth); - const uint InputHeight = static_cast(PPParams.ResolutionScale * fHeight); - PPParams.FSR_EASUParams.UpdateEASUConstantBlock(InputWidth, InputHeight, InputWidth, InputHeight, fWidth, fHeight); - PPParams.FSR_RCASParams.UpdateRCASConstantBlock(); - } - } -} - void Scene::OnLoadComplete(const BuiltinMeshArray_t& builtinMeshes) { SCOPED_CPU_MARKER("Scene.OnLoadComplete"); diff --git a/Source/Engine/Scene/SceneViews.h b/Source/Engine/Scene/SceneViews.h index 8844c3b9..26799df5 100644 --- a/Source/Engine/Scene/SceneViews.h +++ b/Source/Engine/Scene/SceneViews.h @@ -21,7 +21,6 @@ #include "Material.h" #include "Model.h" #include "Transform.h" -#include "Engine/PostProcess/PostProcess.h" #include "Libs/VQUtils/Include/Multithreading/TaskSignal.h" #include "Engine/Core/Memory.h" @@ -34,21 +33,8 @@ struct Transform; class Scene; -struct FSceneRenderOptions +struct FRenderDebugOptions { - struct FFFX_SSSR_UIOptions - { - bool bEnableTemporalVarianceGuidedTracing = true; - int maxTraversalIterations = 128; - int mostDetailedDepthHierarchyMipLevel = 0; - int minTraversalOccupancy = 4; - float depthBufferThickness = 0.45f; - float roughnessThreshold = 0.2f; - float temporalStability = 0.25f; - float temporalVarianceThreshold = 0.0f; - int samplesPerQuad = 1; - }; - bool bForceLOD0_ShadowView = false; bool bForceLOD0_SceneView = false; bool bDrawLightBounds = false; @@ -56,13 +42,53 @@ struct FSceneRenderOptions bool bDrawGameObjectBoundingBoxes = false; bool bDrawLightMeshes = true; bool bDrawVertexLocalAxes = false; - float fVertexLocalAxixSize = 1.0f; - float fYawSliderValue = 0.0f; + float fVertexLocalAxisSize = 1.0f; + + struct FMagnifierOptions + { + bool bEnable = false; + float fMagnifierScreenRadius = 0.35f; + float fMagnificationAmount = 6.0f; + + int ScreenOffsetX = 0; + int ScreenOffsetY = 0; + + // lock + bool bLockPosition = false; + bool bLockPositionHistory = false; + int LockedScreenPositionX = 0; + int LockedScreenPositionY = 0; + float BorderColorLocked[3] = { 0.002f, 0.52f, 0.0f }; // G + float BorderColorFree[3] = { 0.72f, 0.002f, 0.0f }; // R + inline void GetBorderColor(float* pOut) const { memcpy(pOut, bLockPosition ? BorderColorLocked : BorderColorFree, sizeof(float) * 3); } + inline void ToggleLock(int MousePosX, int MousePosY) + { + if (!bEnable) + return; + bLockPositionHistory = bLockPosition; // record histroy + bLockPosition = !bLockPosition; // flip state + const bool bLockSwitchedOn = !this->bLockPositionHistory && bLockPosition; + const bool bLockSwitchedOff = this->bLockPositionHistory && !bLockPosition; + if (bLockSwitchedOn) + { + LockedScreenPositionX = MousePosX; + LockedScreenPositionY = MousePosY; + } + } + } Magnifier; +}; +struct FSceneLightingOptions +{ + float fYawSliderValue = 0.0f; // env map float fAmbientLightingFactor = 0.055f; bool bScreenSpaceAO = true; - FFFX_SSSR_UIOptions FFX_SSSRParameters = {}; - DirectX::XMFLOAT4 OutlineColor = DirectX::XMFLOAT4(1.0f, 0.647f, 0.1f, 1.0f); }; +struct FSceneRenderOptions // these options directly affect scene data gathering +{ + FRenderDebugOptions Debug; + FSceneLightingOptions Lighting; +}; + struct FVisibleMeshSortData { @@ -157,8 +183,7 @@ struct FSceneView float HDRIYawOffset = 0.0f; DirectX::XMMATRIX EnvironmentMapViewProj; const Mesh* pEnvironmentMapMesh = nullptr; - int SceneRTWidth = 0; - int SceneRTHeight = 0; + float DeltaTimeInSeconds = 0.0f; uint NumGameObjectBBRenderCmds = 0; uint NumMeshBBRenderCmds = 0; @@ -173,11 +198,11 @@ struct FSceneView // Culled frustums are not removed from the vector so we track the active ones here uint NumActiveFrustumRenderLists = 0; - VQ_SHADER_DATA::SceneLighting GPULightingData; FSceneRenderOptions sceneRenderOptions; - FPostProcessParameters postProcessParameters; + int iMousePosX = 0; + int iMousePosY = 0; }; struct FSceneDebugView diff --git a/Source/Engine/Scene/Transform.cpp b/Source/Engine/Scene/Transform.cpp index e22727c6..3bc3a3ec 100644 --- a/Source/Engine/Scene/Transform.cpp +++ b/Source/Engine/Scene/Transform.cpp @@ -18,6 +18,7 @@ #include "Transform.h" +#include using namespace DirectX; @@ -26,16 +27,15 @@ Transform::Transform(const XMFLOAT3& position, const Quaternion& rotation, const , _rotation(rotation) , _scale(scale) , _positionPrev(position) + , _rotationPrev(rotation) + , _scalePrev(scale) {} Transform::~Transform() {} Transform & Transform::operator=(const Transform & t) { - this->_positionPrev = t._positionPrev; - this->_position = t._position; - this->_rotation = t._rotation; - this->_scale = t._scale; + memcpy(this, &t, sizeof(Transform)); return *this; } @@ -87,10 +87,10 @@ XMMATRIX Transform::matWorldTransformation() const DirectX::XMMATRIX Transform::matWorldTransformationPrev() const { - XMVECTOR scale = XMLoadFloat3(&_scale); + XMVECTOR scale = XMLoadFloat3(&_scalePrev); XMVECTOR translation = XMLoadFloat3(&_positionPrev); - const Quaternion& Q = _rotation; + const Quaternion& Q = _rotationPrev; XMVECTOR rotation = XMVectorSet(Q.V.x, Q.V.y, Q.V.z, Q.S); XMVECTOR rotOrigin = XMVectorZero(); return XMMatrixAffineTransformation(scale, rotOrigin, rotation, translation); diff --git a/Source/Engine/Scene/Transform.h b/Source/Engine/Scene/Transform.h index 87b527af..141580c4 100644 --- a/Source/Engine/Scene/Transform.h +++ b/Source/Engine/Scene/Transform.h @@ -88,12 +88,22 @@ struct Transform // and using inverse-transpose of rotation/scale matrix static DirectX::XMMATRIX NormalMatrix(const DirectX::XMMATRIX& world); + inline void UpdateHistory() + { + _rotationPrev = _rotation; + _positionPrev = _position; + _scalePrev = _scale; + } + //---------------------------------------------------------------------------------------------------------------- // DATA //---------------------------------------------------------------------------------------------------------------- Quaternion _rotation; DirectX::XMFLOAT3 _position; DirectX::XMFLOAT3 _scale; + + Quaternion _rotationPrev; DirectX::XMFLOAT3 _positionPrev; + DirectX::XMFLOAT3 _scalePrev; }; diff --git a/Source/Engine/Settings.h b/Source/Engine/Settings.h index c4aecbbb..999cbf2b 100644 --- a/Source/Engine/Settings.h +++ b/Source/Engine/Settings.h @@ -18,7 +18,14 @@ #pragma once -enum EDisplayMode +#include "Renderer/Rendering/PostProcess/Upscaling.h" + +// --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +// +// GRAPHICS SETTINGS +// +// --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +enum EDisplayMode : unsigned char { WINDOWED = 0, BORDERLESS_FULLSCREEN, @@ -26,8 +33,7 @@ enum EDisplayMode NUM_DISPLAY_MODES }; - -enum EReflections +enum EReflections : unsigned char { REFLECTIONS_OFF, SCREEN_SPACE_REFLECTIONS__FFX, @@ -35,23 +41,149 @@ enum EReflections NUM_REFLECTION_SETTINGS }; +enum EUpscalingAlgorithm : int +{ + NONE = 0, + FIDELITYFX_SUPER_RESOLUTION_1, + FIDELITYFX_SUPER_RESOLUTION_3, -struct FGraphicsSettings + NUM_UPSCALING_ALGORITHMS +}; +enum ESharpeningAlgorithm : int +{ + NO_SHARPENING = 0, + FIDELITY_FX_CAS, + FIDELITY_FX_RCAS, + + NUM_SHARPENING_ALGORITHMS +}; +enum EAntiAliasingAlgorithm : int +{ + NO_ANTI_ALIASING = 0, + MSAA4, + FSR3_ANTI_ALIASING, + + NUM_ANTI_ALIASING_ALGORITHMS +}; + +struct FDisplaySettings { - bool bVsync = false; + unsigned short DisplayResolutionX = 1600; + unsigned short DisplayResolutionY = 900; + bool bVsync = false; bool bUseTripleBuffering = false; - bool bAntiAliasing = false; +}; +struct FPostProcessingSettings +{ + // typedefs & structs + using AMD_FSR1_Preset = AMD_FidelityFX_SuperResolution1::EPreset; + using AMD_FSR3_Preset = AMD_FidelityFX_SuperResolution3::EPreset; + + struct FFSR3Settings + { + bool bGenerateReactivityMask = false; + float GeneratedReactiveMaskScale = 1.0f; + float GeneratedReactiveMaskCutoffThreshold = 0.0f; + float GeneratedReactiveMaskBinaryValue = 0.0f; + }; + + // upscaling + EUpscalingAlgorithm UpscalingAlgorithm = EUpscalingAlgorithm::FIDELITYFX_SUPER_RESOLUTION_3; + AMD_FSR1_Preset FSR1UpscalingQualityEnum = AMD_FSR1_Preset::ULTRA_QUALITY; + AMD_FSR3_Preset FSR3UpscalingQualityEnum = AMD_FSR3_Preset::NATIVE_AA; + ESharpeningAlgorithm SharpeningAlgorithm = ESharpeningAlgorithm::FIDELITY_FX_RCAS; + FFSR3Settings FSR3Settings; + + // sharpening + float Sharpness = 0.8f; + + // blur + bool EnableGaussianBlur = false; + + // tonemap + float UIHDRBrightness = 1.0f; + float DisplayReferenceBrightnessLevel = 200.0f; + EColorSpace ContentColorSpace = EColorSpace::REC_709; + EDisplayCurve SDROutputDisplayCurve = EDisplayCurve::sRGB; + EDisplayCurve HDROutputDisplayCurve = EDisplayCurve::Linear; + bool EnableGammaCorrection = true; +}; +struct FDebugVisualizationSettings +{ + enum class EDrawMode : int + { + LIT_AND_POSTPROCESSED = 0, + //WIREFRAME, // TODO: add support + //NO_MATERIALS, // TODO: add support + + DEPTH, + NORMALS, + ROUGHNESS, + METALLIC, + AO, + ALBEDO, + REFLECTIONS, + MOTION_VECTORS, + + NUM_DRAW_MODES, + }; + + EDrawMode DrawModeEnum = EDrawMode::LIT_AND_POSTPROCESSED; + bool bUnpackNormals = false; + float fInputStrength = 100.0f; +}; +struct FRenderingSettings +{ + struct FFFX_SSSR_Options + { + bool bEnableTemporalVarianceGuidedTracing = true; + int MaxTraversalIterations = 128; + int MostDetailedDepthHierarchyMipLevel = 0; + int MinTraversalOccupancy = 4; + float DepthBufferThickness = 0.45f; + float RoughnessThreshold = 0.2f; + float TemporalStability = 0.25f; + float TemporalVarianceThreshold = 0.0f; + int SamplesPerQuad = 1; + }; + + EAntiAliasingAlgorithm AntiAliasing = EAntiAliasingAlgorithm::MSAA4; EReflections Reflections = EReflections::REFLECTIONS_OFF; + FFFX_SSSR_Options FFX_SSSR_Options; + float RenderResolutionScale = 1.0f; + float GlobalMipBias = 0.0f; + short MaxFrameRate = -1; // -1: Auto (RefreshRate x 1.15) | 0: Unlimited | : specified value + short EnvironmentMapResolution = 256; + +}; - float RenderScale = 1.0f; - int MaxFrameRate = -1; // -1: Auto (RefreshRate x 1.15) | 0: Unlimited | : specified value - int EnvironmentMapResolution = 256; +struct FGraphicsSettings +{ + FDisplaySettings Display; + FRenderingSettings Rendering; + FPostProcessingSettings PostProcessing; + FDebugVisualizationSettings DebugVizualization; + // command recording bool bEnableAsyncCopy = true; bool bEnableAsyncCompute = true; bool bUseSeparateSubmissionQueue = true; + + // ===================================================================================================================== + + inline bool IsFSR1Enabled() const { return PostProcessing.UpscalingAlgorithm == EUpscalingAlgorithm::FIDELITYFX_SUPER_RESOLUTION_1; } + inline bool IsFSR3Enabled() const { return PostProcessing.UpscalingAlgorithm == EUpscalingAlgorithm::FIDELITYFX_SUPER_RESOLUTION_3; } + inline bool IsFFXCASEnabled() const { return false; } // TODO: handle RCAS (FSR1) vs CAS + inline float GetRenderResolutionX() const { return Rendering.RenderResolutionScale * Display.DisplayResolutionX; } + inline float GetRenderResolutionY() const { return Rendering.RenderResolutionScale * Display.DisplayResolutionY; } + void Validate(); }; - + +// --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +// +// WINDOW SETTINGS +// +// --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- struct FWindowSettings { int Width = -1; @@ -64,9 +196,19 @@ struct FWindowSettings inline bool IsDisplayModeFullscreen() const { return DisplayMode == EDisplayMode::EXCLUSIVE_FULLSCREEN || DisplayMode == EDisplayMode::BORDERLESS_FULLSCREEN; } }; +// --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +// +// ENGINE SETTINGS +// +// --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +struct FEditorSettings +{ + float OutlineColor[4] = { 1.0f, 0.647f, 0.1f, 1.0f }; +}; struct FEngineSettings { FGraphicsSettings gfx; + FEditorSettings Editor; FWindowSettings WndMain; FWindowSettings WndDebug; diff --git a/Source/Engine/UI/VQUI.cpp b/Source/Engine/UI/VQUI.cpp index 07b3397d..dc691339 100644 --- a/Source/Engine/UI/VQUI.cpp +++ b/Source/Engine/UI/VQUI.cpp @@ -91,7 +91,8 @@ static void UpdateImGUIState(HWND hwnd) static const char* szAALabels[] = { "None ##0" - , "MSAAx4" + , "MSAA x4" + , "FidelityFX Super Resolution 3 AA" , "" }; static const char* szSSAOLabels[] = @@ -139,40 +140,6 @@ static constexpr float MAGNIFICATION_AMOUNT_MIN = 1.0f; static constexpr float MAGNIFICATION_AMOUNT_MAX = 32.0f; static constexpr float MAGNIFIER_RADIUS_MIN = 0.01f; static constexpr float MAGNIFIER_RADIUS_MAX = 0.85f; -void FMagnifierUIState::ToggleMagnifierLock() -{ - if (this->bUseMagnifier) - { - this->bLockMagnifierPositionHistory = this->bLockMagnifierPosition; // record histroy - this->bLockMagnifierPosition = !this->bLockMagnifierPosition; // flip state - const bool bLockSwitchedOn = !this->bLockMagnifierPositionHistory && this->bLockMagnifierPosition; - const bool bLockSwitchedOff = this->bLockMagnifierPositionHistory && !this->bLockMagnifierPosition; - if (bLockSwitchedOn) - { - const ImGuiIO& io = ImGui::GetIO(); - this->LockedMagnifiedScreenPositionX = static_cast(io.MousePos.x); - this->LockedMagnifiedScreenPositionY = static_cast(io.MousePos.y); - for (int ch = 0; ch < 3; ++ch) this->pMagnifierParams->fBorderColorRGB[ch] = MAGNIFIER_BORDER_COLOR__LOCKED[ch]; - } - else if (bLockSwitchedOff) - { - for (int ch = 0; ch < 3; ++ch) this->pMagnifierParams->fBorderColorRGB[ch] = MAGNIFIER_BORDER_COLOR__FREE[ch]; - } - } -} - -template static T clamped(const T& v, const T& min, const T& max) -{ - if (v < min) return min; - else if (v > max) return max; - else return v; -} -// These are currently not bound to any mouse input and are here for convenience/reference. -// Mouse scroll is currently wired up to camera for panning and moving in the local Z direction. -// Any application that would prefer otherwise can utilize these for easily controlling the magnifier parameters through the desired input. -void FMagnifierUIState::AdjustMagnifierSize(float increment /*= 0.05f*/) { pMagnifierParams->fMagnifierScreenRadius = clamped(pMagnifierParams->fMagnifierScreenRadius + increment, MAGNIFIER_RADIUS_MIN, MAGNIFIER_RADIUS_MAX); } -void FMagnifierUIState::AdjustMagnifierMagnification(float increment /*= 1.00f*/) { pMagnifierParams->fMagnificationAmount = clamped(pMagnifierParams->fMagnificationAmount + increment, MAGNIFICATION_AMOUNT_MIN, MAGNIFICATION_AMOUNT_MAX); } - // ----------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------- @@ -193,13 +160,6 @@ static void InitializeEngineUIState(FUIState& s) for (int i = 0; i < FUIState::EEditorMode::NUM_EDITOR_MODES; ++i) s.SelectedEditeeIndex[i] = 0; - - // couldn't bother using smart pointers due to inlined default destructors. - // There's never a smooth way to work with them -- either too verbose or breaks compilation. - // Raw ptrs will do for now - - s.mpMagnifierState = std::make_unique(); - s.mpMagnifierState->pMagnifierParams = std::make_unique(); } void FUIState::GetMouseScreenPosition(int& X, int& Y) const @@ -262,6 +222,7 @@ void VQEngine::InitializeUI(HWND hwnd) SamplerDesc.RegisterSpace = 0; SamplerDesc.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; + mUIState.ResolutionScaleSliderValue = mSettings.gfx.Rendering.RenderResolutionScale; InitializeEngineUIState(mUIState); mpRenderer->WaitHeapsInitialized(); @@ -288,8 +249,6 @@ void VQEngine::UpdateUIState(HWND hwnd, float dt) // TODO: remove this hack, properly sync if (!mpScene) return; - - FPostProcessParameters& PPParams = mpScene->GetPostProcessParameters(FRAME_DATA_INDEX); FSceneRenderOptions& SceneParams = mpScene->GetSceneView(FRAME_DATA_INDEX).sceneRenderOptions; ImGuiStyle& style = ImGui::GetStyle(); @@ -304,8 +263,8 @@ void VQEngine::UpdateUIState(HWND hwnd, float dt) { if (mUIState.bWindowVisible_KeyMappings) DrawKeyMappingsWindow(); if (mUIState.bWindowVisible_SceneControls) DrawSceneControlsWindow(mpScene->GetActiveCameraIndex(), mpScene->GetActiveEnvironmentMapPresetIndex(), SceneParams); - if (mUIState.bWindowVisible_Profiler) DrawProfilerWindow(mpScene->GetSceneRenderStats(FRAME_DATA_INDEX), dt); - if (mUIState.bWindowVisible_GraphicsSettingsPanel) DrawGraphicsSettingsWindow(SceneParams, PPParams); + if (mUIState.bWindowVisible_Profiler) DrawProfilerWindow(mpScene->GetSceneRenderStats(FRAME_DATA_INDEX), mSettings.gfx.Rendering.RenderResolutionScale, dt); + if (mUIState.bWindowVisible_GraphicsSettingsPanel) DrawGraphicsSettingsWindow(SceneParams); if (mUIState.bWindowVisible_Editor) DrawEditorWindow(); } @@ -358,14 +317,14 @@ const ImVec4 UI_COLLAPSING_HEADER_COLOR_VALUE = ImVec4(0.0, 0.00, 0.0, 0.7f) constexpr size_t NUM_MAX_ENV_MAP_NAMES = 10; constexpr size_t NUM_MAX_LEVEL_NAMES = 8; constexpr size_t NUM_MAX_CAMERA_NAMES = 10; -constexpr size_t NUM_MAX_DRAW_MODE_NAMES = static_cast(EDrawMode::NUM_DRAW_MODES); -constexpr size_t NUM_MAX_FSR_OPTION_NAMES = AMD_FidelityFX_SuperResolution1::EPreset::NUM_FSR1_PRESET_OPTIONS; +constexpr size_t NUM_MAX_DRAW_MODE_NAMES = static_cast(FDebugVisualizationSettings::EDrawMode::NUM_DRAW_MODES); static const char* szSceneNames [NUM_MAX_LEVEL_NAMES ] = {}; static const char* szEnvMapNames[NUM_MAX_ENV_MAP_NAMES] = {}; static const char* szCameraNames[NUM_MAX_CAMERA_NAMES] = {}; static const char* szDrawModes [NUM_MAX_DRAW_MODE_NAMES] = {}; -static const char* szUpscalingLabels[FPostProcessParameters::EUpscalingAlgorithm::NUM_UPSCALING_ALGORITHMS] = {}; -static const char* szUpscalingQualityLabels[NUM_MAX_FSR_OPTION_NAMES] = {}; +static const char* szUpscalingLabels[EUpscalingAlgorithm::NUM_UPSCALING_ALGORITHMS] = {}; +static const char* szFSR1QualityLabels[AMD_FidelityFX_SuperResolution1::EPreset::NUM_FSR1_PRESET_OPTIONS] = {}; +static const char* szFSR3QualityLabels[AMD_FidelityFX_SuperResolution3::EPreset::NUM_FSR3_PRESET_OPTIONS] = {}; static const char* szMaxFrameRateOptionLabels[3] = {}; // see Settings.h:FGraphicsSettings @@ -416,15 +375,22 @@ static void InitializeStaticCStringData_PostProcessingControls() if (!bPostPRocessLabelsInitialized) { - using namespace AMD_FidelityFX_SuperResolution1; - szUpscalingQualityLabels[EPreset::ULTRA_QUALITY] = "Ultra Quality"; - szUpscalingQualityLabels[EPreset::QUALITY] = "Quality"; - szUpscalingQualityLabels[EPreset::BALANCED] = "Balanced"; - szUpscalingQualityLabels[EPreset::PERFORMANCE] = "Performance"; - szUpscalingQualityLabels[EPreset::CUSTOM] = "Custom"; - - szUpscalingLabels[FPostProcessParameters::EUpscalingAlgorithm::NONE] = "None"; - szUpscalingLabels[FPostProcessParameters::EUpscalingAlgorithm::FIDELITYFX_SUPER_RESOLUTION1] = "AMD FSR1"; + { + using namespace AMD_FidelityFX_SuperResolution1; + szFSR1QualityLabels[EPreset::ULTRA_QUALITY] = "Ultra Quality"; + szFSR1QualityLabels[EPreset::QUALITY] = "Quality"; + szFSR1QualityLabels[EPreset::BALANCED] = "Balanced"; + szFSR1QualityLabels[EPreset::PERFORMANCE] = "Performance"; + szFSR1QualityLabels[EPreset::CUSTOM] = "Custom"; + } + { + using namespace AMD_FidelityFX_SuperResolution3; + for (EPreset p = EPreset::NATIVE_AA; p < EPreset::NUM_FSR3_PRESET_OPTIONS; p = (EPreset)((uint)p + 1)) + szFSR3QualityLabels[p] = GetPresetName(p); + } + szUpscalingLabels[EUpscalingAlgorithm::NONE] = "None"; + szUpscalingLabels[EUpscalingAlgorithm::FIDELITYFX_SUPER_RESOLUTION_1] = "AMD FidelityFX Super Resolution 1"; + szUpscalingLabels[EUpscalingAlgorithm::FIDELITYFX_SUPER_RESOLUTION_3] = "AMD FidelityFX Super Resolution 3"; bPostPRocessLabelsInitialized = true; } @@ -445,26 +411,26 @@ static void InitializeStaticCStringData_EDrawMode() static bool EDrawModeDropdownDataInitialized = false; if (!EDrawModeDropdownDataInitialized) { - auto fnToStr = [](EDrawMode m) { + auto fnToStr = [](FDebugVisualizationSettings::EDrawMode m) { switch (m) { - case EDrawMode::LIT_AND_POSTPROCESSED: return "LIT_AND_POSTPROCESSED"; - //case EDrawMode::WIREFRAME: return "WIREFRAME"; - //case EDrawMode::NO_MATERIALS: return "NO_MATERIALS"; - case EDrawMode::DEPTH: return "DEPTH"; - case EDrawMode::NORMALS: return "NORMALS"; - case EDrawMode::ROUGHNESS: return "ROUGHNESS"; - case EDrawMode::METALLIC: return "METALLIC"; - case EDrawMode::AO: return "AO"; - case EDrawMode::ALBEDO: return "ALBEDO"; - case EDrawMode::REFLECTIONS: return "REFLECTIONS"; - case EDrawMode::MOTION_VECTORS: return "MOTION_VECTORS"; - case EDrawMode::NUM_DRAW_MODES: return "NUM_DRAW_MODES"; + case FDebugVisualizationSettings::EDrawMode::LIT_AND_POSTPROCESSED: return "LIT_AND_POSTPROCESSED"; + //case FDebugVisualizationSettings::EDrawMode::WIREFRAME: return "WIREFRAME"; + //case FDebugVisualizationSettings::EDrawMode::NO_MATERIALS: return "NO_MATERIALS"; + case FDebugVisualizationSettings::EDrawMode::DEPTH: return "DEPTH"; + case FDebugVisualizationSettings::EDrawMode::NORMALS: return "NORMALS"; + case FDebugVisualizationSettings::EDrawMode::ROUGHNESS: return "ROUGHNESS"; + case FDebugVisualizationSettings::EDrawMode::METALLIC: return "METALLIC"; + case FDebugVisualizationSettings::EDrawMode::AO: return "AO"; + case FDebugVisualizationSettings::EDrawMode::ALBEDO: return "ALBEDO"; + case FDebugVisualizationSettings::EDrawMode::REFLECTIONS: return "REFLECTIONS"; + case FDebugVisualizationSettings::EDrawMode::MOTION_VECTORS: return "MOTION_VECTORS"; + case FDebugVisualizationSettings::EDrawMode::NUM_DRAW_MODES: return "NUM_DRAW_MODES"; } return ""; }; - for (int i = 0; i < (int)EDrawMode::NUM_DRAW_MODES; ++i) - szDrawModes[i] = fnToStr((EDrawMode)i); + for (int i = 0; i < (int)FDebugVisualizationSettings::EDrawMode::NUM_DRAW_MODES; ++i) + szDrawModes[i] = fnToStr((FDebugVisualizationSettings::EDrawMode)i); EDrawModeDropdownDataInitialized = true; } @@ -621,14 +587,14 @@ void VQEngine::DrawSceneControlsWindow(int& iSelectedCamera, int& iSelectedEnvMa if (iSelectedEnvMap != INVALID_ID) { - ImGui::SliderFloat("HDRI Rotation", &SceneRenderParams.fYawSliderValue, 0.0f, 1.0f); + ImGui::SliderFloat("HDRI Rotation", &SceneRenderParams.Lighting.fYawSliderValue, 0.0f, 1.0f); } const float MaxAmbientLighting = this->ShouldRenderHDR(mpWinMain->GetHWND()) ? 150.0f : 2.0f; - MathUtil::Clamp(SceneRenderParams.fAmbientLightingFactor, 0.0f, MaxAmbientLighting); - ImGui::SliderFloat("Ambient Lighting Factor", &SceneRenderParams.fAmbientLightingFactor, 0.0f, MaxAmbientLighting, "%.3f"); + MathUtil::Clamp(SceneRenderParams.Lighting.fAmbientLightingFactor, 0.0f, MaxAmbientLighting); + ImGui::SliderFloat("Ambient Lighting Factor", &SceneRenderParams.Lighting.fAmbientLightingFactor, 0.0f, MaxAmbientLighting, "%.3f"); - ImGui::ColorEdit4("Outline Color", reinterpret_cast(&SceneRenderParams.OutlineColor), ImGuiColorEditFlags_DefaultOptions_); + ImGui::ColorEdit4("Outline Color", reinterpret_cast(&mSettings.Editor.OutlineColor), ImGuiColorEditFlags_DefaultOptions_); //ImGui::ColorEdit4(); @@ -728,12 +694,14 @@ void VQEngine::DrawKeyMappingsWindow() } -void VQEngine::DrawProfilerWindow(const FSceneStats& FrameStats, float dt) +void VQEngine::DrawProfilerWindow(const FSceneStats& FrameStats, float RenderRenderResolutionScale, float dt) { const FSceneStats& s = FrameStats; // shorthand rename const uint32 W = mpWinMain->GetWidth(); const uint32 H = mpWinMain->GetHeight(); + const uint32 RenderW = W * RenderRenderResolutionScale; + const uint32 RenderH = H * RenderRenderResolutionScale; const uint32_t PROFILER_WINDOW_POS_X = W - PROFILER_WINDOW_PADDIG_X - PROFILER_WINDOW_SIZE_X; const uint32_t PROFILER_WINDOW_POS_Y = PROFILER_WINDOW_PADDIG_Y; @@ -755,8 +723,9 @@ void VQEngine::DrawProfilerWindow(const FSceneStats& FrameStats, float dt) const int fps = static_cast(1.0f / dt); const float frameTime_ms = dt * 1000.0f; const float frameTime_us = frameTime_ms * 1000.0f; - ImGui::TextColored(DataTextColor , "Resolution : %ix%i", W, H); - ImGui::TextColored(SelectFPSColor(fps), "FPS : %d (%.2f ms)", fps, frameTime_ms); + ImGui::TextColored(DataTextColor , "Display Resolution : %ix%i", W, H); + ImGui::TextColored(DataTextColor , "Render Resolution : %ix%i", RenderW, RenderH); + ImGui::TextColored(SelectFPSColor(fps), "FPS : %d (%.2f ms)", fps, frameTime_ms); DrawFPSChart(fps); DrawFrameTimeChart(); @@ -829,10 +798,10 @@ void VQEngine::DrawProfilerWindow(const FSceneStats& FrameStats, float dt) ImGui::End(); } -void VQEngine::DrawPostProcessSettings(FPostProcessParameters& PPParams) +void VQEngine::DrawPostProcessSettings(FGraphicsSettings& GFXSettings) { // constants - const bool bFSREnabled = PPParams.IsFSREnabled(); + const bool bFSREnabled = GFXSettings.IsFSR1Enabled(); const uint32 W = mpWinMain->GetWidth(); const uint32 H = mpWinMain->GetHeight(); @@ -848,47 +817,116 @@ void VQEngine::DrawPostProcessSettings(FPostProcessParameters& PPParams) ImGui::Text("Upscaling"); ImGui::Separator(); - // upscaling dropdown : None / FidelityFX Super Resolution 1.0 - if (ImGui_RightAlignedCombo("Algorithm", (int*) &PPParams.UpscalingAlgorithm, szUpscalingLabels, _countof(szUpscalingLabels))) + if (ImGui_RightAlignedCombo("Algorithm", (int*) &GFXSettings.PostProcessing.UpscalingAlgorithm, szUpscalingLabels, _countof(szUpscalingLabels))) { + switch (GFXSettings.PostProcessing.UpscalingAlgorithm) + { + case EUpscalingAlgorithm::NONE: + GFXSettings.Rendering.RenderResolutionScale = 1.0f; + break; + case EUpscalingAlgorithm::FIDELITYFX_SUPER_RESOLUTION_1: + GFXSettings.Rendering.RenderResolutionScale = AMD_FidelityFX_SuperResolution1::GetScreenPercentage(GFXSettings.PostProcessing.FSR1UpscalingQualityEnum); + break; + case EUpscalingAlgorithm::FIDELITYFX_SUPER_RESOLUTION_3: + GFXSettings.Rendering.RenderResolutionScale = AMD_FidelityFX_SuperResolution3::GetScreenPercentage(GFXSettings.PostProcessing.FSR3UpscalingQualityEnum); + break; + } + GFXSettings.Validate(); + mUIState.ResolutionScaleSliderValue = GFXSettings.Rendering.RenderResolutionScale; fnSendWindowResizeEvents(); } - if (PPParams.UpscalingAlgorithm != FPostProcessParameters::EUpscalingAlgorithm::NONE) + if (GFXSettings.PostProcessing.UpscalingAlgorithm != EUpscalingAlgorithm::NONE) { // preset: ultra quality / quality / balanced / performance / custom - if (ImGui_RightAlignedCombo("Quality", (int*)&PPParams.UpscalingQualityPresetEnum, szUpscalingQualityLabels, _countof(szUpscalingQualityLabels))) + int* pIndexQualityPreset = nullptr; + const char** pszQualityLabels = nullptr; + int NumQualities = 0; + switch (GFXSettings.PostProcessing.UpscalingAlgorithm) + { + case EUpscalingAlgorithm::FIDELITYFX_SUPER_RESOLUTION_1: + pIndexQualityPreset = (int*)&GFXSettings.PostProcessing.FSR1UpscalingQualityEnum; + pszQualityLabels = szFSR1QualityLabels; + NumQualities = AMD_FidelityFX_SuperResolution1::EPreset::NUM_FSR1_PRESET_OPTIONS; + break; + case EUpscalingAlgorithm::FIDELITYFX_SUPER_RESOLUTION_3: + pIndexQualityPreset = (int*)&GFXSettings.PostProcessing.FSR3UpscalingQualityEnum; + pszQualityLabels = szFSR3QualityLabels; + NumQualities = AMD_FidelityFX_SuperResolution3::EPreset::NUM_FSR3_PRESET_OPTIONS; + break; + } + + bool bShouldUpdateGlobalMipBias = false; + if (ImGui_RightAlignedCombo("Quality", pIndexQualityPreset, pszQualityLabels, NumQualities)) { - if (PPParams.UpscalingQualityPresetEnum != AMD_FidelityFX_SuperResolution1::EPreset::CUSTOM) + switch (GFXSettings.PostProcessing.UpscalingAlgorithm) { - PPParams.ResolutionScale = AMD_FidelityFX_SuperResolution1::GetAMDFSR1ScreenPercentage(PPParams.UpscalingQualityPresetEnum); + case EUpscalingAlgorithm::FIDELITYFX_SUPER_RESOLUTION_1: + if (GFXSettings.PostProcessing.FSR1UpscalingQualityEnum != AMD_FidelityFX_SuperResolution1::EPreset::CUSTOM) + GFXSettings.Rendering.RenderResolutionScale = AMD_FidelityFX_SuperResolution1::GetScreenPercentage(GFXSettings.PostProcessing.FSR1UpscalingQualityEnum); + bShouldUpdateGlobalMipBias = true; + break; + case EUpscalingAlgorithm::FIDELITYFX_SUPER_RESOLUTION_3: + if (GFXSettings.PostProcessing.FSR3UpscalingQualityEnum != AMD_FidelityFX_SuperResolution3::EPreset::CUSTOM) + GFXSettings.Rendering.RenderResolutionScale = AMD_FidelityFX_SuperResolution3::GetScreenPercentage(GFXSettings.PostProcessing.FSR3UpscalingQualityEnum); + bShouldUpdateGlobalMipBias = true; + break; } + mUIState.ResolutionScaleSliderValue = GFXSettings.Rendering.RenderResolutionScale; fnSendWindowResizeEvents(); } // resolution scale - if (PPParams.UpscalingQualityPresetEnum == AMD_FidelityFX_SuperResolution1::EPreset::CUSTOM) + bool bDrawResolutionScaleSlider = false; + switch (GFXSettings.PostProcessing.UpscalingAlgorithm) + { + case EUpscalingAlgorithm::FIDELITYFX_SUPER_RESOLUTION_1: + bDrawResolutionScaleSlider = GFXSettings.PostProcessing.FSR1UpscalingQualityEnum == AMD_FidelityFX_SuperResolution1::EPreset::CUSTOM; + break; + case EUpscalingAlgorithm::FIDELITYFX_SUPER_RESOLUTION_3: + bDrawResolutionScaleSlider = GFXSettings.PostProcessing.FSR3UpscalingQualityEnum == AMD_FidelityFX_SuperResolution3::EPreset::CUSTOM; + break; + } + if (bDrawResolutionScaleSlider) { - // if we are to support resolution scale > 1.0f, we'll need to stop using FSR1 upscaling - // and use a linear min filter for AA - if (ImGui::SliderFloat("Resolution Scale", &PPParams.ResolutionScale, 0.25f, 1.00f, "%.2f")) + ImGui::SliderFloat("Resolution Scale", &mUIState.ResolutionScaleSliderValue, 0.25f, 1.00f, "%.2f"); + + // to avoid updating resolution scale depending resources every tick, + // we do it only after the user let the slider go. + if (ImGui::IsItemDeactivatedAfterEdit()) { + GFXSettings.Rendering.RenderResolutionScale = mUIState.ResolutionScaleSliderValue; + if (GFXSettings.IsFSR3Enabled() || GFXSettings.IsFSR1Enabled()) + bShouldUpdateGlobalMipBias = true; fnSendWindowResizeEvents(); } } + + if(bShouldUpdateGlobalMipBias) + GFXSettings.Rendering.GlobalMipBias = AMD_FidelityFX_SuperResolution3::GetMipBias(GFXSettings.GetRenderResolutionX(), GFXSettings.Display.DisplayResolutionX); + + if (GFXSettings.IsFSR3Enabled()) + { + FPostProcessingSettings::FFSR3Settings& s = GFXSettings.PostProcessing.FSR3Settings; + + ImGui::Checkbox("Generate Reactive Mask", &s.bGenerateReactivityMask); + if (s.bGenerateReactivityMask) + { + ImGui::SliderFloat("Scale", &s.GeneratedReactiveMaskScale, 0.0f, 1.0f, "%.3f"); + ImGui::SliderFloat("Cutoff Threshold", &s.GeneratedReactiveMaskCutoffThreshold, 0.0f, 1.0f, "%.3f"); + ImGui::SliderFloat("Binary Value", &s.GeneratedReactiveMaskBinaryValue, 0.0f, 1.0f, "%.3f"); + } + } } ImGuiSpacing3(); ImGui::Text("Sharpness"); ImGui::Separator(); - float LinearSharpness = PPParams.FSR_RCASParams.GetLinearSharpness(); - if (ImGui::SliderFloat("Amount##", &LinearSharpness, 0.01f, 1.00f, "%.2f")) - { - PPParams.FSR_RCASParams.SetLinearSharpness(LinearSharpness); - PPParams.FSR_RCASParams.UpdateRCASConstantBlock(); - } + + ImGui::SliderFloat("Amount##", &GFXSettings.PostProcessing.Sharpness, 0.01f, 1.00f, "%.2f"); + // // TONEMAPPER @@ -900,23 +938,21 @@ void VQEngine::DrawPostProcessSettings(FPostProcessParameters& PPParams) { if (bHDR) { - const std::string strDispalyCurve = GetDisplayCurveString(PPParams.TonemapperParams.OutputDisplayCurve); - const std::string strColorSpace = GetColorSpaceString(PPParams.TonemapperParams.ContentColorSpace); + const std::string strDispalyCurve = GetDisplayCurveString(GFXSettings.PostProcessing.HDROutputDisplayCurve); + const std::string strColorSpace = GetColorSpaceString(GFXSettings.PostProcessing.ContentColorSpace); ImGui::Text("OutputDevice : %s", strDispalyCurve.c_str() ); ImGui::Text("Color Space : %s", strColorSpace.c_str() ); - ImGui::SliderFloat("UI Brightness", &PPParams.TonemapperParams.UIHDRBrightness, 0.1f, 20.f, "%.1f"); + ImGui::SliderFloat("UI Brightness", &GFXSettings.PostProcessing.UIHDRBrightness, 0.1f, 20.f, "%.1f"); } else { - bool bGamma = PPParams.TonemapperParams.ToggleGammaCorrection; - ImGui::Checkbox("[SDR] Apply Gamma (G)", &bGamma); - PPParams.TonemapperParams.ToggleGammaCorrection = bGamma ? 1 : 0; + ImGui::Checkbox("[SDR] Apply Gamma (G)", &GFXSettings.PostProcessing.EnableGammaCorrection); } } } -void VQEngine::DrawGraphicsSettingsWindow(FSceneRenderOptions& SceneRenderParams, FPostProcessParameters& PPParams) +void VQEngine::DrawGraphicsSettingsWindow(FSceneRenderOptions& SceneRenderParams) { const uint32 W = mpWinMain->GetWidth(); const uint32 H = mpWinMain->GetHeight(); @@ -927,16 +963,14 @@ void VQEngine::DrawGraphicsSettingsWindow(FSceneRenderOptions& SceneRenderParams InitializeStaticCStringData_GraphicsSettings(); // static data - - int iAALabel = gfx.bAntiAliasing ? 1 : 0; - int iSSAOLabel = SceneRenderParams.bScreenSpaceAO ? 1 : 0; - int iReflections = gfx.Reflections; + int iSSAOLabel = SceneRenderParams.Lighting.bScreenSpaceAO ? 1 : 0; + int iReflections = gfx.Rendering.Reflections; const uint32_t GFX_WINDOW_POS_X = W - GFX_WINDOW_SIZE_X - PROFILER_WINDOW_SIZE_X - PROFILER_WINDOW_PADDIG_X - GFX_WINDOW_PADDING_X; const uint32_t GFX_WINDOW_POS_Y = H - GFX_WINDOW_PADDING_Y*2 - GFX_WINDOW_SIZE_Y; ImGui::SetNextWindowPos(ImVec2((float)GFX_WINDOW_POS_X, (float)GFX_WINDOW_POS_Y), ImGuiCond_FirstUseEver); ImGui::SetNextWindowSize(ImVec2(GFX_WINDOW_SIZE_X, GFX_WINDOW_SIZE_Y), ImGuiCond_FirstUseEver); - + ImGui::Begin("GRAPHICS SETTINGS", &mUIState.bWindowVisible_GraphicsSettingsPanel); @@ -946,28 +980,26 @@ void VQEngine::DrawGraphicsSettingsWindow(FSceneRenderOptions& SceneRenderParams if (ImGui::BeginTabItem("Debug")) { InitializeStaticCStringData_EDrawMode(); - int iDrawMode = (int)PPParams.DrawModeEnum; - ImGui_RightAlignedCombo("Draw Mode", &iDrawMode, szDrawModes, _countof(szDrawModes)); - PPParams.DrawModeEnum = (EDrawMode)iDrawMode; - if (PPParams.DrawModeEnum == EDrawMode::NORMALS) - { - bool bUnpackNormals = PPParams.VizParams.iUnpackNormals; - ImGui::Checkbox("Unpack Normals", &bUnpackNormals); - PPParams.VizParams.iUnpackNormals = bUnpackNormals; - } - if (PPParams.DrawModeEnum == EDrawMode::MOTION_VECTORS) + ImGui_RightAlignedCombo("Draw Mode", (int*)&gfx.DebugVizualization.DrawModeEnum, szDrawModes, _countof(szDrawModes)); + + switch (gfx.DebugVizualization.DrawModeEnum) { - ImGui::SliderFloat("MoVec Intensity", &PPParams.VizParams.fInputStrength, 0.0f, 200.0f); + case FDebugVisualizationSettings::EDrawMode::NORMALS: + ImGui::Checkbox("Unpack Normals", &gfx.DebugVizualization.bUnpackNormals); + break; + case FDebugVisualizationSettings::EDrawMode::MOTION_VECTORS: + ImGui::SliderFloat("MoVec Intensity", &gfx.DebugVizualization.fInputStrength, 0.0f, 200.0f); + break; } - ImGui::Checkbox("Show GameObject Bounding Boxes (Shift+N)", &SceneRenderParams.bDrawGameObjectBoundingBoxes); - ImGui::Checkbox("Show Mesh Bounding Boxes (N)", &SceneRenderParams.bDrawMeshBoundingBoxes); - ImGui::Checkbox("Show Light Bounding Volumes (L)", &SceneRenderParams.bDrawLightBounds); - ImGui::Checkbox("Draw Lights", &SceneRenderParams.bDrawLightMeshes); - ImGui::Checkbox("Draw Vertex Axes", &SceneRenderParams.bDrawVertexLocalAxes); - if (SceneRenderParams.bDrawVertexLocalAxes) + ImGui::Checkbox("Show GameObject Bounding Boxes (Shift+N)", &SceneRenderParams.Debug.bDrawGameObjectBoundingBoxes); + ImGui::Checkbox("Show Mesh Bounding Boxes (N)", &SceneRenderParams.Debug.bDrawMeshBoundingBoxes); + ImGui::Checkbox("Show Light Bounding Volumes (L)", &SceneRenderParams.Debug.bDrawLightBounds); + ImGui::Checkbox("Draw Lights", &SceneRenderParams.Debug.bDrawLightMeshes); + ImGui::Checkbox("Draw Vertex Axes", &SceneRenderParams.Debug.bDrawVertexLocalAxes); + if (SceneRenderParams.Debug.bDrawVertexLocalAxes) { - ImGui::SliderFloat("Axis Size", &SceneRenderParams.fVertexLocalAxixSize, 1.0f, 10.0f); + ImGui::SliderFloat("Axis Size", &SceneRenderParams.Debug.fVertexLocalAxisSize, 1.0f, 10.0f); } // @@ -979,67 +1011,67 @@ void VQEngine::DrawGraphicsSettingsWindow(FSceneRenderOptions& SceneRenderParams ImGui::Text("Magnifier"); ImGui::Separator(); { - ImGui::Checkbox("Show Magnifier (Middle Mouse)", &mUIState.mpMagnifierState->bUseMagnifier); + FRenderDebugOptions::FMagnifierOptions& MagnifierOptions = SceneRenderParams.Debug.Magnifier; + ImGui::Checkbox("Show Magnifier (Middle Mouse)", &MagnifierOptions.bEnable); - BeginDisabledUIState(mUIState.mpMagnifierState->bUseMagnifier); + BeginDisabledUIState(MagnifierOptions.bEnable); { - FMagnifierParameters& params = *mUIState.mpMagnifierState->pMagnifierParams; - // Use a local bool state here to track locked state through the UI widget, // and then call ToggleMagnifierLockedState() to update the persistent state (m_UIstate). // The keyboard input for toggling lock directly operates on the persistent state. - const bool bIsMagnifierCurrentlyLocked = mUIState.mpMagnifierState->bLockMagnifierPosition; + const bool bIsMagnifierCurrentlyLocked = MagnifierOptions.bLockPosition; bool bMagnifierToggle = bIsMagnifierCurrentlyLocked; ImGui::Checkbox("Lock Position (Shift + Middle Mouse)", &bMagnifierToggle); if (bMagnifierToggle != bIsMagnifierCurrentlyLocked) - mUIState.mpMagnifierState->ToggleMagnifierLock(); + MagnifierOptions.ToggleLock(io.MousePos.x, io.MousePos.y); - ImGui::SliderFloat("Screen Size", ¶ms.fMagnifierScreenRadius, MAGNIFIER_RADIUS_MIN, MAGNIFIER_RADIUS_MAX); - ImGui::SliderFloat("Magnification", ¶ms.fMagnificationAmount, MAGNIFICATION_AMOUNT_MIN, MAGNIFICATION_AMOUNT_MAX); + + ImGui::SliderFloat("Screen Size" , &MagnifierOptions.fMagnifierScreenRadius, MAGNIFIER_RADIUS_MIN, MAGNIFIER_RADIUS_MAX); + ImGui::SliderFloat("Magnification", &MagnifierOptions.fMagnificationAmount, MAGNIFICATION_AMOUNT_MIN, MAGNIFICATION_AMOUNT_MAX); if (bMagnifierToggle) { - ImGui::SliderInt("OffsetX", ¶ms.iMagnifierOffset[0], -(int)W, W); - ImGui::SliderInt("OffsetY", ¶ms.iMagnifierOffset[1], -(int)H, H); + ImGui::SliderInt("OffsetX", &MagnifierOptions.ScreenOffsetY, -(int)W, W); + ImGui::SliderInt("OffsetY", &MagnifierOptions.ScreenOffsetY, -(int)H, H); } } - EndDisabledUIState(mUIState.mpMagnifierState->bUseMagnifier); + EndDisabledUIState(SceneRenderParams.Debug.Magnifier.bEnable); } ImGui::EndTabItem(); } if (ImGui::BeginTabItem("Display")) { - BeginDisabledUIState(!gfx.bVsync); + BeginDisabledUIState(!gfx.Display.bVsync); { - static int iLimiter = mSettings.gfx.MaxFrameRate == -1 ? 0 : (mSettings.gfx.MaxFrameRate == 0 ? 1 : 2); // see Settings.h - static int CustomFrameLimit = mSettings.gfx.MaxFrameRate; + static int iLimiter = mSettings.gfx.Rendering.MaxFrameRate == -1 ? 0 : (mSettings.gfx.Rendering.MaxFrameRate == 0 ? 1 : 2); // see Settings.h + static int CustomFrameLimit = mSettings.gfx.Rendering.MaxFrameRate; if (ImGui_RightAlignedCombo("FrameRate Limit", &iLimiter, szMaxFrameRateOptionLabels, _countof(szMaxFrameRateOptionLabels))) { switch (iLimiter) { - case 0: mSettings.gfx.MaxFrameRate = -1; break; - case 1: mSettings.gfx.MaxFrameRate = 0; break; - case 2: mSettings.gfx.MaxFrameRate = CustomFrameLimit; break; + case 0: mSettings.gfx.Rendering.MaxFrameRate = -1; break; + case 1: mSettings.gfx.Rendering.MaxFrameRate = 0; break; + case 2: mSettings.gfx.Rendering.MaxFrameRate = CustomFrameLimit; break; default: break; } - SetEffectiveFrameRateLimit(mSettings.gfx.MaxFrameRate); + SetEffectiveFrameRateLimit(mSettings.gfx.Rendering.MaxFrameRate); } if (iLimiter == 2) // custom frame limit value { if (ImGui::SliderInt("MaxFrames", &CustomFrameLimit, 10, 1000)) { - mSettings.gfx.MaxFrameRate = CustomFrameLimit; - SetEffectiveFrameRateLimit(mSettings.gfx.MaxFrameRate); + mSettings.gfx.Rendering.MaxFrameRate = CustomFrameLimit; + SetEffectiveFrameRateLimit(mSettings.gfx.Rendering.MaxFrameRate); } } } - EndDisabledUIState(!gfx.bVsync); + EndDisabledUIState(!gfx.Display.bVsync); - if (ImGui::Checkbox("VSync (V)", &gfx.bVsync)) + if (ImGui::Checkbox("VSync (V)", &gfx.Display.bVsync)) { - mEventQueue_WinToVQE_Renderer.AddItem(std::make_shared(hwnd, gfx.bVsync)); + mEventQueue_WinToVQE_Renderer.AddItem(std::make_shared(hwnd, gfx.Display.bVsync)); } bool bFS = mpWinMain->IsFullscreen(); if (ImGui::Checkbox("Fullscreen (Alt+Enter)", &bFS)) @@ -1052,45 +1084,49 @@ void VQEngine::DrawGraphicsSettingsWindow(FSceneRenderOptions& SceneRenderParams if (ImGui::BeginTabItem("Rendering")) { - if (ImGui_RightAlignedCombo("AntiAliasing (M)", &iAALabel, szAALabels, _countof(szAALabels) - 1)) + const bool bShouldEnableAntiAliasingOptions = !gfx.IsFSR3Enabled(); + BeginDisabledUIState(bShouldEnableAntiAliasingOptions); { - gfx.bAntiAliasing = iAALabel; - Log::Info("AA Changed: %d", gfx.bAntiAliasing); + if (ImGui_RightAlignedCombo("AntiAliasing (M)", (int*)&gfx.Rendering.AntiAliasing, szAALabels, _countof(szAALabels) - 1)) + { + Log::Info("AA Changed: %d", gfx.Rendering.AntiAliasing); + } } + EndDisabledUIState(bShouldEnableAntiAliasingOptions); if (ImGui_RightAlignedCombo("Ambient Occlusion", &iSSAOLabel, szSSAOLabels, _countof(szSSAOLabels) - 1)) { - SceneRenderParams.bScreenSpaceAO = iSSAOLabel == 1; - Log::Info("AO Changed: %d", SceneRenderParams.bScreenSpaceAO); + SceneRenderParams.Lighting.bScreenSpaceAO = iSSAOLabel == 1; + Log::Info("AO Changed: %d", SceneRenderParams.Lighting.bScreenSpaceAO); } - int iRefl = gfx.Reflections; + int iRefl = gfx.Rendering.Reflections; if (ImGui_RightAlignedCombo("Reflections", &iRefl, szReflectionsLabels, _countof(szReflectionsLabels)-1)) { - gfx.Reflections = static_cast(iRefl); - Log::Info("Reflections Changed: %d", gfx.Reflections); + gfx.Rendering.Reflections = static_cast(iRefl); + Log::Info("Reflections Changed: %d", gfx.Rendering.Reflections); } - switch (gfx.Reflections) + switch (gfx.Rendering.Reflections) { case EReflections::SCREEN_SPACE_REFLECTIONS__FFX: { - FSceneRenderOptions::FFFX_SSSR_UIOptions& FFXParams = SceneRenderParams.FFX_SSSRParameters; + FRenderingSettings::FFFX_SSSR_Options& FFXParams = mSettings.gfx.Rendering.FFX_SSSR_Options; ImGui::PushStyleColor(ImGuiCol_Header, UI_COLLAPSING_HEADER_COLOR_VALUE); if (ImGui::CollapsingHeader("SSSR Settings")) { ImGui::PopStyleColor(); - ImGui::SliderFloat("Roughness Threshold", &FFXParams.roughnessThreshold, 0.0f, 1.f); - ImGui::SliderInt("Max Traversal Iterations", &FFXParams.maxTraversalIterations, 0, 256); - ImGui::SliderInt("Min Traversal Occupancy", &FFXParams.minTraversalOccupancy, 0, 32); - ImGui::SliderInt("Most Detailed Level", &FFXParams.mostDetailedDepthHierarchyMipLevel, 0, 5); - ImGui::SliderFloat("Depth Buffer Thickness", &FFXParams.depthBufferThickness, 0.0f, 5.0f); - ImGui::SliderFloat("Temporal Stability", &FFXParams.temporalStability, 0.0f, 1.0f); - ImGui::SliderFloat("Temporal Variance Threshold", &FFXParams.temporalVarianceThreshold, 0.0f, 0.01f); + ImGui::SliderFloat("Roughness Threshold" , &FFXParams.RoughnessThreshold, 0.0f, 1.f); + ImGui::SliderInt("Max Traversal Iterations" , &FFXParams.MaxTraversalIterations, 0, 256); + ImGui::SliderInt("Min Traversal Occupancy" , &FFXParams.MinTraversalOccupancy, 0, 32); + ImGui::SliderInt("Most Detailed Level" , &FFXParams.MostDetailedDepthHierarchyMipLevel, 0, 5); + ImGui::SliderFloat("Depth Buffer Thickness" , &FFXParams.DepthBufferThickness, 0.0f, 5.0f); + ImGui::SliderFloat("Temporal Stability" , &FFXParams.TemporalStability, 0.0f, 1.0f); + ImGui::SliderFloat("Temporal Variance Threshold", &FFXParams.TemporalVarianceThreshold, 0.0f, 0.01f); ImGui::Checkbox("Enable Variance Guided Tracing", &FFXParams.bEnableTemporalVarianceGuidedTracing); ImGui::Text("Samples per Quad"); ImGui::SameLine(); - ImGui::RadioButton("1", &FFXParams.samplesPerQuad, 1); ImGui::SameLine(); - ImGui::RadioButton("2", &FFXParams.samplesPerQuad, 2); ImGui::SameLine(); - ImGui::RadioButton("4", &FFXParams.samplesPerQuad, 4); + ImGui::RadioButton("1", &FFXParams.SamplesPerQuad, 1); ImGui::SameLine(); + ImGui::RadioButton("2", &FFXParams.SamplesPerQuad, 2); ImGui::SameLine(); + ImGui::RadioButton("4", &FFXParams.SamplesPerQuad, 4); ImGui::Separator(); } else @@ -1105,6 +1141,7 @@ void VQEngine::DrawGraphicsSettingsWindow(FSceneRenderOptions& SceneRenderParams break; } + ImGuiSpacing3(); ImGui::Checkbox("Async Compute", &mSettings.gfx.bEnableAsyncCompute); ImGui::Checkbox("Async Copy", &mSettings.gfx.bEnableAsyncCopy); if (ImGui::Checkbox("Separate Submission Queue", &mSettings.gfx.bUseSeparateSubmissionQueue)) @@ -1112,16 +1149,22 @@ void VQEngine::DrawGraphicsSettingsWindow(FSceneRenderOptions& SceneRenderParams mEventQueue_WinToVQE_Renderer.AddItem(std::make_shared(hwnd, mSettings.gfx.bUseSeparateSubmissionQueue)); } - ImGui::Checkbox("ForceLOD0 (Shadow)", &SceneRenderParams.bForceLOD0_ShadowView); - ImGui::Checkbox("ForceLOD0 (Scene )", &SceneRenderParams.bForceLOD0_SceneView); + ImGui::Checkbox("ForceLOD0 Shadow View", &SceneRenderParams.Debug.bForceLOD0_ShadowView); + ImGui::Checkbox("ForceLOD0 Scene View", &SceneRenderParams.Debug.bForceLOD0_SceneView); + const bool bShouldEnableGlobalMipBias = !gfx.IsFSR3Enabled(); + BeginDisabledUIState(bShouldEnableGlobalMipBias); + { + ImGui::SliderFloat("Global Mip Bias", &mSettings.gfx.Rendering.GlobalMipBias, -5.0f, 5.0f, "%.2f"); + } + EndDisabledUIState(bShouldEnableGlobalMipBias); ImGui::EndTabItem(); } if (ImGui::BeginTabItem("Post Processing")) { - DrawPostProcessSettings(PPParams); + DrawPostProcessSettings(mSettings.gfx); ImGui::EndTabItem(); } @@ -1524,7 +1567,25 @@ void VQEngine::DrawMaterialEditor() ImGui::DragFloat("##roughness", &mat.roughness, 0.01f, 0.04f, 1.0f, "%.2f"); StartDrawingMaterialEditorRow("Mip Bias (Normals)"); - ImGui::DragFloat("##mip_bias", &mat.normalMapMipBias, 0.01f, -5.0f, 5.0f, "%.2f"); + ImGui::DragFloat("##mip_bias_normal", &mat.normalMapMipBias, 0.01f, -5.0f, 5.0f, "%.2f"); + + StartDrawingMaterialEditorRow("Mip Bias"); + const float fullWidth = ImGui::GetContentRegionAvail().x; + const float checkboxLabelWidth = ImGui::CalcTextSize("Override ").x; + const float spacing = ImGui::GetStyle().ItemInnerSpacing.x; // spacing between items + const float checkboxWidth = ImGui::GetFrameHeight(); // checkbox square width + const float widthForDrag = ImMax(fullWidth - checkboxLabelWidth - spacing - checkboxWidth - spacing, 50.0f); + ImGui::SetNextItemWidth(widthForDrag); + if (mat.bOverrideGlobalMipBias) + { + ImGui::DragFloat("##mip_bias", &mat.mipMapBias, 0.01f, -5.0f, 5.0f, "%.2f"); + } + else + { + ImGui::LabelText("##global_mip_bias_value", "%.2f", mSettings.gfx.Rendering.GlobalMipBias); + } + ImGui::SameLine(); + ImGui::Checkbox("Override##", &mat.bOverrideGlobalMipBias); StartDrawingMaterialEditorRow("Tiling"); ImGui::DragFloat2("##tiling", reinterpret_cast(&mat.tiling), 0.01f, 0.0f, 10.0f, "%.2f"); diff --git a/Source/Engine/UI/VQUI.h b/Source/Engine/UI/VQUI.h index 2c4bebd2..69ececa0 100644 --- a/Source/Engine/UI/VQUI.h +++ b/Source/Engine/UI/VQUI.h @@ -16,23 +16,6 @@ // // Contact: volkanilbeyli@gmail.com -#include - -struct FMagnifierParameters; -struct FMagnifierUIState -{ - bool bUseMagnifier = false; - bool bLockMagnifierPosition = false; - bool bLockMagnifierPositionHistory = false; - int LockedMagnifiedScreenPositionX = 0; - int LockedMagnifiedScreenPositionY = 0; - std::shared_ptr pMagnifierParams = nullptr; - - void ToggleMagnifierLock(); - void AdjustMagnifierSize(float increment = 0.05f); - void AdjustMagnifierMagnification(float increment = 1.00f); -}; - struct FUIState { bool bWindowVisible_KeyMappings = false; @@ -61,7 +44,8 @@ struct FUIState bool bUIOnSeparateWindow = false; bool bProfiler_ShowEngineStats = true; - std::unique_ptr mpMagnifierState = nullptr; + float ResolutionScaleSliderValue = 1.0f; + void GetMouseScreenPosition(int& X, int& Y) const; }; \ No newline at end of file diff --git a/Source/Engine/VQEngine.h b/Source/Engine/VQEngine.h index 59b8e52b..f787d408 100644 --- a/Source/Engine/VQEngine.h +++ b/Source/Engine/VQEngine.h @@ -60,7 +60,6 @@ class VQRenderer; struct FSceneRenderOptions; class Scene; struct FSceneStats; -struct FPostProcessParameters; class Timer; class Window; @@ -140,9 +139,6 @@ class VQEngine : public IWindowOwner void RenderThread_SignalUpdateThread(); #endif - void RenderThread_LoadWindowSizeDependentResources(HWND hwnd, int Width, int Height, float ResolutionScale); - void RenderThread_UnloadWindowSizeDependentResources(HWND hwnd); - // RENDER() // - Records command lists in parallel per FSceneView // - Submits commands to the GPU @@ -372,11 +368,11 @@ class VQEngine : public IWindowOwner // UI // void UpdateUIState(HWND hwnd, float dt); - void DrawProfilerWindow(const FSceneStats& FrameStats, float dt); + void DrawProfilerWindow(const FSceneStats& FrameStats, float RenderResolutionScale, float dt); void DrawSceneControlsWindow(int& iSelectedCamera, int& iSelectedEnvMap, FSceneRenderOptions& SceneRenderParams); - void DrawPostProcessSettings(FPostProcessParameters& PPParams); + void DrawPostProcessSettings(FGraphicsSettings& GFXSettings); void DrawKeyMappingsWindow(); - void DrawGraphicsSettingsWindow(FSceneRenderOptions& SceneRenderParams, FPostProcessParameters& PPParams); + void DrawGraphicsSettingsWindow(FSceneRenderOptions& SceneRenderParams); void DrawEditorWindow(); void DrawMaterialEditor(); void DrawLightEditor(); diff --git a/Source/Engine/VQEngine_Input.cpp b/Source/Engine/VQEngine_Input.cpp index aa5cea17..4ba9d4f2 100644 --- a/Source/Engine/VQEngine_Input.cpp +++ b/Source/Engine/VQEngine_Input.cpp @@ -94,25 +94,11 @@ void VQEngine::HandleUIInput() const int NUM_BACK_BUFFERS = mpRenderer->GetSwapChainBackBufferCount(mpWinMain->GetHWND()); const int FRAME_DATA_INDEX = mNumUpdateLoopsExecuted % NUM_BACK_BUFFERS; #endif - FPostProcessParameters& PPParams = mpScene->GetPostProcessParameters(FRAME_DATA_INDEX); #if !DISABLE_FIDELITYFX_CAS PPParams.bEnableCAS = !PPParams.bEnableCAS; Log::Info("Toggle FFX-CAS: %d", PPParams.bEnableCAS); #endif } - - /* MAGNIFIER CONTROLS */ - const bool bMidMouseTriggered = input.IsMouseTriggered(Input::EMouseButtons::MOUSE_BUTTON_MIDDLE); - if (bMidMouseTriggered) - { - if (bIsShiftDown) - { - if (mUIState.mpMagnifierState->bUseMagnifier) - mUIState.mpMagnifierState->ToggleMagnifierLock(); - } - else - mUIState.mpMagnifierState->bUseMagnifier ^= 1; - } } } } @@ -161,6 +147,23 @@ void VQEngine::HandleMainWindowInput(Input& input, HWND hwnd) Toggle(mUIState.bHideAllWindows); } + /* MAGNIFIER CONTROLS */ + const bool bMidMouseTriggered = input.IsMouseTriggered(Input::EMouseButtons::MOUSE_BUTTON_MIDDLE); + FSceneView& SceneView = mpScene->GetSceneView(0); + FRenderDebugOptions::FMagnifierOptions& Magnifier = SceneView.sceneRenderOptions.Debug.Magnifier; + if (bMidMouseTriggered) + { + if (bIsShiftDown) + { + if (Magnifier.bEnable) + Magnifier.ToggleLock(io.MousePos.x, io.MousePos.y); + } + else + Magnifier.bEnable ^= 1; + } + SceneView.iMousePosX = Magnifier.bLockPosition ? Magnifier.LockedScreenPositionX : io.MousePos.x; + SceneView.iMousePosY = Magnifier.bLockPosition ? Magnifier.LockedScreenPositionY : io.MousePos.y; + // Graphics Settings Controls if (input.IsKeyTriggered("V")) // Vsync { @@ -169,35 +172,44 @@ void VQEngine::HandleMainWindowInput(Input& input, HWND hwnd) } if (input.IsKeyTriggered("M")) // MSAA { - mSettings.gfx.bAntiAliasing = !mSettings.gfx.bAntiAliasing; - Log::Info("Toggle MSAA: %d", mSettings.gfx.bAntiAliasing); + if (mSettings.gfx.Rendering.AntiAliasing == EAntiAliasingAlgorithm::NO_ANTI_ALIASING) + { + // TODO: handle other MSAA algorithms + mSettings.gfx.Rendering.AntiAliasing = EAntiAliasingAlgorithm::MSAA4; + } + else + { + mSettings.gfx.Rendering.AntiAliasing = EAntiAliasingAlgorithm::NO_ANTI_ALIASING; + } + Log::Info("Toggle MSAA: %d", mSettings.gfx.Rendering.AntiAliasing); } if (input.IsKeyTriggered("G")) // Gamma { - FPostProcessParameters& PPParams = mpScene->GetPostProcessParameters(FRAME_DATA_INDEX); - PPParams.TonemapperParams.ToggleGammaCorrection = PPParams.TonemapperParams.ToggleGammaCorrection == 1 ? 0 : 1; - Log::Info("Tonemapper: ApplyGamma=%d (SDR-only)", PPParams.TonemapperParams.ToggleGammaCorrection); + mSettings.gfx.PostProcessing.EnableGammaCorrection = !mSettings.gfx.PostProcessing.EnableGammaCorrection; + Log::Info("Tonemapper: ApplyGamma=%d (SDR-only)", mSettings.gfx.PostProcessing.EnableGammaCorrection); } + +#if 0 // temporarily disabled, TODO: enable it if (input.IsKeyTriggered("J")) // Upscaling toggle { WaitUntilRenderingFinishes(); - FPostProcessParameters& PPParams = mpScene->GetPostProcessParameters(FRAME_DATA_INDEX); - if (PPParams.UpscalingAlgorithm != FPostProcessParameters::EUpscalingAlgorithm::NONE) + if (PPParams.UpscalingAlgorithm != EUpscalingAlgorithm::NONE) { PPParams.UpscalingAlgorithmLastValue = PPParams.UpscalingAlgorithm; } - PPParams.UpscalingAlgorithm = PPParams.IsFSREnabled() - ? FPostProcessParameters::EUpscalingAlgorithm::NONE + PPParams.UpscalingAlgorithm = PPParams.IsFSR1Enabled() + ? EUpscalingAlgorithm::NONE : PPParams.UpscalingAlgorithmLastValue; const uint32 W = mpWinMain->GetWidth(); const uint32 H = mpWinMain->GetHeight(); mEventQueue_WinToVQE_Renderer.AddItem(std::make_unique(W, H, hwnd)); mEventQueue_WinToVQE_Update.AddItem(std::make_unique(W, H, hwnd)); - Log::Info("Toggle FSR: %d", PPParams.IsFSREnabled()); + Log::Info("Toggle FSR: %d", PPParams.IsFSR1Enabled()); } +#endif // Scene switching if (!mbLoadingLevel) diff --git a/Source/Engine/VQEngine_Main.cpp b/Source/Engine/VQEngine_Main.cpp index 6e0d3830..7f7c9239 100644 --- a/Source/Engine/VQEngine_Main.cpp +++ b/Source/Engine/VQEngine_Main.cpp @@ -36,7 +36,7 @@ constexpr const char* BUILD_CONFIG = "-Debug"; #else constexpr const char* BUILD_CONFIG = ""; #endif -constexpr const char* VQENGINE_VERSION = "v0.11.0"; +constexpr const char* VQENGINE_VERSION = "v0.12.0"; #define REPORT_SYSTEM_INFO 1 @@ -150,17 +150,30 @@ void VQEngine::InitializeInput() if (mpWinDebug) RegisterWindowForInput(mpWinDebug); } +void FGraphicsSettings::Validate() +{ + if (IsFSR3Enabled()) + { + if (Rendering.AntiAliasing != EAntiAliasingAlgorithm::FSR3_ANTI_ALIASING) + { + Log::Warning("FSR3 is enabled, but AntiAliasingAlgorithm is not set to FSR3_ANTI_ALIASING. Overriding value \"%d\".", Rendering.AntiAliasing); + } + Rendering.AntiAliasing = EAntiAliasingAlgorithm::FSR3_ANTI_ALIASING; + Rendering.GlobalMipBias = AMD_FidelityFX_SuperResolution3::GetMipBias(GetRenderResolutionX(), Display.DisplayResolutionX); + } + else + { + if(Rendering.AntiAliasing == EAntiAliasingAlgorithm::FSR3_ANTI_ALIASING) + Rendering.AntiAliasing = EAntiAliasingAlgorithm::NO_ANTI_ALIASING; + } +} + void VQEngine::InitializeEngineSettings(const FStartupParameters& Params) { SCOPED_CPU_MARKER("InitializeEngineSettings"); const FEngineSettings& p = Params.EngineSettings; - // Defaults FEngineSettings& s = mSettings; - s.gfx.bVsync = false; - s.gfx.bUseTripleBuffering = true; - s.gfx.RenderScale = 1.0f; - s.gfx.MaxFrameRate = -1; // Auto s.WndMain.Width = 1920; s.WndMain.Height = 1080; @@ -186,13 +199,13 @@ void VQEngine::InitializeEngineSettings(const FStartupParameters& Params) FileParser::ParseEngineSettingsFile(paramFile); const FEngineSettings& pf = paramFile.EngineSettings; - if (paramFile.bOverrideGFXSetting_bVSync) s.gfx.bVsync = pf.gfx.bVsync; - if (paramFile.bOverrideGFXSetting_bAA) s.gfx.bAntiAliasing = pf.gfx.bAntiAliasing; - if (paramFile.bOverrideGFXSetting_bUseTripleBuffering) s.gfx.bUseTripleBuffering = pf.gfx.bUseTripleBuffering; - if (paramFile.bOverrideGFXSetting_RenderScale) s.gfx.RenderScale = pf.gfx.RenderScale; - if (paramFile.bOverrideGFXSetting_bMaxFrameRate) s.gfx.MaxFrameRate = pf.gfx.MaxFrameRate; - if (paramFile.bOverrideGFXSetting_EnvironmentMapResolution) s.gfx.EnvironmentMapResolution = pf.gfx.EnvironmentMapResolution; - if (paramFile.bOverrideGFXSettings_Reflections) s.gfx.Reflections = pf.gfx.Reflections; + if (paramFile.bOverrideGFXSetting_bVSync) s.gfx.Display.bVsync = pf.gfx.Display.bVsync; + if (paramFile.bOverrideGFXSetting_bAA) s.gfx.Rendering.AntiAliasing = pf.gfx.Rendering.AntiAliasing; + if (paramFile.bOverrideGFXSetting_bUseTripleBuffering) s.gfx.Display.bUseTripleBuffering = pf.gfx.Display.bUseTripleBuffering; + if (paramFile.bOverrideGFXSetting_RenderScale) s.gfx.Rendering.RenderResolutionScale = pf.gfx.Rendering.RenderResolutionScale; + if (paramFile.bOverrideGFXSetting_bMaxFrameRate) s.gfx.Rendering.MaxFrameRate = pf.gfx.Rendering.MaxFrameRate; + if (paramFile.bOverrideGFXSetting_EnvironmentMapResolution) s.gfx.Rendering.EnvironmentMapResolution = pf.gfx.Rendering.EnvironmentMapResolution; + if (paramFile.bOverrideGFXSettings_Reflections) s.gfx.Rendering.Reflections = pf.gfx.Rendering.Reflections; if (paramFile.bOverrideENGSetting_MainWindowWidth) s.WndMain.Width = pf.WndMain.Width; if (paramFile.bOverrideENGSetting_MainWindowHeight) s.WndMain.Height = pf.WndMain.Height; @@ -217,12 +230,12 @@ void VQEngine::InitializeEngineSettings(const FStartupParameters& Params) // Override #1 : if there's command line params - if (Params.bOverrideGFXSetting_bVSync) s.gfx.bVsync = p.gfx.bVsync; - if (Params.bOverrideGFXSetting_bAA) s.gfx.bAntiAliasing = p.gfx.bAntiAliasing; - if (Params.bOverrideGFXSetting_bUseTripleBuffering) s.gfx.bUseTripleBuffering = p.gfx.bUseTripleBuffering; - if (Params.bOverrideGFXSetting_RenderScale) s.gfx.RenderScale = p.gfx.RenderScale; - if (Params.bOverrideGFXSetting_bMaxFrameRate) s.gfx.MaxFrameRate = p.gfx.MaxFrameRate; - if (Params.bOverrideGFXSettings_Reflections) s.gfx.Reflections = p.gfx.Reflections; + if (Params.bOverrideGFXSetting_bVSync) s.gfx.Display.bVsync = p.gfx.Display.bVsync; + if (Params.bOverrideGFXSetting_bAA) s.gfx.Rendering.AntiAliasing = p.gfx.Rendering.AntiAliasing; + if (Params.bOverrideGFXSetting_bUseTripleBuffering) s.gfx.Display.bUseTripleBuffering = p.gfx.Display.bUseTripleBuffering; + if (Params.bOverrideGFXSetting_RenderScale) s.gfx.Rendering.RenderResolutionScale = p.gfx.Rendering.RenderResolutionScale; + if (Params.bOverrideGFXSetting_bMaxFrameRate) s.gfx.Rendering.MaxFrameRate = p.gfx.Rendering.MaxFrameRate; + if (Params.bOverrideGFXSettings_Reflections) s.gfx.Rendering.Reflections = p.gfx.Rendering.Reflections; if (Params.bOverrideENGSetting_MainWindowWidth) s.WndMain.Width = p.WndMain.Width; if (Params.bOverrideENGSetting_MainWindowHeight) s. WndMain.Height = p.WndMain.Height; @@ -244,6 +257,8 @@ void VQEngine::InitializeEngineSettings(const FStartupParameters& Params) } if (Params.bOverrideENGSetting_StartupScene) strncpy_s(s.StartupScene, p.StartupScene, sizeof(s.StartupScene)); + + mSettings.gfx.Validate(); } void VQEngine::InitializeWindows(const FStartupParameters& Params) @@ -344,7 +359,7 @@ void VQEngine::InitializeScenes() void VQEngine::InitializeEngineThreads() { SCOPED_CPU_MARKER("InitializeEngineThreads"); - const int NUM_SWAPCHAIN_BACKBUFFERS = mSettings.gfx.bUseTripleBuffering ? 3 : 2; + const int NUM_SWAPCHAIN_BACKBUFFERS = mSettings.gfx.Display.bUseTripleBuffering ? 3 : 2; const size_t HWThreads = ThreadPool::sHardwareThreadCount; const size_t HWCores = HWThreads / 2; const size_t NumRuntimeWorkers = HWCores - 1; // reserve 1 core for Update + Render threads diff --git a/Source/Engine/VQEngine_Render.cpp b/Source/Engine/VQEngine_Render.cpp index ec902874..801bc702 100644 --- a/Source/Engine/VQEngine_Render.cpp +++ b/Source/Engine/VQEngine_Render.cpp @@ -161,7 +161,7 @@ void VQEngine::RenderThread_Inititalize() #endif // Initialize swapchains for each rendering window // all windows use the same number of swapchains as the main window - const int NUM_SWAPCHAIN_BUFFERS = mSettings.gfx.bUseTripleBuffering ? 3 : 2; + const int NUM_SWAPCHAIN_BUFFERS = mSettings.gfx.Display.bUseTripleBuffering ? 3 : 2; { SCOPED_CPU_MARKER("mpWinMainInitContext"); const bool bIsContainingWindowOnHDRScreen = VQSystemInfo::FMonitorInfo::CheckHDRSupport(hwndMain); @@ -171,7 +171,7 @@ void VQEngine::RenderThread_Inititalize() Log::Warning("RenderThread_Initialize(): HDR Swapchain requested, but the containing monitor does not support HDR. Falling back to SDR Swapchain, and will enable HDR swapchain when the window is moved to a HDR-capable display"); } - mpRenderer->InitializeRenderContext(mpWinMain.get(), NUM_SWAPCHAIN_BUFFERS, mSettings.gfx.bVsync, bCreateHDRSwapchain, mSettings.gfx.bUseSeparateSubmissionQueue); + mpRenderer->InitializeRenderContext(mpWinMain.get(), NUM_SWAPCHAIN_BUFFERS, mSettings.gfx.Display.bVsync, bCreateHDRSwapchain, mSettings.gfx.bUseSeparateSubmissionQueue); mEventQueue_VQEToWin_Main.AddItem(std::make_shared(hwndMain)); } if(mpWinDebug) @@ -210,7 +210,7 @@ void VQEngine::RenderThread_Inititalize() const int H = bFullscreen ? mpWinMain->GetFullscreenHeight() : mpWinMain->GetHeight(); const float fResolutionScale = 1.0f; // Post process parameters are not initialized at this stage to determine the resolution scale - RenderThread_LoadWindowSizeDependentResources(hwndMain, W, H, fResolutionScale); + mpRenderer->LoadWindowSizeDependentResources(hwndMain, mSettings.gfx, this->ShouldRenderHDR(hwndMain)); }); } @@ -314,34 +314,6 @@ void VQEngine::WaitForBuiltinMeshGeneration() mBuiltinMeshGenSignal.Wait([&]() { return mbBuiltinMeshGenFinished.load(); }); } - -// ------------------------------------------------------------------------------------------------------------------------------------------------------------ -// -// LOAD -// -// ------------------------------------------------------------------------------------------------------------------------------------------------------------ -void VQEngine::RenderThread_LoadWindowSizeDependentResources(HWND hwnd, int Width, int Height, float fResolutionScale) -{ - SCOPED_CPU_MARKER("RenderThread_LoadWindowSizeDependentResources()"); - - if (hwnd == mpWinMain->GetHWND()) - { - mpRenderer->LoadWindowSizeDependentResources(hwnd, Width, Height, fResolutionScale, this->ShouldRenderHDR(hwnd)); - } - // TODO: generic implementation of other window procedures for load -} - -void VQEngine::RenderThread_UnloadWindowSizeDependentResources(HWND hwnd) -{ - SCOPED_CPU_MARKER("RenderThread_UnloadWindowSizeDependentResources()"); - if (hwnd == mpWinMain->GetHWND()) - { - mpRenderer->UnloadWindowSizeDependentResources(hwnd); - } - // TODO: generic implementation of other window procedures for unload -} - - // ------------------------------------------------------------------------------------------------------------------------------------------------------------ // // RENDER @@ -366,7 +338,6 @@ void VQEngine::RenderThread_RenderMainWindow() const FSceneView& SceneView = mpScene->GetSceneView(FRAME_DATA_INDEX); const FSceneShadowViews& SceneShadowView = mpScene->GetShadowView(FRAME_DATA_INDEX); - const FPostProcessParameters& PPParams = mpScene->GetPostProcessParameters(FRAME_DATA_INDEX); const HWND hwndMain = mpWinMain->GetHWND(); const bool bHDR = this->ShouldRenderHDR(hwndMain); const Window* pWindow = mpWinMain.get(); @@ -379,8 +350,8 @@ void VQEngine::RenderThread_RenderMainWindow() } else { - hr = mpRenderer->PreRenderScene(WorkerThreads, pWindow, SceneView, SceneShadowView, PPParams, mSettings.gfx, mUIState); - hr = mpRenderer->RenderScene(WorkerThreads, pWindow, SceneView, SceneShadowView, PPParams, mSettings.gfx, mUIState, bHDR); + hr = mpRenderer->PreRenderScene(WorkerThreads, pWindow, SceneView, SceneShadowView, mSettings.gfx, mUIState); + hr = mpRenderer->RenderScene(WorkerThreads, pWindow, SceneView, SceneShadowView, mSettings.gfx, mUIState, bHDR); } if (hr == DXGI_STATUS_OCCLUDED) { RenderThread_HandleStatusOccluded(); } diff --git a/Source/Engine/VQEngine_Update.cpp b/Source/Engine/VQEngine_Update.cpp index ffef7221..71ef3b4e 100644 --- a/Source/Engine/VQEngine_Update.cpp +++ b/Source/Engine/VQEngine_Update.cpp @@ -199,7 +199,7 @@ void VQEngine::UpdateThread_UpdateAppState(const float dt) mLoadingScreenData.RotateLoadingScreenImageIndex(); float dt_loading = mpTimer->StopGetDeltaTimeAndReset(); - SetEffectiveFrameRateLimit(mSettings.gfx.MaxFrameRate); + SetEffectiveFrameRateLimit(mSettings.gfx.Rendering.MaxFrameRate); Log::Info("Loading completed in %.2fs, starting scene simulation", dt_loading); mpTimer->Start(); UpdateThread_UpdateScene_MainWnd(dt); @@ -234,7 +234,7 @@ void VQEngine::UpdateThread_PostUpdate() return; } - mpScene->PostUpdate(mWorkerThreads, mUIState, mAppState == EAppState::SIMULATING, FRAME_DATA_INDEX); + mpScene->PostUpdate(mWorkerThreads, mUIState, mAppState == EAppState::SIMULATING, mSettings, FRAME_DATA_INDEX); ImGuiIO& io = ImGui::GetIO(); HWND hwndMain = mpWinMain->GetHWND(); @@ -424,24 +424,6 @@ const FDisplayHDRProfile* VQEngine::GetHDRProfileIfExists(const wchar_t* pwStrLo // --------------------------------------------------------------------- -// since the MagnifierPass is used for swapchain passthrough, we gotta -// update the pass paramteres in an update loop. -static void UpdateMagnifierParameters(FMagnifierUIState* pMagnifierUIState, const FUIState& ui, int W, int H) -{ - int MouseX, MouseY = 0; - ui.GetMouseScreenPosition(MouseX, MouseY); - - FMagnifierParameters& params = *pMagnifierUIState->pMagnifierParams; - const bool bLocked = pMagnifierUIState->bLockMagnifierPosition; - params.uImageHeight = H; - params.uImageWidth = W; - params.iMousePos[0] = bLocked ? pMagnifierUIState->LockedMagnifiedScreenPositionX : MouseX; - params.iMousePos[1] = bLocked ? pMagnifierUIState->LockedMagnifiedScreenPositionY : MouseY; - memcpy(params.fBorderColorRGB, bLocked ? MAGNIFIER_BORDER_COLOR__LOCKED : MAGNIFIER_BORDER_COLOR__FREE, sizeof(float) * 3); - - MagnifierPass::KeepMagnifierOnScreen(*pMagnifierUIState->pMagnifierParams); -} - void VQEngine::UpdateThread_UpdateScene_MainWnd(const float dt) { std::unique_ptr& pWin = mpWinMain; @@ -467,7 +449,6 @@ void VQEngine::UpdateThread_UpdateScene_MainWnd(const float dt) HandleMainWindowInput(input, hwnd); } HandleUIInput(); - UpdateMagnifierParameters(mUIState.mpMagnifierState.get(), mUIState, mpWinMain->GetWidth(), mpWinMain->GetHeight()); } void VQEngine::UpdateThread_UpdateScene_DebugWnd(const float dt) @@ -490,7 +471,7 @@ void VQEngine::Load_SceneData_Dispatch() mQueue_SceneLoad.pop(); - const int NUM_SWAPCHAIN_BACKBUFFERS = mSettings.gfx.bUseTripleBuffering ? 3 : 2; + const int NUM_SWAPCHAIN_BACKBUFFERS = mSettings.gfx.Display.bUseTripleBuffering ? 3 : 2; const Input& input = mInputStates.at(mpWinMain->GetHWND()); auto fnCreateSceneInstance = [&](const std::string& SceneType, std::unique_ptr& pScene) -> void @@ -503,7 +484,7 @@ void VQEngine::Load_SceneData_Dispatch() else if (SceneType == "Terrain") pScene = std::make_unique(*this, NUM_SWAPCHAIN_BACKBUFFERS, input, mpWinMain, *mpRenderer); }; - const bool bUpscalingEnabled = mpScene ? mpScene->GetPostProcessParameters(0).IsFSREnabled() : false; + const bool bUpscalingEnabled = mpScene ? mSettings.gfx.IsFSR1Enabled() : false; if (mpScene) { this->WaitUntilRenderingFinishes(); @@ -536,15 +517,16 @@ void VQEngine::Load_SceneData_Dispatch() { const uint32 W = mpWinMain->GetWidth(); const uint32 H = mpWinMain->GetHeight(); - mEventQueue_WinToVQE_Renderer.AddItem(std::make_unique(W, H, mpWinMain->GetHWND())); - mEventQueue_WinToVQE_Update.AddItem(std::make_unique(W, H, mpWinMain->GetHWND())); + HWND hwnd = mpWinMain->GetHWND(); + mEventQueue_WinToVQE_Renderer.AddItem(std::make_unique(W, H, hwnd)); + mEventQueue_WinToVQE_Update.AddItem(std::make_unique(W, H, hwnd)); } //---------------------------------------------------------------------- // start loading environment map textures if (!SceneRep.EnvironmentMapPreset.empty()) { - mWorkers_Simulation.AddTask([=]() { LoadEnvironmentMap(SceneRep.EnvironmentMapPreset, mSettings.gfx.EnvironmentMapResolution); }); + mWorkers_Simulation.AddTask([=]() { LoadEnvironmentMap(SceneRep.EnvironmentMapPreset, mSettings.gfx.Rendering.EnvironmentMapResolution); }); } // start loading textures, models, materials with worker threads @@ -673,7 +655,7 @@ void VQEngine::StartLoadingEnvironmentMap(int IndexEnvMap) mbLoadingEnvironmentMap = true; mWorkers_Simulation.AddTask([&, IndexEnvMap]() { - LoadEnvironmentMap(mResourceNames.mEnvironmentMapPresetNames[IndexEnvMap], mSettings.gfx.EnvironmentMapResolution); + LoadEnvironmentMap(mResourceNames.mEnvironmentMapPresetNames[IndexEnvMap], mSettings.gfx.Rendering.EnvironmentMapResolution); }); } diff --git a/Source/Renderer/CMakeLists.txt b/Source/Renderer/CMakeLists.txt index c441cd2c..9a4193f2 100644 --- a/Source/Renderer/CMakeLists.txt +++ b/Source/Renderer/CMakeLists.txt @@ -10,22 +10,22 @@ set (LibHeadersD3D12X "Libs/D3DX12/d3dx12.h" ) set (LibFFX_CACAO - "Libs/AMDFidelityFX/CACAO/ffx_cacao_defines.h" - "Libs/AMDFidelityFX/CACAO/ffx_cacao.cpp" - "Libs/AMDFidelityFX/CACAO/ffx_cacao.h" - "Libs/AMDFidelityFX/CACAO/ffx_cacao_impl.cpp" - "Libs/AMDFidelityFX/CACAO/ffx_cacao_impl.h" + "Libs/AMD/CACAO/ffx_cacao_defines.h" + "Libs/AMD/CACAO/ffx_cacao.cpp" + "Libs/AMD/CACAO/ffx_cacao.h" + "Libs/AMD/CACAO/ffx_cacao_impl.cpp" + "Libs/AMD/CACAO/ffx_cacao_impl.h" ) set (LibFFX_SSSR - "Libs/AMDFidelityFX/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_128spp.cpp" - "Libs/AMDFidelityFX/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_16spp.cpp" - "Libs/AMDFidelityFX/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_1spp.cpp" - "Libs/AMDFidelityFX/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_256spp.cpp" - "Libs/AMDFidelityFX/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_2spp.cpp" - "Libs/AMDFidelityFX/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_32spp.cpp" - "Libs/AMDFidelityFX/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_4spp.cpp" - "Libs/AMDFidelityFX/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_64spp.cpp" - "Libs/AMDFidelityFX/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_8spp.cpp" + "Libs/AMD/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_128spp.cpp" + "Libs/AMD/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_16spp.cpp" + "Libs/AMD/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_1spp.cpp" + "Libs/AMD/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_256spp.cpp" + "Libs/AMD/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_2spp.cpp" + "Libs/AMD/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_32spp.cpp" + "Libs/AMD/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_4spp.cpp" + "Libs/AMD/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_64spp.cpp" + "Libs/AMD/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_8spp.cpp" ) set (LibD3D12MA "Libs/D3D12MA/src/D3D12MemAlloc.h" @@ -100,7 +100,12 @@ set(RenderingSources "Rendering/LoadingScreenRendering.cpp" "Rendering/Batching.cpp" ) - +set (PostProcessHeaders + "Rendering/PostProcess/Upscaling.h" +) +set (PostProcessSources + "Rendering/PostProcess/Upscaling.cpp" +) # Render Passes set(RenderPassHeaders "Rendering/RenderPass/RenderPass.h" @@ -112,6 +117,7 @@ set(RenderPassHeaders "Rendering/RenderPass/MagnifierPass.h" "Rendering/RenderPass/ObjectIDPass.h" "Rendering/RenderPass/OutlinePass.h" + "Rendering/RenderPass/FSR3UpscalePass.h" ) set(RenderPassSources "Rendering/RenderPass/RenderPass.cpp" @@ -123,6 +129,7 @@ set(RenderPassSources "Rendering/RenderPass/MagnifierPass.cpp" "Rendering/RenderPass/ObjectIDPass.cpp" "Rendering/RenderPass/OutlinePass.cpp" + "Rendering/RenderPass/FSR3UpscalePass.cpp" ) # Renderer @@ -166,33 +173,33 @@ set (Shaders "../../Shaders/VQPlatform.h" ) set (FFX_CAS_Shaders - "../../Shaders/AMDFidelityFX/CAS/ffx_a.h" - "../../Shaders/AMDFidelityFX/CAS/ffx_cas.h" + "../../Shaders/AMD/CAS/ffx_a.h" + "../../Shaders/AMD/CAS/ffx_cas.h" ) set (FFX_FSR_Shaders - "../../Shaders/AMDFidelityFX/FSR1.0/ffx_a.h" - "../../Shaders/AMDFidelityFX/FSR1.0/ffx_fsr1.h" + "../../Shaders/AMD/FSR1.0/ffx_a.h" + "../../Shaders/AMD/FSR1.0/ffx_fsr1.h" ) set (FFX_SPD_Shaders - "../../Shaders/AMDFidelityFX/SPD/ffx_a.h" - "../../Shaders/AMDFidelityFX/SPD/ffx_spd.h" + "../../Shaders/AMD/SPD/ffx_a.h" + "../../Shaders/AMD/SPD/ffx_spd.h" ) set (FFX_CACAO_Shaders - "../../Shaders/AMDFidelityFX/CACAO/ffx_cacao.hlsl" + "../../Shaders/AMD/CACAO/ffx_cacao.hlsl" ) set (FFX_SSSR_Shaders - "../../Shaders/AMDFidelityFX/SSSR/ffx_sssr.h" + "../../Shaders/AMD/SSSR/ffx_sssr.h" ) set (FFX_DNSR_Shaders - "../../Shaders/AMDFidelityFX/DNSR/ffx_denoiser_reflections_common.h" - "../../Shaders/AMDFidelityFX/DNSR/ffx_denoiser_reflections_config.h" - "../../Shaders/AMDFidelityFX/DNSR/ffx_denoiser_reflections_prefilter.h" - "../../Shaders/AMDFidelityFX/DNSR/ffx_denoiser_reflections_reproject.h" - "../../Shaders/AMDFidelityFX/DNSR/ffx_denoiser_reflections_resolve_temporal.h" - "../../Shaders/AMDFidelityFX/DNSR/ffx_denoiser_shadows_filter.h" - "../../Shaders/AMDFidelityFX/DNSR/ffx_denoiser_shadows_prepare.h" - "../../Shaders/AMDFidelityFX/DNSR/ffx_denoiser_shadows_tileclassification.h" - "../../Shaders/AMDFidelityFX/DNSR/ffx_denoiser_shadows_util.h" + "../../Shaders/AMD/DNSR/ffx_denoiser_reflections_common.h" + "../../Shaders/AMD/DNSR/ffx_denoiser_reflections_config.h" + "../../Shaders/AMD/DNSR/ffx_denoiser_reflections_prefilter.h" + "../../Shaders/AMD/DNSR/ffx_denoiser_reflections_reproject.h" + "../../Shaders/AMD/DNSR/ffx_denoiser_reflections_resolve_temporal.h" + "../../Shaders/AMD/DNSR/ffx_denoiser_shadows_filter.h" + "../../Shaders/AMD/DNSR/ffx_denoiser_shadows_prepare.h" + "../../Shaders/AMD/DNSR/ffx_denoiser_shadows_tileclassification.h" + "../../Shaders/AMD/DNSR/ffx_denoiser_shadows_util.h" ) set (ShadersScreenSpaceReflections "../../Shaders/ScreenSpaceReflections/ClassifyReflectionTiles.hlsl" @@ -210,19 +217,20 @@ source_group("Resources" FILES ${ResourceHeaders} ${ResourceSources}) source_group("Pipeline" FILES ${PipelineHeaders} ${PipelineSources}) source_group("Rendering" FILES ${RenderingHeaders} ${RenderingSources}) source_group("Rendering\\RenderPass" FILES ${RenderPassHeaders} ${RenderPassSources}) +source_group("Rendering\\PostProcess" FILES ${PostProcessHeaders} ${PostProcessSources}) source_group("Renderer" FILES ${Renderer}) source_group("Shaders" FILES ${Shaders}) source_group("Shaders\\ScreenSpaceReflections" FILES ${ShadersScreenSpaceReflections}) -source_group("Shaders\\AMD-FidelityFX\\CAS" FILES ${FFX_CAS_Shaders}) -source_group("Shaders\\AMD-FidelityFX\\FSR1" FILES ${FFX_FSR_Shaders}) -source_group("Shaders\\AMD-FidelityFX\\SPD" FILES ${FFX_SPD_Shaders}) -source_group("Shaders\\AMD-FidelityFX\\CACAO" FILES ${FFX_CACAO_Shaders}) -source_group("Shaders\\AMD-FidelityFX\\SSSR" FILES ${FFX_SSSR_Shaders}) -source_group("Shaders\\AMD-FidelityFX\\DNSR" FILES ${FFX_DNSR_Shaders}) +source_group("Shaders\\AMD\\CAS" FILES ${FFX_CAS_Shaders}) +source_group("Shaders\\AMD\\FSR1" FILES ${FFX_FSR_Shaders}) +source_group("Shaders\\AMD\\SPD" FILES ${FFX_SPD_Shaders}) +source_group("Shaders\\AMD\\CACAO" FILES ${FFX_CACAO_Shaders}) +source_group("Shaders\\AMD\\SSSR" FILES ${FFX_SSSR_Shaders}) +source_group("Shaders\\AMD\\DNSR" FILES ${FFX_DNSR_Shaders}) -source_group("Libs\\AMD-FidelityFX\\CACAO" FILES ${LibFFX_CACAO}) -source_group("Libs\\AMD-FidelityFX\\SSSR" FILES ${LibFFX_SSSR}) +source_group("Libs\\AMD\\CACAO" FILES ${LibFFX_CACAO}) +source_group("Libs\\AMD\\SSSR" FILES ${LibFFX_SSSR}) source_group("Libs\\D3D12X" FILES ${LibHeadersD3D12X}) source_group("Libs\\D3D12MA" FILES ${LibD3D12MA}) @@ -259,6 +267,7 @@ add_library(${PROJECT_NAME} STATIC ${PipelineHeaders} ${PipelineSources} ${RenderingHeaders} ${RenderingSources} ${RenderPassHeaders} ${RenderPassSources} + ${PostProcessHeaders} ${PostProcessSources} ${Renderer} ${Shaders} @@ -276,6 +285,15 @@ add_definitions(-DFFX_CACAO_ENABLE_D3D12) target_include_directories(${PROJECT_NAME} PUBLIC "../") # Engine / Renderer / Scenes target_include_directories(${PROJECT_NAME} PUBLIC "../../") # VQE root target_include_directories(${PROJECT_NAME} PUBLIC "./") # Renderer root +target_include_directories(${PROJECT_NAME} PUBLIC "./Libs/AMD/FidelityFX-SDK/ffx-api/include/") add_custom_command(TARGET ${PROJECT_NAME} PRE_BUILD - COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/Libs/AMDFidelityFX/CACAO/build_shaders_dxil.bat) + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/Libs/AMD/CACAO/build_shaders_dxil.bat +) + +add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + "${CMAKE_CURRENT_SOURCE_DIR}/Libs/AMD/FidelityFX-SDK/PrebuiltSignedDLL/amd_fidelityfx_dx12.dll" + "${CMAKE_CURRENT_SOURCE_DIR}/../../Bin/${CMAKE_CFG_INTDIR}/" + COMMENT "Copying amd_fidelityfx_dx12.dll to Bin directory" +) \ No newline at end of file diff --git a/Source/Renderer/Libs/AMDFidelityFX/CACAO/build_shaders_dxil.bat b/Source/Renderer/Libs/AMD/CACAO/build_shaders_dxil.bat similarity index 100% rename from Source/Renderer/Libs/AMDFidelityFX/CACAO/build_shaders_dxil.bat rename to Source/Renderer/Libs/AMD/CACAO/build_shaders_dxil.bat diff --git a/Source/Renderer/Libs/AMDFidelityFX/CACAO/ffx_cacao.cpp b/Source/Renderer/Libs/AMD/CACAO/ffx_cacao.cpp similarity index 100% rename from Source/Renderer/Libs/AMDFidelityFX/CACAO/ffx_cacao.cpp rename to Source/Renderer/Libs/AMD/CACAO/ffx_cacao.cpp diff --git a/Source/Renderer/Libs/AMDFidelityFX/CACAO/ffx_cacao.h b/Source/Renderer/Libs/AMD/CACAO/ffx_cacao.h similarity index 100% rename from Source/Renderer/Libs/AMDFidelityFX/CACAO/ffx_cacao.h rename to Source/Renderer/Libs/AMD/CACAO/ffx_cacao.h diff --git a/Source/Renderer/Libs/AMDFidelityFX/CACAO/ffx_cacao.hlsl b/Source/Renderer/Libs/AMD/CACAO/ffx_cacao.hlsl similarity index 100% rename from Source/Renderer/Libs/AMDFidelityFX/CACAO/ffx_cacao.hlsl rename to Source/Renderer/Libs/AMD/CACAO/ffx_cacao.hlsl diff --git a/Source/Renderer/Libs/AMDFidelityFX/CACAO/ffx_cacao_bindings.hlsl b/Source/Renderer/Libs/AMD/CACAO/ffx_cacao_bindings.hlsl similarity index 100% rename from Source/Renderer/Libs/AMDFidelityFX/CACAO/ffx_cacao_bindings.hlsl rename to Source/Renderer/Libs/AMD/CACAO/ffx_cacao_bindings.hlsl diff --git a/Source/Renderer/Libs/AMDFidelityFX/CACAO/ffx_cacao_defines.h b/Source/Renderer/Libs/AMD/CACAO/ffx_cacao_defines.h similarity index 100% rename from Source/Renderer/Libs/AMDFidelityFX/CACAO/ffx_cacao_defines.h rename to Source/Renderer/Libs/AMD/CACAO/ffx_cacao_defines.h diff --git a/Source/Renderer/Libs/AMDFidelityFX/CACAO/ffx_cacao_impl.cpp b/Source/Renderer/Libs/AMD/CACAO/ffx_cacao_impl.cpp similarity index 100% rename from Source/Renderer/Libs/AMDFidelityFX/CACAO/ffx_cacao_impl.cpp rename to Source/Renderer/Libs/AMD/CACAO/ffx_cacao_impl.cpp diff --git a/Source/Renderer/Libs/AMDFidelityFX/CACAO/ffx_cacao_impl.h b/Source/Renderer/Libs/AMD/CACAO/ffx_cacao_impl.h similarity index 100% rename from Source/Renderer/Libs/AMDFidelityFX/CACAO/ffx_cacao_impl.h rename to Source/Renderer/Libs/AMD/CACAO/ffx_cacao_impl.h diff --git a/Source/Renderer/Libs/AMD/FidelityFX-SDK b/Source/Renderer/Libs/AMD/FidelityFX-SDK new file mode 160000 index 00000000..c6efa6bf --- /dev/null +++ b/Source/Renderer/Libs/AMD/FidelityFX-SDK @@ -0,0 +1 @@ +Subproject commit c6efa6bf7f2027b3ec94f28578bb5965eabb9e55 diff --git a/Source/Renderer/Libs/AMDFidelityFX/SSSR/samplerCPP/README.txt b/Source/Renderer/Libs/AMD/SSSR/samplerCPP/README.txt similarity index 100% rename from Source/Renderer/Libs/AMDFidelityFX/SSSR/samplerCPP/README.txt rename to Source/Renderer/Libs/AMD/SSSR/samplerCPP/README.txt diff --git a/Source/Renderer/Libs/AMDFidelityFX/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_128spp.cpp b/Source/Renderer/Libs/AMD/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_128spp.cpp similarity index 100% rename from Source/Renderer/Libs/AMDFidelityFX/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_128spp.cpp rename to Source/Renderer/Libs/AMD/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_128spp.cpp diff --git a/Source/Renderer/Libs/AMDFidelityFX/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_16spp.cpp b/Source/Renderer/Libs/AMD/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_16spp.cpp similarity index 100% rename from Source/Renderer/Libs/AMDFidelityFX/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_16spp.cpp rename to Source/Renderer/Libs/AMD/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_16spp.cpp diff --git a/Source/Renderer/Libs/AMDFidelityFX/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_1spp.cpp b/Source/Renderer/Libs/AMD/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_1spp.cpp similarity index 100% rename from Source/Renderer/Libs/AMDFidelityFX/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_1spp.cpp rename to Source/Renderer/Libs/AMD/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_1spp.cpp diff --git a/Source/Renderer/Libs/AMDFidelityFX/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_256spp.cpp b/Source/Renderer/Libs/AMD/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_256spp.cpp similarity index 100% rename from Source/Renderer/Libs/AMDFidelityFX/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_256spp.cpp rename to Source/Renderer/Libs/AMD/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_256spp.cpp diff --git a/Source/Renderer/Libs/AMDFidelityFX/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_2spp.cpp b/Source/Renderer/Libs/AMD/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_2spp.cpp similarity index 100% rename from Source/Renderer/Libs/AMDFidelityFX/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_2spp.cpp rename to Source/Renderer/Libs/AMD/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_2spp.cpp diff --git a/Source/Renderer/Libs/AMDFidelityFX/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_32spp.cpp b/Source/Renderer/Libs/AMD/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_32spp.cpp similarity index 100% rename from Source/Renderer/Libs/AMDFidelityFX/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_32spp.cpp rename to Source/Renderer/Libs/AMD/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_32spp.cpp diff --git a/Source/Renderer/Libs/AMDFidelityFX/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_4spp.cpp b/Source/Renderer/Libs/AMD/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_4spp.cpp similarity index 100% rename from Source/Renderer/Libs/AMDFidelityFX/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_4spp.cpp rename to Source/Renderer/Libs/AMD/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_4spp.cpp diff --git a/Source/Renderer/Libs/AMDFidelityFX/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_64spp.cpp b/Source/Renderer/Libs/AMD/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_64spp.cpp similarity index 100% rename from Source/Renderer/Libs/AMDFidelityFX/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_64spp.cpp rename to Source/Renderer/Libs/AMD/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_64spp.cpp diff --git a/Source/Renderer/Libs/AMDFidelityFX/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_8spp.cpp b/Source/Renderer/Libs/AMD/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_8spp.cpp similarity index 100% rename from Source/Renderer/Libs/AMDFidelityFX/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_8spp.cpp rename to Source/Renderer/Libs/AMD/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_8spp.cpp diff --git a/Source/Renderer/Pipeline/PipelineStateObjects.cpp b/Source/Renderer/Pipeline/PipelineStateObjects.cpp index 89471ec1..7093fa9f 100644 --- a/Source/Renderer/Pipeline/PipelineStateObjects.cpp +++ b/Source/Renderer/Pipeline/PipelineStateObjects.cpp @@ -1066,8 +1066,8 @@ std::vector VQRenderer::LoadBuiltinPSODescs_Legacy() psoDesc.BlendState.RenderTarget[0].SrcBlend = D3D12_BLEND_SRC_ALPHA; psoDesc.BlendState.RenderTarget[0].DestBlend = D3D12_BLEND_INV_SRC_ALPHA; psoDesc.BlendState.RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD; - psoDesc.BlendState.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_INV_SRC_ALPHA; - psoDesc.BlendState.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_ZERO; + psoDesc.BlendState.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_SRC_ALPHA; + psoDesc.BlendState.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_DEST_ALPHA; psoDesc.BlendState.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD; psoDesc.BlendState.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; psoDesc.DepthStencilState.DepthEnable = FALSE; @@ -1100,13 +1100,13 @@ std::vector VQRenderer::LoadBuiltinPSODescs_Legacy() psoDesc.pRootSignature = mRootSignatureLookup.at(EBuiltinRootSignatures::LEGACY__UI_HDR_Composite); psoDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT); psoDesc.RasterizerState.CullMode = D3D12_CULL_MODE_NONE; - psoDesc.BlendState.RenderTarget[0].BlendEnable = false; - psoDesc.BlendState.RenderTarget[0].SrcBlend = D3D12_BLEND_SRC_ALPHA; - psoDesc.BlendState.RenderTarget[0].DestBlend = D3D12_BLEND_INV_SRC_ALPHA; - psoDesc.BlendState.RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD; - psoDesc.BlendState.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_INV_SRC_ALPHA; + psoDesc.BlendState.RenderTarget[0].BlendEnable = true; + psoDesc.BlendState.RenderTarget[0].SrcBlend = D3D12_BLEND_SRC_ALPHA; + psoDesc.BlendState.RenderTarget[0].DestBlend = D3D12_BLEND_INV_SRC_ALPHA; + psoDesc.BlendState.RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD; + psoDesc.BlendState.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_ZERO; psoDesc.BlendState.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_ZERO; - psoDesc.BlendState.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD; + psoDesc.BlendState.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_MAX; psoDesc.BlendState.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; psoDesc.DepthStencilState.DepthEnable = FALSE; psoDesc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL; @@ -1152,6 +1152,15 @@ std::vector VQRenderer::LoadBuiltinPSODescs_Legacy() descs[EBuiltinPSOs::SKYDOME_PSO] = psoLoadDesc; + psoLoadDesc.PSOName = "PSO_Skydome_Masked"; + psoDesc.NumRenderTargets = 2; + psoDesc.RTVFormats[1] = DXGI_FORMAT_R16_FLOAT; + psoLoadDesc.ShaderStageCompileDescs[1].Macros.push_back(FShaderMacro{"PS_OUTPUT_MASK", "1"}); + descs[EBuiltinPSOs::SKYDOME_MASK_PSO] = psoLoadDesc; + psoLoadDesc.ShaderStageCompileDescs[1].Macros.pop_back(); + psoDesc.RTVFormats[1] = DXGI_FORMAT_UNKNOWN; + psoDesc.NumRenderTargets = 1; + // MSAA PSO psoLoadDesc.PSOName = "PSO_Skydome_MSAA4"; psoDesc.SampleDesc.Count = 4; diff --git a/Source/Renderer/Pipeline/PipelineStateObjects.h b/Source/Renderer/Pipeline/PipelineStateObjects.h index c3c9fc5b..ea7daf33 100644 --- a/Source/Renderer/Pipeline/PipelineStateObjects.h +++ b/Source/Renderer/Pipeline/PipelineStateObjects.h @@ -59,6 +59,7 @@ enum EBuiltinPSOs // TODO: remove the hardcoded PSOs when a generic Shader solut TONEMAPPER_PSO, HDR_FP16_SWAPCHAIN_PSO, SKYDOME_PSO, + SKYDOME_MASK_PSO, SKYDOME_PSO_MSAA_4, WIREFRAME_PSO, WIREFRAME_PSO_MSAA_4, diff --git a/Source/Renderer/Pipeline/RootSignatures.cpp b/Source/Renderer/Pipeline/RootSignatures.cpp index 2ec074a6..70d5432c 100644 --- a/Source/Renderer/Pipeline/RootSignatures.cpp +++ b/Source/Renderer/Pipeline/RootSignatures.cpp @@ -537,16 +537,13 @@ void VQRenderer::LoadBuiltinRootSignatures() // UIHDRComposite Root Signature : [16] { - CD3DX12_DESCRIPTOR_RANGE1 ranges[3]; + CD3DX12_DESCRIPTOR_RANGE1 ranges[1]; ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0, 0, D3D12_DESCRIPTOR_RANGE_FLAG_NONE); - ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 1, 0, D3D12_DESCRIPTOR_RANGE_FLAG_NONE); - ranges[2].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0, 0, D3D12_DESCRIPTOR_RANGE_FLAG_NONE); + //ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0, 0, D3D12_DESCRIPTOR_RANGE_FLAG_NONE); - CD3DX12_ROOT_PARAMETER1 rootParameters[3]; + CD3DX12_ROOT_PARAMETER1 rootParameters[2]; rootParameters[0].InitAsDescriptorTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_PIXEL); - rootParameters[1].InitAsDescriptorTable(1, &ranges[1], D3D12_SHADER_VISIBILITY_PIXEL); - //rootParameters[1].InitAsDescriptorTable(1, &ranges[1], D3D12_SHADER_VISIBILITY_PIXEL); - rootParameters[2].InitAsConstants(1, 0); + rootParameters[1].InitAsConstants(1, 0); CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC rootSignatureDesc; rootSignatureDesc.Init_1_1(_countof(rootParameters), rootParameters, 0, NULL, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); diff --git a/Source/Renderer/Renderer.cpp b/Source/Renderer/Renderer.cpp index a3c07de8..fe15c232 100644 --- a/Source/Renderer/Renderer.cpp +++ b/Source/Renderer/Renderer.cpp @@ -38,6 +38,7 @@ #include "Rendering/RenderPass/MagnifierPass.h" #include "Rendering/RenderPass/ObjectIDPass.h" #include "Rendering/RenderPass/OutlinePass.h" +#include "Rendering/RenderPass/FSR3UpscalePass.h" #include "Engine/Core/Window.h" #include "Engine/Core/Platform.h" @@ -239,7 +240,7 @@ void VQRenderer::Initialize(const FGraphicsSettings& Settings) mLatchDeviceInitialized.count_down(); } - const int NumSwapchainBuffers = Settings.bUseTripleBuffering ? 3 : 2; + const int NumSwapchainBuffers = Settings.Display.bUseTripleBuffering ? 3 : 2; ID3D12Device* pDevice = mDevice.GetDevicePtr(); // Create Command Queues of different types @@ -583,6 +584,7 @@ void VQRenderer::Load() mRenderPasses[ERenderPass::ObjectID ] = std::make_shared(*this); mRenderPasses[ERenderPass::ScreenSpaceReflections] = std::make_shared(*this); mRenderPasses[ERenderPass::Outline ] = std::make_shared(*this); + mRenderPasses[ERenderPass::FSR3Upscale ] = std::make_shared(*this); { SCOPED_CPU_MARKER_C("WaitRootSignatures", 0xFF0000AA); mLatchRootSignaturesInitialized.wait(); @@ -709,14 +711,6 @@ void VQRenderer::Destroy() void VQRenderer::OnWindowSizeChanged(HWND hwnd, unsigned w, unsigned h) { - if (!CheckContext(hwnd)) - return; - - FWindowRenderContext& ctx = mRenderContextLookup.at(hwnd); - ctx.WindowDisplayResolutionX = w; - ctx.WindowDisplayResolutionY = h; - - } SwapChain& VQRenderer::GetWindowSwapChain(HWND hwnd) { return mRenderContextLookup.at(hwnd).SwapChain; } @@ -751,10 +745,6 @@ void VQRenderer::InitializeRenderContext(const Window* pWin, int NumSwapchainBuf } ctx.InitializeContext(pWin, pVQDevice, NumSwapchainBuffers, bVSync, bHDRSwapchain); - // Save other context data - ctx.WindowDisplayResolutionX = pWin->GetWidth(); - ctx.WindowDisplayResolutionY = pWin->GetHeight(); - // save the render context this->mRenderContextLookup.emplace(pWin->GetHWND(), std::move(ctx)); mLatchSwapchainInitialized.count_down(); diff --git a/Source/Renderer/Renderer.h b/Source/Renderer/Renderer.h index ea69b304..f221fc2b 100644 --- a/Source/Renderer/Renderer.h +++ b/Source/Renderer/Renderer.h @@ -133,7 +133,7 @@ class VQRenderer // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- void WaitForLoadCompletion() const; void OnWindowSizeChanged(HWND hwnd, unsigned w, unsigned h); - void LoadWindowSizeDependentResources(HWND hwnd, unsigned w, unsigned h, float fResolutionScale, bool bHDR); + void LoadWindowSizeDependentResources(HWND hwnd, const FGraphicsSettings& GFXSettings, bool bHDR); void UnloadWindowSizeDependentResources(HWND hwnd); // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -172,6 +172,7 @@ class VQRenderer inline void WaitForTexture(TextureID ID) const { mTextureManager.WaitForTexture(ID); }; // blocks caller until texture is loaded TextureManager& GetTextureManager() { return mTextureManager; } + const FTexture* GetTexture(TextureID Id) const; ID3D12Resource* GetTextureResource(TextureID Id) const; DXGI_FORMAT GetTextureFormat(TextureID Id) const; bool GetTextureAlphaChannelUsed(TextureID Id) const; @@ -252,7 +253,6 @@ class VQRenderer const Window* pWindow, const FSceneView& SceneView, const FSceneShadowViews& ShadowView, - const FPostProcessParameters& PPParams, const FGraphicsSettings& GFXSettings, const FUIState& UIState ); @@ -261,7 +261,6 @@ class VQRenderer const Window* pWindow, const FSceneView& SceneView, const FSceneShadowViews& ShadowView, - const FPostProcessParameters& PPParams, const FGraphicsSettings& GFXSettings, const FUIState& UIState, bool bHDRDisplay @@ -288,6 +287,9 @@ class VQRenderer void ResetNumFramesRendered() { mRenderStats.mNumFramesRendered = 0; } const FRenderStats& GetRenderStats() const { return mRenderStats; } + bool ShouldEnableCameraJitters(const FGraphicsSettings& gfx) const; + void GetCameraPixelSpaceJitter(const FGraphicsSettings& gfx, size_t iFrame, float& JitterX, float& JitterY) const; + // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // Frame Sync // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -320,9 +322,9 @@ class VQRenderer // render command execution context CommandQueue mRenderingCmdQueues[NUM_COMMAND_QUEUE_TYPES]; std::vector> mRenderingCommandAllocators[NUM_COMMAND_QUEUE_TYPES]; // pre queue, per back buffer, per recording thread - std::vector> mpRenderingCmds[NUM_COMMAND_QUEUE_TYPES]; // per queue, per back buffer, per recording thread - std::vector> mCmdClosed[NUM_COMMAND_QUEUE_TYPES]; // per queue, per back buffer, per recording thread - std::vector mDynamicHeap_RenderingConstantBuffer; // per recording thread + std::vector> mpRenderingCmds[NUM_COMMAND_QUEUE_TYPES]; // per queue, per back buffer, per recording thread + std::vector> mCmdClosed[NUM_COMMAND_QUEUE_TYPES]; // per queue, per back buffer, per recording thread + std::vector mDynamicHeap_RenderingConstantBuffer; // per recording thread UINT mNumCurrentlyRecordingRenderingThreads[NUM_COMMAND_QUEUE_TYPES]; std::vector mAsyncComputeSSAOReadyFence; std::vector mAsyncComputeSSAODoneFence; @@ -333,10 +335,10 @@ class VQRenderer FCommandRecordingThreadConfig mRenderWorkerConfig[NUM_RENDER_THREAD_WORK_IDS]; // frame presentation context - CommandQueue mRenderingPresentationQueue; - bool mWaitForSubmitWorker = false; - TaskSignal mSubmitWorkerSignal; - std::thread mFrameSubmitThread; // currenly unused, main thread submits the frame + CommandQueue mRenderingPresentationQueue; + bool mWaitForSubmitWorker = false; + TaskSignal mSubmitWorkerSignal; + std::thread mFrameSubmitThread; // currenly unused, main thread submits the frame std::atomic mStopTrheads = false; // background gpu task execution context @@ -347,12 +349,12 @@ class VQRenderer NUM_BACKGROUND_TASK_THREADS, }; - CommandQueue mBackgroundTaskCmdQueues[NUM_COMMAND_QUEUE_TYPES]; + CommandQueue mBackgroundTaskCmdQueues[NUM_COMMAND_QUEUE_TYPES]; ID3D12CommandAllocator* mBackgroundTaskCommandAllocators[NUM_COMMAND_QUEUE_TYPES][NUM_BACKGROUND_TASK_THREADS]; - ID3D12CommandList* mpBackgroundTaskCmds[NUM_COMMAND_QUEUE_TYPES][NUM_BACKGROUND_TASK_THREADS]; - DynamicBufferHeap mDynamicHeap_BackgroundTaskConstantBuffer[NUM_BACKGROUND_TASK_THREADS]; - UINT mNumCurrentlyRecordingBackgroundTaskThreads[NUM_COMMAND_QUEUE_TYPES]; - Fence mBackgroundTaskFencesPerQueue[NUM_COMMAND_QUEUE_TYPES]; + ID3D12CommandList* mpBackgroundTaskCmds[NUM_COMMAND_QUEUE_TYPES][NUM_BACKGROUND_TASK_THREADS]; + DynamicBufferHeap mDynamicHeap_BackgroundTaskConstantBuffer[NUM_BACKGROUND_TASK_THREADS]; + UINT mNumCurrentlyRecordingBackgroundTaskThreads[NUM_COMMAND_QUEUE_TYPES]; + Fence mBackgroundTaskFencesPerQueue[NUM_COMMAND_QUEUE_TYPES]; // memory allocator D3D12MA::Allocator* mpAllocator = nullptr; @@ -393,7 +395,7 @@ class VQRenderer std::unordered_map mPSOs; ThreadPool mWorkers_PSOLoad; ThreadPool mWorkers_ShaderLoad; - struct FPSOCompileResult { ID3D12PipelineState* pPSO; PSO_ID id; }; + struct FPSOCompileResult { ID3D12PipelineState* pPSO; PSO_ID id; }; struct FShaderLoadTaskContext { std::queue TaskQueue; }; std::vector > mPSOCompileResults; std::vector> mShaderCompileResults; @@ -407,25 +409,24 @@ class VQRenderer std::vector mFrameSceneDrawData; // per-frame if pipelined update+render threads // init sync - std::latch mLatchDeviceInitialized{ 1 }; - std::latch mLatchCmdQueuesInitialized{ 1 }; - std::latch mLatchMemoryAllocatorInitialized{ 1 }; - std::latch mLatchHeapsInitialized{ 1 }; - std::latch mLatchRootSignaturesInitialized{ 1 }; - std::latch mLatchSignalLoadingScreenReady{ 1 }; - std::latch mLatchPSOLoaderDispatched{ 1 }; - std::latch mLatchRenderPassesInitialized{ 1 }; - std::latch mLatchSwapchainInitialized{ 1 }; - std::latch mLatchDefaultResourcesLoaded{ 1 }; - std::latch mLatchWindowSizeDependentResourcesInitialized{ 1 }; - bool mbWindowSizeDependentResourcesFirstInitiazliationDone = false; + std::latch mLatchDeviceInitialized{ 1 }; + std::latch mLatchCmdQueuesInitialized{ 1 }; + std::latch mLatchMemoryAllocatorInitialized{ 1 }; + std::latch mLatchHeapsInitialized{ 1 }; + std::latch mLatchRootSignaturesInitialized{ 1 }; + std::latch mLatchSignalLoadingScreenReady{ 1 }; + std::latch mLatchPSOLoaderDispatched{ 1 }; + std::latch mLatchRenderPassesInitialized{ 1 }; + std::latch mLatchSwapchainInitialized{ 1 }; + std::latch mLatchDefaultResourcesLoaded{ 1 }; + std::latch mLatchWindowSizeDependentResourcesInitialized{ 1 }; + bool mbWindowSizeDependentResourcesFirstInitiazliationDone = false; // bookkeeping std::unordered_map mLookup_ProceduralTextureSRVs; std::unordered_map mLookup_ProceduralTextureIDs; std::unordered_map mShaderCacheDirtyMap; - FRenderStats mRenderStats; private: @@ -454,8 +455,9 @@ class VQRenderer // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // Render (Private) // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + struct FPostProcessOutput { ID3D12Resource* pRsc; SRV_ID srv; }; void RenderObjectIDPass(int iThread, ID3D12CommandList* pCmdCopy, DynamicBufferHeap* pCBufferHeap, D3D12_GPU_VIRTUAL_ADDRESS perViewCBAddr, const FSceneView& SceneView, const FSceneShadowViews& ShadowView, const int BACK_BUFFER_INDEX, const FGraphicsSettings& GFXSettings); - void TransitionForSceneRendering(ID3D12GraphicsCommandList* pCmd, FWindowRenderContext& ctx, const FPostProcessParameters& PPParams, const FGraphicsSettings& GFXSettings); + void TransitionForSceneRendering(ID3D12GraphicsCommandList* pCmd, FWindowRenderContext& ctx, const FGraphicsSettings& GFXSettings); void RenderDirectionalShadowMaps(ID3D12GraphicsCommandList* pCmd, DynamicBufferHeap* pCBufferHeap, const FSceneShadowViews& ShadowView, const FSceneView& SceneView); void RenderSpotShadowMaps(ID3D12GraphicsCommandList* pCmd, DynamicBufferHeap* pCBufferHeap, const FSceneShadowViews& ShadowView, const FSceneView& SceneView); void RenderPointShadowMaps(ID3D12GraphicsCommandList* pCmd, DynamicBufferHeap* pCBufferHeap, const FSceneShadowViews& ShadowView, const FSceneView& SceneView, size_t iBegin, size_t NumPointLights); @@ -467,25 +469,26 @@ class VQRenderer void ResolveMSAA_DepthPrePass(ID3D12GraphicsCommandList* pCmd, DynamicBufferHeap* pCBufferHeap); void CopyDepthForCompute(ID3D12GraphicsCommandList* pCmd); void RenderAmbientOcclusion(ID3D12GraphicsCommandList* pCmd, const FSceneView& SceneView, const FGraphicsSettings& GFXSettings, bool bAsyncCompute); - void RenderSceneColor(ID3D12GraphicsCommandList* pCmd, DynamicBufferHeap* pCBufferHeap, const FSceneView& SceneView, const FPostProcessParameters& PPParams, D3D12_GPU_VIRTUAL_ADDRESS perViewCBAddr, D3D12_GPU_VIRTUAL_ADDRESS perFrameCBAddr, const FGraphicsSettings& GFXSettings, bool bHDR); + void RenderSceneColor(ID3D12GraphicsCommandList* pCmd, DynamicBufferHeap* pCBufferHeap, const FSceneView& SceneView, D3D12_GPU_VIRTUAL_ADDRESS perViewCBAddr, D3D12_GPU_VIRTUAL_ADDRESS perFrameCBAddr, const FGraphicsSettings& GFXSettings, bool bHDR); void RenderBoundingBoxes(ID3D12GraphicsCommandList* pCmd, DynamicBufferHeap* pCBufferHeap, const FSceneView& SceneView, bool bMSAA); void RenderOutline(ID3D12GraphicsCommandList* pCmd, DynamicBufferHeap* pCBufferHeap, D3D12_GPU_VIRTUAL_ADDRESS perViewCBAddr, const FSceneView& SceneView, bool bMSAA, const std::vector& rtvHandles); void RenderLightBounds(ID3D12GraphicsCommandList* pCmd, DynamicBufferHeap* pCBufferHeap, const FSceneView& SceneView, bool bMSAA, bool bReflectionsEnabled); void RenderDebugVertexAxes(ID3D12GraphicsCommandList* pCmd, DynamicBufferHeap* pCBufferHeap, const FSceneView& SceneView, bool bMSAA); - void ResolveMSAA(ID3D12GraphicsCommandList* pCmd, DynamicBufferHeap* pCBufferHeap, const FPostProcessParameters& PPParams, const FGraphicsSettings& GFXSettings); + void ResolveMSAA(ID3D12GraphicsCommandList* pCmd, DynamicBufferHeap* pCBufferHeap, const FGraphicsSettings& GFXSettings); void DownsampleDepth(ID3D12GraphicsCommandList* pCmd, DynamicBufferHeap* pCBufferHeap, TextureID DepthTextureID, SRV_ID SRVDepth); void RenderReflections(ID3D12GraphicsCommandList* pCmd, DynamicBufferHeap* pCBufferHeap, const FSceneView& SceneView, const FGraphicsSettings& GFXSettings); - void RenderSceneBoundingVolumes(ID3D12GraphicsCommandList* pCmd, DynamicBufferHeap* pCBufferHeap, D3D12_GPU_VIRTUAL_ADDRESS perViewCBAddr, const FSceneView& SceneView, bool bMSAA); + void RenderSceneBoundingVolumes(ID3D12GraphicsCommandList* pCmd, DynamicBufferHeap* pCBufferHeap, D3D12_GPU_VIRTUAL_ADDRESS perViewCBAddr, const FSceneView& SceneView, const FGraphicsSettings& GFXSettings); void CompositeReflections(ID3D12GraphicsCommandList* pCmd, DynamicBufferHeap* pCBufferHeap, const FSceneView& SceneView, const FGraphicsSettings& GFXSettings); - void TransitionForPostProcessing(ID3D12GraphicsCommandList* pCmd, const FPostProcessParameters& PPParams, const FGraphicsSettings& GFXSettings); - void TransitionForUI(ID3D12GraphicsCommandList* pCmd, const FPostProcessParameters& PPParams, const FGraphicsSettings& GFXSettings, bool bHDRDisplay, ID3D12Resource* pRsc, ID3D12Resource* pSwapChainRT); - ID3D12Resource* RenderPostProcess(ID3D12GraphicsCommandList* pCmd, DynamicBufferHeap* pCBufferHeap, const FPostProcessParameters& PPParams, bool bHDR); - void RenderUI(ID3D12GraphicsCommandList* pCmd, DynamicBufferHeap* pCBufferHeap, FWindowRenderContext& ctx, const FPostProcessParameters& PPParams, ID3D12Resource* pRscIn, const SRV& srv_ColorIn, const FUIState& UIState, bool bHDR); - void CompositUIToHDRSwapchain(ID3D12GraphicsCommandList* pCmd, DynamicBufferHeap* pCBufferHeap, FWindowRenderContext& ctx, const FPostProcessParameters& PPParams, const Window* pWindow); + void TransitionForPostProcessing(ID3D12GraphicsCommandList* pCmd, const FGraphicsSettings& GFXSettings); + void TransitionForUI(ID3D12GraphicsCommandList* pCmd, const FGraphicsSettings& GFXSettings, bool bHDRDisplay, ID3D12Resource* pRsc, ID3D12Resource* pSwapChainRT); + FPostProcessOutput RenderPostProcess(ID3D12GraphicsCommandList* pCmd, DynamicBufferHeap* pCBufferHeap, const FSceneView& SceneView, const FGraphicsSettings& GFXSettings, bool bHDR); + void SwapChainRenderPass(ID3D12GraphicsCommandList* pCmd, DynamicBufferHeap* pCBufferHeap, const FSceneView& SceneView, const FGraphicsSettings& GFXSettings, D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle, SRV srv_ColorIn, bool bHDRDisplay); + void RenderUI(ID3D12GraphicsCommandList* pCmd, DynamicBufferHeap* pCBufferHeap, D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle, const FUIState& UIState, const FSceneView& SceneView, const FGraphicsSettings& GFXSettings, bool bHDRDisplay); + void CompositUIToHDRSwapchain(ID3D12GraphicsCommandList* pCmd, DynamicBufferHeap* pCBufferHeap, FWindowRenderContext& ctx, const FGraphicsSettings& GFXSettings); HRESULT PresentFrame(FWindowRenderContext& ctx); void DrawShadowViewMeshList(ID3D12GraphicsCommandList* pCmd, const std::vector& drawParams, size_t iDepthMode); - void BatchDrawCalls(ThreadPool& WorkerThreads, const FSceneView& SceneView, const FSceneShadowViews& SceneShadowView, FWindowRenderContext& ctx, const FPostProcessParameters& PPParams, const FGraphicsSettings& GFXSettings); + void BatchDrawCalls(ThreadPool& WorkerThreads, const FSceneView& SceneView, const FSceneShadowViews& SceneShadowView, FWindowRenderContext& ctx, const FGraphicsSettings& GFXSettings); void FrameSubmitThread_Main(); // @@ -493,13 +496,13 @@ class VQRenderer // public: static std::vector< VQSystemInfo::FGPUInfo > EnumerateDX12Adapters(bool bEnableDebugLayer, bool bEnumerateSoftwareAdapters = false, IDXGIFactory6* pFactory = nullptr); - static const std::string_view& DXGIFormatAsString(DXGI_FORMAT format); + static const std::string_view& DXGIFormatAsString(DXGI_FORMAT format); // todo: return const char* static EProceduralTextures GetProceduralTextureEnumFromName(const std::string& ProceduralTextureName); static D3D12_COMMAND_LIST_TYPE GetDX12CmdListType(ECommandQueueType type); static bool ShouldEnableAsyncCompute(const FGraphicsSettings& GFXSettings, const FSceneView& SceneView, const FSceneShadowViews& ShadowView); static bool ShouldUseMotionVectorsTarget(const FGraphicsSettings& GFXSettings); - static bool ShouldUseVisualizationTarget(const FPostProcessParameters& PPParams); + static bool ShouldUseVisualizationTarget(const FGraphicsSettings& GFXSettings); static std::wstring GetFullPathOfShader(LPCWSTR shaderFileName); static std::wstring GetFullPathOfShader(const std::string& shaderFileName); diff --git a/Source/Renderer/Rendering/Batching.cpp b/Source/Renderer/Rendering/Batching.cpp index e5977355..512019ef 100644 --- a/Source/Renderer/Rendering/Batching.cpp +++ b/Source/Renderer/Rendering/Batching.cpp @@ -203,6 +203,8 @@ static void BatchMainViewDrawCalls( const FVisibleMeshDataSoA& ViewVisibleMeshes, const XMMATRIX viewProj, // take in copy for less cache thrashing const XMMATRIX viewProjPrev, // take in copy for less cache thrashing + const XMMATRIX jitteredViewProj, + const XMMATRIX jitteredViewProjPrev, DynamicBufferHeap& CBHeap, const VQRenderer* pRenderer ) @@ -218,6 +220,8 @@ static void BatchMainViewDrawCalls( if (NumInstancedDrawCalls == 0) return; + //const bool bShouldUpoadJitteredMatrices = pRenderer->ShouldEnableCameraJitters(); + std::vector cbAddr(NumInstancedDrawCalls); std::vector pPerObj(NumInstancedDrawCalls); for (size_t i = 0; i < NumInstancedDrawCalls; ++i) @@ -241,6 +245,20 @@ static void BatchMainViewDrawCalls( ++iDraw; } } + { + SCOPED_CPU_MARKER("matJitteredWorldViewProj"); + size_t iDraw = 0; + for (const FDrawCallInputDataRange& r : drawCallRanges) + { + size_t iInstance = 0; + for (size_t i = r.iStart; i < r.iStart + r.Stride; ++i) + { + const Transform& tf = ViewVisibleMeshes.Transform[i]; + pPerObj[iDraw]->matJitteredWorldViewProj[iInstance++] = tf.matWorldTransformation() * jitteredViewProj; + } + ++iDraw; + } + } { SCOPED_CPU_MARKER("matWorld"); size_t iDraw = 0; @@ -269,6 +287,20 @@ static void BatchMainViewDrawCalls( ++iDraw; } } + { + SCOPED_CPU_MARKER("matJitteredWorldViewProjPrev"); + size_t iDraw = 0; + for (const FDrawCallInputDataRange& r : drawCallRanges) + { + size_t iInstance = 0; + for (size_t i = r.iStart; i < r.iStart + r.Stride; ++i) + { + const Transform& tf = ViewVisibleMeshes.Transform[i]; + pPerObj[iDraw]->matJitteredWorldViewProjPrev[iInstance++] = tf.matWorldTransformationPrev() * jitteredViewProjPrev; + } + ++iDraw; + } + } { SCOPED_CPU_MARKER("matNormal"); size_t iDraw = 0; @@ -533,8 +565,14 @@ static void BatchBoundingBoxRenderCommandData( int NumBBsToProcess = (int)BBs.size(); size_t i = 0; int iBB = 0; + while (NumBBsToProcess > 0) { + if (iBegin + i >= cmds.size()) + { + Log::Warning("BatchBoundingBoxRenderCommandData called with empty wireframe render data"); + return; + } FInstancedWireframeRenderData& cmd = cmds[iBegin + i]; cmd.matWorldViewProj.resize(std::min(MAX_INSTANCE_COUNT__UNLIT_SHADER, (size_t)NumBBsToProcess)); cmd.vertexIndexBuffer = { VB, IB }; @@ -559,8 +597,8 @@ static void BatchInstanceData_BoundingBox(FSceneDrawData& SceneDrawData , const DirectX::XMMATRIX matViewProj) { SCOPED_CPU_MARKER("BoundingBox"); - const bool bDrawGameObjectBBs = SceneView.sceneRenderOptions.bDrawGameObjectBoundingBoxes; - const bool bDrawMeshBBs = SceneView.sceneRenderOptions.bDrawMeshBoundingBoxes; + const bool bDrawGameObjectBBs = SceneView.sceneRenderOptions.Debug.bDrawGameObjectBoundingBoxes; + const bool bDrawMeshBBs = SceneView.sceneRenderOptions.Debug.bDrawMeshBoundingBoxes; const float Transparency = 0.75f; const XMFLOAT4 BBColor_GameObj = XMFLOAT4(0.0f, 0.2f, 0.8f, Transparency); @@ -616,7 +654,7 @@ static void BatchInstanceData_BoundingBox(FSceneDrawData& SceneDrawData // Game Object Bounding Boxes // -------------------------------------------------------------- size_t iBoundingBox = 0; - if (SceneView.sceneRenderOptions.bDrawGameObjectBoundingBoxes) + if (SceneView.sceneRenderOptions.Debug.bDrawGameObjectBoundingBoxes) { #if RENDER_INSTANCED_BOUNDING_BOXES fnBatch(SceneDrawData.boundingBoxRenderParams @@ -635,7 +673,7 @@ static void BatchInstanceData_BoundingBox(FSceneDrawData& SceneDrawData // -------------------------------------------------------------- // Mesh Bounding Boxes // -------------------------------------------------------------- - if (SceneView.sceneRenderOptions.bDrawMeshBoundingBoxes) + if (SceneView.sceneRenderOptions.Debug.bDrawMeshBoundingBoxes) { iBoundingBox = SceneView.NumGameObjectBBRenderCmds; @@ -658,8 +696,7 @@ void VQRenderer::BatchDrawCalls( ThreadPool& RenderWorkerThreadPool, const FSceneView& SceneView, const FSceneShadowViews& SceneShadowView, - FWindowRenderContext& ctx, - const FPostProcessParameters& PPParams, + FWindowRenderContext& ctx, const FGraphicsSettings& GFXSettings ) { @@ -688,12 +725,33 @@ void VQRenderer::BatchDrawCalls( // ---------------------------------------------------SYNC --------------------------------------------------- MainViewFrustumRenderList.DataReadySignal.Wait(); // -------------------------------------------------- SYNC --------------------------------------------------- + + // get jitter info + const uint64 iFrame = mRenderStats.mNumFramesRendered; + const uint64 iFramePrev = iFrame == 0 ? 0 : iFrame - 1; + float PixelJitterX, PixelJitterY; + float PixelJitterXPrev, PixelJitterYPrev; + this->GetCameraPixelSpaceJitter(GFXSettings, iFrame , PixelJitterX , PixelJitterY); + this->GetCameraPixelSpaceJitter(GFXSettings, iFramePrev, PixelJitterXPrev, PixelJitterYPrev); + + const float RenderResolutionWidth = GFXSettings.GetRenderResolutionX(); + const float RenderResolutionHeight = GFXSettings.GetRenderResolutionY(); + + const float JitterX = 2.0f * PixelJitterX / RenderResolutionWidth; + const float JitterY = -2.0f * PixelJitterY / RenderResolutionHeight; + const XMMATRIX matJitterOffset = XMMatrixTranslation(JitterX, JitterY, 0.0f); + + const float JitterXPrev = 2.0f * PixelJitterXPrev / RenderResolutionWidth; + const float JitterYPrev = -2.0f * PixelJitterYPrev / RenderResolutionHeight; + const XMMATRIX matJitterOffsetPrev = XMMatrixTranslation(JitterXPrev, JitterYPrev, 0.0f); BatchMainViewDrawCalls( DrawData.mainViewDrawParams, MainViewFrustumRenderList.Data, SceneView.viewProj, SceneView.viewProjPrev, + SceneView.viewProj * matJitterOffset, + SceneView.viewProjPrev * matJitterOffsetPrev, CBHeap, this ); diff --git a/Source/Renderer/Rendering/HDR.h b/Source/Renderer/Rendering/HDR.h index 1509dcb8..55f60b7e 100644 --- a/Source/Renderer/Rendering/HDR.h +++ b/Source/Renderer/Rendering/HDR.h @@ -108,9 +108,9 @@ inline constexpr const char* GetDisplayCurveString(EDisplayCurve dc) { switch (dc) { - case sRGB: return "sRGB"; + case sRGB: return "sRGB (Gamma 2.2)"; case ST2084: return "ST2084 (PQ)"; - case Linear: return "scRGB"; + case Linear: return "scRGB (Linear)"; } return ""; } diff --git a/Source/Renderer/Rendering/LoadingScreenRendering.cpp b/Source/Renderer/Rendering/LoadingScreenRendering.cpp index fef1fe21..a0df1648 100644 --- a/Source/Renderer/Rendering/LoadingScreenRendering.cpp +++ b/Source/Renderer/Rendering/LoadingScreenRendering.cpp @@ -101,10 +101,10 @@ HRESULT VQRenderer::RenderLoadingScreen(const Window* pWindow, const FLoadingScr pCmd->ClearRenderTargetView(rtvHandle, clearColor, 0, nullptr); // Draw Triangle - const float RenderResolutionX = static_cast(ctx.WindowDisplayResolutionX); - const float RenderResolutionY = static_cast(ctx.WindowDisplayResolutionY); - D3D12_VIEWPORT viewport { 0.0f, 0.0f, RenderResolutionX, RenderResolutionY, 0.0f, 1.0f }; - D3D12_RECT scissorsRect { 0, 0, (LONG)RenderResolutionX, (LONG)RenderResolutionY }; + const float RenderResolutionX = static_cast(pWindow->GetWidth()); + const float RenderResolutionY = static_cast(pWindow->GetHeight()); + D3D12_VIEWPORT viewport { 0.0f, 0.0f, RenderResolutionX, RenderResolutionY, 0.0f, 1.0f }; + D3D12_RECT scissorsRect { 0, 0, (LONG)RenderResolutionX, (LONG)RenderResolutionY }; D3D12_INDEX_BUFFER_VIEW nullIBV = {}; nullIBV.Format = DXGI_FORMAT_R32_UINT; diff --git a/Source/Renderer/Rendering/PostProcess/Upscaling.cpp b/Source/Renderer/Rendering/PostProcess/Upscaling.cpp new file mode 100644 index 00000000..1471f9e2 --- /dev/null +++ b/Source/Renderer/Rendering/PostProcess/Upscaling.cpp @@ -0,0 +1,113 @@ +// VQE +// Copyright(C) 2025 - Volkan Ilbeyli +// +// This program 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. +// +// This program 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 this program.If not, see . +// +// Contact: volkanilbeyli@gmail.com + +#define FFX_DEBUG_LOG 0 + +#define A_CPU 1 + +#include "Upscaling.h" + +#include "Engine/Core/Types.h" +#if FFX_DEBUG_LOG +#include "Libs/VQUtils/Include/Log.h" +#endif + +#include + +//#include "Shaders/AMD/CAS/ffx_a.h" +#include "Shaders/AMD/FSR1.0/ffx_a.h" +#include "Shaders/AMD/CAS/ffx_cas.h" +#include "Shaders/AMD/FSR1.0/ffx_fsr1.h" + +namespace AMD_FidelityFX_SuperResolution1 +{ + //float FShaderParameters::RCAS::GetLinearSharpness() const { return std::powf(0.5f, this->RCASSharpnessStops); } + + static float GetSharpnessStops(float Sharpness) + { + return std::log10f(Sharpness) / std::log10f(0.5f); + } + + void FShaderParameters::RCAS::UpdateConstantBlock(float Sharpness) + { + const float SharpnessStops = GetSharpnessStops(Sharpness); +#if FFX_DEBUG_LOG + Log::Info("[FidelityFX][FSR-RCAS]: FsrRcasCon() called with Sharpness=%.2f | SharpnessStops=%.2f", + Sharpness, + SharpnessStops + ); +#endif + FsrRcasCon(reinterpret_cast(&this->RCASConstantBlock[0]), SharpnessStops); + } + + void FShaderParameters::EASU::UpdateConstantBlock( + uint InputWidth + , uint InputHeight + , uint InputContainerWidth + , uint InputContainerHeight + , uint OutputWidth + , uint OutputHeight + ) + { +#if FFX_DEBUG_LOG + Log::Info("[FidelityFX][Super Resolution]: FsrEasuCon() called with InputResolution=%ux%u, ContainerDimensions=%ux%u, OutputResolution==%ux%u", + InputWidth + , InputHeight + , InputContainerWidth + , InputContainerHeight + , OutputWidth + , OutputHeight); +#endif + FsrEasuCon( + reinterpret_cast(&this->EASUConstantBlock[0]) + , reinterpret_cast(&this->EASUConstantBlock[4]) + , reinterpret_cast(&this->EASUConstantBlock[8]) + , reinterpret_cast(&this->EASUConstantBlock[12]) + , static_cast(InputWidth) // This the rendered image resolution being upscaled + , static_cast(InputHeight) + , static_cast(InputContainerWidth) // This is the resolution of the resource containing the input image (useful for dynamic resolution) + , static_cast(InputContainerHeight) + , static_cast(OutputWidth) // This is the display resolution which the input image gets upscaled to + , static_cast(OutputHeight) + ); + } + +#if !DISABLE_FIDELITYFX_CAS + void FPostProcessParameters::FFFXCAS::UpdateCASConstantBlock( + uint InputWidth + , uint InputHeight + , uint OutputWidth + , uint OutputHeight) + { +#if FFX_DEBUG_LOG + Log::Info("[FidelityFX][CAS]: CasSetup() called with Sharpness=%.2f, InputResolution=%ux%u, OutputResolution==%ux%u", + this->CASSharpen + , InputWidth + , InputHeight + , OutputWidth + , OutputHeight); +#endif + CasSetup(&this->CASConstantBlock[0], &this->CASConstantBlock[4], this->CASSharpen, + static_cast(InputWidth), + static_cast(InputHeight), // input resolution + static_cast(OutputWidth), + static_cast(OutputHeight) // output resolution + ); + } +#endif +} diff --git a/Source/Renderer/Rendering/PostProcess/Upscaling.h b/Source/Renderer/Rendering/PostProcess/Upscaling.h new file mode 100644 index 00000000..c0120cba --- /dev/null +++ b/Source/Renderer/Rendering/PostProcess/Upscaling.h @@ -0,0 +1,121 @@ +// VQE +// Copyright(C) 2020 - Volkan Ilbeyli +// +// This program 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. +// +// This program 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 this program.If not, see . +// +// Contact: volkanilbeyli@gmail.com +#pragma once + +#include "Engine/Core/Types.h" + +#include "Renderer/Rendering/HDR.h" + +#include + +#define DISABLE_FIDELITYFX_CAS 1 // disable ffx cas but keep implementaiton around, now using fsr1 rcas + +class ID3D12Device; + + +namespace AMD_FidelityFX_SuperResolution1 +{ + // AMD FidelityFX Super Resolution 1.0: Spatial Upscaling and RCAS + + enum EPreset : int + { + ULTRA_QUALITY = 0, + QUALITY, + BALANCED, + PERFORMANCE, + CUSTOM, + + NUM_FSR1_PRESET_OPTIONS + }; + inline const char* GetVersionString() { return "1.0"; } + inline float GetScreenPercentage(EPreset ePreset) + { + switch (ePreset) + { + case EPreset::ULTRA_QUALITY: return 0.77f; + case EPreset::QUALITY : return 0.67f; + case EPreset::BALANCED : return 0.58f; + case EPreset::PERFORMANCE : return 0.50f; + } + return 1.0f; + } + struct FShaderParameters + { + struct RCAS + { + unsigned RCASConstantBlock[4]; + void UpdateConstantBlock(float Sharpness); + }; + struct EASU + { + unsigned EASUConstantBlock[16]; + void UpdateConstantBlock( + uint InputWidth, uint InputHeight, + uint InputContainerWidth, uint InputContainerHeight, + uint OutputWidth, uint OutputHeight + ); + }; + EASU easu; + RCAS rcas; + }; +} + +namespace AMD_FidelityFX_SuperResolution3 +{ + enum EPreset : int + { + NATIVE_AA = 0, + QUALITY, + BALANCED, + PERFORMANCE, + ULTRA_PERFORMANCE, + CUSTOM, + + NUM_FSR3_PRESET_OPTIONS + }; + inline const char* GetVersionString() { return "3.1.4"; } + inline const char* GetPresetName(EPreset ePreset) + { + switch (ePreset) + { + case EPreset::NATIVE_AA : return "Native AA"; + case EPreset::QUALITY : return "Quality"; + case EPreset::BALANCED : return "Balanced"; + case EPreset::PERFORMANCE : return "Performance"; + case EPreset::ULTRA_PERFORMANCE: return "UltraPerformance"; + case EPreset::CUSTOM : return "Custom"; + } + return "Unknown Preset"; + } + inline float GetScreenPercentage(EPreset ePreset) + { + switch (ePreset) + { + case EPreset::NATIVE_AA : return 1.00000f; + case EPreset::QUALITY : return 0.66667f; + case EPreset::BALANCED : return 0.58802f; + case EPreset::PERFORMANCE : return 0.50000f; + case EPreset::ULTRA_PERFORMANCE: return 0.33333f; + } + return -1.0f; + } + inline float GetMipBias(uint RenderResolutionX, uint OutputResolutionX) + { + return std::log2(float(RenderResolutionX) / (float)OutputResolutionX) - 1.0f; + } +} diff --git a/Source/Renderer/Rendering/RenderPass/AmbientOcclusion.cpp b/Source/Renderer/Rendering/RenderPass/AmbientOcclusion.cpp index 8b62e988..2e3dbecc 100644 --- a/Source/Renderer/Rendering/RenderPass/AmbientOcclusion.cpp +++ b/Source/Renderer/Rendering/RenderPass/AmbientOcclusion.cpp @@ -17,7 +17,7 @@ // Contact: volkanilbeyli@gmail.com #include "AmbientOcclusion.h" -#include "Renderer/Libs/AMDFidelityFX/CACAO/ffx_cacao_impl.h" +#include "Renderer/Libs/AMD/CACAO/ffx_cacao_impl.h" #include "Libs/VQUtils/Include/Log.h" diff --git a/Source/Renderer/Rendering/RenderPass/AmbientOcclusion.h b/Source/Renderer/Rendering/RenderPass/AmbientOcclusion.h index 46b4b2c2..1065b85a 100644 --- a/Source/Renderer/Rendering/RenderPass/AmbientOcclusion.h +++ b/Source/Renderer/Rendering/RenderPass/AmbientOcclusion.h @@ -21,7 +21,7 @@ // #define FFX_CACAO_ENABLE_PROFILING 1 // #define FFX_CACAO_ENABLE_NATIVE_RESOLUTION 1 -#include "Renderer/Libs/AMDFidelityFX/CACAO/ffx_cacao.h" +#include "Renderer/Libs/AMD/CACAO/ffx_cacao.h" #include #include diff --git a/Source/Renderer/Rendering/RenderPass/FSR3UpscalePass.cpp b/Source/Renderer/Rendering/RenderPass/FSR3UpscalePass.cpp new file mode 100644 index 00000000..6d7e8d33 --- /dev/null +++ b/Source/Renderer/Rendering/RenderPass/FSR3UpscalePass.cpp @@ -0,0 +1,372 @@ +// VQE +// Copyright(C) 2020 - Volkan Ilbeyli +// +// This program 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. +// +// This program 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 this program.If not, see . +// +// Contact: volkanilbeyli@gmail.com +#pragma once + +#include "RenderPass.h" +#include "FSR3UpscalePass.h" +#include "Renderer.h" + +#include "Libs/VQUtils/Include/Log.h" +#include "Engine/GPUMarker.h" + +#include "ffx_api/dx12/ffx_api_dx12.h" +#include "ffx_api/ffx_upscale.h" + +struct FSR3UpscalePass::ContextImpl +{ + ffxContext ctx = {}; +}; + + +FSR3UpscalePass::FSR3UpscalePass(VQRenderer& Renderer) + : RenderPassBase(Renderer) +{ +} + +FSR3UpscalePass::~FSR3UpscalePass() +{ +} + +bool FSR3UpscalePass::Initialize() +{ + assert(!pImpl); + pImpl = new ContextImpl(); + return pImpl != nullptr; +} + +void FSR3UpscalePass::Destroy() +{ + assert(pImpl); + if (pImpl) + { + delete pImpl; + pImpl = nullptr; + } +} + +static void FSR3MessageCallback(uint type, const wchar_t* msg) +{ + switch (type) + { + case FFX_API_MESSAGE_TYPE_ERROR: + Log::Error("[FFX_FSR3]: %ls", msg); + break; + case FFX_API_MESSAGE_TYPE_WARNING: + Log::Warning("[FFX_FSR3]: %ls", msg); + break; + default: + assert(false); + break; + } +} +void FSR3UpscalePass::OnCreateWindowSizeDependentResources(unsigned DisplayWidth, unsigned DisplayHeight, const IRenderPassResourceCollection* pRscParameters) +{ + assert(pImpl); + if (!pImpl) + { + Log::Error("FSR3 Create: Memory not allocated for context"); + return; + } + + ID3D12Device* pDevice = mRenderer.GetDevicePtr(); + assert(pDevice); + + const FResourceCollection* pResourceInput = static_cast(pRscParameters); + const uint RenderResolutionX = pResourceInput->fResolutionScale * DisplayWidth; + const uint RenderResolutionY = pResourceInput->fResolutionScale * DisplayHeight; + const FTexture* pTexture = mRenderer.GetTexture(pResourceInput->texColorInput); + assert(pTexture); + if (!pTexture) + { + Log::Error("FSR3 OnCreateWindowSizeDependentResources(): invalid input texture, ID=%d", pResourceInput->texColorInput); + return; + } + + ffxCreateBackendDX12Desc backendDesc{}; + backendDesc.device = pDevice; + backendDesc.header.type = FFX_API_CREATE_CONTEXT_DESC_TYPE_BACKEND_DX12; + + ffxCreateContextDescUpscale createUpscaling = {}; + createUpscaling.header.type = FFX_API_CREATE_CONTEXT_DESC_TYPE_UPSCALE; + createUpscaling.header.pNext = &backendDesc.header; + createUpscaling.maxUpscaleSize = { DisplayWidth, DisplayHeight }; + createUpscaling.maxRenderSize = { RenderResolutionX, RenderResolutionY }; + createUpscaling.flags = FFX_UPSCALE_ENABLE_AUTO_EXPOSURE | FFX_UPSCALE_ENABLE_HIGH_DYNAMIC_RANGE; +#if _DEBUG + createUpscaling.flags |= FFX_UPSCALE_ENABLE_DEBUG_CHECKING; + createUpscaling.fpMessage = FSR3MessageCallback; +#endif + + ffxReturnCode_t retCode = ffxCreateContext(&pImpl->ctx, &createUpscaling.header, nullptr); + bool bSucceeded = retCode == 0; + if (!bSucceeded) + { + Log::Error("FSR3: Error (%d) creating ffxContext", retCode); + texOutput = INVALID_ID; + return; + } + + FTextureRequest createDesc = {}; + createDesc.bCPUReadback = false; + createDesc.bCubemap = pTexture->IsCubemap; + createDesc.bGenerateMips = pTexture->MipCount > 1; + createDesc.InitialState = D3D12_RESOURCE_STATES::D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE; + createDesc.Name = "FSR3_Output"; + createDesc.D3D12Desc.Dimension = D3D12_RESOURCE_DIMENSION::D3D12_RESOURCE_DIMENSION_TEXTURE2D; + createDesc.D3D12Desc.Format = pTexture->Format; + createDesc.D3D12Desc.MipLevels = pTexture->MipCount; + createDesc.D3D12Desc.DepthOrArraySize = pTexture->ArraySlices; + createDesc.D3D12Desc.Height = DisplayHeight; + createDesc.D3D12Desc.Width = DisplayWidth; + createDesc.D3D12Desc.SampleDesc.Count = 1; + createDesc.D3D12Desc.Flags = D3D12_RESOURCE_FLAGS::D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; + texOutput = mRenderer.CreateTexture(createDesc); + + // TODO: enable conditional resource consumption + //if (pResourceInput->bAllocateReactivityMaskTexture) + { + createDesc.Name = "FSR3_ReactivityMask"; + createDesc.D3D12Desc.Width = RenderResolutionX; + createDesc.D3D12Desc.Height = RenderResolutionY; + createDesc.D3D12Desc.Format = DXGI_FORMAT_R16_FLOAT; + texReactivityMask = mRenderer.CreateTexture(createDesc); + } + //if (pResourceInput->bAllocateTransparencyAndCompositionMaskTexture) + { + createDesc.Name = "FSR3_TransparencyAndCompositionMask"; + createDesc.D3D12Desc.Width = RenderResolutionX; + createDesc.D3D12Desc.Height = RenderResolutionY; + createDesc.D3D12Desc.Format = DXGI_FORMAT_R16_FLOAT; + createDesc.D3D12Desc.Flags = D3D12_RESOURCE_FLAGS::D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; + createDesc.InitialState = D3D12_RESOURCE_STATES::D3D12_RESOURCE_STATE_RENDER_TARGET; + texTransparencyAndCompositionMask = mRenderer.CreateTexture(createDesc); + } + + srvOutput = mRenderer.AllocateSRV(1); + mRenderer.InitializeSRV(srvOutput, 0, texOutput); + + if (pResourceInput->bAllocateReactivityMaskTexture) mRenderer.WaitForTexture(texReactivityMask); + //if (pResourceInput->bAllocateTransparencyAndCompositionMaskTexture) + { + rtvTransparencyAndCompositionMask = mRenderer.AllocateRTV(1); + mRenderer.InitializeRTV(rtvTransparencyAndCompositionMask, 0, texTransparencyAndCompositionMask); + } +} + +void FSR3UpscalePass::OnDestroyWindowSizeDependentResources() +{ + assert(pImpl); + if (!pImpl) + { + Log::Error("FSR3 Destroy: Memory not allocated for context"); + return; // don't crash + } + + ffxReturnCode_t retCode = ffxDestroyContext(&pImpl->ctx, nullptr); + bool bSucceeded = retCode == 0; + if (!bSucceeded) + { + Log::Error("Error (%d) destroying ffxContext", retCode); + } + + if (rtvTransparencyAndCompositionMask != INVALID_ID) + //mRenderer.DestroyRTV(rtvTransparencyAndCompositionMask); + + mRenderer.DestroySRV(srvOutput); + mRenderer.DestroyTexture(texOutput); + + if (texReactivityMask != INVALID_ID) mRenderer.DestroyTexture(texReactivityMask); + if (texTransparencyAndCompositionMask != INVALID_ID) mRenderer.DestroyTexture(texTransparencyAndCompositionMask); +} + +void FSR3UpscalePass::RecordCommands(const IRenderPassDrawParameters* pDrawParameters) +{ + assert(pImpl); + if (!pImpl) + { + Log::Error("FSR3 Dispatch: Memory not allocated for context"); + return; // don't crash + } + + const Parameters* pParams = static_cast(pDrawParameters); + assert(pParams->pCmd); + + const FResourceCollection& rsc = pParams->Resources; + assert(rsc.texColorInput != INVALID_ID); + assert(rsc.texDepthBuffer != INVALID_ID); + assert(rsc.texMotionVectors != INVALID_ID); + + int RenderSizeX, RenderSizeY; + mRenderer.GetTextureDimensions(rsc.texColorInput, RenderSizeX, RenderSizeY); + assert(RenderSizeX > 0 && RenderSizeY > 0); + + int OutputSizeX, OutputSizeY; + mRenderer.WaitForTexture(texOutput); + mRenderer.GetTextureDimensions(texOutput, OutputSizeX, OutputSizeY); + assert(OutputSizeX > 0 && OutputSizeY > 0); + + int MotionVectorScaleX, MotionVectorScaleY; + mRenderer.GetTextureDimensions(rsc.texMotionVectors, MotionVectorScaleX, MotionVectorScaleY); + assert(MotionVectorScaleX > 0 && MotionVectorScaleY > 0); + + ID3D12Resource* pRscColorInput = mRenderer.GetTextureResource(rsc.texColorInput); + ID3D12Resource* pRscDepthBuffer = mRenderer.GetTextureResource(rsc.texDepthBuffer); + ID3D12Resource* pRscMoVec = mRenderer.GetTextureResource(rsc.texMotionVectors); + ID3D12Resource* pRscOutput = mRenderer.GetTextureResource(texOutput); + assert(pRscColorInput); + assert(pRscDepthBuffer); + assert(pRscMoVec); + assert(pRscOutput); + ID3D12Resource* pRscExposure = rsc.texExposure == INVALID_ID ? nullptr : mRenderer.GetTextureResource(rsc.texExposure); + ID3D12Resource* pRscReactiveMask = texReactivityMask == INVALID_ID ? nullptr : mRenderer.GetTextureResource(texReactivityMask); + ID3D12Resource* pRscTransparencyAndComposition = texTransparencyAndCompositionMask == INVALID_ID ? nullptr : mRenderer.GetTextureResource(texTransparencyAndCompositionMask); + + ffxReturnCode_t retCode = 0; + if (pParams->bUseGeneratedReactiveMask) + { + SCOPED_GPU_MARKER(pParams->pCmd, "FSR3GenerateRactivityMaskPass"); + assert(pRscReactiveMask); + ID3D12Resource* pRscOpaqueOnly = mRenderer.GetTextureResource(rsc.texOpaqueOnly); + assert(pRscOpaqueOnly); + + ffxDispatchDescUpscaleGenerateReactiveMask GenReactiveMaskDesc = {}; + GenReactiveMaskDesc.header.type = FFX_API_DISPATCH_DESC_TYPE_UPSCALE_GENERATEREACTIVEMASK; + GenReactiveMaskDesc.commandList = pParams->pCmd; + GenReactiveMaskDesc.colorOpaqueOnly = ffxApiGetResourceDX12(pRscOpaqueOnly, FFX_API_RESOURCE_STATE_COMPUTE_READ, 0); + GenReactiveMaskDesc.colorPreUpscale = ffxApiGetResourceDX12(pRscColorInput, FFX_API_RESOURCE_STATE_COMPUTE_READ, 0); + GenReactiveMaskDesc.outReactive = ffxApiGetResourceDX12(pRscReactiveMask, FFX_API_RESOURCE_STATE_UNORDERED_ACCESS, 0); + GenReactiveMaskDesc.renderSize.width = (uint)RenderSizeX; + GenReactiveMaskDesc.renderSize.height = (uint)RenderSizeY; + GenReactiveMaskDesc.scale = pParams->GeneratedReactiveMaskScale; + GenReactiveMaskDesc.cutoffThreshold = pParams->GeneratedReactiveMaskCutoffThreshold; + GenReactiveMaskDesc.binaryValue = pParams->GeneratedReactiveMaskBinaryValue; + GenReactiveMaskDesc.flags; + + CD3DX12_RESOURCE_BARRIER barriers[] = + { + CD3DX12_RESOURCE_BARRIER::Transition(pRscReactiveMask, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS), + }; + pParams->pCmd->ResourceBarrier(_countof(barriers), barriers); + + retCode = ffxDispatch(&pImpl->ctx, &GenReactiveMaskDesc.header); + + barriers[0] = CD3DX12_RESOURCE_BARRIER::Transition(pRscReactiveMask, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); + pParams->pCmd->ResourceBarrier(_countof(barriers), barriers); + } + { + SCOPED_GPU_MARKER(pParams->pCmd, "FSR3UpcalePass"); + ffxDispatchDescUpscale DispatchDescUpscale = {}; + DispatchDescUpscale.header.type = FFX_API_DISPATCH_DESC_TYPE_UPSCALE; + DispatchDescUpscale.commandList = pParams->pCmd; + + DispatchDescUpscale.color = ffxApiGetResourceDX12(pRscColorInput , FFX_API_RESOURCE_STATE_COMPUTE_READ, 0); + DispatchDescUpscale.depth = ffxApiGetResourceDX12(pRscDepthBuffer , FFX_API_RESOURCE_STATE_COMPUTE_READ, 0); + DispatchDescUpscale.motionVectors = ffxApiGetResourceDX12(pRscMoVec , FFX_API_RESOURCE_STATE_COMPUTE_READ, 0); + DispatchDescUpscale.exposure = ffxApiGetResourceDX12(pRscExposure , FFX_API_RESOURCE_STATE_COMPUTE_READ, 0); + DispatchDescUpscale.reactive = ffxApiGetResourceDX12(pRscReactiveMask , FFX_API_RESOURCE_STATE_COMPUTE_READ, 0); + DispatchDescUpscale.transparencyAndComposition = ffxApiGetResourceDX12(pRscTransparencyAndComposition, FFX_API_RESOURCE_STATE_COMPUTE_READ, 0); + DispatchDescUpscale.output = ffxApiGetResourceDX12(pRscOutput , FFX_API_RESOURCE_STATE_UNORDERED_ACCESS, 0); + + GetJitterXY(DispatchDescUpscale.jitterOffset.x, DispatchDescUpscale.jitterOffset.y, (uint)RenderSizeX, (uint)OutputSizeX, pParams->iFrame); + DispatchDescUpscale.motionVectorScale.x = -MotionVectorScaleX; // - because MVs expected pointing from this frame to prev frame + DispatchDescUpscale.motionVectorScale.y = -MotionVectorScaleY; // - because MVs expected pointing from this frame to prev frame + + DispatchDescUpscale.renderSize.width = (uint)RenderSizeX; + DispatchDescUpscale.renderSize.height = (uint)RenderSizeY; + DispatchDescUpscale.upscaleSize.width = (uint)OutputSizeX; + DispatchDescUpscale.upscaleSize.height = (uint)OutputSizeY; + DispatchDescUpscale.enableSharpening = pParams->bEnableSharpening; + DispatchDescUpscale.sharpness = pParams->fSharpness; + + DispatchDescUpscale.frameTimeDelta = pParams->fDeltaTimeMilliseconds; + DispatchDescUpscale.preExposure = pParams->fPreExposure; + DispatchDescUpscale.reset = this->bClearHistoryBuffers; + DispatchDescUpscale.cameraNear = pParams->fCameraNear; + DispatchDescUpscale.cameraFar = pParams->fCameraFar; + DispatchDescUpscale.cameraFovAngleVertical = pParams->fCameraFoVAngleVerticalRadians; + DispatchDescUpscale.viewSpaceToMetersFactor = pParams->fViewSpaceToMetersFactor; + + FfxApiDispatchFsrUpscaleFlags flags = {}; + /* + FFX_UPSCALE_FLAG_DRAW_DEBUG_VIEW + FFX_UPSCALE_FLAG_NON_LINEAR_COLOR_SRGB + FFX_UPSCALE_FLAG_NON_LINEAR_COLOR_PQ + */ + DispatchDescUpscale.flags = flags; + + retCode = ffxDispatch(&pImpl->ctx, &DispatchDescUpscale.header); + } + + if (this->bClearHistoryBuffers) + { + this->bClearHistoryBuffers = false; + } + + bool bSucceeded = retCode == 0; + if (!bSucceeded) + { + Log::Error("FSR3: Error (%d) dispatching", retCode); + } +} + +void FSR3UpscalePass::GetJitterXY(float& OutPixelSpaceJitterX, float& OutPixelSpaceJitterY, uint RenderResolutionX, uint OutputResolutionX, size_t iFrame) const +{ + OutPixelSpaceJitterX = 0.0f; + OutPixelSpaceJitterY = 0.0f; + + const bool bContextInitialized = pImpl->ctx != nullptr; + if (!bContextInitialized) + { + return; + } + + ffxReturnCode_t ret = 0; + int NumPhases = 0; + { + ffxQueryDescUpscaleGetJitterPhaseCount desc = {}; + desc.header.type = FFX_API_QUERY_DESC_TYPE_UPSCALE_GETJITTERPHASECOUNT; + desc.displayWidth = OutputResolutionX; + desc.renderWidth = RenderResolutionX; + desc.pOutPhaseCount = &NumPhases; + + ret = ffxQuery(&pImpl->ctx, &desc.header); + if (ret != 0) + { + Log::Warning("ffxQuery for phase count unssuccessful"); + return; + } + } + + iFrame = iFrame % NumPhases; + ffxQueryDescUpscaleGetJitterOffset desc; + desc.header.type = FFX_API_QUERY_DESC_TYPE_UPSCALE_GETJITTEROFFSET; + desc.index = iFrame; + desc.phaseCount = NumPhases; + desc.pOutX = &OutPixelSpaceJitterX; + desc.pOutY = &OutPixelSpaceJitterY; + + ret = ffxQuery(&pImpl->ctx, &desc.header); + if (ret != 0) + { + Log::Warning("ffxQuery for jitter offset unssuccessful"); + return; + } + + //Log::Info("ffx Jitter[%d/%d] {%.4f, %.4f}", iFrame, NumPhases, OutPixelSpaceJitterX, OutPixelSpaceJitterY); +} + diff --git a/Source/Renderer/Rendering/RenderPass/FSR3UpscalePass.h b/Source/Renderer/Rendering/RenderPass/FSR3UpscalePass.h new file mode 100644 index 00000000..0065d8cd --- /dev/null +++ b/Source/Renderer/Rendering/RenderPass/FSR3UpscalePass.h @@ -0,0 +1,143 @@ +// VQE +// Copyright(C) 2020 - Volkan Ilbeyli +// +// This program 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. +// +// This program 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 this program.If not, see . +// +// Contact: volkanilbeyli@gmail.com +#pragma once + +#include "RenderPass.h" + +#include "Renderer/Rendering/PostProcess/Upscaling.h" + +#include "Renderer/Pipeline/PipelineStateObjects.h" + + +struct FSR3UpscalePass : public RenderPassBase +{ + struct FResourceCollection : public IRenderPassResourceCollection + { + float fResolutionScale = 0.0f; + TextureID texOpaqueOnly = INVALID_ID; + TextureID texColorInput = INVALID_ID; + TextureID texDepthBuffer = INVALID_ID; + TextureID texMotionVectors = INVALID_ID; + TextureID texExposure = INVALID_ID; + + bool bAllocateReactivityMaskTexture = false; + bool bAllocateTransparencyAndCompositionMaskTexture = false; + }; + struct Parameters : public IRenderPassDrawParameters + { + ID3D12GraphicsCommandList* pCmd = nullptr; + + bool bEnableSharpening = true; + float fSharpness = 0.8f; + float fDeltaTimeMilliseconds = 0.0f; + float fCameraNear = 0.0f; + float fCameraFar = 0.0f; + float fCameraFoVAngleVerticalRadians = 0.0f; + float fPreExposure = 1.0f; + float fViewSpaceToMetersFactor = 1.0f; + uint32 iFrame = 0; + + bool bUseGeneratedReactiveMask = false; + float GeneratedReactiveMaskScale = 1.0f; + float GeneratedReactiveMaskCutoffThreshold = 0.0f; + float GeneratedReactiveMaskBinaryValue = 0.0f; + + FResourceCollection Resources; + }; + +public: + FSR3UpscalePass(VQRenderer& Renderer); + ~FSR3UpscalePass() override; + + bool Initialize() override; + void Destroy() override; + + void OnCreateWindowSizeDependentResources(unsigned Width, unsigned Height, const IRenderPassResourceCollection* pRscParameters = nullptr) override; + void OnDestroyWindowSizeDependentResources() override; + + void RecordCommands(const IRenderPassDrawParameters* pDrawParameters = nullptr) override; + + std::vector CollectPSOCreationParameters() override { return std::vector(); } + + void GetJitterXY(float& OutPixelSpaceJitterX, float& OutPixelSpaceJitterY, uint RenderResolutionX, uint OutputResolutionX, size_t iFrame) const; + + inline void SetClearHistoryBuffers() { this->bClearHistoryBuffers = true; } + + + enum EResources + { + ReactivityMask, + TransparencyAndCompositionMask, + Output + }; + inline TextureID GetTextureID(EResources eRsc) const + { + switch (eRsc) + { + case EResources::ReactivityMask: return texReactivityMask; + case EResources::TransparencyAndCompositionMask: return texTransparencyAndCompositionMask; + case EResources::Output: return texOutput; + } + return INVALID_ID; + } + inline SRV_ID GetSRV_ID(EResources eRsc) const + { + switch (eRsc) + { + case EResources::Output: return srvOutput; + } + return INVALID_ID; + } + inline RTV_ID GetRTV_ID(EResources eRsc) const + { + switch (eRsc) + { + case EResources::TransparencyAndCompositionMask: return rtvTransparencyAndCompositionMask; + } + return INVALID_ID; + } + +private: + bool bClearHistoryBuffers = false; + + // "reactivity" means how much influence the samples rendered for the + // current frame have over the production of the final upscaled image. + // + // adjusts the accumulation balance. + // pixelValue + // 0: use the default FSR composition strategy + // 1: alpha value for alpha-blended objects + // recommended clamping the maximum reactive value to around 0.9 + TextureID texReactivityMask = INVALID_ID; + + // denotes the areas of other specialist rendering like raytraced reflections or + // animated textures which should be accounted for during the upscaling process. + // + // adjusts the pixel history protection mechanisms + // pixelValue + // 0: does not perform any additional modification to the lock for that pixel. + // 1: the lock for that pixel should be completely removed + TextureID texTransparencyAndCompositionMask = INVALID_ID; + RTV_ID rtvTransparencyAndCompositionMask = INVALID_ID; + + TextureID texOutput = INVALID_ID; + SRV_ID srvOutput = INVALID_ID; + + struct ContextImpl; + ContextImpl* pImpl = nullptr; +}; \ No newline at end of file diff --git a/Source/Renderer/Rendering/RenderPass/MagnifierPass.cpp b/Source/Renderer/Rendering/RenderPass/MagnifierPass.cpp index 8ee6c9f9..4ce2d669 100644 --- a/Source/Renderer/Rendering/RenderPass/MagnifierPass.cpp +++ b/Source/Renderer/Rendering/RenderPass/MagnifierPass.cpp @@ -56,7 +56,7 @@ void MagnifierPass::RecordCommands(const IRenderPassDrawParameters* pDrawParamet const FDrawParameters* pParams = static_cast(pDrawParameters); assert(pParams); assert(pParams->pCmd); - assert(pParams->pCBufferHeap); + assert(pParams->cbAddr != 0); assert(pParams->pCBufferParams); ID3D12GraphicsCommandList* pCmd = pParams->pCmd; @@ -70,17 +70,12 @@ void MagnifierPass::RecordCommands(const IRenderPassDrawParameters* pDrawParamet D3D12_VIEWPORT viewport{ 0.0f, 0.0f, W, H, 0.0f, 1.0f }; D3D12_RECT scissorsRect{ 0, 0, (LONG)W, (LONG)H }; - D3D12_GPU_VIRTUAL_ADDRESS cbAddr = {}; - FMagnifierParameters* CB = nullptr; - pParams->pCBufferHeap->AllocConstantBuffer(sizeof(FMagnifierParameters), (void**)&CB, &cbAddr); - memcpy(CB, pParams->pCBufferParams.get(), sizeof(FMagnifierParameters)); - - pCmd->SetPipelineState(mRenderer.GetPSO(PSOMagnifierPS)); + pCmd->SetPipelineState(mRenderer.GetPSO(pParams->bHDROutput ? PSOMagnifierPSHDR : PSOMagnifierPS)); pCmd->OMSetRenderTargets(1, &pParams->RTV, FALSE, NULL); pCmd->SetGraphicsRootSignature(mRenderer.GetBuiltinRootSignature(EBuiltinRootSignatures::LEGACY__FullScreenTriangle)); pCmd->SetGraphicsRootDescriptorTable(0, pParams->SRVColorInput.GetGPUDescHandle()); - pCmd->SetGraphicsRootConstantBufferView(1, cbAddr); + pCmd->SetGraphicsRootConstantBufferView(1, pParams->cbAddr); pCmd->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); pCmd->IASetVertexBuffers(0, 1, NULL); @@ -126,6 +121,10 @@ std::vector MagnifierPass::CollectPSOCreationParamet std::vector params; params.push_back({ &PSOMagnifierPS, psoLoadDesc }); + psoDesc.RTVFormats[0] = DXGI_FORMAT_R16G16B16A16_FLOAT; + psoLoadDesc.PSOName = "PSO_MagnifierHDR"; + params.push_back({ &PSOMagnifierPSHDR, psoLoadDesc }); + return params; } diff --git a/Source/Renderer/Rendering/RenderPass/MagnifierPass.h b/Source/Renderer/Rendering/RenderPass/MagnifierPass.h index d27d648e..2087e0e1 100644 --- a/Source/Renderer/Rendering/RenderPass/MagnifierPass.h +++ b/Source/Renderer/Rendering/RenderPass/MagnifierPass.h @@ -21,31 +21,16 @@ #include "Renderer/Resources/ResourceViews.h" // TODO: use IDs instead of SRV & IBV in draw params #include -static constexpr float MAGNIFIER_BORDER_COLOR__LOCKED[3] = { 0.002f, 0.52f, 0.0f }; // G -static constexpr float MAGNIFIER_BORDER_COLOR__FREE[3] = { 0.72f, 0.002f, 0.0f }; // R - class DynamicBufferHeap; struct FMagnifierParameters { - FMagnifierParameters() - : uImageWidth(1) - , uImageHeight(1) - , iMousePos{ 0, 0 } - , fBorderColorRGB{ 1, 1, 1, 1 } - , fMagnificationAmount(6.0f) - , fMagnifierScreenRadius(0.35f) - , iMagnifierOffset{ 500, -500 } - {} - - uint32_t uImageWidth; - uint32_t uImageHeight; - int iMousePos[2]; // in pixels, driven by ImGuiIO.MousePos.xy - - float fBorderColorRGB[4]; // Linear RGBA - - float fMagnificationAmount; // [1-...] - float fMagnifierScreenRadius; // [0-1] - mutable int iMagnifierOffset[2]; // in pixels + uint32_t uImageWidth = 1; + uint32_t uImageHeight = 1; + int iMousePos[2] = { 0, 0 }; // in pixels, driven by ImGuiIO.MousePos.xy + float fBorderColorRGB[4] = { 1, 1, 1, 1 }; // Linear RGBA + float fMagnificationAmount = 6.0f; // [1-...] + float fMagnifierScreenRadius = 0.35f; // [0-1] + mutable int iMagnifierOffset[2] = { 500, -500 }; // in pixels }; class MagnifierPass : public RenderPassBase @@ -55,11 +40,12 @@ class MagnifierPass : public RenderPassBase struct FDrawParameters : public IRenderPassDrawParameters { ID3D12GraphicsCommandList* pCmd = nullptr; - DynamicBufferHeap* pCBufferHeap = nullptr; - std::shared_ptr pCBufferParams; + const FMagnifierParameters* pCBufferParams = nullptr; + D3D12_GPU_VIRTUAL_ADDRESS cbAddr = 0; D3D12_CPU_DESCRIPTOR_HANDLE RTV = {}; SRV SRVColorInput = {}; IBV IndexBufferView = {}; + bool bHDROutput = false; }; struct FResourceCollection : public IRenderPassResourceCollection {}; @@ -88,6 +74,7 @@ class MagnifierPass : public RenderPassBase const bool bOutputsToSwapchain = true; PSO_ID PSOMagnifierPS = INVALID_ID; + PSO_ID PSOMagnifierPSHDR = INVALID_ID; // resources for CS implementation, used when bOutputsToSwapchain==false PSO_ID PSOMagnifierCS = INVALID_ID; diff --git a/Source/Renderer/Rendering/RenderPass/ObjectIDPass.cpp b/Source/Renderer/Rendering/RenderPass/ObjectIDPass.cpp index c5cdfd73..a1796123 100644 --- a/Source/Renderer/Rendering/RenderPass/ObjectIDPass.cpp +++ b/Source/Renderer/Rendering/RenderPass/ObjectIDPass.cpp @@ -165,6 +165,8 @@ void ObjectIDPass::RecordCommands(const IRenderPassDrawParameters* pDrawParamete assert(pParams->pCmdCopy); assert(pParams->pSceneView); assert(pParams->pSceneDrawData); + assert(pParams->RenderResolutionX > 0); + assert(pParams->RenderResolutionY > 0); ID3D12GraphicsCommandList* pCmd = pParams->pCmd; ID3D12GraphicsCommandList* pCmdCpy = static_cast(pParams->pCmdCopy); @@ -176,10 +178,8 @@ void ObjectIDPass::RecordCommands(const IRenderPassDrawParameters* pDrawParamete const DSV& dsv = mRenderer.GetDSV(DSVPassOutput); const RTV& rtv = mRenderer.GetRTV(RTVPassOutput); - const float RenderResolutionX = static_cast(pParams->pSceneView->SceneRTWidth); - const float RenderResolutionY = static_cast(pParams->pSceneView->SceneRTHeight); - D3D12_VIEWPORT viewport{ 0.0f, 0.0f, RenderResolutionX, RenderResolutionY, 0.0f, 1.0f }; - D3D12_RECT scissorsRect{ 0, 0, (LONG)RenderResolutionX, (LONG)RenderResolutionY }; + D3D12_VIEWPORT viewport{ 0.0f, 0.0f, pParams->RenderResolutionX, pParams->RenderResolutionY, 0.0f, 1.0f }; + D3D12_RECT scissorsRect{ 0, 0, (LONG)pParams->RenderResolutionX, (LONG)pParams->RenderResolutionY }; D3D12_CLEAR_FLAGS DSVClearFlags = D3D12_CLEAR_FLAGS::D3D12_CLEAR_FLAG_DEPTH; const float clearColor[] = { 0, 0, 0, 0 }; diff --git a/Source/Renderer/Rendering/RenderPass/ObjectIDPass.h b/Source/Renderer/Rendering/RenderPass/ObjectIDPass.h index 0c6fd22a..abac0d69 100644 --- a/Source/Renderer/Rendering/RenderPass/ObjectIDPass.h +++ b/Source/Renderer/Rendering/RenderPass/ObjectIDPass.h @@ -36,9 +36,11 @@ class ObjectIDPass : public RenderPassBase ID3D12GraphicsCommandList* pCmd = nullptr; ID3D12CommandList* pCmdCopy = nullptr; D3D12_GPU_VIRTUAL_ADDRESS cbPerView = 0; - bool bEnableAsyncCopy = false; const FSceneView* pSceneView = nullptr; const FSceneDrawData* pSceneDrawData = nullptr; + float RenderResolutionX = 0; + float RenderResolutionY = 0; + bool bEnableAsyncCopy = false; }; ObjectIDPass(VQRenderer& Renderer); diff --git a/Source/Renderer/Rendering/RenderPass/RenderPass.h b/Source/Renderer/Rendering/RenderPass/RenderPass.h index a5b46ecf..29d93863 100644 --- a/Source/Renderer/Rendering/RenderPass/RenderPass.h +++ b/Source/Renderer/Rendering/RenderPass/RenderPass.h @@ -36,6 +36,7 @@ enum ERenderPass Magnifier, ObjectID, Outline, + FSR3Upscale, NUM_RENDER_PASSES }; diff --git a/Source/Renderer/Rendering/RenderPass/ScreenSpaceReflections.cpp b/Source/Renderer/Rendering/RenderPass/ScreenSpaceReflections.cpp index d384d92a..fe2a634c 100644 --- a/Source/Renderer/Rendering/RenderPass/ScreenSpaceReflections.cpp +++ b/Source/Renderer/Rendering/RenderPass/ScreenSpaceReflections.cpp @@ -46,7 +46,7 @@ THE SOFTWARE. ********************************************************************/ namespace _1spp { -#include "Renderer/Libs/AMDFidelityFX/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_1spp.cpp" +#include "Renderer/Libs/AMD/SSSR/samplerCPP/samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_1spp.cpp" } struct FBlueNoiseSamplerStateCPU { @@ -111,8 +111,8 @@ void ScreenSpaceReflectionsPass::OnCreateWindowSizeDependentResources(unsigned W } //==============================Create denoising-related resources============================== { - const UINT Widt8 = DIV_AND_ROUND_UP(Width , 8u); - const UINT Heigh8 = DIV_AND_ROUND_UP(Height, 8u); + const UINT Width8 = DIV_AND_ROUND_UP(Width , 8u); + const UINT Height8 = DIV_AND_ROUND_UP(Height, 8u); enum EDescs { RADIANCE = 0, @@ -127,13 +127,13 @@ void ScreenSpaceReflectionsPass::OnCreateWindowSizeDependentResources(unsigned W }; std::array descs = { - CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R16G16B16A16_FLOAT, Width, Height, 1, 1, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS) - , CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R11G11B10_FLOAT , Widt8, Heigh8, 1, 1, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS) - , CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R16_FLOAT , Width, Height, 1, 1, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS) - , CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R16_FLOAT , Width, Height, 1, 1, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS) - , CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R32_FLOAT , Width, Height, 1, 1, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS) - , CD3DX12_RESOURCE_DESC::Tex2D(pParams->NormalBufferFormat , Width, Height, 1, 1, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS) - , CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8_UNORM , Width, Height, 1, 1, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS) + CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R16G16B16A16_FLOAT, Width, Height , 1, 1, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS) + , CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R11G11B10_FLOAT , Width8, Height8, 1, 1, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS) + , CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R16_FLOAT , Width, Height , 1, 1, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS) + , CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R16_FLOAT , Width, Height , 1, 1, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS) + , CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R32_FLOAT , Width, Height , 1, 1, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS) + , CD3DX12_RESOURCE_DESC::Tex2D(pParams->NormalBufferFormat , Width, Height , 1, 1, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS) + , CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8_UNORM , Width, Height , 1, 1, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS) }; const D3D12_RESOURCE_STATES rscStateSRV = D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE; const D3D12_RESOURCE_STATES rscStateUAV = D3D12_RESOURCE_STATE_UNORDERED_ACCESS; diff --git a/Source/Renderer/Rendering/RenderResources.cpp b/Source/Renderer/Rendering/RenderResources.cpp index 613671ae..56d0e0f5 100644 --- a/Source/Renderer/Rendering/RenderResources.cpp +++ b/Source/Renderer/Rendering/RenderResources.cpp @@ -21,12 +21,12 @@ #include "Libs/VQUtils/Include/Image.h" #include "Rendering/RenderPass/AmbientOcclusion.h" #include "Rendering/RenderPass/ScreenSpaceReflections.h" +#include "Rendering/RenderPass/FSR3UpscalePass.h" #include "Engine/GPUMarker.h" -void VQRenderer::LoadWindowSizeDependentResources(HWND hwnd, unsigned Width, unsigned Height, float fResolutionScale, bool bRenderingHDR) +void VQRenderer::LoadWindowSizeDependentResources(HWND hwnd, const FGraphicsSettings& GFXSettings, bool bRenderingHDR) { - assert(Width >= 1 && Height >= 1); SCOPED_CPU_MARKER("LoadWindowSizeDependentResources"); { @@ -34,8 +34,16 @@ void VQRenderer::LoadWindowSizeDependentResources(HWND hwnd, unsigned Width, uns mLatchDefaultResourcesLoaded.wait(); } - const uint RenderResolutionX = static_cast(Width * fResolutionScale); - const uint RenderResolutionY = static_cast(Height * fResolutionScale); + + const uint RenderResolutionX = static_cast(GFXSettings.GetRenderResolutionX()); + const uint RenderResolutionY = static_cast(GFXSettings.GetRenderResolutionY()); + assert(RenderResolutionX >= 1 && RenderResolutionY >= 1); + + const uint DisplayResolutionX = GFXSettings.Display.DisplayResolutionX; + const uint DisplayResolutionY = GFXSettings.Display.DisplayResolutionY; + assert(DisplayResolutionX >= 1 && DisplayResolutionY >= 1); + + const bool bTonemapperOutputsDisplayResolution = GFXSettings.IsFSR3Enabled(); constexpr DXGI_FORMAT MainColorRTFormat = DXGI_FORMAT_R16G16B16A16_FLOAT; const DXGI_FORMAT TonemapperOutputFormat = bRenderingHDR ? VQRenderer::PREFERRED_HDR_FORMAT : DXGI_FORMAT_R8G8B8A8_UNORM; @@ -246,8 +254,8 @@ void VQRenderer::LoadWindowSizeDependentResources(HWND hwnd, unsigned Width, uns FTextureRequest desc("TonemapperOut"); desc.D3D12Desc = CD3DX12_RESOURCE_DESC::Tex2D( TonemapperOutputFormat - , RenderResolutionX - , RenderResolutionY + , bTonemapperOutputsDisplayResolution ? DisplayResolutionX : RenderResolutionX + , bTonemapperOutputsDisplayResolution ? DisplayResolutionY : RenderResolutionY , 1 // Array Size , 1 // MIP levels , 1 // MSAA SampleCount @@ -301,8 +309,8 @@ void VQRenderer::LoadWindowSizeDependentResources(HWND hwnd, unsigned Width, uns FTextureRequest desc("FSR_EASU_Out"); desc.D3D12Desc = CD3DX12_RESOURCE_DESC::Tex2D( TonemapperOutputFormat - , Width - , Height + , DisplayResolutionX + , DisplayResolutionY , 1 // Array Size , 1 // MIP levels , 1 // MSAA SampleCount @@ -318,8 +326,8 @@ void VQRenderer::LoadWindowSizeDependentResources(HWND hwnd, unsigned Width, uns FTextureRequest desc("FSR_RCAS_Out"); desc.D3D12Desc = CD3DX12_RESOURCE_DESC::Tex2D( TonemapperOutputFormat - , Width - , Height + , DisplayResolutionX + , DisplayResolutionY , 1 // Array Size , 1 // MIP levels , 1 // MSAA SampleCount @@ -336,8 +344,8 @@ void VQRenderer::LoadWindowSizeDependentResources(HWND hwnd, unsigned Width, uns FTextureRequest desc("UI_SDR"); desc.D3D12Desc = CD3DX12_RESOURCE_DESC::Tex2D( DXGI_FORMAT_R8G8B8A8_UNORM - , Width - , Height + , DisplayResolutionX + , DisplayResolutionY , 1 // Array Size , 1 // MIP levels , 1 // MSAA SampleCount @@ -395,7 +403,7 @@ void VQRenderer::LoadWindowSizeDependentResources(HWND hwnd, unsigned Width, uns } mRenderPasses[ERenderPass::Magnifier]->OnCreateWindowSizeDependentResources(RenderResolutionX, RenderResolutionY, nullptr); - mRenderPasses[ERenderPass::Outline]->OnCreateWindowSizeDependentResources(Width, Height, nullptr); + mRenderPasses[ERenderPass::Outline]->OnCreateWindowSizeDependentResources(DisplayResolutionX, DisplayResolutionY, nullptr); { SCOPED_CPU_MARKER_C("WAIT_COPY_Q", 0xFFFF0000); @@ -403,7 +411,15 @@ void VQRenderer::LoadWindowSizeDependentResources(HWND hwnd, unsigned Width, uns Fence& CopyFence = mCopyObjIDDoneFence[BACK_BUFFER_INDEX]; CopyFence.WaitOnCPU(CopyFence.GetValue()); } - mRenderPasses[ERenderPass::ObjectID]->OnCreateWindowSizeDependentResources(Width, Height, nullptr); + mRenderPasses[ERenderPass::ObjectID]->OnCreateWindowSizeDependentResources(DisplayResolutionX, DisplayResolutionY, nullptr); + + // TODO: conditionally create resources + FSR3UpscalePass::FResourceCollection upscaleInitParams = {}; + upscaleInitParams.fResolutionScale = GFXSettings.Rendering.RenderResolutionScale; + upscaleInitParams.texColorInput = r.Tex_SceneColor; + upscaleInitParams.bAllocateTransparencyAndCompositionMaskTexture = true; + mRenderPasses[ERenderPass::FSR3Upscale]->OnCreateWindowSizeDependentResources(DisplayResolutionX, DisplayResolutionY, &upscaleInitParams); + if (!mbWindowSizeDependentResourcesFirstInitiazliationDone) { diff --git a/Source/Renderer/Rendering/RenderResources.h b/Source/Renderer/Rendering/RenderResources.h index bc34197f..a6118ec2 100644 --- a/Source/Renderer/Rendering/RenderResources.h +++ b/Source/Renderer/Rendering/RenderResources.h @@ -25,8 +25,7 @@ constexpr bool MSAA_ENABLE = true; constexpr uint MSAA_SAMPLE_COUNT = 4; -struct FRenderingResources {}; -struct FRenderingResources_MainWindow : public FRenderingResources +struct FRenderingResources_MainWindow { TextureID Tex_ShadowMaps_Spot = INVALID_ID; TextureID Tex_ShadowMaps_Point = INVALID_ID; @@ -119,7 +118,7 @@ struct FRenderingResources_MainWindow : public FRenderingResources SRV_ID SRV_NullCubemap = INVALID_ID; SRV_ID SRV_NullTexture2D = INVALID_ID; }; -struct FRenderingResources_DebugWindow : public FRenderingResources +struct FRenderingResources_DebugWindow { // TODO }; diff --git a/Source/Renderer/Rendering/SceneRendering.cpp b/Source/Renderer/Rendering/SceneRendering.cpp index 0992fd5a..e4647614 100644 --- a/Source/Renderer/Rendering/SceneRendering.cpp +++ b/Source/Renderer/Rendering/SceneRendering.cpp @@ -25,6 +25,7 @@ #include "RenderPass/MagnifierPass.h" #include "RenderPass/ObjectIDPass.h" #include "RenderPass/OutlinePass.h" +#include "RenderPass/FSR3UpscalePass.h" #include "Shaders/LightingConstantBufferData.h" @@ -158,6 +159,34 @@ FSceneDrawData& VQRenderer::GetSceneDrawData(int FRAME_INDEX) return mFrameSceneDrawData[0]; } +bool VQRenderer::ShouldEnableCameraJitters(const FGraphicsSettings& gfx) const +{ + return gfx.PostProcessing.UpscalingAlgorithm == EUpscalingAlgorithm::FIDELITYFX_SUPER_RESOLUTION_3; +} + +void VQRenderer::GetCameraPixelSpaceJitter(const FGraphicsSettings& gfx, size_t iFrame, float& JitterX, float& JitterY) const +{ + JitterX = 0.0f; + JitterY = 0.0f; + + switch (gfx.PostProcessing.UpscalingAlgorithm) + { + case EUpscalingAlgorithm::FIDELITYFX_SUPER_RESOLUTION_3: + { + if (mRenderPasses[ERenderPass::FSR3Upscale] != nullptr) + { + const FSR3UpscalePass* pPass = static_cast(mRenderPasses[ERenderPass::FSR3Upscale].get()); + assert(pPass); + + const uint DisplayResolutionX = gfx.Display.DisplayResolutionX; + const uint RenderResolutionX = DisplayResolutionX * gfx.Rendering.RenderResolutionScale; + pPass->GetJitterXY(JitterX, JitterY, RenderResolutionX, DisplayResolutionX, iFrame); + return; + } + } + } +} + static uint32_t GetNumShadowViewCmdRecordingThreads(const FSceneShadowViews& ShadowView) { #if RENDER_THREAD__MULTI_THREADED_COMMAND_RECORDING @@ -175,13 +204,12 @@ HRESULT VQRenderer::PreRenderScene( , const Window* pWindow , const FSceneView& SceneView , const FSceneShadowViews& SceneShadowView - , const FPostProcessParameters& PPParams , const FGraphicsSettings& GFXSettings , const FUIState& UIState ) { SCOPED_CPU_MARKER("Renderer.PreRenderScene"); - WaitMainSwapchainReady(); + WaitMainSwapchainReady(); FWindowRenderContext& ctx = this->GetWindowRenderContext(pWindow->GetHWND()); @@ -192,7 +220,7 @@ HRESULT VQRenderer::PreRenderScene( const bool bAsyncSubmit = mWaitForSubmitWorker; const bool bUseAsyncCompute = ShouldEnableAsyncCompute(GFXSettings, SceneView, SceneShadowView); const bool bUseAsyncCopy = GFXSettings.bEnableAsyncCopy; - const bool bVizualizationEnabled = PPParams.DrawModeEnum != EDrawMode::LIT_AND_POSTPROCESSED; + const bool bVizualizationEnabled = GFXSettings.DebugVizualization.DrawModeEnum != FDebugVisualizationSettings::EDrawMode::LIT_AND_POSTPROCESSED; #if RENDER_THREAD__MULTI_THREADED_COMMAND_RECORDING const uint32_t NumCmdRecordingThreads_GFX @@ -248,7 +276,7 @@ HRESULT VQRenderer::PreRenderScene( if (!SceneView.FrustumRenderLists.empty()) { - BatchDrawCalls(WorkerThreads, SceneView, SceneShadowView, ctx, PPParams, GFXSettings); + BatchDrawCalls(WorkerThreads, SceneView, SceneShadowView, ctx, GFXSettings); } if (mWaitForSubmitWorker) // not really used, need to offload submit to a non-worker thread (sync issues on main) @@ -306,7 +334,7 @@ HRESULT VQRenderer::PreRenderScene( return S_OK; } -HRESULT VQRenderer::RenderScene(ThreadPool& WorkerThreads, const Window* pWindow, const FSceneView& SceneView, const FSceneShadowViews& ShadowView, const FPostProcessParameters& PPParams, const FGraphicsSettings& GFXSettings, const FUIState& UIState, bool bHDRDisplay) +HRESULT VQRenderer::RenderScene(ThreadPool& WorkerThreads, const Window* pWindow, const FSceneView& SceneView, const FSceneShadowViews& ShadowView, const FGraphicsSettings& GFXSettings, const FUIState& UIState, bool bHDRDisplay) { SCOPED_CPU_MARKER("Renderer.RenderScene"); #if VQENGINE_MT_PIPELINED_UPDATE_AND_RENDER_THREADS @@ -347,83 +375,38 @@ HRESULT VQRenderer::RenderScene(ThreadPool& WorkerThreads, const Window* pWindow FWindowRenderContext& ctx = this->GetWindowRenderContext(hwnd); - HRESULT hr = S_OK; - const int NUM_BACK_BUFFERS = ctx.GetNumSwapchainBuffers(); - const int BACK_BUFFER_INDEX = ctx.GetCurrentSwapchainBufferIndex(); + HRESULT hr = S_OK; + const int NUM_BACK_BUFFERS = ctx.GetNumSwapchainBuffers(); + const int BACK_BUFFER_INDEX = ctx.GetCurrentSwapchainBufferIndex(); - const bool bReflectionsEnabled = GFXSettings.Reflections != EReflections::REFLECTIONS_OFF && GFXSettings.Reflections == EReflections::SCREEN_SPACE_REFLECTIONS__FFX; // TODO: remove the && after RayTracing is added - const bool bDownsampleDepth = GFXSettings.Reflections == EReflections::SCREEN_SPACE_REFLECTIONS__FFX; - const bool& bMSAA = GFXSettings.bAntiAliasing; + const bool bReflectionsEnabled = GFXSettings.Rendering.Reflections != EReflections::REFLECTIONS_OFF && GFXSettings.Rendering.Reflections == EReflections::SCREEN_SPACE_REFLECTIONS__FFX; // TODO: remove the && after RayTracing is added + const bool bDownsampleDepth = GFXSettings.Rendering.Reflections == EReflections::SCREEN_SPACE_REFLECTIONS__FFX; + const bool bMSAA = GFXSettings.Rendering.AntiAliasing == EAntiAliasingAlgorithm::MSAA4; const bool bAsyncCompute = ShouldEnableAsyncCompute(GFXSettings, SceneView, ShadowView); - const bool bVizualizationEnabled = PPParams.DrawModeEnum != EDrawMode::LIT_AND_POSTPROCESSED; - const bool bFFXCASEnabled = PPParams.IsFFXCASEnabled() && PPParams.Sharpness > 0.0f; - const bool bFSREnabled = PPParams.IsFSREnabled(); + const bool bVizualizationEnabled = GFXSettings.DebugVizualization.DrawModeEnum != FDebugVisualizationSettings::EDrawMode::LIT_AND_POSTPROCESSED; + const bool bFFXCASEnabled = GFXSettings.IsFFXCASEnabled() && GFXSettings.PostProcessing.Sharpness > 0.0f; + const bool bFSREnabled = GFXSettings.IsFSR1Enabled(); const FRenderingResources_MainWindow& rsc = this->GetRenderingResources_MainWindow(); - ID3D12Resource* pRscNormals = this->GetTextureResource(rsc.Tex_SceneNormals); - ID3D12Resource* pRscNormalsMSAA = this->GetTextureResource(rsc.Tex_SceneNormalsMSAA); + ID3D12Resource* pRscNormals = this->GetTextureResource(rsc.Tex_SceneNormals); + ID3D12Resource* pRscNormalsMSAA = this->GetTextureResource(rsc.Tex_SceneNormalsMSAA); ID3D12Resource* pRscDepthResolve = this->GetTextureResource(rsc.Tex_SceneDepthResolve); - ID3D12Resource* pRscDepthMSAA = this->GetTextureResource(rsc.Tex_SceneDepthMSAA); - ID3D12Resource* pRscDepth = this->GetTextureResource(rsc.Tex_SceneDepth); - ID3D12Resource* pSwapChainRT = ctx.SwapChain.GetCurrentBackBufferRenderTarget(); - - - ID3D12Resource* pRsc = nullptr; + ID3D12Resource* pRscDepthMSAA = this->GetTextureResource(rsc.Tex_SceneDepthMSAA); + ID3D12Resource* pRscDepth = this->GetTextureResource(rsc.Tex_SceneDepth); + ID3D12Resource* pRscSwapChainRT = ctx.SwapChain.GetCurrentBackBufferRenderTarget(); + + D3D12_CPU_DESCRIPTOR_HANDLE RTVHandleSwapchain = ctx.SwapChain.GetCurrentBackBufferRTVHandle(); + ID3D12CommandList* pCmdCpy = (ID3D12CommandList*)mpRenderingCmds[COPY][BACK_BUFFER_INDEX][0]; CommandQueue& GFXCmdQ = this->GetCommandQueue(ECommandQueueType::GFX); CommandQueue& CPYCmdQ = this->GetCommandQueue(ECommandQueueType::COPY); CommandQueue& CMPCmdQ = this->GetCommandQueue(ECommandQueueType::COMPUTE); - - // --------------------------------------------------------------------------------------------------- - // TODO: undo const cast and assign in a proper spot ------------------------------------------------- - FSceneView& RefSceneView = const_cast(SceneView); - FPostProcessParameters& RefPPParams = const_cast(PPParams); - - RefSceneView.SceneRTWidth = static_cast(ctx.WindowDisplayResolutionX * (PPParams.IsFSREnabled() ? PPParams.ResolutionScale : 1.0f)); - RefSceneView.SceneRTHeight = static_cast(ctx.WindowDisplayResolutionY * (PPParams.IsFSREnabled() ? PPParams.ResolutionScale : 1.0f)); - RefPPParams.SceneRTWidth = SceneView.SceneRTWidth; - RefPPParams.SceneRTHeight = SceneView.SceneRTHeight; - RefPPParams.DisplayResolutionWidth = ctx.WindowDisplayResolutionX; - RefPPParams.DisplayResolutionHeight = ctx.WindowDisplayResolutionY; - if (bHDRDisplay) // do some settings override for some render paths - { -#if !DISABLE_FIDELITYFX_CAS - if (RefPPParams.IsFFXCASEnabled()) - { - Log::Warning("FidelityFX CAS HDR not implemented, turning CAS off"); - RefPPParams.bEnableCAS = false; - } -#endif - if (RefPPParams.IsFSREnabled()) - { - // TODO: HDR conversion pass to handle color range and precision/packing, shader variants etc. - Log::Warning("FidelityFX Super Resolution HDR not implemented yet, turning FSR off"); - // RefPPParams.bEnableFSR = false; - RefPPParams.UpscalingAlgorithm = FPostProcessParameters::EUpscalingAlgorithm::NONE; // TODO: enable resolution scaling for HDR -#if 0 - // this causes UI pass PSO to not match the render target format - mEventQueue_WinToVQE_Renderer.AddItem(std::make_unique(W, H, hwnd)); - mEventQueue_WinToVQE_Update.AddItem(std::make_unique(W, H, hwnd)); -#endif - } - } - assert(PPParams.DisplayResolutionHeight != 0); - assert(PPParams.DisplayResolutionWidth != 0); - // TODO: undo const cast and assign in a proper spot ------------------------------------------------- - // --------------------------------------------------------------------------------------------------- - - - const SRV& srv_UIColorIn = bVizualizationEnabled ? - this->GetSRV(rsc.SRV_PostProcess_VisualizationOut) : ( - bFFXCASEnabled - ? this->GetSRV(rsc.SRV_PostProcess_FFXCASOut) - : (bFSREnabled - ? this->GetSRV(rsc.SRV_PostProcess_FSR_RCASOut) - : this->GetSRV(rsc.SRV_PostProcess_TonemapperOut))); - - const float RenderResolutionX = static_cast(SceneView.SceneRTWidth); - const float RenderResolutionY = static_cast(SceneView.SceneRTHeight); + + FPostProcessOutput PostProcessOutput = {}; + + const float RenderResolutionX = static_cast(GFXSettings.Display.DisplayResolutionX * GFXSettings.Rendering.RenderResolutionScale); + const float RenderResolutionY = static_cast(GFXSettings.Display.DisplayResolutionY * GFXSettings.Rendering.RenderResolutionScale); UINT64 SSAODoneFenceValue = mAsyncComputeSSAODoneFence[BACK_BUFFER_INDEX].GetValue(); D3D12_GPU_VIRTUAL_ADDRESS cbPerFrame = {}; @@ -435,11 +418,12 @@ HRESULT VQRenderer::RenderScene(ThreadPool& WorkerThreads, const Window* pWindow assert(pPerFrame); pPerFrame->Lights = SceneView.GPULightingData; - pPerFrame->fAmbientLightingFactor = SceneView.sceneRenderOptions.fAmbientLightingFactor; + pPerFrame->fAmbientLightingFactor = SceneView.sceneRenderOptions.Lighting.fAmbientLightingFactor; pPerFrame->f2PointLightShadowMapDimensions = { 1024.0f, 1024.f }; // TODO pPerFrame->f2SpotLightShadowMapDimensions = { 1024.0f, 1024.f }; // TODO pPerFrame->f2DirectionalLightShadowMapDimensions = { 2048.0f, 2048.0f }; // TODO pPerFrame->fHDRIOffsetInRadians = SceneView.HDRIYawOffset; + pPerFrame->fGlobalMipBias = GFXSettings.Rendering.GlobalMipBias; if (bHDRDisplay) { @@ -461,7 +445,7 @@ HRESULT VQRenderer::RenderScene(ThreadPool& WorkerThreads, const Window* pWindow pPerView->ScreenDimensions.x = RenderResolutionX; pPerView->ScreenDimensions.y = RenderResolutionY; pPerView->MaxEnvMapLODLevels = static_cast(rsc.EnvironmentMap.GetNumSpecularIrradianceCubemapLODLevels(*this)); - pPerView->EnvironmentMapDiffuseOnlyIllumination = GFXSettings.Reflections == EReflections::SCREEN_SPACE_REFLECTIONS__FFX; + pPerView->EnvironmentMapDiffuseOnlyIllumination = GFXSettings.Rendering.Reflections == EReflections::SCREEN_SPACE_REFLECTIONS__FFX; const FFrustumPlaneset planes = FFrustumPlaneset::ExtractFromMatrix(SceneView.viewProj, true); memcpy(pPerView->WorldFrustumPlanes, planes.abcd, sizeof(planes.abcd)); } @@ -500,9 +484,9 @@ HRESULT VQRenderer::RenderScene(ThreadPool& WorkerThreads, const Window* pWindow RenderAmbientOcclusion(pCmd, SceneView, GFXSettings, bAsyncCompute); - TransitionForSceneRendering(pCmd, ctx, PPParams, GFXSettings); + TransitionForSceneRendering(pCmd, ctx, GFXSettings); - RenderSceneColor(pCmd, &CBHeap, SceneView, PPParams, cbPerView, cbPerFrame, GFXSettings, bHDRDisplay); + RenderSceneColor(pCmd, &CBHeap, SceneView, cbPerView, cbPerFrame, GFXSettings, bHDRDisplay); if (!bReflectionsEnabled) { @@ -514,29 +498,38 @@ HRESULT VQRenderer::RenderScene(ThreadPool& WorkerThreads, const Window* pWindow RenderOutline(pCmd, &CBHeap, cbPerView, SceneView, bMSAA, { rtvHandle }); } - ResolveMSAA(pCmd, &CBHeap, PPParams, GFXSettings); + ResolveMSAA(pCmd, &CBHeap, GFXSettings); - TransitionForPostProcessing(pCmd, PPParams, GFXSettings); + TransitionForPostProcessing(pCmd, GFXSettings); if (bReflectionsEnabled) { RenderReflections(pCmd, &CBHeap, SceneView, GFXSettings); // render scene-debugging stuff that shouldn't be in reflections: bounding volumes, etc - RenderSceneBoundingVolumes(pCmd, &CBHeap, cbPerView, SceneView, bMSAA); + RenderSceneBoundingVolumes(pCmd, &CBHeap, cbPerView, SceneView, GFXSettings); CompositeReflections(pCmd, &CBHeap, SceneView, GFXSettings); } - pRsc = RenderPostProcess(pCmd, &CBHeap, PPParams, bHDRDisplay); + PostProcessOutput = RenderPostProcess(pCmd, &CBHeap, SceneView, GFXSettings, bHDRDisplay); + + TransitionForUI(pCmd, GFXSettings, bHDRDisplay, PostProcessOutput.pRsc, pRscSwapChainRT); - TransitionForUI(pCmd, PPParams, GFXSettings, bHDRDisplay, pRsc, pSwapChainRT); + SwapChainRenderPass(pCmd, &CBHeap, SceneView, GFXSettings, RTVHandleSwapchain, GetSRV(PostProcessOutput.srv), bHDRDisplay); - RenderUI(pCmd, &CBHeap, ctx, PPParams, pRsc, srv_UIColorIn, UIState, bHDRDisplay); + D3D12_CPU_DESCRIPTOR_HANDLE RTVHandleUI = bHDRDisplay ? this->GetRTV(rsc.RTV_UI_SDR).GetCPUDescHandle(): RTVHandleSwapchain; + RenderUI(pCmd, &CBHeap, RTVHandleUI, UIState, SceneView, GFXSettings, bHDRDisplay); if (bHDRDisplay) { - CompositUIToHDRSwapchain(pCmd, &CBHeap, ctx, PPParams, pWindow); + CompositUIToHDRSwapchain(pCmd, &CBHeap, ctx, GFXSettings); + } + + { + SCOPED_GPU_MARKER(pCmd, "SwapchainTransitionToPresent"); + CD3DX12_RESOURCE_BARRIER barrier = CD3DX12_RESOURCE_BARRIER::Transition(pRscSwapChainRT, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT); + pCmd->ResourceBarrier(1, &barrier); } } @@ -724,9 +717,9 @@ HRESULT VQRenderer::RenderScene(ThreadPool& WorkerThreads, const Window* pWindow RenderAmbientOcclusion(pCmd_ThisThread, SceneView, GFXSettings, bAsyncCompute); } - TransitionForSceneRendering(pCmd_ThisThread, ctx, PPParams, GFXSettings); + TransitionForSceneRendering(pCmd_ThisThread, ctx, GFXSettings); - RenderSceneColor(pCmd_ThisThread, &CBHeap_This, SceneView, PPParams, cbPerView, cbPerFrame, GFXSettings, bHDRDisplay); + RenderSceneColor(pCmd_ThisThread, &CBHeap_This, SceneView, cbPerView, cbPerFrame, GFXSettings, bHDRDisplay); if (!bReflectionsEnabled) { @@ -738,29 +731,37 @@ HRESULT VQRenderer::RenderScene(ThreadPool& WorkerThreads, const Window* pWindow RenderOutline(pCmd_ThisThread, &CBHeap_This, cbPerView, SceneView, bMSAA, { rtvHandle }); } - ResolveMSAA(pCmd_ThisThread, &CBHeap_This, PPParams, GFXSettings); + ResolveMSAA(pCmd_ThisThread, &CBHeap_This, GFXSettings); - TransitionForPostProcessing(pCmd_ThisThread, PPParams, GFXSettings); + TransitionForPostProcessing(pCmd_ThisThread, GFXSettings); if (bReflectionsEnabled) { RenderReflections(pCmd_ThisThread, &CBHeap_This, SceneView, GFXSettings); // render scene-debugging stuff that shouldn't be in reflections: bounding volumes, etc - RenderSceneBoundingVolumes(pCmd_ThisThread, &CBHeap_This, cbPerView, SceneView, bMSAA); + RenderSceneBoundingVolumes(pCmd_ThisThread, &CBHeap_This, cbPerView, SceneView, GFXSettings); CompositeReflections(pCmd_ThisThread, &CBHeap_This, SceneView, GFXSettings); } - pRsc = RenderPostProcess(pCmd_ThisThread, &CBHeap_This, PPParams, bHDRDisplay); + PostProcessOutput = RenderPostProcess(pCmd_ThisThread, &CBHeap_This, SceneView, GFXSettings, bHDRDisplay); - TransitionForUI(pCmd_PresentThread, PPParams, GFXSettings, bHDRDisplay, pRsc, pSwapChainRT); + TransitionForUI(pCmd_PresentThread, GFXSettings, bHDRDisplay, PostProcessOutput.pRsc, pRscSwapChainRT); + + SwapChainRenderPass(pCmd_PresentThread, &CBHeap_This, SceneView, GFXSettings, RTVHandleSwapchain, GetSRV(PostProcessOutput.srv), bHDRDisplay); - RenderUI(pCmd_PresentThread, &CBHeap_This, ctx, PPParams, pRsc, srv_UIColorIn, UIState, bHDRDisplay); + D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = bHDRDisplay ? this->GetRTV(rsc.RTV_UI_SDR).GetCPUDescHandle() : RTVHandleSwapchain; + RenderUI(pCmd_PresentThread, &CBHeap_This, rtvHandle, UIState, SceneView, GFXSettings, bHDRDisplay); if (bHDRDisplay) { - CompositUIToHDRSwapchain(pCmd_PresentThread, &CBHeap_This, ctx, PPParams, pWindow); + CompositUIToHDRSwapchain(pCmd_PresentThread, &CBHeap_This, ctx, GFXSettings); + } + { + SCOPED_GPU_MARKER(pCmd_PresentThread, "SwapchainTransitionToPresent"); + CD3DX12_RESOURCE_BARRIER barrier = CD3DX12_RESOURCE_BARRIER::Transition(pRscSwapChainRT, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT); + pCmd_PresentThread->ResourceBarrier(1, &barrier); } // SYNC Render Workers @@ -889,14 +890,7 @@ HRESULT VQRenderer::RenderScene(ThreadPool& WorkerThreads, const Window* pWindow #if 0 Log::Info("RenderScene[%d]", ctx.GetCurrentSwapchainBufferIndex()); #endif - - HRESULT hr = PresentFrame(ctx); - - #if !EXECUTE_CMD_LISTS_ON_WORKER - //if (hr == DXGI_STATUS_OCCLUDED) { RenderThread_HandleStatusOccluded(); } - //if (hr == DXGI_ERROR_DEVICE_REMOVED) { RenderThread_HandleDeviceRemoved(); } - #endif - + hr = PresentFrame(ctx); #if EXECUTE_CMD_LISTS_ON_WORKER mSubmitWorkerSignal.Notify(); @@ -923,6 +917,8 @@ void VQRenderer::RenderObjectIDPass(int iThread, ID3D12CommandList* pCmdCopy, Dy params.pSceneDrawData = &mFrameSceneDrawData[0]; params.cbPerView = perViewCBAddr; params.bEnableAsyncCopy = GFXSettings.bEnableAsyncCopy; + params.RenderResolutionX = GFXSettings.GetRenderResolutionX(); + params.RenderResolutionY = GFXSettings.GetRenderResolutionY(); pObjectIDPass->RecordCommands(¶ms); } @@ -1272,7 +1268,7 @@ void VQRenderer::RenderDepthPrePass( { SCOPED_GPU_MARKER(pCmd, "RenderDepthPrePass"); - const bool& bMSAA = GFXSettings.bAntiAliasing; + const bool bMSAA = GFXSettings.Rendering.AntiAliasing == EAntiAliasingAlgorithm::MSAA4; const FRenderingResources_MainWindow& rsc = this->GetRenderingResources_MainWindow(); const FSceneDrawData& SceneDrawData = mFrameSceneDrawData[0]; // [0] since we don't have parallel update+render @@ -1290,8 +1286,8 @@ void VQRenderer::RenderDepthPrePass( D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = rtvNormals.GetCPUDescHandle(); D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = dsvColor.GetCPUDescHandle(); - const float RenderResolutionX = static_cast(SceneView.SceneRTWidth); - const float RenderResolutionY = static_cast(SceneView.SceneRTHeight); + const float RenderResolutionX = static_cast(GFXSettings.Display.DisplayResolutionX * GFXSettings.Rendering.RenderResolutionScale); + const float RenderResolutionY = static_cast(GFXSettings.Display.DisplayResolutionY * GFXSettings.Rendering.RenderResolutionScale); D3D12_VIEWPORT viewport{ 0.0f, 0.0f, RenderResolutionX, RenderResolutionY, 0.0f, 1.0f }; D3D12_RECT scissorsRect{ 0, 0, (LONG)RenderResolutionX, (LONG)RenderResolutionY }; @@ -1504,7 +1500,7 @@ void VQRenderer::RenderAmbientOcclusion(ID3D12GraphicsCommandList* pCmd, const F { const FRenderingResources_MainWindow& rsc = this->GetRenderingResources_MainWindow(); - const bool& bMSAA = GFXSettings.bAntiAliasing; + const bool bMSAA = GFXSettings.Rendering.AntiAliasing == EAntiAliasingAlgorithm::MSAA4; std::shared_ptr pAOPass = std::static_pointer_cast(this->GetRenderPass(ERenderPass::AmbientOcclusion)); ID3D12Resource* pRscAmbientOcclusion = this->GetTextureResource(rsc.Tex_AmbientOcclusion); @@ -1517,9 +1513,9 @@ void VQRenderer::RenderAmbientOcclusion(ID3D12GraphicsCommandList* pCmd, const F SCOPED_GPU_MARKER(pCmd, pStrPass[pAOPass->GetMethod()]); static bool sbScreenSpaceAO_Previous = false; - const bool bSSAOToggledOff = sbScreenSpaceAO_Previous && !SceneView.sceneRenderOptions.bScreenSpaceAO; + const bool bSSAOToggledOff = sbScreenSpaceAO_Previous && !SceneView.sceneRenderOptions.Lighting.bScreenSpaceAO; - if (SceneView.sceneRenderOptions.bScreenSpaceAO) + if (SceneView.sceneRenderOptions.Lighting.bScreenSpaceAO) { AmbientOcclusionPass::FDrawParameters drawParams = {}; DirectX::XMStoreFloat4x4(&drawParams.matNormalToView, SceneView.view); @@ -1551,26 +1547,26 @@ void VQRenderer::RenderAmbientOcclusion(ID3D12GraphicsCommandList* pCmd, const F pCmd->ResourceBarrier(1, &barrierWR); } - sbScreenSpaceAO_Previous = SceneView.sceneRenderOptions.bScreenSpaceAO; + sbScreenSpaceAO_Previous = SceneView.sceneRenderOptions.Lighting.bScreenSpaceAO; } static bool IsFFX_SSSREnabled(const FGraphicsSettings& GFXSettings) { - return GFXSettings.Reflections == EReflections::SCREEN_SPACE_REFLECTIONS__FFX; + return GFXSettings.Rendering.Reflections == EReflections::SCREEN_SPACE_REFLECTIONS__FFX; } bool VQRenderer::ShouldUseMotionVectorsTarget(const FGraphicsSettings& GFXSettings) { return IsFFX_SSSREnabled(GFXSettings); } -bool VQRenderer::ShouldUseVisualizationTarget(const FPostProcessParameters& PPParams) +bool VQRenderer::ShouldUseVisualizationTarget(const FGraphicsSettings& GFXSettings) { - return PPParams.DrawModeEnum == EDrawMode::ALBEDO - || PPParams.DrawModeEnum == EDrawMode::ROUGHNESS - || PPParams.DrawModeEnum == EDrawMode::METALLIC; + return GFXSettings.DebugVizualization.DrawModeEnum == FDebugVisualizationSettings::EDrawMode::ALBEDO + || GFXSettings.DebugVizualization.DrawModeEnum == FDebugVisualizationSettings::EDrawMode::ROUGHNESS + || GFXSettings.DebugVizualization.DrawModeEnum == FDebugVisualizationSettings::EDrawMode::METALLIC; } -void VQRenderer::TransitionForSceneRendering(ID3D12GraphicsCommandList* pCmd, FWindowRenderContext& ctx, const FPostProcessParameters& PPParams, const FGraphicsSettings& GFXSettings) +void VQRenderer::TransitionForSceneRendering(ID3D12GraphicsCommandList* pCmd, FWindowRenderContext& ctx, const FGraphicsSettings& GFXSettings) { - const bool& bMSAA = GFXSettings.bAntiAliasing; + const bool bMSAA = GFXSettings.Rendering.AntiAliasing == EAntiAliasingAlgorithm::MSAA4; const FRenderingResources_MainWindow& rsc = this->GetRenderingResources_MainWindow(); @@ -1598,7 +1594,7 @@ void VQRenderer::TransitionForSceneRendering(ID3D12GraphicsCommandList* pCmd, FW vBarriers.push_back(CD3DX12_RESOURCE_BARRIER::Transition(pRscShadowMaps_Point, D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)); vBarriers.push_back(CD3DX12_RESOURCE_BARRIER::Transition(pRscShadowMaps_Directional, D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)); - if (ShouldUseVisualizationTarget(PPParams)) + if (ShouldUseVisualizationTarget(GFXSettings)) { vBarriers.push_back(bMSAA ? CD3DX12_RESOURCE_BARRIER::Transition(pRscVizMSAA, D3D12_RESOURCE_STATE_RESOLVE_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET) @@ -1619,10 +1615,9 @@ void VQRenderer::TransitionForSceneRendering(ID3D12GraphicsCommandList* pCmd, FW void VQRenderer::RenderSceneColor( ID3D12GraphicsCommandList* pCmd, DynamicBufferHeap* pCBufferHeap, - const FSceneView& SceneView, - const FPostProcessParameters& PPParams, + const FSceneView& SceneView, D3D12_GPU_VIRTUAL_ADDRESS perViewCBAddr, - D3D12_GPU_VIRTUAL_ADDRESS perFrameCBAddr, + D3D12_GPU_VIRTUAL_ADDRESS perFrameCBAddr, const FGraphicsSettings& GFXSettings, bool bHDR ) @@ -1631,17 +1626,17 @@ void VQRenderer::RenderSceneColor( struct FFrameConstantBuffer { DirectX::XMMATRIX matModelViewProj; }; struct FFrameConstantBuffer2 { DirectX::XMMATRIX matModelViewProj; int iTextureConfig; int iTextureOutput; }; - + const FRenderingResources_MainWindow& rsc = this->GetRenderingResources_MainWindow(); const bool bHDRDisplay = bHDR; // TODO: this->ShouldRenderHDR(pWindow->GetHWND()); const bool bHasEnvironmentMapHDRTexture = rsc.EnvironmentMap.SRV_HDREnvironment != INVALID_ID; const bool bDrawEnvironmentMap = bHasEnvironmentMapHDRTexture && rsc.SRV_BRDFIntegrationLUT != INVALID_ID; - const bool bUseVisualizationRenderTarget = ShouldUseVisualizationTarget(PPParams); + const bool bUseVisualizationRenderTarget = ShouldUseVisualizationTarget(GFXSettings); const bool bRenderMotionVectors = ShouldUseMotionVectorsTarget(GFXSettings); const bool bRenderScreenSpaceReflections = IsFFX_SSSREnabled(GFXSettings); - - const bool& bMSAA = GFXSettings.bAntiAliasing; + const bool bMSAA = GFXSettings.Rendering.AntiAliasing == EAntiAliasingAlgorithm::MSAA4; + const bool bOutputMaskRT = GFXSettings.IsFSR3Enabled() && bDrawEnvironmentMap; const RTV& rtvColor = this->GetRTV(bMSAA ? rsc.RTV_SceneColorMSAA : rsc.RTV_SceneColor); const RTV& rtvColorViz = this->GetRTV(bMSAA ? rsc.RTV_SceneVisualizationMSAA : rsc.RTV_SceneVisualization); @@ -1658,22 +1653,30 @@ void VQRenderer::RenderSceneColor( // Clear Depth & Render targets D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = dsvColor.GetCPUDescHandle(); const float clearColor[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - - std::vector rtvHandles(1, rtvColor.GetCPUDescHandle()); - if (bUseVisualizationRenderTarget) rtvHandles.push_back(rtvColorViz.GetCPUDescHandle()); - if (bRenderMotionVectors) rtvHandles.push_back(rtvMoVec.GetCPUDescHandle()); - + { SCOPED_GPU_MARKER(pCmd, "Clear"); - for (D3D12_CPU_DESCRIPTOR_HANDLE& rtv : rtvHandles) - pCmd->ClearRenderTargetView(rtv, clearColor, 0, nullptr); - } + size_t iRTV = 0; + D3D12_CPU_DESCRIPTOR_HANDLE rtvHandles[4] = { 0, 0, 0, 0 }; + rtvHandles[iRTV++] = rtvColor.GetCPUDescHandle(); + if (bUseVisualizationRenderTarget) rtvHandles[iRTV++] = rtvColorViz.GetCPUDescHandle(); + if (bRenderMotionVectors) rtvHandles[iRTV++] = rtvMoVec.GetCPUDescHandle(); + if (bOutputMaskRT) + { + std::shared_ptr pFSR3Pass = std::static_pointer_cast(GetRenderPass(ERenderPass::FSR3Upscale)); + assert(pFSR3Pass); + rtvHandles[iRTV++] = GetRTV(pFSR3Pass->GetRTV_ID(FSR3UpscalePass::EResources::TransparencyAndCompositionMask)).GetCPUDescHandle(); + } + + for (size_t i = 0; i < iRTV; ++i) + pCmd->ClearRenderTargetView(rtvHandles[i], clearColor, 0, nullptr); - pCmd->OMSetRenderTargets((UINT)rtvHandles.size(), rtvHandles.data(), FALSE, &dsvHandle); + pCmd->OMSetRenderTargets(iRTV, rtvHandles, FALSE, &dsvHandle); + } // Set Viewport & Scissors - const float RenderResolutionX = static_cast(SceneView.SceneRTWidth); - const float RenderResolutionY = static_cast(SceneView.SceneRTHeight); + const float RenderResolutionX = static_cast(GFXSettings.Display.DisplayResolutionX * GFXSettings.Rendering.RenderResolutionScale); + const float RenderResolutionY = static_cast(GFXSettings.Display.DisplayResolutionY * GFXSettings.Rendering.RenderResolutionScale); D3D12_VIEWPORT viewport{ 0.0f, 0.0f, RenderResolutionX, RenderResolutionY, 0.0f, 1.0f }; D3D12_RECT scissorsRect{ 0, 0, (LONG)RenderResolutionX, (LONG)RenderResolutionY }; pCmd->RSSetViewports(1, &viewport); @@ -1822,6 +1825,20 @@ void VQRenderer::RenderSceneColor( if (bDrawEnvironmentMap) { SCOPED_GPU_MARKER(pCmd, "EnvironmentMap"); + if (bOutputMaskRT) + { + // re-arrange RTVs because forward lighting has higher number of RTVs potentiall bound + size_t iRTV = 0; + D3D12_CPU_DESCRIPTOR_HANDLE rtvHandles[2] = { 0, 0 }; + rtvHandles[iRTV++] = rtvColor.GetCPUDescHandle(); + if (bOutputMaskRT) + { + std::shared_ptr pFSR3Pass = std::static_pointer_cast(GetRenderPass(ERenderPass::FSR3Upscale)); + assert(pFSR3Pass); + rtvHandles[iRTV++] = GetRTV(pFSR3Pass->GetRTV_ID(FSR3UpscalePass::EResources::TransparencyAndCompositionMask)).GetCPUDescHandle(); + } + pCmd->OMSetRenderTargets(iRTV, rtvHandles, FALSE, &dsvHandle); + } ID3D12DescriptorHeap* ppHeaps[] = { this->GetDescHeap(EResourceHeapType::CBV_SRV_UAV_HEAP) }; @@ -1830,7 +1847,13 @@ void VQRenderer::RenderSceneColor( pCBufferHeap->AllocConstantBuffer(sizeof(FFrameConstantBuffer ), (void**)(&pConstBuffer), &cbAddr); pConstBuffer->matModelViewProj = SceneView.EnvironmentMapViewProj; - pCmd->SetPipelineState(this->GetPSO(bMSAA ? EBuiltinPSOs::SKYDOME_PSO_MSAA_4 : EBuiltinPSOs::SKYDOME_PSO)); + EBuiltinPSOs psoID = bMSAA ? EBuiltinPSOs::SKYDOME_PSO_MSAA_4 : EBuiltinPSOs::SKYDOME_PSO; + if (bOutputMaskRT) + { + psoID = EBuiltinPSOs::SKYDOME_MASK_PSO; + } + + pCmd->SetPipelineState(this->GetPSO(psoID)); pCmd->SetGraphicsRootSignature(this->GetBuiltinRootSignature(EBuiltinRootSignatures::LEGACY__HelloWorldCube)); pCmd->SetDescriptorHeaps(_countof(ppHeaps), ppHeaps); @@ -2027,7 +2050,7 @@ void VQRenderer::RenderDebugVertexAxes(ID3D12GraphicsCommandList* pCmd, DynamicB const FSceneDrawData& SceneDrawData = mFrameSceneDrawData[0]; // [0] since we don't have parallel update+render - if (!SceneView.sceneRenderOptions.bDrawVertexLocalAxes || SceneDrawData.debugVertexAxesRenderParams.empty()) + if (!SceneView.sceneRenderOptions.Debug.bDrawVertexLocalAxes || SceneDrawData.debugVertexAxesRenderParams.empty()) { return; } @@ -2042,7 +2065,7 @@ void VQRenderer::RenderDebugVertexAxes(ID3D12GraphicsCommandList* pCmd, DynamicB pCBuffer->matWorld = cmd.matWorld [0]; pCBuffer->matNormal = cmd.matNormal[0]; pCBuffer->matViewProj = SceneView.viewProj; - pCBuffer->LocalAxisSize = SceneView.sceneRenderOptions.fVertexLocalAxixSize; + pCBuffer->LocalAxisSize = SceneView.sceneRenderOptions.Debug.fVertexLocalAxisSize; const uint32 NumInstances = 1; const uint32 NumIndices = cmd.numIndices; @@ -2057,9 +2080,9 @@ void VQRenderer::RenderDebugVertexAxes(ID3D12GraphicsCommandList* pCmd, DynamicB } } -void VQRenderer::ResolveMSAA(ID3D12GraphicsCommandList* pCmd, DynamicBufferHeap* pCBufferHeap, const FPostProcessParameters& PPParams, const FGraphicsSettings& GFXSettings) +void VQRenderer::ResolveMSAA(ID3D12GraphicsCommandList* pCmd, DynamicBufferHeap* pCBufferHeap, const FGraphicsSettings& GFXSettings) { - const bool& bMSAA = GFXSettings.bAntiAliasing; + const bool bMSAA = GFXSettings.Rendering.AntiAliasing == EAntiAliasingAlgorithm::MSAA4; if (!bMSAA) return; @@ -2075,7 +2098,7 @@ void VQRenderer::ResolveMSAA(ID3D12GraphicsCommandList* pCmd, DynamicBufferHeap* auto pRscMoVecMSAA = this->GetTextureResource(rsc.Tex_SceneMotionVectorsMSAA); auto pRscDepthMSAA = this->GetTextureResource(rsc.Tex_SceneDepthMSAA); - const bool bUseVizualization = ShouldUseVisualizationTarget(PPParams); + const bool bUseVizualization = ShouldUseVisualizationTarget(GFXSettings); const bool bRenderMotionVectors = ShouldUseMotionVectorsTarget(GFXSettings); const bool bResolveRoughness = IsFFX_SSSREnabled(GFXSettings) && false; @@ -2195,7 +2218,7 @@ static DirectX::XMMATRIX GetHDRIRotationMatrix(float fHDIROffsetInRadians) } void VQRenderer::RenderReflections(ID3D12GraphicsCommandList* pCmd, DynamicBufferHeap* pCBufferHeap, const FSceneView& SceneView, const FGraphicsSettings& GFXSettings) { - const FSceneRenderOptions::FFFX_SSSR_UIOptions& UIParams = SceneView.sceneRenderOptions.FFX_SSSRParameters; + const FRenderingSettings::FFFX_SSSR_Options& Options = GFXSettings.Rendering.FFX_SSSR_Options; const FRenderingResources_MainWindow& rsc = this->GetRenderingResources_MainWindow(); const FEnvironmentMapRenderingResources& EnvMapRsc = rsc.EnvironmentMap; @@ -2208,8 +2231,10 @@ void VQRenderer::RenderReflections(ID3D12GraphicsCommandList* pCmd, DynamicBuffe { this->GetTextureDimensions(EnvMapRsc.Tex_IrradianceSpec, EnvMapSpecIrrCubemapDimX, EnvMapSpecIrrCubemapDimY); } - - switch (GFXSettings.Reflections) + + const float RenderResolutionX = static_cast(GFXSettings.Display.DisplayResolutionX * GFXSettings.Rendering.RenderResolutionScale); + const float RenderResolutionY = static_cast(GFXSettings.Display.DisplayResolutionY * GFXSettings.Rendering.RenderResolutionScale); + switch (GFXSettings.Rendering.Reflections) { case EReflections::SCREEN_SPACE_REFLECTIONS__FFX: { @@ -2224,21 +2249,21 @@ void VQRenderer::RenderReflections(ID3D12GraphicsCommandList* pCmd, DynamicBuffe params.ffxCBuffer.invProjection = SceneView.projInverse; params.ffxCBuffer.view = SceneView.view; params.ffxCBuffer.invView = SceneView.viewInverse; - params.ffxCBuffer.bufferDimensions[0] = SceneView.SceneRTWidth; - params.ffxCBuffer.bufferDimensions[1] = SceneView.SceneRTHeight; + params.ffxCBuffer.bufferDimensions[0] = RenderResolutionX; + params.ffxCBuffer.bufferDimensions[1] = RenderResolutionY; params.ffxCBuffer.envMapRotation = GetHDRIRotationMatrix(SceneView.HDRIYawOffset); params.ffxCBuffer.inverseBufferDimensions[0] = 1.0f / params.ffxCBuffer.bufferDimensions[0]; params.ffxCBuffer.inverseBufferDimensions[1] = 1.0f / params.ffxCBuffer.bufferDimensions[1]; params.ffxCBuffer.frameIndex = static_cast(mRenderStats.mNumFramesRendered); - params.ffxCBuffer.temporalStabilityFactor = UIParams.temporalStability; - params.ffxCBuffer.depthBufferThickness = UIParams.depthBufferThickness; - params.ffxCBuffer.roughnessThreshold = UIParams.roughnessThreshold; - params.ffxCBuffer.varianceThreshold = UIParams.temporalVarianceThreshold; - params.ffxCBuffer.maxTraversalIntersections = UIParams.maxTraversalIterations; - params.ffxCBuffer.minTraversalOccupancy = UIParams.minTraversalOccupancy; - params.ffxCBuffer.mostDetailedMip = UIParams.mostDetailedDepthHierarchyMipLevel; - params.ffxCBuffer.samplesPerQuad = UIParams.samplesPerQuad; - params.ffxCBuffer.temporalVarianceGuidedTracingEnabled = UIParams.bEnableTemporalVarianceGuidedTracing; + params.ffxCBuffer.temporalStabilityFactor = Options.TemporalStability; + params.ffxCBuffer.depthBufferThickness = Options.DepthBufferThickness; + params.ffxCBuffer.roughnessThreshold = Options.RoughnessThreshold; + params.ffxCBuffer.varianceThreshold = Options.TemporalVarianceThreshold; + params.ffxCBuffer.maxTraversalIntersections = Options.MaxTraversalIterations; + params.ffxCBuffer.minTraversalOccupancy = Options.MinTraversalOccupancy; + params.ffxCBuffer.mostDetailedMip = Options.MostDetailedDepthHierarchyMipLevel; + params.ffxCBuffer.samplesPerQuad = Options.SamplesPerQuad; + params.ffxCBuffer.temporalVarianceGuidedTracingEnabled = Options.bEnableTemporalVarianceGuidedTracing; params.ffxCBuffer.envMapSpecularIrradianceCubemapMipLevelCount = EnvMapRsc.GetNumSpecularIrradianceCubemapLODLevels(*this); params.TexDepthHierarchy = rsc.Tex_DownsampledSceneDepth; params.TexNormals = rsc.Tex_SceneNormals; @@ -2267,7 +2292,7 @@ void VQRenderer::RenderReflections(ID3D12GraphicsCommandList* pCmd, DynamicBuffe case EReflections::RAY_TRACED_REFLECTIONS: default: - Log::Warning("RenderReflections(): unrecognized setting or missing implementation for reflection enum: %d", GFXSettings.Reflections); + Log::Warning("RenderReflections(): unrecognized setting or missing implementation for reflection enum: %d", GFXSettings.Rendering.Reflections); return; case EReflections::REFLECTIONS_OFF: @@ -2283,11 +2308,12 @@ static bool ShouldSkipBoundsPass(const FSceneDrawData& SceneDrawData) && SceneDrawData.outlineRenderParams.empty() && SceneDrawData.debugVertexAxesRenderParams.empty(); } -void VQRenderer::RenderSceneBoundingVolumes(ID3D12GraphicsCommandList* pCmd, DynamicBufferHeap* pCBufferHeap, D3D12_GPU_VIRTUAL_ADDRESS perViewCBAddr, const FSceneView& SceneView, bool bMSAA) +void VQRenderer::RenderSceneBoundingVolumes(ID3D12GraphicsCommandList* pCmd, DynamicBufferHeap* pCBufferHeap, D3D12_GPU_VIRTUAL_ADDRESS perViewCBAddr, const FSceneView& SceneView, const FGraphicsSettings& GFXSettings) { SCOPED_GPU_MARKER(pCmd, "RenderSceneBoundingVolumes"); const FSceneDrawData& SceneDrawData = mFrameSceneDrawData[0]; // [0] since we don't have parallel update+render const bool bNoBoundingVolumeToRender = ShouldSkipBoundsPass(SceneDrawData); + const bool bMSAA = GFXSettings.Rendering.AntiAliasing == EAntiAliasingAlgorithm::MSAA4; if (bNoBoundingVolumeToRender) return; @@ -2302,8 +2328,8 @@ void VQRenderer::RenderSceneBoundingVolumes(ID3D12GraphicsCommandList* pCmd, Dyn D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = this->GetDSV(bMSAA ? rsc.DSV_SceneDepthMSAA : rsc.DSV_SceneDepth).GetCPUDescHandle(); D3D12_CPU_DESCRIPTOR_HANDLE rtvBVHandle = this->GetRTV(rsc.RTV_SceneColorBoundingVolumes).GetCPUDescHandle(); - const float RenderResolutionX = static_cast(SceneView.SceneRTWidth); - const float RenderResolutionY = static_cast(SceneView.SceneRTHeight); + const float RenderResolutionX = static_cast(GFXSettings.Display.DisplayResolutionX * GFXSettings.Rendering.RenderResolutionScale); + const float RenderResolutionY = static_cast(GFXSettings.Display.DisplayResolutionY * GFXSettings.Rendering.RenderResolutionScale); D3D12_VIEWPORT viewport{ 0.0f, 0.0f, RenderResolutionX, RenderResolutionY, 0.0f, 1.0f }; D3D12_RECT scissorsRect{ 0, 0, (LONG)RenderResolutionX, (LONG)RenderResolutionY }; @@ -2364,7 +2390,9 @@ void VQRenderer::CompositeReflections(ID3D12GraphicsCommandList* pCmd, DynamicBu const FSceneDrawData& SceneDrawData = mFrameSceneDrawData[0]; // [0] since we don't have parallel update+render const bool bNoBoundingVolumeToRender = ShouldSkipBoundsPass(SceneDrawData); - const bool& bMSAA = GFXSettings.bAntiAliasing; + const float RenderResolutionX = static_cast(GFXSettings.Display.DisplayResolutionX * GFXSettings.Rendering.RenderResolutionScale); + const float RenderResolutionY = static_cast(GFXSettings.Display.DisplayResolutionY * GFXSettings.Rendering.RenderResolutionScale); + const bool bMSAA = GFXSettings.Rendering.AntiAliasing == EAntiAliasingAlgorithm::MSAA4; const FRenderingResources_MainWindow& rsc = this->GetRenderingResources_MainWindow(); std::shared_ptr pReflectionsPass = std::static_pointer_cast(this->GetRenderPass(ERenderPass::ScreenSpaceReflections)); @@ -2379,8 +2407,8 @@ void VQRenderer::CompositeReflections(ID3D12GraphicsCommandList* pCmd, DynamicBu params.SRVReflectionRadiance = pReflectionsPass->GetPassOutputSRV(); params.SRVBoundingVolumes = bNoBoundingVolumeToRender ? INVALID_ID : rsc.SRV_SceneColorBoundingVolumes; params.UAVSceneRadiance = rsc.UAV_SceneColor; - params.iSceneRTWidth = SceneView.SceneRTWidth; - params.iSceneRTHeight = SceneView.SceneRTHeight; + params.iSceneRTWidth = RenderResolutionX; + params.iSceneRTHeight = RenderResolutionY; { D3D12_RESOURCE_BARRIER barriers[] = { @@ -2401,15 +2429,16 @@ void VQRenderer::CompositeReflections(ID3D12GraphicsCommandList* pCmd, DynamicBu } } -void VQRenderer::TransitionForPostProcessing(ID3D12GraphicsCommandList* pCmd, const FPostProcessParameters& PPParams, const FGraphicsSettings& GFXSettings) +void VQRenderer::TransitionForPostProcessing(ID3D12GraphicsCommandList* pCmd, const FGraphicsSettings& GFXSettings) { - const bool& bMSAA = GFXSettings.bAntiAliasing; + const bool bMSAA = GFXSettings.Rendering.AntiAliasing == EAntiAliasingAlgorithm::MSAA4; const FRenderingResources_MainWindow& rsc = this->GetRenderingResources_MainWindow(); - const bool bCASEnabled = PPParams.IsFFXCASEnabled() && PPParams.Sharpness > 0.0f; - const bool bFSREnabled = PPParams.IsFSREnabled(); - const bool bVizualizationEnabled = PPParams.DrawModeEnum != EDrawMode::LIT_AND_POSTPROCESSED; - const bool bVizualizationSceneTargetUsed = ShouldUseVisualizationTarget(PPParams); + const bool bCASEnabled = GFXSettings.IsFFXCASEnabled() && GFXSettings.PostProcessing.Sharpness > 0.0f; + const bool bFSR1Enabled = GFXSettings.IsFSR1Enabled(); + const bool bFSR3Enabled = GFXSettings.IsFSR3Enabled(); + const bool bVizualizationEnabled = GFXSettings.DebugVizualization.DrawModeEnum != FDebugVisualizationSettings::EDrawMode::LIT_AND_POSTPROCESSED; + const bool bVizualizationSceneTargetUsed = ShouldUseVisualizationTarget(GFXSettings); const bool bMotionVectorsEnabled = ShouldUseMotionVectorsTarget(GFXSettings); ID3D12Resource* pRscPostProcessInput = this->GetTextureResource(rsc.Tex_SceneColor); @@ -2422,7 +2451,7 @@ void VQRenderer::TransitionForPostProcessing(ID3D12GraphicsCommandList* pCmd, co ID3D12Resource* pRscMoVec = this->GetTextureResource(rsc.Tex_SceneMotionVectors); ID3D12Resource* pRscVizOut = this->GetTextureResource(rsc.Tex_PostProcess_VisualizationOut); ID3D12Resource* pRscPostProcessOut = bVizualizationEnabled ? pRscVizOut - : (bFSREnabled + : (bFSR1Enabled ? pRscFSROut : (bCASEnabled ? pRscFFXCASOut @@ -2443,9 +2472,14 @@ void VQRenderer::TransitionForPostProcessing(ID3D12GraphicsCommandList* pCmd, co , CD3DX12_RESOURCE_BARRIER::Transition(pRscShadowMaps_Point , D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_DEPTH_WRITE) , CD3DX12_RESOURCE_BARRIER::Transition(pRscShadowMaps_Directional, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_DEPTH_WRITE) }; - if ((bFSREnabled || bCASEnabled) && !bVizualizationEnabled) + if ((bFSR1Enabled || bCASEnabled) && !bVizualizationEnabled) barriers.push_back(CD3DX12_RESOURCE_BARRIER::Transition(pRscTonemapperOut, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS)); - + if (bFSR3Enabled) + { + const FSR3UpscalePass* pFSR3Pass = static_cast(mRenderPasses[ERenderPass::FSR3Upscale].get()); + ID3D12Resource* pFSR3Rsc = this->GetTextureResource(pFSR3Pass->GetTextureID(FSR3UpscalePass::EResources::Output)); + barriers.push_back(CD3DX12_RESOURCE_BARRIER::Transition(pFSR3Rsc, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS)); + } if (bVizualizationSceneTargetUsed) { barriers.push_back(bMSAA @@ -2461,13 +2495,13 @@ void VQRenderer::TransitionForPostProcessing(ID3D12GraphicsCommandList* pCmd, co pCmd->ResourceBarrier((UINT)barriers.size(), barriers.data()); } -void VQRenderer::TransitionForUI(ID3D12GraphicsCommandList* pCmd, const FPostProcessParameters& PPParams, const FGraphicsSettings& GFXSettings, bool bHDRDisplay, ID3D12Resource* pRsc, ID3D12Resource* pSwapChainRT) +void VQRenderer::TransitionForUI(ID3D12GraphicsCommandList* pCmd, const FGraphicsSettings& GFXSettings, bool bHDRDisplay, ID3D12Resource* pRsc, ID3D12Resource* pSwapChainRT) { SCOPED_GPU_MARKER(pCmd, "TransitionForUI"); - const bool bVizualizationEnabled = PPParams.DrawModeEnum != EDrawMode::LIT_AND_POSTPROCESSED; - const bool bFFXCASEnabled = PPParams.IsFFXCASEnabled() && PPParams.Sharpness > 0.0f; - const bool bFSREnabled = PPParams.IsFSREnabled(); + const bool bVizualizationEnabled = GFXSettings.DebugVizualization.DrawModeEnum != FDebugVisualizationSettings::EDrawMode::LIT_AND_POSTPROCESSED; + const bool bFFXCASEnabled = GFXSettings.IsFFXCASEnabled() && GFXSettings.PostProcessing.Sharpness > 0.0f; + const bool bFSREnabled = GFXSettings.IsFSR1Enabled(); const FRenderingResources_MainWindow& rsc = this->GetRenderingResources_MainWindow(); @@ -2480,8 +2514,9 @@ void VQRenderer::TransitionForUI(ID3D12GraphicsCommandList* pCmd, const FPostPro CD3DX12_RESOURCE_BARRIER SwapChainTransition = CD3DX12_RESOURCE_BARRIER::Transition(pSwapChainRT, D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET); CD3DX12_RESOURCE_BARRIER UITransition = CD3DX12_RESOURCE_BARRIER::Transition(pRscUI, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET); - CD3DX12_RESOURCE_BARRIER barriers[3]; int iB = 0; - barriers[iB++] = bHDRDisplay ? UITransition : SwapChainTransition; + CD3DX12_RESOURCE_BARRIER barriers[4]; int iB = 0; + barriers[iB++] = SwapChainTransition; + if (bHDRDisplay) barriers[iB++] = UITransition; if (bVizualizationEnabled) { barriers[iB++] = CD3DX12_RESOURCE_BARRIER::Transition(pRsc, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); @@ -2504,12 +2539,24 @@ void VQRenderer::TransitionForUI(ID3D12GraphicsCommandList* pCmd, const FPostPro pCmd->ResourceBarrier(iB, barriers); } -ID3D12Resource* VQRenderer::RenderPostProcess(ID3D12GraphicsCommandList* pCmd, DynamicBufferHeap* pCBufferHeap, const FPostProcessParameters& PPParams, bool bHDR) -{ - ID3D12DescriptorHeap* ppHeaps[] = { this->GetDescHeap(EResourceHeapType::CBV_SRV_UAV_HEAP) }; + + + +VQRenderer::FPostProcessOutput VQRenderer::RenderPostProcess( + ID3D12GraphicsCommandList* pCmd, + DynamicBufferHeap* pCBufferHeap, + const FSceneView& SceneView, + const FGraphicsSettings& GFXSettings, + bool bHDR +) +{ + SCOPED_GPU_MARKER(pCmd, "RenderPostProcess"); const FRenderingResources_MainWindow& rsc = this->GetRenderingResources_MainWindow(); + FPostProcessOutput output = { .pRsc = nullptr, .srv = rsc.SRV_SceneColor }; + ID3D12DescriptorHeap* ppHeaps[] = { this->GetDescHeap(EResourceHeapType::CBV_SRV_UAV_HEAP) }; + // pass io const SRV& srv_ColorIn = this->GetSRV(rsc.SRV_SceneColor); const UAV& uav_TonemapperOut = this->GetUAV(rsc.UAV_PostProcess_TonemapperOut); @@ -2520,348 +2567,403 @@ ID3D12Resource* VQRenderer::RenderPostProcess(ID3D12GraphicsCommandList* pCmd, D const SRV& srv_FSR_EASUOut = this->GetSRV(rsc.SRV_PostProcess_FSR_EASUOut); const UAV& uav_FSR_RCASOut = this->GetUAV(rsc.UAV_PostProcess_FSR_RCASOut); const SRV& srv_FSR_RCASOut = this->GetSRV(rsc.SRV_PostProcess_FSR_RCASOut); + const SRV& srv_blurOutput = this->GetSRV(rsc.SRV_PostProcess_BlurOutput); ID3D12Resource* pRscTonemapperOut = this->GetTextureResource(rsc.Tex_PostProcess_TonemapperOut); - constexpr bool PP_ENABLE_BLUR_PASS = false; // compute dispatch dimensions - const int& InputImageWidth = PPParams.SceneRTWidth; - const int& InputImageHeight = PPParams.SceneRTHeight; - assert(PPParams.SceneRTWidth != 0); - assert(PPParams.SceneRTHeight != 0); + + const int SceneRenderResolutionX = GFXSettings.Display.DisplayResolutionX * GFXSettings.Rendering.RenderResolutionScale; + const int SceneRenderResolutionY = GFXSettings.Display.DisplayResolutionY * GFXSettings.Rendering.RenderResolutionScale; + assert(SceneRenderResolutionX != 0); + assert(SceneRenderResolutionY != 0); + constexpr int DispatchGroupDimensionX = 8; constexpr int DispatchGroupDimensionY = 8; - const int DispatchRenderX = (InputImageWidth + (DispatchGroupDimensionX - 1)) / DispatchGroupDimensionX; - const int DispatchRenderY = (InputImageHeight + (DispatchGroupDimensionY - 1)) / DispatchGroupDimensionY; - constexpr int DispatchZ = 1; - - // cmds - ID3D12Resource* pRscOutput = nullptr; - if (PPParams.DrawModeEnum != EDrawMode::LIT_AND_POSTPROCESSED) + + TextureID texOutput = INVALID_ID; + + if (GFXSettings.DebugVizualization.DrawModeEnum != FDebugVisualizationSettings::EDrawMode::LIT_AND_POSTPROCESSED) { SCOPED_GPU_MARKER(pCmd, "RenderPostProcess_DebugViz"); std::shared_ptr pReflectionsPass = std::static_pointer_cast(this->GetRenderPass(ERenderPass::ScreenSpaceReflections)); + const int DispatchRenderX = (SceneRenderResolutionX + (DispatchGroupDimensionX - 1)) / DispatchGroupDimensionX; + const int DispatchRenderY = (SceneRenderResolutionY + (DispatchGroupDimensionY - 1)) / DispatchGroupDimensionY; + constexpr int DispatchZ = 1; + // cbuffer - using cbuffer_t = FPostProcessParameters::FVizualizationParams; - cbuffer_t* pConstBuffer = {}; + struct FVizualizationParams + { + int iDrawMode = 0; + int iUnpackNormals = 0; + float fInputStrength = 100.0f; + }; + FVizualizationParams* pConstBuffer = {}; D3D12_GPU_VIRTUAL_ADDRESS cbAddr = {}; - pCBufferHeap->AllocConstantBuffer(sizeof(cbuffer_t), (void**)&pConstBuffer, &cbAddr); - memcpy(pConstBuffer, &PPParams.VizParams, sizeof(PPParams.VizParams)); - pConstBuffer->iDrawMode = static_cast(PPParams.DrawModeEnum); // iDrawMode is not connected to the UI + pCBufferHeap->AllocConstantBuffer(sizeof(FVizualizationParams), (void**)&pConstBuffer, &cbAddr); + pConstBuffer->fInputStrength = GFXSettings.DebugVizualization.fInputStrength; + pConstBuffer->iUnpackNormals = GFXSettings.DebugVizualization.bUnpackNormals ? 1 : 0; + pConstBuffer->iDrawMode = static_cast(GFXSettings.DebugVizualization.DrawModeEnum); // iDrawMode is not connected to the UI - SRV SRVIn = srv_ColorIn; - switch (PPParams.DrawModeEnum) + SRV_ID srvID = rsc.SRV_SceneColor; + switch (GFXSettings.DebugVizualization.DrawModeEnum) { - case EDrawMode::DEPTH : SRVIn = this->GetSRV(rsc.SRV_SceneDepth); break; - case EDrawMode::NORMALS : SRVIn = this->GetSRV(rsc.SRV_SceneNormals); break; - case EDrawMode::AO : SRVIn = this->GetSRV(rsc.SRV_FFXCACAO_Out); break; - case EDrawMode::ALBEDO : // same as below - case EDrawMode::METALLIC : SRVIn = this->GetSRV(rsc.SRV_SceneVisualization); break; - case EDrawMode::ROUGHNESS : srv_ColorIn; break; - case EDrawMode::REFLECTIONS : SRVIn = this->GetSRV(pReflectionsPass->GetPassOutputSRV()); break; - case EDrawMode::MOTION_VECTORS: SRVIn = this->GetSRV(rsc.SRV_SceneMotionVectors); break; + case FDebugVisualizationSettings::EDrawMode::DEPTH : srvID = rsc.SRV_SceneDepth; break; + case FDebugVisualizationSettings::EDrawMode::NORMALS : srvID = rsc.SRV_SceneNormals; break; + case FDebugVisualizationSettings::EDrawMode::AO : srvID = rsc.SRV_FFXCACAO_Out; break; + case FDebugVisualizationSettings::EDrawMode::ALBEDO : // same as below + case FDebugVisualizationSettings::EDrawMode::METALLIC : srvID = rsc.SRV_SceneVisualization; break; + case FDebugVisualizationSettings::EDrawMode::ROUGHNESS : srv_ColorIn; break; + case FDebugVisualizationSettings::EDrawMode::REFLECTIONS : srvID = pReflectionsPass->GetPassOutputSRV(); break; + case FDebugVisualizationSettings::EDrawMode::MOTION_VECTORS: srvID = rsc.SRV_SceneMotionVectors; break; } pCmd->SetPipelineState(this->GetPSO(EBuiltinPSOs::VIZUALIZATION_CS_PSO)); pCmd->SetComputeRootSignature(this->GetBuiltinRootSignature(EBuiltinRootSignatures::CS__SRV1_UAV1_ROOTCBV1)); pCmd->SetDescriptorHeaps(_countof(ppHeaps), ppHeaps); - pCmd->SetComputeRootDescriptorTable(0, SRVIn.GetGPUDescHandle()); + pCmd->SetComputeRootDescriptorTable(0, GetSRV(srvID).GetGPUDescHandle()); pCmd->SetComputeRootDescriptorTable(1, uav_VisualizationOut.GetGPUDescHandle()); pCmd->SetComputeRootConstantBufferView(2, cbAddr); pCmd->Dispatch(DispatchRenderX, DispatchRenderY, DispatchZ); - pRscOutput = this->GetTextureResource(rsc.Tex_PostProcess_VisualizationOut); + output.pRsc = this->GetTextureResource(rsc.Tex_PostProcess_VisualizationOut); + output.srv = srvID; + return output; + } + + // FSR3 must be + // ------------------------------------- + // after before + // ------------------------------------- + // SSR Film Grain + // SSAO Chromatic Aberration + // Denoising Vignette + // Exposure Tonemapping + // Bloom + // Depth of Field + // Motion Blur + // ------------------------------------- + if (GFXSettings.IsFSR3Enabled()) + { + const FPostProcessingSettings::FFSR3Settings& Settings = GFXSettings.PostProcessing.FSR3Settings; + + const XMMATRIX& proj = SceneView.proj; + const float fNear = -proj.r[3].m128_f32[2] / proj.r[2].m128_f32[2]; + const float fFar = -proj.r[3].m128_f32[2] / (proj.r[2].m128_f32[2] - 1.0f); + const float fVerticalFoVRadians = 2.0f * atanf(1.0f / proj.r[1].m128_f32[1]); + + FSR3UpscalePass::Parameters params = {}; + params.pCmd = pCmd; + params.bEnableSharpening = true; + params.fSharpness = GFXSettings.PostProcessing.Sharpness; + params.fDeltaTimeMilliseconds = SceneView.DeltaTimeInSeconds * 1000.0f; + params.fCameraFar = fFar; + params.fCameraNear = fNear; + params.fCameraFoVAngleVerticalRadians = fVerticalFoVRadians; + params.fViewSpaceToMetersFactor = 1.0f; + params.fPreExposure = 1.0f; + params.iFrame = mRenderStats.mNumFramesRendered; + + params.Resources.fResolutionScale = GFXSettings.Rendering.RenderResolutionScale; + params.Resources.texColorInput = rsc.Tex_SceneColor; + params.Resources.texDepthBuffer = rsc.Tex_SceneDepthResolve; + params.Resources.texMotionVectors = rsc.Tex_SceneMotionVectors; + params.Resources.texExposure = INVALID_ID; + params.Resources.texOpaqueOnly = rsc.Tex_SceneColor; // TODO: need a separate opaque-only color texture + + params.bUseGeneratedReactiveMask = Settings.bGenerateReactivityMask; + params.GeneratedReactiveMaskScale = Settings.GeneratedReactiveMaskScale; + params.GeneratedReactiveMaskCutoffThreshold = Settings.GeneratedReactiveMaskCutoffThreshold; + params.GeneratedReactiveMaskBinaryValue = Settings.GeneratedReactiveMaskBinaryValue; + + FSR3UpscalePass* pFSR3Pass = static_cast(mRenderPasses[ERenderPass::FSR3Upscale].get()); + pFSR3Pass->RecordCommands(¶ms); + + TextureID texOutput = pFSR3Pass->GetTextureID(FSR3UpscalePass::EResources::Output); + output.pRsc = this->GetTextureResource(texOutput); + output.srv = pFSR3Pass->GetSRV_ID(FSR3UpscalePass::EResources::Output); + texOutput = texOutput; + + CD3DX12_RESOURCE_BARRIER barriers[] = + { + CD3DX12_RESOURCE_BARRIER::Transition(output.pRsc, D3D12_RESOURCE_STATE_UNORDERED_ACCESS , D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE), + }; + pCmd->ResourceBarrier(_countof(barriers), barriers); } - else + + if constexpr (PP_ENABLE_BLUR_PASS && GFXSettings.PostProcessing.EnableGaussianBlur) { - SCOPED_GPU_MARKER(pCmd, "RenderPostProcess"); - const SRV& srv_blurOutput = this->GetSRV(rsc.SRV_PostProcess_BlurOutput); + SCOPED_GPU_MARKER(pCmd, "BlurCS"); + const int DispatchRenderX = (GFXSettings.Display.DisplayResolutionX + (DispatchGroupDimensionX - 1)) / DispatchGroupDimensionX; + const int DispatchRenderY = (GFXSettings.Display.DisplayResolutionY + (DispatchGroupDimensionY - 1)) / DispatchGroupDimensionY; + constexpr int DispatchZ = 1; - if constexpr (PP_ENABLE_BLUR_PASS && PPParams.bEnableGaussianBlur) + const UAV& uav_BlurIntermediate = this->GetUAV(rsc.UAV_PostProcess_BlurIntermediate); + const UAV& uav_BlurOutput = this->GetUAV(rsc.UAV_PostProcess_BlurOutput); + const SRV& srv_blurIntermediate = this->GetSRV(rsc.SRV_PostProcess_BlurIntermediate); + auto pRscBlurIntermediate = this->GetTextureResource(rsc.Tex_PostProcess_BlurIntermediate); + auto pRscBlurOutput = this->GetTextureResource(rsc.Tex_PostProcess_BlurOutput); + + struct FBlurParams // Gaussian Blur Pass { - SCOPED_GPU_MARKER(pCmd, "BlurCS"); - const UAV& uav_BlurIntermediate = this->GetUAV(rsc.UAV_PostProcess_BlurIntermediate); - const UAV& uav_BlurOutput = this->GetUAV(rsc.UAV_PostProcess_BlurOutput); - const SRV& srv_blurIntermediate = this->GetSRV(rsc.SRV_PostProcess_BlurIntermediate); - auto pRscBlurIntermediate = this->GetTextureResource(rsc.Tex_PostProcess_BlurIntermediate); - auto pRscBlurOutput = this->GetTextureResource(rsc.Tex_PostProcess_BlurOutput); + int iImageSizeX; + int iImageSizeY; + }; + FBlurParams* pBlurParams = nullptr; + D3D12_GPU_VIRTUAL_ADDRESS cbAddr = {}; + pCBufferHeap->AllocConstantBuffer(sizeof(FBlurParams), (void**)&pBlurParams, &cbAddr); + pBlurParams->iImageSizeX = SceneRenderResolutionX; + pBlurParams->iImageSizeY = SceneRenderResolutionY; + { + SCOPED_GPU_MARKER(pCmd, "BlurX"); + pCmd->SetPipelineState(this->GetPSO(EBuiltinPSOs::GAUSSIAN_BLUR_CS_NAIVE_X_PSO)); + pCmd->SetComputeRootSignature(this->GetBuiltinRootSignature(EBuiltinRootSignatures::CS__SRV1_UAV1_ROOTCBV1)); - FPostProcessParameters::FBlurParams* pBlurParams = nullptr; + const int FFXDispatchGroupDimension = 16; + const int FFXDispatchX = (SceneRenderResolutionX + (FFXDispatchGroupDimension - 1)) / FFXDispatchGroupDimension; + const int FFXDispatchY = (SceneRenderResolutionY + (FFXDispatchGroupDimension - 1)) / FFXDispatchGroupDimension; - D3D12_GPU_VIRTUAL_ADDRESS cbAddr = {}; - pCBufferHeap->AllocConstantBuffer(sizeof(FPostProcessParameters::FBlurParams), (void**)&pBlurParams, &cbAddr); - pBlurParams->iImageSizeX = PPParams.SceneRTWidth; - pBlurParams->iImageSizeY = PPParams.SceneRTHeight; + pCmd->SetComputeRootDescriptorTable(0, srv_ColorIn.GetGPUDescHandle()); + pCmd->SetComputeRootDescriptorTable(1, uav_BlurIntermediate.GetGPUDescHandle()); + pCmd->SetComputeRootConstantBufferView(2, cbAddr); + pCmd->Dispatch(DispatchRenderX, DispatchRenderY, DispatchZ); + const CD3DX12_RESOURCE_BARRIER pBarriers[] = { - SCOPED_GPU_MARKER(pCmd, "BlurX"); - pCmd->SetPipelineState(this->GetPSO(EBuiltinPSOs::GAUSSIAN_BLUR_CS_NAIVE_X_PSO)); - pCmd->SetComputeRootSignature(this->GetBuiltinRootSignature(EBuiltinRootSignatures::CS__SRV1_UAV1_ROOTCBV1)); + CD3DX12_RESOURCE_BARRIER::Transition(pRscBlurIntermediate, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE) + , CD3DX12_RESOURCE_BARRIER::Transition(pRscBlurOutput , D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS) - const int FFXDispatchGroupDimension = 16; - const int FFXDispatchX = (InputImageWidth + (FFXDispatchGroupDimension - 1)) / FFXDispatchGroupDimension; - const int FFXDispatchY = (InputImageHeight + (FFXDispatchGroupDimension - 1)) / FFXDispatchGroupDimension; + }; + pCmd->ResourceBarrier(_countof(pBarriers), pBarriers); + } + { + SCOPED_GPU_MARKER(pCmd, "BlurY"); + pCmd->SetPipelineState(this->GetPSO(EBuiltinPSOs::GAUSSIAN_BLUR_CS_NAIVE_Y_PSO)); + pCmd->SetComputeRootDescriptorTable(0, srv_blurIntermediate.GetGPUDescHandle()); + pCmd->SetComputeRootDescriptorTable(1, uav_BlurOutput.GetGPUDescHandle()); + pCmd->SetComputeRootConstantBufferView(2, cbAddr); + pCmd->Dispatch(DispatchRenderX, DispatchRenderY, DispatchZ); - pCmd->SetComputeRootDescriptorTable(0, srv_ColorIn.GetGPUDescHandle()); - pCmd->SetComputeRootDescriptorTable(1, uav_BlurIntermediate.GetGPUDescHandle()); - pCmd->SetComputeRootConstantBufferView(2, cbAddr); - pCmd->Dispatch(DispatchRenderX, DispatchRenderY, DispatchZ); + const CD3DX12_RESOURCE_BARRIER pBarriers[] = + { + CD3DX12_RESOURCE_BARRIER::Transition(pRscBlurOutput , D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE) + , CD3DX12_RESOURCE_BARRIER::Transition(pRscBlurIntermediate, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS) + }; + pCmd->ResourceBarrier(_countof(pBarriers), pBarriers); + } - const CD3DX12_RESOURCE_BARRIER pBarriers[] = - { - CD3DX12_RESOURCE_BARRIER::Transition(pRscBlurIntermediate, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE) - , CD3DX12_RESOURCE_BARRIER::Transition(pRscBlurOutput , D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS) + output.pRsc = pRscBlurOutput; + output.srv = rsc.SRV_PostProcess_BlurOutput; + texOutput = rsc.Tex_PostProcess_BlurOutput; + } - }; - pCmd->ResourceBarrier(_countof(pBarriers), pBarriers); - } + { + SCOPED_GPU_MARKER(pCmd, "TonemapperCS"); + const int DispatchRenderX = (GFXSettings.Display.DisplayResolutionX + (DispatchGroupDimensionX - 1)) / DispatchGroupDimensionX; + const int DispatchRenderY = (GFXSettings.Display.DisplayResolutionY + (DispatchGroupDimensionY - 1)) / DispatchGroupDimensionY; + constexpr int DispatchZ = 1; + struct FTonemapperParams + { + EColorSpace ContentColorSpace = EColorSpace::REC_709; + EDisplayCurve OutputDisplayCurve = EDisplayCurve::sRGB; + float DisplayReferenceBrightnessLevel = 200.0f; + int ToggleGammaCorrection = 1; + float UIHDRBrightness = 1.0f; + }; + FTonemapperParams* pConstBuffer = {}; + D3D12_GPU_VIRTUAL_ADDRESS cbAddr = {}; + pCBufferHeap->AllocConstantBuffer(sizeof(FTonemapperParams), (void**)&pConstBuffer, &cbAddr); + pConstBuffer->ContentColorSpace = GFXSettings.PostProcessing.ContentColorSpace; + pConstBuffer->DisplayReferenceBrightnessLevel = GFXSettings.PostProcessing.DisplayReferenceBrightnessLevel; + pConstBuffer->OutputDisplayCurve = bHDR ? GFXSettings.PostProcessing.HDROutputDisplayCurve : GFXSettings.PostProcessing.SDROutputDisplayCurve; + pConstBuffer->ToggleGammaCorrection = GFXSettings.PostProcessing.EnableGammaCorrection; + pConstBuffer->UIHDRBrightness = GFXSettings.PostProcessing.UIHDRBrightness; + + pCmd->SetPipelineState(this->GetPSO(EBuiltinPSOs::TONEMAPPER_PSO)); + pCmd->SetComputeRootSignature(this->GetBuiltinRootSignature(EBuiltinRootSignatures::CS__SRV1_UAV1_ROOTCBV1)); + pCmd->SetDescriptorHeaps(_countof(ppHeaps), ppHeaps); + pCmd->SetComputeRootDescriptorTable(0, GetSRV(output.srv).GetGPUDescHandle()); + pCmd->SetComputeRootDescriptorTable(1, uav_TonemapperOut.GetGPUDescHandle()); + pCmd->SetComputeRootConstantBufferView(2, cbAddr); + pCmd->Dispatch(DispatchRenderX, DispatchRenderY, DispatchZ); - { - SCOPED_GPU_MARKER(pCmd, "BlurY"); - pCmd->SetPipelineState(this->GetPSO(EBuiltinPSOs::GAUSSIAN_BLUR_CS_NAIVE_Y_PSO)); - pCmd->SetComputeRootDescriptorTable(0, srv_blurIntermediate.GetGPUDescHandle()); - pCmd->SetComputeRootDescriptorTable(1, uav_BlurOutput.GetGPUDescHandle()); - pCmd->SetComputeRootConstantBufferView(2, cbAddr); - pCmd->Dispatch(DispatchRenderX, DispatchRenderY, DispatchZ); - - const CD3DX12_RESOURCE_BARRIER pBarriers[] = - { - CD3DX12_RESOURCE_BARRIER::Transition(pRscBlurOutput , D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE) - , CD3DX12_RESOURCE_BARRIER::Transition(pRscBlurIntermediate, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS) - }; - pCmd->ResourceBarrier(_countof(pBarriers), pBarriers); - } - } + output.pRsc = pRscTonemapperOut; + output.srv = rsc.SRV_PostProcess_TonemapperOut; + } +#if !DISABLE_FIDELITYFX_CAS + if(PPParams.IsFFXCASEnabled() && PPParams.Sharpness > 0.0f) + { + ID3D12Resource* pRscFFXCASOut = this->GetTextureResource(rsc.Tex_PostProcess_FFXCASOut); + const CD3DX12_RESOURCE_BARRIER barriers[] = { - SCOPED_GPU_MARKER(pCmd, "TonemapperCS"); + CD3DX12_RESOURCE_BARRIER::Transition(pRscTonemapperOut, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE) + }; + pCmd->ResourceBarrier(_countof(barriers), barriers); - FPostProcessParameters::FTonemapper* pConstBuffer = {}; - D3D12_GPU_VIRTUAL_ADDRESS cbAddr = {}; - pCBufferHeap->AllocConstantBuffer(sizeof(FPostProcessParameters::FTonemapper), (void**)&pConstBuffer, &cbAddr); - *pConstBuffer = PPParams.TonemapperParams; + SCOPED_GPU_MARKER(pCmd, "FFX-CAS CS"); - pCmd->SetPipelineState(this->GetPSO(EBuiltinPSOs::TONEMAPPER_PSO)); - pCmd->SetComputeRootSignature(this->GetBuiltinRootSignature(EBuiltinRootSignatures::CS__SRV1_UAV1_ROOTCBV1)); - pCmd->SetDescriptorHeaps(_countof(ppHeaps), ppHeaps); - pCmd->SetComputeRootDescriptorTable(0, PP_ENABLE_BLUR_PASS ? srv_blurOutput.GetGPUDescHandle() : srv_ColorIn.GetGPUDescHandle()); - pCmd->SetComputeRootDescriptorTable(1, uav_TonemapperOut.GetGPUDescHandle()); - pCmd->SetComputeRootConstantBufferView(2, cbAddr); - pCmd->Dispatch(DispatchRenderX, DispatchRenderY, DispatchZ); - pRscOutput = pRscTonemapperOut; + unsigned* pConstBuffer = {}; + D3D12_GPU_VIRTUAL_ADDRESS cbAddr = {}; + const size_t cbSize = sizeof(unsigned) * 8; + pCBufferHeap->AllocConstantBuffer(cbSize, (void**)&pConstBuffer, &cbAddr); + memcpy(pConstBuffer, PPParams.FFXCASParams.CASConstantBlock, cbSize); + + + ID3D12PipelineState* pPSO = this->GetPSO(EBuiltinPSOs::FFX_CAS_CS_PSO); + assert(pPSO); + pCmd->SetPipelineState(pPSO); + pCmd->SetComputeRootSignature(this->GetBuiltinRootSignature(EBuiltinRootSignatures::CS__SRV1_UAV1_ROOTCBV1)); + pCmd->SetComputeRootDescriptorTable(0, srv_TonemapperOut.GetGPUDescHandle()); + pCmd->SetComputeRootDescriptorTable(1, uav_FFXCASOut.GetGPUDescHandle()); + pCmd->SetComputeRootConstantBufferView(2, cbAddr); + + // each FFX-CAS CS thread processes 4 pixels. + // workgroup is 64 threads, hence 256 (16x16) pixels are processed per thread group that is dispatched + constexpr int CAS_WORKGROUP_WORK_DIMENSION = 16; + const int CASDispatchX = (SceneRenderResolutionX + (CAS_WORKGROUP_WORK_DIMENSION - 1)) / CAS_WORKGROUP_WORK_DIMENSION; + const int CASDispatchY = (SceneRenderResolutionY + (CAS_WORKGROUP_WORK_DIMENSION - 1)) / CAS_WORKGROUP_WORK_DIMENSION; + pCmd->Dispatch(CASDispatchX, CASDispatchY, DispatchZ); + pRscOutput = pRscFFXCASOut; + } +#endif + + if (GFXSettings.IsFSR1Enabled()) // FSR & CAS are mutually exclusive + { + if (bHDR) + { + // TODO: color conversion pass, barriers etc. } -#if !DISABLE_FIDELITYFX_CAS - if(PPParams.IsFFXCASEnabled() && PPParams.Sharpness > 0.0f) + CD3DX12_RESOURCE_BARRIER barriers[] = { - ID3D12Resource* pRscFFXCASOut = this->GetTextureResource(rsc.Tex_PostProcess_FFXCASOut); - const CD3DX12_RESOURCE_BARRIER pBarriers[] = - { - CD3DX12_RESOURCE_BARRIER::Transition(pRscTonemapperOut, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE) - }; - pCmd->ResourceBarrier(_countof(pBarriers), pBarriers); + CD3DX12_RESOURCE_BARRIER::Transition(pRscTonemapperOut, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE) + }; + pCmd->ResourceBarrier(_countof(barriers), barriers); - SCOPED_GPU_MARKER(pCmd, "FFX-CAS CS"); + ID3D12Resource* pRscFSR1Out = nullptr; + TextureID texFSR1Out = INVALID_ID; - unsigned* pConstBuffer = {}; + { + SCOPED_GPU_MARKER(pCmd, "FSR-EASU CS"); + + AMD_FidelityFX_SuperResolution1::FShaderParameters::EASU* pConstBuffer = {}; + const size_t cbSize = sizeof(AMD_FidelityFX_SuperResolution1::FShaderParameters::EASU); D3D12_GPU_VIRTUAL_ADDRESS cbAddr = {}; - const size_t cbSize = sizeof(unsigned) * 8; pCBufferHeap->AllocConstantBuffer(cbSize, (void**)&pConstBuffer, &cbAddr); - memcpy(pConstBuffer, PPParams.FFXCASParams.CASConstantBlock, cbSize); - + const uint OutputResolutionX = GFXSettings.Display.DisplayResolutionX; + const uint OutputResolutionY = GFXSettings.Display.DisplayResolutionY; + const uint InputResolutionX = OutputResolutionX * GFXSettings.Rendering.RenderResolutionScale; + const uint InputResolutionY = OutputResolutionY * GFXSettings.Rendering.RenderResolutionScale; + pConstBuffer->UpdateConstantBlock( + InputResolutionX, InputResolutionY, + InputResolutionX, InputResolutionY, + OutputResolutionX, OutputResolutionY + ); - ID3D12PipelineState* pPSO = this->GetPSO(EBuiltinPSOs::FFX_CAS_CS_PSO); + ID3D12PipelineState* pPSO = this->GetPSO(EBuiltinPSOs::FFX_FSR1_EASU_CS_PSO); assert(pPSO); pCmd->SetPipelineState(pPSO); - pCmd->SetComputeRootSignature(this->GetBuiltinRootSignature(EBuiltinRootSignatures::CS__SRV1_UAV1_ROOTCBV1)); - pCmd->SetComputeRootDescriptorTable(0, srv_TonemapperOut.GetGPUDescHandle()); - pCmd->SetComputeRootDescriptorTable(1, uav_FFXCASOut.GetGPUDescHandle()); + pCmd->SetComputeRootSignature(this->GetBuiltinRootSignature(EBuiltinRootSignatures::LEGACY__FFX_FSR1)); + pCmd->SetComputeRootDescriptorTable(0, GetSRV(output.srv).GetGPUDescHandle()); + pCmd->SetComputeRootDescriptorTable(1, uav_FSR_EASUOut.GetGPUDescHandle()); pCmd->SetComputeRootConstantBufferView(2, cbAddr); - - // each FFX-CAS CS thread processes 4 pixels. + + // each FSR-EASU CS thread processes 4 pixels. // workgroup is 64 threads, hence 256 (16x16) pixels are processed per thread group that is dispatched - constexpr int CAS_WORKGROUP_WORK_DIMENSION = 16; - const int CASDispatchX = (InputImageWidth + (CAS_WORKGROUP_WORK_DIMENSION - 1)) / CAS_WORKGROUP_WORK_DIMENSION; - const int CASDispatchY = (InputImageHeight + (CAS_WORKGROUP_WORK_DIMENSION - 1)) / CAS_WORKGROUP_WORK_DIMENSION; - pCmd->Dispatch(CASDispatchX, CASDispatchY, DispatchZ); - pRscOutput = pRscFFXCASOut; + constexpr int WORKGROUP_WORK_DIMENSION = 16; + const int DispatchX = (GFXSettings.Display.DisplayResolutionX + (WORKGROUP_WORK_DIMENSION - 1)) / WORKGROUP_WORK_DIMENSION; + const int DispatchY = (GFXSettings.Display.DisplayResolutionY + (WORKGROUP_WORK_DIMENSION - 1)) / WORKGROUP_WORK_DIMENSION; + pCmd->Dispatch(DispatchX, DispatchY, 1); + + texFSR1Out = rsc.Tex_PostProcess_FSR_EASUOut; + pRscFSR1Out = this->GetTextureResource(rsc.Tex_PostProcess_FSR_EASUOut); + output.srv = rsc.SRV_PostProcess_FSR_EASUOut; } -#endif - - if (PPParams.IsFSREnabled()) // FSR & CAS are mutually exclusive + + const bool bFFX_RCAS_Enabled = true; // TODO: drive with UI ? + if (bFFX_RCAS_Enabled) { - if (bHDR) - { - // TODO: color conversion pass, barriers etc. - } + ID3D12Resource* pRscEASUOut = this->GetTextureResource(rsc.Tex_PostProcess_FSR_EASUOut); + ID3D12Resource* pRscRCASOut = this->GetTextureResource(rsc.Tex_PostProcess_FSR_RCASOut); - std::vector pBarriers = - { - CD3DX12_RESOURCE_BARRIER::Transition(pRscTonemapperOut - , D3D12_RESOURCE_STATE_UNORDERED_ACCESS - , D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE - ) - }; - pCmd->ResourceBarrier((UINT)pBarriers.size(), pBarriers.data()); - - { - SCOPED_GPU_MARKER(pCmd, "FSR-EASU CS"); - - unsigned* pConstBuffer = {}; - D3D12_GPU_VIRTUAL_ADDRESS cbAddr = {}; - const size_t cbSize = sizeof(unsigned) * 16; - pCBufferHeap->AllocConstantBuffer(cbSize, (void**)&pConstBuffer, &cbAddr); - memcpy(pConstBuffer, PPParams.FSR_EASUParams.EASUConstantBlock, cbSize); - - ID3D12PipelineState* pPSO = this->GetPSO(EBuiltinPSOs::FFX_FSR1_EASU_CS_PSO); - assert(pPSO); - pCmd->SetPipelineState(pPSO); - pCmd->SetComputeRootSignature(this->GetBuiltinRootSignature(EBuiltinRootSignatures::LEGACY__FFX_FSR1)); - pCmd->SetComputeRootDescriptorTable(0, srv_TonemapperOut.GetGPUDescHandle()); - pCmd->SetComputeRootDescriptorTable(1, uav_FSR_EASUOut.GetGPUDescHandle()); - pCmd->SetComputeRootConstantBufferView(2, cbAddr); - - // each FSR-EASU CS thread processes 4 pixels. - // workgroup is 64 threads, hence 256 (16x16) pixels are processed per thread group that is dispatched - constexpr int WORKGROUP_WORK_DIMENSION = 16; - const int DispatchX = (PPParams.DisplayResolutionWidth + (WORKGROUP_WORK_DIMENSION - 1)) / WORKGROUP_WORK_DIMENSION; - const int DispatchY = (PPParams.DisplayResolutionHeight + (WORKGROUP_WORK_DIMENSION - 1)) / WORKGROUP_WORK_DIMENSION; - pCmd->Dispatch(DispatchX, DispatchY, DispatchZ); - } - const bool bFFX_RCAS_Enabled = true; // TODO: drive with UI ? - ID3D12Resource* pRscFSR1Out = this->GetTextureResource(rsc.Tex_PostProcess_FSR_RCASOut); - if (bFFX_RCAS_Enabled) + SCOPED_GPU_MARKER(pCmd, "FSR-RCAS CS"); { - ID3D12Resource* pRscEASUOut = this->GetTextureResource(rsc.Tex_PostProcess_FSR_EASUOut); - ID3D12Resource* pRscRCASOut = this->GetTextureResource(rsc.Tex_PostProcess_FSR_RCASOut); - - SCOPED_GPU_MARKER(pCmd, "FSR-RCAS CS"); + CD3DX12_RESOURCE_BARRIER barriers[] = { - std::vector barriers; - barriers.push_back(CD3DX12_RESOURCE_BARRIER::Transition(pRscEASUOut - , D3D12_RESOURCE_STATE_UNORDERED_ACCESS - , D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE - )); - pCmd->ResourceBarrier((UINT)barriers.size(), barriers.data()); - } + CD3DX12_RESOURCE_BARRIER::Transition(pRscEASUOut, D3D12_RESOURCE_STATE_UNORDERED_ACCESS , D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE), + }; + pCmd->ResourceBarrier(_countof(barriers), barriers); + } - ID3D12PipelineState* pPSO = this->GetPSO(EBuiltinPSOs::FFX_FSR1_RCAS_CS_PSO); + ID3D12PipelineState* pPSO = this->GetPSO(EBuiltinPSOs::FFX_FSR1_RCAS_CS_PSO); - FPostProcessParameters::FFSR1_RCAS* pConstBuffer = {}; - D3D12_GPU_VIRTUAL_ADDRESS cbAddr = {}; - pCBufferHeap->AllocConstantBuffer(sizeof(FPostProcessParameters::FFSR1_RCAS), (void**)&pConstBuffer, &cbAddr); - *pConstBuffer = PPParams.FSR_RCASParams; + AMD_FidelityFX_SuperResolution1::FShaderParameters::RCAS* pConstBuffer = {}; + D3D12_GPU_VIRTUAL_ADDRESS cbAddr = {}; + pCBufferHeap->AllocConstantBuffer(sizeof(AMD_FidelityFX_SuperResolution1::FShaderParameters::RCAS), (void**)&pConstBuffer, &cbAddr); + pConstBuffer->UpdateConstantBlock(GFXSettings.PostProcessing.Sharpness); - pCmd->SetPipelineState(pPSO); - pCmd->SetComputeRootSignature(this->GetBuiltinRootSignature(EBuiltinRootSignatures::LEGACY__FFX_FSR1)); - pCmd->SetComputeRootDescriptorTable(0, srv_FSR_EASUOut.GetGPUDescHandle()); - pCmd->SetComputeRootDescriptorTable(1, uav_FSR_RCASOut.GetGPUDescHandle()); - pCmd->SetComputeRootConstantBufferView(2, cbAddr); + pCmd->SetPipelineState(pPSO); + pCmd->SetComputeRootSignature(this->GetBuiltinRootSignature(EBuiltinRootSignatures::LEGACY__FFX_FSR1)); + pCmd->SetComputeRootDescriptorTable(0, srv_FSR_EASUOut.GetGPUDescHandle()); + pCmd->SetComputeRootDescriptorTable(1, uav_FSR_RCASOut.GetGPUDescHandle()); + pCmd->SetComputeRootConstantBufferView(2, cbAddr); - // each FSR-RCAS CS thread processes 4 pixels. - // workgroup is 64 threads, hence 256 (16x16) pixels are processed per thread group that is dispatched - constexpr int WORKGROUP_WORK_DIMENSION = 16; - const int DispatchX = (PPParams.DisplayResolutionWidth + (WORKGROUP_WORK_DIMENSION - 1)) / WORKGROUP_WORK_DIMENSION; - const int DispatchY = (PPParams.DisplayResolutionHeight + (WORKGROUP_WORK_DIMENSION - 1)) / WORKGROUP_WORK_DIMENSION; - pCmd->Dispatch(DispatchX, DispatchY, DispatchZ); + // each FSR-RCAS CS thread processes 4 pixels. + // workgroup is 64 threads, hence 256 (16x16) pixels are processed per thread group that is dispatched + constexpr int WORKGROUP_WORK_DIMENSION = 16; + const int DispatchX = (GFXSettings.Display.DisplayResolutionX + (WORKGROUP_WORK_DIMENSION - 1)) / WORKGROUP_WORK_DIMENSION; + const int DispatchY = (GFXSettings.Display.DisplayResolutionY + (WORKGROUP_WORK_DIMENSION - 1)) / WORKGROUP_WORK_DIMENSION; + pCmd->Dispatch(DispatchX, DispatchY, 1); + { + const CD3DX12_RESOURCE_BARRIER barriers[] = { - const CD3DX12_RESOURCE_BARRIER pBarriers[] = - { - CD3DX12_RESOURCE_BARRIER::Transition(pRscEASUOut, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS), - CD3DX12_RESOURCE_BARRIER::Transition(pRscRCASOut, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE) - }; - pCmd->ResourceBarrier(_countof(pBarriers), pBarriers); - } - + CD3DX12_RESOURCE_BARRIER::Transition(pRscEASUOut, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS), + CD3DX12_RESOURCE_BARRIER::Transition(pRscRCASOut, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE) + }; + pCmd->ResourceBarrier(_countof(barriers), barriers); } - pRscOutput = pRscFSR1Out; + texFSR1Out = rsc.Tex_PostProcess_FSR_RCASOut; + pRscFSR1Out = this->GetTextureResource(rsc.Tex_PostProcess_FSR_RCASOut); + output.srv = rsc.SRV_PostProcess_FSR_RCASOut; } + + output.pRsc = pRscFSR1Out; + texOutput = texFSR1Out; } - return pRscOutput; + return output; } -void VQRenderer::RenderUI(ID3D12GraphicsCommandList* pCmd, DynamicBufferHeap* pCBufferHeap, FWindowRenderContext& ctx, const FPostProcessParameters& PPParams, ID3D12Resource* pRscInput, const SRV& srv_ColorIn, const FUIState& UIState, bool bHDR) +void VQRenderer::RenderUI( + ID3D12GraphicsCommandList* pCmd, + DynamicBufferHeap* pCBufferHeap, + D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle, + const FUIState& UIState, + const FSceneView& SceneView, + const FGraphicsSettings& GFXSettings, + bool bHDRDisplay +) { const FRenderingResources_MainWindow& rsc = this->GetRenderingResources_MainWindow(); - const float RenderResolutionX = static_cast(PPParams.DisplayResolutionWidth); - const float RenderResolutionY = static_cast(PPParams.DisplayResolutionHeight); - D3D12_VIEWPORT viewport{ 0.0f, 0.0f, RenderResolutionX, RenderResolutionY, 0.0f, 1.0f }; ID3D12DescriptorHeap* ppHeaps[] = { this->GetDescHeap(EResourceHeapType::CBV_SRV_UAV_HEAP) }; - D3D12_RECT scissorsRect{ 0, 0, (LONG)RenderResolutionX, (LONG)RenderResolutionY }; - - ID3D12Resource* pSwapChainRT = ctx.SwapChain.GetCurrentBackBufferRenderTarget(); - - D3D12_INDEX_BUFFER_VIEW nullIBV = {}; - nullIBV.Format = DXGI_FORMAT_R32_UINT; - nullIBV.SizeInBytes = 0; - nullIBV.BufferLocation = 0; -#if 0 - Log::Info("RenderUI: Backbuffer[%d]: 0x%08x | pCmd = %p", swapchain.GetCurrentBackBufferIndex(), pSwapChainRT, pCmd); -#endif - - D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = bHDR - ? this->GetRTV(rsc.RTV_UI_SDR).GetCPUDescHandle() - : ctx.SwapChain.GetCurrentBackBufferRTVHandle(); - - if (!bHDR) + +#if !VQENGINE_MT_PIPELINED_UPDATE_AND_RENDER_THREADS { - if (UIState.mpMagnifierState->bUseMagnifier) - { - SCOPED_GPU_MARKER(pCmd, "MagnifierPass"); - MagnifierPass::FDrawParameters MagnifierDrawParams; - MagnifierDrawParams.pCmd = pCmd; - MagnifierDrawParams.pCBufferHeap = pCBufferHeap; - MagnifierDrawParams.IndexBufferView = nullIBV; - MagnifierDrawParams.RTV = rtvHandle; - MagnifierDrawParams.SRVColorInput = srv_ColorIn; - MagnifierDrawParams.pCBufferParams = UIState.mpMagnifierState->pMagnifierParams; - this->GetRenderPass(ERenderPass::Magnifier)->RecordCommands(&MagnifierDrawParams); - } - else - { - SCOPED_GPU_MARKER(pCmd, "SwapchainPassthrough"); - pCmd->SetPipelineState(this->GetPSO(bHDR ? EBuiltinPSOs::HDR_FP16_SWAPCHAIN_PSO : EBuiltinPSOs::FULLSCREEN_TRIANGLE_PSO)); - pCmd->SetGraphicsRootSignature(this->GetBuiltinRootSignature(EBuiltinRootSignatures::LEGACY__FullScreenTriangle)); - pCmd->SetDescriptorHeaps(_countof(ppHeaps), ppHeaps); - pCmd->SetGraphicsRootDescriptorTable(0, srv_ColorIn.GetGPUDescHandle()); - - pCmd->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - pCmd->IASetVertexBuffers(0, 1, NULL); - pCmd->IASetIndexBuffer(&nullIBV); - - pCmd->RSSetViewports(1, &viewport); - pCmd->RSSetScissorRects(1, &scissorsRect); - - pCmd->OMSetRenderTargets(1, &rtvHandle, FALSE, NULL); + SCOPED_GPU_MARKER(pCmd, "UI"); - pCmd->DrawInstanced(3, 1, 0, 0); - } - } - else - { - if (UIState.mpMagnifierState->bUseMagnifier) - { - // TODO: make magnifier work w/ HDR when the new HDR monitor arrives - } - else + if (bHDRDisplay) { - pCmd->OMSetRenderTargets(1, &rtvHandle, FALSE, NULL); - const float clearColor[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - pCmd->ClearRenderTargetView(rtvHandle, clearColor, 0, NULL); + const FLOAT clearColor[4] = { 0,0,0,0 }; + pCmd->ClearRenderTargetView(rtvHandle, clearColor, 0, nullptr); } - } - -#if !VQENGINE_MT_PIPELINED_UPDATE_AND_RENDER_THREADS - { - SCOPED_GPU_MARKER(pCmd, "UI"); struct cb { @@ -2971,16 +3073,84 @@ void VQRenderer::RenderUI(ID3D12GraphicsCommandList* pCmd, DynamicBufferHeap* pC } #endif - if(!bHDR) +} + +void VQRenderer::SwapChainRenderPass( + ID3D12GraphicsCommandList* pCmd, + DynamicBufferHeap* pCBufferHeap, + const FSceneView& SceneView, + const FGraphicsSettings& GFXSettings, + D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle, + SRV srv_ColorIn, + bool bHDRDisplay +) +{ + const FRenderDebugOptions::FMagnifierOptions& Magnifier = SceneView.sceneRenderOptions.Debug.Magnifier; + + const float DisplayResolutionX = static_cast(GFXSettings.Display.DisplayResolutionX); + const float DisplayResolutionY = static_cast(GFXSettings.Display.DisplayResolutionY); + D3D12_VIEWPORT viewport{ 0.0f, 0.0f, DisplayResolutionX, DisplayResolutionY, 0.0f, 1.0f }; + D3D12_RECT scissorsRect{ 0, 0, (LONG)DisplayResolutionX, (LONG)DisplayResolutionY }; + + D3D12_INDEX_BUFFER_VIEW nullIBV = {}; + nullIBV.Format = DXGI_FORMAT_R32_UINT; + nullIBV.SizeInBytes = 0; + nullIBV.BufferLocation = 0; + + if (Magnifier.bEnable) { - SCOPED_GPU_MARKER(pCmd, "SwapchainTransitionToPresent"); - // Transition SwapChain for Present - CD3DX12_RESOURCE_BARRIER barrier = CD3DX12_RESOURCE_BARRIER::Transition(pSwapChainRT, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT); - pCmd->ResourceBarrier(1, &barrier); + SCOPED_GPU_MARKER(pCmd, "MagnifierPass"); + D3D12_GPU_VIRTUAL_ADDRESS cbAddr = {}; + FMagnifierParameters* CB = nullptr; + pCBufferHeap->AllocConstantBuffer(sizeof(FMagnifierParameters), (void**)&CB, &cbAddr); + *CB = FMagnifierParameters(); + CB->fMagnificationAmount = Magnifier.fMagnificationAmount; + CB->fMagnifierScreenRadius = Magnifier.fMagnifierScreenRadius; + CB->iMagnifierOffset[0] = Magnifier.ScreenOffsetX; + CB->iMagnifierOffset[1] = Magnifier.ScreenOffsetY; + CB->iMousePos[0] = SceneView.iMousePosX; + CB->iMousePos[1] = SceneView.iMousePosY; + CB->uImageWidth = static_cast(DisplayResolutionX); + CB->uImageHeight = static_cast(DisplayResolutionY); + Magnifier.GetBorderColor(CB->fBorderColorRGB); + MagnifierPass::KeepMagnifierOnScreen(*CB); + + MagnifierPass::FDrawParameters MagnifierDrawParams; + MagnifierDrawParams.pCmd = pCmd; + MagnifierDrawParams.IndexBufferView = nullIBV; + MagnifierDrawParams.RTV = rtvHandle; + MagnifierDrawParams.SRVColorInput = srv_ColorIn; + MagnifierDrawParams.cbAddr = cbAddr; + MagnifierDrawParams.pCBufferParams = CB; + MagnifierDrawParams.bHDROutput = bHDRDisplay; + this->GetRenderPass(ERenderPass::Magnifier)->RecordCommands(&MagnifierDrawParams); + } + else + { + SCOPED_GPU_MARKER(pCmd, "SwapchainPassthrough"); + pCmd->SetPipelineState(this->GetPSO(bHDRDisplay ? EBuiltinPSOs::HDR_FP16_SWAPCHAIN_PSO : EBuiltinPSOs::FULLSCREEN_TRIANGLE_PSO)); + pCmd->SetGraphicsRootSignature(this->GetBuiltinRootSignature(EBuiltinRootSignatures::LEGACY__FullScreenTriangle)); + pCmd->SetGraphicsRootDescriptorTable(0, srv_ColorIn.GetGPUDescHandle()); + + pCmd->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + pCmd->IASetVertexBuffers(0, 1, NULL); + pCmd->IASetIndexBuffer(&nullIBV); + + pCmd->RSSetViewports(1, &viewport); + pCmd->RSSetScissorRects(1, &scissorsRect); + + pCmd->OMSetRenderTargets(1, &rtvHandle, FALSE, NULL); + + pCmd->DrawInstanced(3, 1, 0, 0); } } -void VQRenderer::CompositUIToHDRSwapchain(ID3D12GraphicsCommandList* pCmd, DynamicBufferHeap* pCBufferHeap, FWindowRenderContext& ctx, const FPostProcessParameters& PPParams, const Window* pWindow) +void VQRenderer::CompositUIToHDRSwapchain( + ID3D12GraphicsCommandList* pCmd, + DynamicBufferHeap* pCBufferHeap, + FWindowRenderContext& ctx, + const FGraphicsSettings& GFXSettings +) { SCOPED_GPU_MARKER(pCmd, "CompositUIToHDRSwapchain"); @@ -2992,31 +3162,25 @@ void VQRenderer::CompositUIToHDRSwapchain(ID3D12GraphicsCommandList* pCmd, Dynam nullIBV.SizeInBytes = 0; nullIBV.BufferLocation = 0; - const bool bFFXCASEnabled = PPParams.IsFFXCASEnabled() && PPParams.Sharpness > 0.0f; - const bool bFSREnabled = PPParams.IsFSREnabled(); + const bool bFFXCASEnabled = GFXSettings.IsFFXCASEnabled() && GFXSettings.PostProcessing.Sharpness > 0.0f; + const bool bFSREnabled = GFXSettings.IsFSR1Enabled(); ID3D12Resource* pSwapChainRT = ctx.SwapChain.GetCurrentBackBufferRenderTarget(); D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = ctx.SwapChain.GetCurrentBackBufferRTVHandle(); ID3D12Resource* pRscUI = this->GetTextureResource(rsc.Tex_UI_SDR); const SRV& srv_UI_SDR = this->GetSRV(rsc.SRV_UI_SDR); - const SRV& srv_SceneColor = bFFXCASEnabled - ? this->GetSRV(rsc.SRV_PostProcess_FFXCASOut) - : (bFSREnabled - ? this->GetSRV(rsc.SRV_PostProcess_FSR_RCASOut) - : this->GetSRV(rsc.SRV_PostProcess_TonemapperOut)); - const int W = pWindow->GetWidth(); - const int H = pWindow->GetHeight(); + const int W = GFXSettings.Display.DisplayResolutionX; + const int H = GFXSettings.Display.DisplayResolutionY; - // transition barriers - std::vector< CD3DX12_RESOURCE_BARRIER> barriers; - CD3DX12_RESOURCE_BARRIER SwapChainTransition = CD3DX12_RESOURCE_BARRIER::Transition(pSwapChainRT, D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET); - CD3DX12_RESOURCE_BARRIER UITransition = CD3DX12_RESOURCE_BARRIER::Transition(pRscUI, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); - barriers.push_back(UITransition); - barriers.push_back(SwapChainTransition); - pCmd->ResourceBarrier((UINT)barriers.size(), barriers.data()); + size_t iBarrier = 0; + CD3DX12_RESOURCE_BARRIER barriers[2] = {}; + barriers[iBarrier++] = CD3DX12_RESOURCE_BARRIER::Transition(pRscUI, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + //if () + //barriers[iBarrier++] = CD3DX12_RESOURCE_BARRIER::Transition(pSwapChainRT, D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET); + + pCmd->ResourceBarrier(iBarrier, barriers); - // states D3D12_VIEWPORT vp = {}; vp.Width = static_cast(W); vp.Height = static_cast(H); @@ -3029,32 +3193,20 @@ void VQRenderer::CompositUIToHDRSwapchain(ID3D12GraphicsCommandList* pCmd, Dynam D3D12_GPU_VIRTUAL_ADDRESS cbAddr = {}; const size_t cbSize = sizeof(float) * 1; pCBufferHeap->AllocConstantBuffer(cbSize, (void**)&pConstBuffer, &cbAddr); - *pConstBuffer = PPParams.TonemapperParams.UIHDRBrightness; - + *pConstBuffer = GFXSettings.PostProcessing.UIHDRBrightness; // set states pCmd->SetPipelineState(this->GetPSO(EBuiltinPSOs::UI_HDR_scRGB_PSO)); // TODO: HDR10/PQ PSO? pCmd->SetGraphicsRootSignature(this->GetBuiltinRootSignature(EBuiltinRootSignatures::LEGACY__UI_HDR_Composite)); - pCmd->SetGraphicsRootDescriptorTable(0, srv_SceneColor.GetGPUDescHandle()); - pCmd->SetGraphicsRootDescriptorTable(1, srv_UI_SDR.GetGPUDescHandle()); - //pCmd->SetGraphicsRootConstantBufferView(1, cbAddr); - pCmd->SetGraphicsRoot32BitConstant(2, *((UINT*)pConstBuffer), 0); + pCmd->SetGraphicsRootDescriptorTable(0, srv_UI_SDR.GetGPUDescHandle()); + pCmd->SetGraphicsRoot32BitConstant(1, *((UINT*)pConstBuffer), 0); pCmd->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); pCmd->IASetVertexBuffers(0, 1, NULL); pCmd->IASetIndexBuffer(&nullIBV); pCmd->RSSetScissorRects(1, &rect); pCmd->RSSetViewports(1, &vp); pCmd->OMSetRenderTargets(1, &rtvHandle, FALSE, NULL); - - // draw fullscreen triangle pCmd->DrawInstanced(3, 1, 0, 0); - - { - //SCOPED_GPU_MARKER(pCmd, "SwapchainTransitionToPresent"); - // Transition SwapChain for Present - CD3DX12_RESOURCE_BARRIER barrier = CD3DX12_RESOURCE_BARRIER::Transition(pSwapChainRT, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT); - pCmd->ResourceBarrier(1, &barrier); - } } HRESULT VQRenderer::PresentFrame(FWindowRenderContext& ctx) @@ -3073,4 +3225,7 @@ void VQRenderer::ClearRenderPassHistories() std::shared_ptr pReclectionsPass = std::static_pointer_cast(GetRenderPass(ERenderPass::ScreenSpaceReflections)); pReclectionsPass->SetClearHistoryBuffers(); + + std::shared_ptr pFSR3Pass = std::static_pointer_cast(GetRenderPass(ERenderPass::FSR3Upscale)); + pFSR3Pass->SetClearHistoryBuffers(); } diff --git a/Source/Renderer/Rendering/WindowRenderContext.h b/Source/Renderer/Rendering/WindowRenderContext.h index 0b305749..df5ace0b 100644 --- a/Source/Renderer/Rendering/WindowRenderContext.h +++ b/Source/Renderer/Rendering/WindowRenderContext.h @@ -23,45 +23,22 @@ #include "Resources/ResourceHeaps.h" #include "Resources/Buffer.h" -#if 1 - namespace D3D12MA { class Allocator; } class Window; struct ID3D12RootSignature; struct ID3D12PipelineState; class Device; -class FWindowRenderContext +struct FWindowRenderContext { -public: FWindowRenderContext(CommandQueue& PresentQueueIn) : PresentQueue(PresentQueueIn) {} void InitializeContext(const Window* pWin, Device* pDevice, int NumSwapchainBuffers, bool bVSync, bool bHDRSwapchain); void CleanupContext(); - inline unsigned short GetNumSwapchainBuffers() const { return SwapChain.GetNumBackBuffers(); } - inline unsigned short GetCurrentSwapchainBufferIndex() const { return SwapChain.GetCurrentBackBufferIndex(); } - -#if 0 - inline DynamicBufferHeap& GetConstantBufferHeap(size_t iThread) { return mDynamicHeap_RenderingConstantBuffer[iThread]; } - inline ID3D12CommandList* GetCommandListPtr(ECommandQueueType eQueueType, size_t THREAD_INDEX) { return GetCommandListPtrs(eQueueType)[THREAD_INDEX]; }; - inline UINT GetNumCurrentlyRecordingThreads(ECommandQueueType eQueueType) const { return mNumCurrentlyRecordingRenderingThreads[eQueueType]; } - - // returns the current back buffer's command allocators - inline std::vector& GetCommandAllocators(ECommandQueueType eQueueType) { return mRenderingCommandAllocators[eQueueType][SwapChain.GetCurrentBackBufferIndex()]; }; - inline std::vector& GetCommandListPtrs(ECommandQueueType eQueueType){ return mpRenderingCmds[eQueueType]; } - inline std::vector& GetGFXCommandListPtrs() { return GetCommandListPtrs(ECommandQueueType::GFX); } - inline std::vector& GetComputeCommandListPtrs() { return GetCommandListPtrs(ECommandQueueType::COMPUTE); } - inline std::vector& GetCopyCommandListPtrs() { return GetCommandListPtrs(ECommandQueueType::COPY); } -#endif - -public: - int WindowDisplayResolutionX = -1; - int WindowDisplayResolutionY = -1; + inline unsigned short GetNumSwapchainBuffers() const { return SwapChain.GetNumBackBuffers(); } + inline unsigned short GetCurrentSwapchainBufferIndex() const { return SwapChain.GetCurrentBackBufferIndex(); } Device* pDevice = nullptr; SwapChain SwapChain; CommandQueue& PresentQueue; }; - - -#endif \ No newline at end of file diff --git a/Source/Renderer/Resources/Renderer_Resources.cpp b/Source/Renderer/Resources/Renderer_Resources.cpp index 11b42b38..6211a640 100644 --- a/Source/Renderer/Resources/Renderer_Resources.cpp +++ b/Source/Renderer/Resources/Renderer_Resources.cpp @@ -331,6 +331,13 @@ void VQRenderer::InitializeDSV(DSV_ID dsvID, uint32 heapIndex, TextureID texID, assert(pDevice); mTextureManager.WaitForTexture(texID); + assert(pTexture->Resource); + if (!pTexture->Resource) + { + Log::Error("InitializeDSV failed: texture resource was null, TexID=%", texID); + return; + } + const D3D12_RESOURCE_DESC texDesc = pTexture->Resource->GetDesc(); D3D12_DEPTH_STENCIL_VIEW_DESC DSViewDesc = {}; @@ -949,6 +956,7 @@ const CBV_SRV_UAV& VQRenderer::GetUnorderedAccessView(UAV_ID Id) const { return const DSV& VQRenderer::GetDepthStencilView(RTV_ID Id) const { return mDSVs.at(Id); } const RTV& VQRenderer::GetRenderTargetView(RTV_ID Id) const { return mRTVs.at(Id); } +const FTexture* VQRenderer::GetTexture(TextureID Id) const { return mTextureManager.GetTexture(Id); } ID3D12Resource* VQRenderer::GetTextureResource(TextureID Id) const { return mTextureManager.GetTextureResource(Id); } DXGI_FORMAT VQRenderer::GetTextureFormat(TextureID Id) const { return mTextureManager.GetTextureFormat(Id); } bool VQRenderer::GetTextureAlphaChannelUsed(TextureID Id) const { return mTextureManager.GetTextureAlphaChannelUsed(Id); } diff --git a/Source/Renderer/Resources/TextureManager.cpp b/Source/Renderer/Resources/TextureManager.cpp index f2a79438..23eaef47 100644 --- a/Source/Renderer/Resources/TextureManager.cpp +++ b/Source/Renderer/Resources/TextureManager.cpp @@ -330,7 +330,7 @@ TextureID TextureManager::CreateTexture(const FTextureRequest& Request, bool bCh // Assign ID and initialize metadata TextureID id = GenerateUniqueID(); #if LOG_TEXTURE_CREATE - Log::Info("CreateTexture (%d) %s", id, Request.Name.c_str()); + Log::Info("CreateTexture ID=%d %s [%dx%d]", id, Request.Name.c_str(), Request.D3D12Desc.Width, Request.D3D12Desc.Height); #endif { SCOPED_CPU_MARKER("CacheRequest"); diff --git a/Source/Scenes/StressTestScene.cpp b/Source/Scenes/StressTestScene.cpp index c23182d8..35790d44 100644 --- a/Source/Scenes/StressTestScene.cpp +++ b/Source/Scenes/StressTestScene.cpp @@ -49,9 +49,9 @@ void StressTestScene::UpdateScene(float dt, FSceneView& SceneView) constexpr float HDRI_ROTATION_SPEED = 0.01f; if (bAnimateEnvironmentMapRotation) { - SceneView.sceneRenderOptions.fYawSliderValue += HDRI_ROTATION_SPEED * dt; - if (SceneView.sceneRenderOptions.fYawSliderValue > 1.0f) - SceneView.sceneRenderOptions.fYawSliderValue = 0.0f; + SceneView.sceneRenderOptions.Lighting.fYawSliderValue += HDRI_ROTATION_SPEED * dt; + if (SceneView.sceneRenderOptions.Lighting.fYawSliderValue > 1.0f) + SceneView.sceneRenderOptions.Lighting.fYawSliderValue = 0.0f; } // animation