From 8fe25bf9876f3f360e05febbab168aaa93ad786b Mon Sep 17 00:00:00 2001 From: Stephen Saunders Date: Wed, 25 Jan 2023 14:23:14 -0500 Subject: [PATCH] Fix legacy SSAO for NVRHI Vulkan and enable SSAO compute shader alternative --- neo/renderer/Image_intrinsic.cpp | 4 +- neo/renderer/NVRHI/RenderBackend_NVRHI.cpp | 12 ----- neo/renderer/Passes/SsaoPass.cpp | 13 +++-- neo/renderer/Passes/SsaoPass.h | 4 +- neo/renderer/RenderBackend.cpp | 48 ++++++++++++++----- .../builtin/SSAO/AmbientOcclusion_AO.ps.hlsl | 8 ++-- neo/shaders/builtin/SSAO/ssao_blur.cs.hlsl | 12 +++-- neo/shaders/builtin/SSAO/ssao_compute.cs.hlsl | 3 ++ .../builtin/SSAO/ssao_deinterleave.cs.hlsl | 3 ++ neo/shaders/builtin/mipmapgen.cs.hlsl | 4 +- 10 files changed, 67 insertions(+), 44 deletions(-) diff --git a/neo/renderer/Image_intrinsic.cpp b/neo/renderer/Image_intrinsic.cpp index 3ac87991..6b0266fe 100644 --- a/neo/renderer/Image_intrinsic.cpp +++ b/neo/renderer/Image_intrinsic.cpp @@ -1101,8 +1101,8 @@ void idImageManager::CreateIntrinsicImages() gbufferNormalsRoughnessImage = ImageFromFunction( "_currentNormals", R_GeometryBufferImage_ResNative ); - ambientOcclusionImage[0] = ImageFromFunction( "_ao0", R_SMAAImage_ResNative ); - ambientOcclusionImage[1] = ImageFromFunction( "_ao1", R_SMAAImage_ResNative ); + ambientOcclusionImage[0] = ImageFromFunction( "_ao0", R_AmbientOcclusionImage_ResNative ); + ambientOcclusionImage[1] = ImageFromFunction( "_ao1", R_AmbientOcclusionImage_ResNative ); hierarchicalZbufferImage = ImageFromFunction( "_cszBuffer", R_HierarchicalZBufferImage_ResNative ); diff --git a/neo/renderer/NVRHI/RenderBackend_NVRHI.cpp b/neo/renderer/NVRHI/RenderBackend_NVRHI.cpp index ac2b982d..a70e5980 100644 --- a/neo/renderer/NVRHI/RenderBackend_NVRHI.cpp +++ b/neo/renderer/NVRHI/RenderBackend_NVRHI.cpp @@ -249,12 +249,6 @@ void idRenderBackend::Init() currentJointOffset = 0; prevBindingLayoutType = -1; - // RB: FIXME but for now disable it to avoid validation errors - if( deviceManager->GetGraphicsAPI() == nvrhi::GraphicsAPI::VULKAN ) - { - r_useSSAO.SetBool( false ); - } - deviceManager->GetDevice()->waitForIdle(); deviceManager->GetDevice()->runGarbageCollection(); } @@ -1858,12 +1852,6 @@ void idRenderBackend::CheckCVars() r_antiAliasing.ClearModified(); } #endif - - // RB: FIXME but for now disable it to avoid validation errors - if( deviceManager->GetGraphicsAPI() == nvrhi::GraphicsAPI::VULKAN ) - { - r_useSSAO.SetBool( false ); - } } /* diff --git a/neo/renderer/Passes/SsaoPass.cpp b/neo/renderer/Passes/SsaoPass.cpp index d02b747f..7dbbd00f 100644 --- a/neo/renderer/Passes/SsaoPass.cpp +++ b/neo/renderer/Passes/SsaoPass.cpp @@ -34,6 +34,9 @@ If you have questions concerning this license or the applicable additional terms struct SsaoConstants { + idVec2i viewportOrigin; + idVec2i viewportSize; + idVec2 clipToView; idVec2 invQuantizedGbufferSize; @@ -224,7 +227,7 @@ void SsaoPass::CreateBindingSet( void SsaoPass::Render( nvrhi::ICommandList* commandList, const SsaoParameters& params, - viewDef_t* viewDef, + const viewDef_t* viewDef, int bindingSetIndex ) { assert( m_Deinterleave.BindingSets[bindingSetIndex] ); @@ -241,17 +244,19 @@ void SsaoPass::Render( quarterResExtent.maxY = ( quarterResExtent.maxY + 3 ) / 4; SsaoConstants ssaoConstants = {}; + ssaoConstants.viewportOrigin = idVec2i( viewDef->viewport.x1, viewDef->viewport.y1 ); + ssaoConstants.viewportSize = idVec2i( viewDef->viewport.GetWidth(), viewDef->viewport.GetHeight() ); ssaoConstants.clipToView = idVec2( viewDef->projectionMatrix[2 * 4 + 3] / viewDef->projectionMatrix[0 * 4 + 0], - viewDef->projectionMatrix[2 * 4 + 3] / viewDef->projectionMatrix[0 * 4 + 1] ); + viewDef->projectionMatrix[2 * 4 + 3] / viewDef->projectionMatrix[1 * 4 + 1] ); ssaoConstants.invQuantizedGbufferSize = 1.f / m_QuantizedGbufferTextureSize; ssaoConstants.quantizedViewportOrigin = idVec2i( quarterResExtent.minX, quarterResExtent.minY ) * 4; ssaoConstants.amount = params.amount; ssaoConstants.invBackgroundViewDepth = ( params.backgroundViewDepth > 0.f ) ? 1.f / params.backgroundViewDepth : 0.f; ssaoConstants.radiusWorld = params.radiusWorld; ssaoConstants.surfaceBias = params.surfaceBias; - ssaoConstants.powerExponent = params.powerExponent; ssaoConstants.radiusToScreen = 0.5f * viewDef->viewport.GetHeight() * abs( viewDef->projectionMatrix[1 * 4 + 1] ); + ssaoConstants.powerExponent = params.powerExponent; commandList->writeBuffer( m_ConstantBuffer, &ssaoConstants, sizeof( ssaoConstants ) ); uint32_t dispatchWidth = ( quarterResExtent.width() + 7 ) / 8; @@ -277,4 +282,4 @@ void SsaoPass::Render( commandList->dispatch( dispatchWidth, dispatchHeight, 1 ); commandList->endMarker(); -} \ No newline at end of file +} diff --git a/neo/renderer/Passes/SsaoPass.h b/neo/renderer/Passes/SsaoPass.h index edbbcd2c..902e21af 100644 --- a/neo/renderer/Passes/SsaoPass.h +++ b/neo/renderer/Passes/SsaoPass.h @@ -93,8 +93,8 @@ public: void Render( nvrhi::ICommandList* commandList, const SsaoParameters& params, - viewDef_t* viewDef, + const viewDef_t* viewDef, int bindingSetIndex = 0 ); }; -#endif \ No newline at end of file +#endif diff --git a/neo/renderer/RenderBackend.cpp b/neo/renderer/RenderBackend.cpp index 50070c44..320b6d77 100644 --- a/neo/renderer/RenderBackend.cpp +++ b/neo/renderer/RenderBackend.cpp @@ -5878,7 +5878,7 @@ void idRenderBackend::DrawScreenSpaceAmbientOcclusion( const viewDef_t* _viewDef } // FIXME: the hierarchical depth buffer does not work with the MSAA depth texture source - if( r_useSSAO.GetInteger() <= 0 || r_useSSAO.GetInteger() > 1 || R_GetMSAASamples() > 1 ) + if( !r_useSSAO.GetBool() || R_GetMSAASamples() > 1 ) { return; } @@ -5908,7 +5908,6 @@ void idRenderBackend::DrawScreenSpaceAmbientOcclusion( const viewDef_t* _viewDef #if defined( USE_NVRHI ) commandList->clearTextureFloat( globalImages->hierarchicalZbufferImage->GetTextureHandle(), nvrhi::AllSubresources, nvrhi::Color( 1.f ) ); commandList->clearTextureFloat( globalImages->ambientOcclusionImage[0]->GetTextureHandle(), nvrhi::AllSubresources, nvrhi::Color( 1.f ) ); - commandList->clearTextureFloat( globalImages->ambientOcclusionImage[1]->GetTextureHandle(), nvrhi::AllSubresources, nvrhi::Color( 1.f ) ); #endif // build hierarchical depth buffer @@ -6147,6 +6146,10 @@ void idRenderBackend::DrawScreenSpaceAmbientOcclusion( const viewDef_t* _viewDef if( r_ssaoFiltering.GetBool() ) { float jitterTexScale[4]; + +#if defined( USE_NVRHI ) + commandList->clearTextureFloat( globalImages->ambientOcclusionImage[1]->GetTextureHandle(), nvrhi::AllSubresources, nvrhi::Color( 1.f ) ); +#endif // AO blur X globalFramebuffers.ambientOcclusionFBO[1]->Bind(); @@ -6241,7 +6244,7 @@ void idRenderBackend::DrawScreenSpaceAmbientOcclusion2( const viewDef_t* _viewDe return; } - if( r_useSSAO.GetInteger() <= 0 || r_useSSAO.GetInteger() < 2 ) + if( !r_useSSAO.GetBool() ) { return; } @@ -6257,7 +6260,24 @@ void idRenderBackend::DrawScreenSpaceAmbientOcclusion2( const viewDef_t* _viewDe return; } - //GL_CheckErrors(); + renderLog.OpenMainBlock( MRB_SSAO_PASS ); + renderLog.OpenBlock( "Render_NewSSAO", colorBlue ); + + commandList->clearTextureFloat( globalImages->ambientOcclusionImage[0]->GetTextureHandle(), nvrhi::AllSubresources, nvrhi::Color( 1.f ) ); + + SsaoParameters ssaoParams; + // SRS - these are the defaults, but explicitly listed here for testing and possible adjustment + ssaoParams.amount = 2.f; + ssaoParams.backgroundViewDepth = 100.f; + ssaoParams.radiusWorld = 0.5f; + ssaoParams.surfaceBias = .1f; + ssaoParams.powerExponent = 2.f; + ssaoParams.enableBlur = true; + ssaoParams.blurSharpness = 16.f; + ssaoPass->Render( commandList, ssaoParams, _viewDef, 0 ); + + renderLog.CloseBlock(); + renderLog.CloseMainBlock(); #endif } @@ -6600,14 +6620,7 @@ void idRenderBackend::ExecuteBackEndCommands( const emptyCommand_t* cmds ) delete hiZGenPass; } - if( deviceManager->GetGraphicsAPI() == nvrhi::GraphicsAPI::VULKAN ) - { - hiZGenPass = NULL; - } - else - { - hiZGenPass = new MipMapGenPass( deviceManager->GetDevice(), globalImages->hierarchicalZbufferImage->GetTextureHandle() ); - } + hiZGenPass = new MipMapGenPass( deviceManager->GetDevice(), globalImages->hierarchicalZbufferImage->GetTextureHandle() ); } @@ -6854,7 +6867,16 @@ void idRenderBackend::DrawViewInternal( const viewDef_t* _viewDef, const int ste //------------------------------------------------- // build hierarchical depth buffer and SSAO render target //------------------------------------------------- - DrawScreenSpaceAmbientOcclusion( _viewDef, false ); +#if defined( USE_NVRHI ) + if( r_useNewSsaoPass.GetBool() ) + { + DrawScreenSpaceAmbientOcclusion2( _viewDef, false ); + } + else +#endif + { + DrawScreenSpaceAmbientOcclusion( _viewDef, false ); + } //------------------------------------------------- // render static lighting and consider SSAO results diff --git a/neo/shaders/builtin/SSAO/AmbientOcclusion_AO.ps.hlsl b/neo/shaders/builtin/SSAO/AmbientOcclusion_AO.ps.hlsl index ea847563..5d6afbf3 100644 --- a/neo/shaders/builtin/SSAO/AmbientOcclusion_AO.ps.hlsl +++ b/neo/shaders/builtin/SSAO/AmbientOcclusion_AO.ps.hlsl @@ -93,11 +93,11 @@ static const float projScale = 500.0; #define VALUE_TYPE float -Texture2D t_NormalRoughness : register( t0 VK_DESCRIPTOR_SET( 1 ) ); -Texture2D t_ViewDepth : register( t1 VK_DESCRIPTOR_SET( 1 ) ); -Texture2D t_BlueNoise : register( t2 VK_DESCRIPTOR_SET( 1 ) ); +Texture2D t_NormalRoughness : register( t0 VK_DESCRIPTOR_SET( 0 ) ); +Texture2D t_ViewDepth : register( t1 VK_DESCRIPTOR_SET( 0 ) ); +Texture2D t_BlueNoise : register( t2 VK_DESCRIPTOR_SET( 0 ) ); -SamplerState blueNoiseSampler : register( s0 VK_DESCRIPTOR_SET( 2 ) ); +SamplerState blueNoiseSampler : register( s0 VK_DESCRIPTOR_SET( 1 ) ); #define CS_Z_buffer t_ViewDepth diff --git a/neo/shaders/builtin/SSAO/ssao_blur.cs.hlsl b/neo/shaders/builtin/SSAO/ssao_blur.cs.hlsl index e7e9d42c..09c096bf 100644 --- a/neo/shaders/builtin/SSAO/ssao_blur.cs.hlsl +++ b/neo/shaders/builtin/SSAO/ssao_blur.cs.hlsl @@ -26,6 +26,9 @@ struct SsaoConstants { + int2 viewportOrigin; + int2 viewportSize; + float2 clipToView; float2 invQuantizedGbufferSize; @@ -168,10 +171,9 @@ void main( uint2 groupId : SV_GroupID, uint2 threadId : SV_GroupThreadID, uint2 #endif int2 storePos = int2( globalId.xy ) + g_Ssao.quantizedViewportOrigin; - float2 storePosF = float2( storePos ); - //if (all(storePosF >= g_Ssao.view.viewportOrigin.xy) && all(storePosF < g_Ssao.view.viewportOrigin.xy + g_Ssao.view.viewportSize.xy)) - //{ - // u_RenderTarget[storePos] = totalOcclusion; - //} + if (all(storePos >= g_Ssao.viewportOrigin.xy) && all(storePos < g_Ssao.viewportOrigin.xy + g_Ssao.viewportSize.xy)) + { + u_RenderTarget[storePos] = totalOcclusion; + } } diff --git a/neo/shaders/builtin/SSAO/ssao_compute.cs.hlsl b/neo/shaders/builtin/SSAO/ssao_compute.cs.hlsl index 902ad610..12a880f4 100644 --- a/neo/shaders/builtin/SSAO/ssao_compute.cs.hlsl +++ b/neo/shaders/builtin/SSAO/ssao_compute.cs.hlsl @@ -26,6 +26,9 @@ struct SsaoConstants { + int2 viewportOrigin; + int2 viewportSize; + float2 clipToView; float2 invQuantizedGbufferSize; diff --git a/neo/shaders/builtin/SSAO/ssao_deinterleave.cs.hlsl b/neo/shaders/builtin/SSAO/ssao_deinterleave.cs.hlsl index 695c90a2..371fdf95 100644 --- a/neo/shaders/builtin/SSAO/ssao_deinterleave.cs.hlsl +++ b/neo/shaders/builtin/SSAO/ssao_deinterleave.cs.hlsl @@ -26,6 +26,9 @@ struct SsaoConstants { + int2 viewportOrigin; + int2 viewportSize; + float2 clipToView; float2 invQuantizedGbufferSize; diff --git a/neo/shaders/builtin/mipmapgen.cs.hlsl b/neo/shaders/builtin/mipmapgen.cs.hlsl index 145db1e2..715eb0ab 100644 --- a/neo/shaders/builtin/mipmapgen.cs.hlsl +++ b/neo/shaders/builtin/mipmapgen.cs.hlsl @@ -83,7 +83,7 @@ cbuffer c_MipMapgen : register( b0 ) MipmmapGenConstants g_MipMapGen; }; -RWTexture2D u_output[NUM_LODS] : register( u0 ); +RWTexture2D u_output[] : register( u0 ); Texture2D t_input : register( t0 ); // *INDENT-ON* @@ -138,4 +138,4 @@ groupshared VALUE_TYPE s_ReductionData[GROUP_SIZE][GROUP_SIZE]; GroupMemoryBarrierWithGroupSync(); } -} \ No newline at end of file +}