From 7703d4221dd5a8498ea31ce93b9e2748c1cdc7be Mon Sep 17 00:00:00 2001 From: Stephen Saunders Date: Tue, 8 Nov 2022 15:27:09 -0500 Subject: [PATCH] Vulkan timer query fixes, support in-game display mode / window size / vsync changes --- neo/renderer/NVRHI/RenderBackend_NVRHI.cpp | 15 ++++++++- neo/renderer/RenderLog.cpp | 36 +++++++++++++--------- neo/renderer/RenderLog.h | 4 +-- neo/sys/sdl/sdl_events.cpp | 21 ++++++++++--- neo/sys/sdl/sdl_vkimp.cpp | 22 ++++++------- 5 files changed, 63 insertions(+), 35 deletions(-) diff --git a/neo/renderer/NVRHI/RenderBackend_NVRHI.cpp b/neo/renderer/NVRHI/RenderBackend_NVRHI.cpp index 24d5d122..e265f7a5 100644 --- a/neo/renderer/NVRHI/RenderBackend_NVRHI.cpp +++ b/neo/renderer/NVRHI/RenderBackend_NVRHI.cpp @@ -192,7 +192,6 @@ void idRenderBackend::Init() // RB: FIXME but for now disable it to avoid validation errors if( deviceManager->GetGraphicsAPI() == nvrhi::GraphicsAPI::VULKAN ) { - glConfig.timerQueryAvailable = false; r_useSSAO.SetBool( false ); } } @@ -1711,6 +1710,13 @@ void idRenderBackend::CheckCVars() R_SetColorMappings(); } + // SRS - support dynamic changes to vsync setting + if( r_swapInterval.IsModified() ) + { + r_swapInterval.ClearModified(); + deviceManager->SetVsyncEnabled( r_swapInterval.GetBool() ); + } + // filtering /*if( r_maxAnisotropicFiltering.IsModified() || r_useTrilinearFiltering.IsModified() || r_lodBias.IsModified() ) { @@ -2145,6 +2151,13 @@ idRenderBackend::ResizeImages */ void idRenderBackend::ResizeImages() { + glimpParms_t parms; + + parms.width = glConfig.nativeScreenWidth; + parms.height = glConfig.nativeScreenHeight; + parms.multiSamples = glConfig.multisamples; + + deviceManager->UpdateWindowSize( parms ); } void idRenderBackend::SetCurrentImage( idImage* image ) diff --git a/neo/renderer/RenderLog.cpp b/neo/renderer/RenderLog.cpp index daf4be0c..41f5d5a6 100644 --- a/neo/renderer/RenderLog.cpp +++ b/neo/renderer/RenderLog.cpp @@ -324,7 +324,7 @@ idRenderLog::idRenderLog() void idRenderLog::Init() { #if defined( USE_NVRHI ) - for( int i = 0; i < MRB_TOTAL_QUERIES; i++ ) + for( int i = 0; i < MRB_TOTAL * NUM_FRAME_DATA; i++ ) { timerQueries.Append( deviceManager->GetDevice()->createTimerQuery() ); timerUsed.Append( false ); @@ -335,12 +335,7 @@ void idRenderLog::Init() void idRenderLog::Shutdown() { #if defined( USE_NVRHI ) - if( commandList ) - { - commandList.Reset(); - } - - for( int i = 0; i < MRB_TOTAL_QUERIES; i++ ) + for( int i = 0; i < MRB_TOTAL * NUM_FRAME_DATA; i++ ) { timerQueries[i].Reset(); } @@ -356,6 +351,9 @@ void idRenderLog::StartFrame( nvrhi::ICommandList* _commandList ) void idRenderLog::EndFrame() { +#if defined( USE_NVRHI ) + commandList = nullptr; +#endif } @@ -376,8 +374,11 @@ void idRenderLog::OpenMainBlock( renderLogMainBlock_t block ) int timerIndex = mainBlock + frameParity * MRB_TOTAL; - commandList->beginTimerQuery( timerQueries[ timerIndex ] ); - timerUsed[ timerIndex ] = true; + // SRS - Only issue a new start timer query if timer slot unused + if( !timerUsed[ timerIndex ] ) + { + commandList->beginTimerQuery( timerQueries[ timerIndex ] ); + } #elif defined( USE_VULKAN ) if( vkcontext.queryIndex[ vkcontext.frameParity ] >= ( NUM_TIMESTAMP_QUERIES - 1 ) ) @@ -437,7 +438,12 @@ void idRenderLog::CloseMainBlock( int _block ) int timerIndex = block + frameParity * MRB_TOTAL; - commandList->endTimerQuery( timerQueries[ timerIndex ] ); + // SRS - Only issue a new end timer query if timer slot unused + if( !timerUsed[ timerIndex ] ) + { + commandList->endTimerQuery( timerQueries[ timerIndex ] ); + timerUsed[ timerIndex ] = true; + } #elif defined( USE_VULKAN ) if( vkcontext.queryIndex[ vkcontext.frameParity ] >= ( NUM_TIMESTAMP_QUERIES - 1 ) ) @@ -448,7 +454,7 @@ void idRenderLog::CloseMainBlock( int _block ) VkCommandBuffer commandBuffer = vkcontext.commandBuffer[ vkcontext.frameParity ]; VkQueryPool queryPool = vkcontext.queryPools[ vkcontext.frameParity ]; - uint32 queryIndex = vkcontext.queryAssignedIndex[ vkcontext.frameParity ][ mainBlock * 2 + 1 ] = vkcontext.queryIndex[ vkcontext.frameParity ]++; + uint32 queryIndex = vkcontext.queryAssignedIndex[ vkcontext.frameParity ][ block * 2 + 1 ] = vkcontext.queryIndex[ vkcontext.frameParity ]++; vkCmdWriteTimestamp( commandBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, queryPool, queryIndex ); #elif defined(__APPLE__) @@ -457,12 +463,12 @@ void idRenderLog::CloseMainBlock( int _block ) if( !r_useShadowMapping.GetBool() || glConfig.vendor != VENDOR_AMD || r_skipAMDWorkarounds.GetBool() ) { glEndQuery( GL_TIME_ELAPSED_EXT ); - glcontext.renderLogMainBlockTimeQueryIssued[ glcontext.frameParity ][ mainBlock * 2 + 1 ]++; + glcontext.renderLogMainBlockTimeQueryIssued[ glcontext.frameParity ][ block * 2 + 1 ]++; } #else - glQueryCounter( glcontext.renderLogMainBlockTimeQueryIds[ glcontext.frameParity ][ mainBlock * 2 + 1 ], GL_TIMESTAMP ); - glcontext.renderLogMainBlockTimeQueryIssued[ glcontext.frameParity ][ mainBlock * 2 + 1 ]++; + glQueryCounter( glcontext.renderLogMainBlockTimeQueryIds[ glcontext.frameParity ][ block * 2 + 1 ], GL_TIMESTAMP ); + glcontext.renderLogMainBlockTimeQueryIssued[ glcontext.frameParity ][ block * 2 + 1 ]++; #endif } } @@ -475,7 +481,7 @@ idRenderLog::FetchGPUTimers void idRenderLog::FetchGPUTimers( backEndCounters_t& pc ) { frameCounter++; - frameParity ^= 1; + frameParity = ( frameParity + 1 ) % NUM_FRAME_DATA; #if defined( USE_NVRHI ) diff --git a/neo/renderer/RenderLog.h b/neo/renderer/RenderLog.h index 5d6b81da..b8345a0e 100644 --- a/neo/renderer/RenderLog.h +++ b/neo/renderer/RenderLog.h @@ -82,8 +82,8 @@ private: uint64 frameCounter; uint32 frameParity; - idStaticList timerQueries; - idStaticList timerUsed; + idStaticList timerQueries; + idStaticList timerUsed; #endif public: diff --git a/neo/sys/sdl/sdl_events.cpp b/neo/sys/sdl/sdl_events.cpp index a894309b..1a35e307 100644 --- a/neo/sys/sdl/sdl_events.cpp +++ b/neo/sys/sdl/sdl_events.cpp @@ -970,11 +970,19 @@ sysEvent_t Sys_GetEvent() { int w = ev.window.data1; int h = ev.window.data2; - r_windowWidth.SetInteger( w ); - r_windowHeight.SetInteger( h ); + + // SRS - Only save window resized events when in windowed modes + if( !renderSystem->IsFullScreen() ) + { + r_windowWidth.SetInteger( w ); + r_windowHeight.SetInteger( h ); + } glConfig.nativeScreenWidth = w; glConfig.nativeScreenHeight = h; + + // SRS - Make sure ImGui gets new window boundaries + ImGuiHook::NotifyDisplaySizeChanged( glConfig.nativeScreenWidth, glConfig.nativeScreenHeight ); break; } @@ -982,8 +990,13 @@ sysEvent_t Sys_GetEvent() { int x = ev.window.data1; int y = ev.window.data2; - r_windowX.SetInteger( x ); - r_windowY.SetInteger( y ); + + // SRS - Only save window moved events when in windowed modes + if( !renderSystem->IsFullScreen() ) + { + r_windowX.SetInteger( x ); + r_windowY.SetInteger( y ); + } break; } } diff --git a/neo/sys/sdl/sdl_vkimp.cpp b/neo/sys/sdl/sdl_vkimp.cpp index 9f295188..b689cc0a 100644 --- a/neo/sys/sdl/sdl_vkimp.cpp +++ b/neo/sys/sdl/sdl_vkimp.cpp @@ -137,19 +137,17 @@ bool DeviceManager::CreateWindowDeviceAndSwapChain( const glimpParms_t& parms, c glConfig.isFullscreen = parms.fullScreen; - UpdateWindowSize( parms ); - return true; } -void DeviceManager::UpdateWindowSize( const glimpParms_t& params ) +void DeviceManager::UpdateWindowSize( const glimpParms_t& parms ) { windowVisible = true; - if( int( deviceParms.backBufferWidth ) != params.width || - int( deviceParms.backBufferHeight ) != params.height || + if( int( deviceParms.backBufferWidth ) != parms.width || + int( deviceParms.backBufferHeight ) != parms.height || #if ID_MSAA - int( deviceParms.backBufferSampleCount ) != params.multiSamples || + int( deviceParms.backBufferSampleCount ) != parms.multiSamples || #endif ( deviceParms.vsyncEnabled != requestedVSync && GetGraphicsAPI() == nvrhi::GraphicsAPI::VULKAN ) ) { @@ -157,16 +155,14 @@ void DeviceManager::UpdateWindowSize( const glimpParms_t& params ) BackBufferResizing(); - deviceParms.backBufferWidth = params.width; - deviceParms.backBufferHeight = params.height; - deviceParms.backBufferSampleCount = params.multiSamples; + deviceParms.backBufferWidth = parms.width; + deviceParms.backBufferHeight = parms.height; + deviceParms.backBufferSampleCount = parms.multiSamples; deviceParms.vsyncEnabled = requestedVSync; ResizeSwapChain(); BackBufferResized(); } - - deviceParms.vsyncEnabled = requestedVSync; } #endif @@ -362,7 +358,7 @@ bool VKimp_Init( glimpParms_t parms ) #endif // RB begin - glConfig.displayFrequency = 60; + glConfig.displayFrequency = 60; // FIXME: should use parms.displayHz and set mode correctly from start glConfig.isStereoPixelFormat = parms.stereo; glConfig.multisamples = parms.multiSamples; @@ -451,7 +447,7 @@ static bool SetScreenParmsFullscreen( glimpParms_t parms ) // change settings in that display mode according to parms // FIXME: check if refreshrate, width and height are supported? - // m.refresh_rate = parms.displayHz; + m.refresh_rate = parms.displayHz; m.w = parms.width; m.h = parms.height;