Fix overwrite of RC_DRAW_VIEW_3D timestamps by RC_DRAW_VIEW_GUI rendering pass

This commit is contained in:
Stephen Saunders 2021-09-22 17:40:11 -04:00
parent 1c41e52fc0
commit f75701a9ab
6 changed files with 96 additions and 58 deletions

View file

@ -350,7 +350,7 @@ static void R_CheckPortableExtensions()
#if defined(__APPLE__)
// SRS - DSA not available in Apple OpenGL 4.1, but enable for OSX anyways since elapsed time query will be used to get timing info instead
glConfig.timerQueryAvailable = ( GLEW_ARB_timer_query != 0 || GLEW_EXT_timer_query != 0 ) && ( glConfig.vendor != VENDOR_INTEL || r_skipIntelWorkarounds.GetBool() ) && glConfig.driverType != GLDRV_OPENGL_MESA;
glConfig.timerQueryAvailable = ( GLEW_ARB_timer_query != 0 || GLEW_EXT_timer_query != 0 );
#else
// GL_ARB_timer_query using the DSA interface
glConfig.timerQueryAvailable = ( GLEW_ARB_direct_state_access != 0 && GLEW_ARB_timer_query != 0 );
@ -1960,6 +1960,9 @@ void idRenderBackend::StereoRenderExecuteBackEndCommands( const emptyCommand_t*
// off to a texture.
bool foundEye[2] = { false, false };
// SRS - Save glConfig.timerQueryAvailable state so it can be disabled for RC_DRAW_VIEW_GUI then restored after it is finished
const bool timerQueryAvailable = glConfig.timerQueryAvailable;
for( int stereoEye = 1; stereoEye >= -1; stereoEye -= 2 )
{
// set up the target texture we will draw to
@ -1991,10 +1994,25 @@ void idRenderBackend::StereoRenderExecuteBackEndCommands( const emptyCommand_t*
}
foundEye[ targetEye ] = true;
DrawView( dsc, stereoEye );
if( cmds->commandId == RC_DRAW_VIEW_GUI )
{
// SRS - Capture separate timestamps for GUI rendering
renderLog.OpenMainBlock( MRB_DRAW_GUI );
renderLog.OpenBlock( "Render_DrawViewGUI", colorBlue );
// SRS - Disable detailed timestamps during GUI rendering so they do not overwrite timestamps from 3D rendering
glConfig.timerQueryAvailable = false;
DrawView( dsc, stereoEye );
// SRS - Restore timestamp capture state after GUI rendering is finished
glConfig.timerQueryAvailable = timerQueryAvailable;
renderLog.CloseBlock();
renderLog.CloseMainBlock();
}
else
{
DrawView( dsc, stereoEye );
}
}
break;
@ -2016,6 +2034,7 @@ void idRenderBackend::StereoRenderExecuteBackEndCommands( const emptyCommand_t*
PostProcess( cmds );
}
break;
default:
common->Error( "RB_ExecuteBackEndCommands: bad commandId" );
break;

View file

@ -5561,6 +5561,9 @@ void idRenderBackend::ExecuteBackEndCommands( const emptyCommand_t* cmds )
// needed for editor rendering
GL_SetDefaultState();
// SRS - Save glConfig.timerQueryAvailable state so it can be disabled for RC_DRAW_VIEW_GUI then restored after it is finished
const bool timerQueryAvailable = glConfig.timerQueryAvailable;
for( ; cmds != NULL; cmds = ( const emptyCommand_t* )cmds->next )
{
@ -5569,19 +5572,27 @@ void idRenderBackend::ExecuteBackEndCommands( const emptyCommand_t* cmds )
case RC_NOP:
break;
case RC_DRAW_VIEW_3D:
case RC_DRAW_VIEW_GUI:
// SRS - Capture separate timestamps for GUI rendering
renderLog.OpenMainBlock( MRB_DRAW_GUI );
renderLog.OpenBlock( "Render_DrawViewGUI", colorBlue );
// SRS - Disable detailed timestamps during GUI rendering so they do not overwrite timestamps from 3D rendering
glConfig.timerQueryAvailable = false;
DrawView( cmds, 0 );
if( ( ( const drawSurfsCommand_t* )cmds )->viewDef->viewEntitys )
{
c_draw3d++;
}
else
{
c_draw2d++;
}
c_draw2d++;
// SRS - Restore timestamp capture state after GUI rendering is finished
glConfig.timerQueryAvailable = timerQueryAvailable;
renderLog.CloseBlock();
renderLog.CloseMainBlock();
break;
case RC_DRAW_VIEW_3D:
DrawView( cmds, 0 );
c_draw3d++;
break;
case RC_SET_BUFFER:
SetBuffer( cmds );
c_setBuffers++;

View file

@ -57,7 +57,8 @@ const char* renderLogMainBlockLabels[] =
ASSERT_ENUM_STRING( MRB_DRAW_DEBUG_TOOLS, 10 ),
ASSERT_ENUM_STRING( MRB_CAPTURE_COLORBUFFER, 11 ),
ASSERT_ENUM_STRING( MRB_POSTPROCESS, 12 ),
ASSERT_ENUM_STRING( MRB_TOTAL, 13 )
ASSERT_ENUM_STRING( MRB_DRAW_GUI, 13 ),
ASSERT_ENUM_STRING( MRB_TOTAL, 14 )
};
#if defined( USE_VULKAN )
@ -603,38 +604,37 @@ idRenderLog::OpenMainBlock
*/
void idRenderLog::OpenMainBlock( renderLogMainBlock_t block )
{
mainBlock = block;
// SRS - Use glConfig.timerQueryAvailable flag to control timestamp capture for all platforms
if( glConfig.timerQueryAvailable )
{
mainBlock = block;
#if defined( USE_VULKAN )
if( vkcontext.queryIndex[ vkcontext.frameParity ] >= ( NUM_TIMESTAMP_QUERIES - 1 ) )
{
return;
}
if( vkcontext.queryIndex[ vkcontext.frameParity ] >= ( NUM_TIMESTAMP_QUERIES - 1 ) )
{
return;
}
VkCommandBuffer commandBuffer = vkcontext.commandBuffer[ vkcontext.frameParity ];
VkQueryPool queryPool = vkcontext.queryPools[ vkcontext.frameParity ];
VkCommandBuffer commandBuffer = vkcontext.commandBuffer[ vkcontext.frameParity ];
VkQueryPool queryPool = vkcontext.queryPools[ vkcontext.frameParity ];
uint32 queryIndex = vkcontext.queryAssignedIndex[ vkcontext.frameParity ][ mainBlock * 2 + 0 ] = vkcontext.queryIndex[ vkcontext.frameParity ]++;
vkCmdWriteTimestamp( commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, queryPool, queryIndex );
uint32 queryIndex = vkcontext.queryAssignedIndex[ vkcontext.frameParity ][ mainBlock * 2 + 0 ] = vkcontext.queryIndex[ vkcontext.frameParity ]++;
vkCmdWriteTimestamp( commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, queryPool, queryIndex );
// SRS - For OSX use elapsed time query for Apple OpenGL 4.1 using GL_TIME_ELAPSED vs GL_TIMESTAMP (which is not implemented on OSX)
#elif defined(__APPLE__)
// SRS - For OSX use elapsed time query for Apple OpenGL 4.1 using GL_TIME_ELAPSED vs GL_TIMESTAMP (which is not implemented on OSX)
// SRS - OSX AMD drivers have a rendering bug (flashing colours) with an elasped time query when Shadow Mapping is on - turn off query for that case unless r_skipAMDWorkarounds is set
if( !r_useShadowMapping.GetBool() || glConfig.vendor != VENDOR_AMD || r_skipAMDWorkarounds.GetBool() )
{
if( glcontext.renderLogMainBlockTimeQueryIds[ glcontext.frameParity ][ mainBlock * 2 + 1 ] == 0 )
{
glGenQueries( 1, &glcontext.renderLogMainBlockTimeQueryIds[ glcontext.frameParity ][ mainBlock * 2 + 1 ] );
}
// SRS - OSX AMD drivers have a rendering bug (flashing colours) with an elasped time query when Shadow Mapping is on - turn off query for that case unless r_skipAMDWorkarounds is set
if( glConfig.timerQueryAvailable && ( !r_useShadowMapping.GetBool() || glConfig.vendor != VENDOR_AMD || r_skipAMDWorkarounds.GetBool() ) )
{
if( glcontext.renderLogMainBlockTimeQueryIds[ glcontext.frameParity ][ mainBlock * 2 + 1 ] == 0 )
{
glGenQueries( 1, &glcontext.renderLogMainBlockTimeQueryIds[ glcontext.frameParity ][ mainBlock * 2 + 1 ] );
}
glBeginQuery( GL_TIME_ELAPSED_EXT, glcontext.renderLogMainBlockTimeQueryIds[ glcontext.frameParity ][ mainBlock * 2 + 1 ] );
}
glBeginQuery( GL_TIME_ELAPSED_EXT, glcontext.renderLogMainBlockTimeQueryIds[ glcontext.frameParity ][ mainBlock * 2 + 1 ] );
}
#else
if( glConfig.timerQueryAvailable )
{
if( glcontext.renderLogMainBlockTimeQueryIds[ glcontext.frameParity ][ mainBlock * 2 ] == 0 )
{
glCreateQueries( GL_TIMESTAMP, 2, &glcontext.renderLogMainBlockTimeQueryIds[ glcontext.frameParity ][ mainBlock * 2 ] );
@ -642,8 +642,8 @@ void idRenderLog::OpenMainBlock( renderLogMainBlock_t block )
glQueryCounter( glcontext.renderLogMainBlockTimeQueryIds[ glcontext.frameParity ][ mainBlock * 2 + 0 ], GL_TIMESTAMP );
glcontext.renderLogMainBlockTimeQueryIssued[ glcontext.frameParity ][ mainBlock * 2 + 0 ]++;
}
#endif
}
}
/*
@ -653,37 +653,36 @@ idRenderLog::CloseMainBlock
*/
void idRenderLog::CloseMainBlock()
{
// SRS - Use glConfig.timerQueryAvailable flag to control timestamp capture for all platforms
if( glConfig.timerQueryAvailable )
{
#if defined( USE_VULKAN )
if( vkcontext.queryIndex[ vkcontext.frameParity ] >= ( NUM_TIMESTAMP_QUERIES - 1 ) )
{
return;
}
if( vkcontext.queryIndex[ vkcontext.frameParity ] >= ( NUM_TIMESTAMP_QUERIES - 1 ) )
{
return;
}
VkCommandBuffer commandBuffer = vkcontext.commandBuffer[ vkcontext.frameParity ];
VkQueryPool queryPool = vkcontext.queryPools[ vkcontext.frameParity ];
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 ]++;
vkCmdWriteTimestamp( commandBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, queryPool, queryIndex );
uint32 queryIndex = vkcontext.queryAssignedIndex[ vkcontext.frameParity ][ mainBlock * 2 + 1 ] = vkcontext.queryIndex[ vkcontext.frameParity ]++;
vkCmdWriteTimestamp( commandBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, queryPool, queryIndex );
// SRS - For OSX use elapsed time query for Apple OpenGL 4.1 using GL_TIME_ELAPSED vs GL_TIMESTAMP (which is not implemented on OSX)
#elif defined(__APPLE__)
// SRS - OSX AMD drivers have a rendering bug (flashing colours) with an elasped time query when Shadow Mapping is on - turn off query for that case unless r_skipAMDWorkarounds is set
if( glConfig.timerQueryAvailable && ( !r_useShadowMapping.GetBool() || glConfig.vendor != VENDOR_AMD || r_skipAMDWorkarounds.GetBool() ) )
{
glEndQuery( GL_TIME_ELAPSED_EXT );
glcontext.renderLogMainBlockTimeQueryIssued[ glcontext.frameParity ][ mainBlock * 2 + 1 ]++;
}
// SRS - For OSX use elapsed time query for Apple OpenGL 4.1 using GL_TIME_ELAPSED vs GL_TIMESTAMP (which is not implemented on OSX)
// SRS - OSX AMD drivers have a rendering bug (flashing colours) with an elasped time query when Shadow Mapping is on - turn off query for that case unless r_skipAMDWorkarounds is set
if( !r_useShadowMapping.GetBool() || glConfig.vendor != VENDOR_AMD || r_skipAMDWorkarounds.GetBool() )
{
glEndQuery( GL_TIME_ELAPSED_EXT );
glcontext.renderLogMainBlockTimeQueryIssued[ glcontext.frameParity ][ mainBlock * 2 + 1 ]++;
}
#else
if( glConfig.timerQueryAvailable )
{
glQueryCounter( glcontext.renderLogMainBlockTimeQueryIds[ glcontext.frameParity ][ mainBlock * 2 + 1 ], GL_TIMESTAMP );
glcontext.renderLogMainBlockTimeQueryIssued[ glcontext.frameParity ][ mainBlock * 2 + 1 ]++;
}
#endif
}
}
#endif

View file

@ -55,6 +55,7 @@ enum renderLogMainBlock_t
MRB_DRAW_DEBUG_TOOLS,
MRB_CAPTURE_COLORBUFFER,
MRB_POSTPROCESS,
MRB_DRAW_GUI,
MRB_TOTAL,
MRB_TOTAL_QUERIES = MRB_TOTAL * 2,

View file

@ -778,6 +778,13 @@ void idRenderSystemLocal::SwapCommandBuffers_FinishRendering(
{
glGetQueryObjectui64vEXT( glcontext.renderLogMainBlockTimeQueryIds[ glcontext.frameParity ^ 1 ][ MRB_DRAW_DEBUG_TOOLS * 2 + 1], GL_QUERY_RESULT, &gpuEndNanoseconds );
backend.pc.gpuMicroSec += gpuEndNanoseconds / 1000;
}
if( glcontext.renderLogMainBlockTimeQueryIssued[ glcontext.frameParity ^ 1 ][ MRB_DRAW_GUI * 2 + 1 ] > 0 )
{
glGetQueryObjectui64vEXT( glcontext.renderLogMainBlockTimeQueryIds[ glcontext.frameParity ^ 1 ][ MRB_DRAW_GUI * 2 + 1], GL_QUERY_RESULT, &gpuEndNanoseconds );
backend.pc.gpuMicroSec += gpuEndNanoseconds / 1000;
}

View file

@ -1498,6 +1498,7 @@ void idRenderBackend::Init()
idLib::Printf( "----- Initializing Vulkan driver -----\n" );
glConfig.driverType = GLDRV_VULKAN;
glConfig.timerQueryAvailable = true; // SRS - Use glConfig.timerQueryAvailable flag to control Vulkan timestamp capture
glConfig.gpuSkinningAvailable = true;
// create the Vulkan instance and enable validation layers