2012-11-26 18:58:24 +00:00
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Doom 3 BFG Edition GPL Source Code
2012-11-28 15:47:07 +00:00
Copyright ( C ) 1993 - 2012 id Software LLC , a ZeniMax Media company .
2020-05-03 11:39:38 +00:00
Copyright ( C ) 2013 - 2020 Robert Beckebans
2012-11-26 18:58:24 +00:00
2012-11-28 15:47:07 +00:00
This file is part of the Doom 3 BFG Edition GPL Source Code ( " Doom 3 BFG Edition Source Code " ) .
2012-11-26 18:58:24 +00:00
Doom 3 BFG Edition Source Code is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with Doom 3 BFG Edition Source Code . If not , see < http : //www.gnu.org/licenses/>.
In addition , the Doom 3 BFG Edition Source Code is also subject to certain additional terms . You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code . If not , please request a copy in writing from id Software at the address below .
If you have questions concerning this license or the applicable additional terms , you may contact in writing id Software LLC , c / o ZeniMax Media Inc . , Suite 120 , Rockville , Maryland 20850 USA .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
2017-09-03 08:22:36 +00:00
# include "RenderCommon.h"
2021-07-29 13:42:02 +00:00
# pragma hdrstop
2012-11-26 18:58:24 +00:00
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Contains the RenderLog implementation .
TODO : Emit statistics to the logfile at the end of views and frames .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
idCVar r_logLevel ( " r_logLevel " , " 2 " , CVAR_INTEGER , " 1 = blocks only, 2 = everything " , 1 , 2 ) ;
static const int LOG_LEVEL_BLOCKS_ONLY = 1 ;
static const int LOG_LEVEL_EVERYTHING = 2 ;
2012-11-28 15:47:07 +00:00
const char * renderLogMainBlockLabels [ ] =
{
2020-05-04 23:21:29 +00:00
ASSERT_ENUM_STRING ( MRB_GPU_TIME , 0 ) ,
2012-11-26 18:58:24 +00:00
ASSERT_ENUM_STRING ( MRB_BEGIN_DRAWING_VIEW , 1 ) ,
ASSERT_ENUM_STRING ( MRB_FILL_DEPTH_BUFFER , 2 ) ,
2020-05-03 11:39:38 +00:00
ASSERT_ENUM_STRING ( MRB_FILL_GEOMETRY_BUFFER , 3 ) , // RB
ASSERT_ENUM_STRING ( MRB_SSAO_PASS , 4 ) , // RB
ASSERT_ENUM_STRING ( MRB_AMBIENT_PASS , 5 ) , // RB
ASSERT_ENUM_STRING ( MRB_DRAW_INTERACTIONS , 6 ) ,
ASSERT_ENUM_STRING ( MRB_DRAW_SHADER_PASSES , 7 ) ,
ASSERT_ENUM_STRING ( MRB_FOG_ALL_LIGHTS , 8 ) ,
ASSERT_ENUM_STRING ( MRB_DRAW_SHADER_PASSES_POST , 9 ) ,
ASSERT_ENUM_STRING ( MRB_DRAW_DEBUG_TOOLS , 10 ) ,
ASSERT_ENUM_STRING ( MRB_CAPTURE_COLORBUFFER , 11 ) ,
ASSERT_ENUM_STRING ( MRB_POSTPROCESS , 12 ) ,
2021-09-22 21:40:11 +00:00
ASSERT_ENUM_STRING ( MRB_DRAW_GUI , 13 ) ,
ASSERT_ENUM_STRING ( MRB_TOTAL , 14 )
2012-11-26 18:58:24 +00:00
} ;
2020-05-04 23:21:29 +00:00
# if defined( USE_VULKAN )
compile_time_assert ( NUM_TIMESTAMP_QUERIES > = ( MRB_TOTAL_QUERIES ) ) ;
2020-05-03 11:39:38 +00:00
# endif
2012-11-26 18:58:24 +00:00
extern uint64 Sys_Microseconds ( ) ;
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
PIX events on all platforms
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
2012-11-28 15:47:07 +00:00
pixEvent_t
2012-11-26 18:58:24 +00:00
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
struct pixEvent_t
{
2012-11-26 18:58:24 +00:00
char name [ 256 ] ;
uint64 cpuTime ;
uint64 gpuTime ;
} ;
idCVar r_pix ( " r_pix " , " 0 " , CVAR_INTEGER , " print GPU/CPU event timing " ) ;
2020-05-04 23:21:29 +00:00
# if !defined( USE_VULKAN )
2019-11-11 19:27:44 +00:00
static const int MAX_PIX_EVENTS = 256 ;
// defer allocation of this until needed, so we don't waste lots of memory
pixEvent_t * pixEvents ; // [MAX_PIX_EVENTS]
int numPixEvents ;
int numPixLevels ;
static GLuint timeQueryIds [ MAX_PIX_EVENTS ] ;
2018-10-03 21:40:35 +00:00
# endif
2012-11-26 18:58:24 +00:00
/*
= = = = = = = = = = = = = = = = = = = = = = = =
PC_BeginNamedEvent
FIXME : this is not thread safe on the PC
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2020-05-03 11:39:38 +00:00
void PC_BeginNamedEvent ( const char * szName , const idVec4 & color )
2012-11-28 15:47:07 +00:00
{
2020-05-03 11:39:38 +00:00
# if defined( USE_VULKAN )
// start an annotated group of calls under the this name
if ( vkcontext . debugMarkerSupportAvailable )
{
VkDebugMarkerMarkerInfoEXT label = { } ;
label . sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT ;
label . pMarkerName = szName ;
label . color [ 0 ] = color . x ;
label . color [ 1 ] = color . y ;
label . color [ 2 ] = color . z ;
label . color [ 3 ] = color . w ;
qvkCmdDebugMarkerBeginEXT ( vkcontext . commandBuffer [ vkcontext . frameParity ] , & label ) ;
}
else if ( vkcontext . debugUtilsSupportAvailable )
{
VkDebugUtilsLabelEXT label = { } ;
label . sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT ;
label . pLabelName = szName ;
label . color [ 0 ] = color . x ;
label . color [ 1 ] = color . y ;
label . color [ 2 ] = color . z ;
label . color [ 3 ] = color . w ;
qvkCmdBeginDebugUtilsLabelEXT ( vkcontext . commandBuffer [ vkcontext . frameParity ] , & label ) ;
}
# else
// RB: colors are not supported in OpenGL
// only do this if RBDOOM-3-BFG was started by RenderDoc or some similar tool
if ( glConfig . gremedyStringMarkerAvailable & & glConfig . khronosDebugAvailable )
{
glPushDebugGroup ( GL_DEBUG_SOURCE_APPLICATION_ARB , 0 , GLsizei ( strlen ( szName ) ) , szName ) ;
}
# endif
2016-01-09 21:24:57 +00:00
#if 0
2012-11-28 15:47:07 +00:00
if ( ! r_pix . GetBool ( ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
if ( ! pixEvents )
{
2012-11-26 18:58:24 +00:00
// lazy allocation to not waste memory
2012-11-28 15:47:07 +00:00
pixEvents = ( pixEvent_t * ) Mem_ClearedAlloc ( sizeof ( * pixEvents ) * MAX_PIX_EVENTS , TAG_CRAP ) ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
if ( numPixEvents > = MAX_PIX_EVENTS )
{
2012-11-26 18:58:24 +00:00
idLib : : FatalError ( " PC_BeginNamedEvent: event overflow " ) ;
}
2012-11-28 15:47:07 +00:00
if ( + + numPixLevels > 1 )
{
2012-11-26 18:58:24 +00:00
return ; // only get top level timing information
}
2012-12-17 16:30:59 +00:00
if ( ! glGetQueryObjectui64vEXT )
2012-11-28 15:47:07 +00:00
{
2012-11-26 18:58:24 +00:00
return ;
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
GL_CheckErrors ( ) ;
2012-11-28 15:47:07 +00:00
if ( timeQueryIds [ 0 ] = = 0 )
{
2014-08-20 09:09:02 +00:00
glGenQueries ( MAX_PIX_EVENTS , timeQueryIds ) ;
2012-11-26 18:58:24 +00:00
}
2012-12-17 16:30:59 +00:00
glFinish ( ) ;
2014-08-20 09:09:02 +00:00
glBeginQuery ( GL_TIME_ELAPSED_EXT , timeQueryIds [ numPixEvents ] ) ;
2012-11-26 18:58:24 +00:00
GL_CheckErrors ( ) ;
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
pixEvent_t * ev = & pixEvents [ numPixEvents + + ] ;
2012-11-26 18:58:24 +00:00
strncpy ( ev - > name , szName , sizeof ( ev - > name ) - 1 ) ;
ev - > cpuTime = Sys_Microseconds ( ) ;
# endif
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
PC_EndNamedEvent
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void PC_EndNamedEvent ( )
{
2020-05-03 11:39:38 +00:00
# if defined( USE_VULKAN )
if ( vkcontext . debugMarkerSupportAvailable )
{
qvkCmdDebugMarkerEndEXT ( vkcontext . commandBuffer [ vkcontext . frameParity ] ) ;
}
else if ( vkcontext . debugUtilsSupportAvailable )
{
qvkCmdEndDebugUtilsLabelEXT ( vkcontext . commandBuffer [ vkcontext . frameParity ] ) ;
}
# else
// only do this if RBDOOM-3-BFG was started by RenderDoc or some similar tool
if ( glConfig . gremedyStringMarkerAvailable & & glConfig . khronosDebugAvailable )
{
glPopDebugGroup ( ) ;
}
# endif
2016-01-09 21:24:57 +00:00
#if 0
2012-11-28 15:47:07 +00:00
if ( ! r_pix . GetBool ( ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
if ( numPixLevels < = 0 )
{
2012-11-26 18:58:24 +00:00
idLib : : FatalError ( " PC_EndNamedEvent: level underflow " ) ;
}
2012-11-28 15:47:07 +00:00
if ( - - numPixLevels > 0 )
{
2012-11-26 18:58:24 +00:00
// only do timing on top level events
return ;
}
2012-12-17 16:30:59 +00:00
if ( ! glGetQueryObjectui64vEXT )
2012-11-28 15:47:07 +00:00
{
2012-11-26 18:58:24 +00:00
return ;
}
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
pixEvent_t * ev = & pixEvents [ numPixEvents - 1 ] ;
2012-11-26 18:58:24 +00:00
ev - > cpuTime = Sys_Microseconds ( ) - ev - > cpuTime ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
GL_CheckErrors ( ) ;
2014-08-20 09:09:02 +00:00
glEndQuery ( GL_TIME_ELAPSED_EXT ) ;
2012-11-26 18:58:24 +00:00
GL_CheckErrors ( ) ;
# endif
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
PC_EndFrame
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void PC_EndFrame ( )
{
2016-01-09 21:24:57 +00:00
#if 0
2012-11-28 15:47:07 +00:00
if ( ! r_pix . GetBool ( ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
int64 totalGPU = 0 ;
int64 totalCPU = 0 ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
idLib : : Printf ( " ----- GPU Events ----- \n " ) ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < numPixEvents ; i + + )
{
pixEvent_t * ev = & pixEvents [ i ] ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
int64 gpuTime = 0 ;
2012-12-17 16:30:59 +00:00
glGetQueryObjectui64vEXT ( timeQueryIds [ i ] , GL_QUERY_RESULT , ( GLuint64EXT * ) & gpuTime ) ;
2012-11-26 18:58:24 +00:00
ev - > gpuTime = gpuTime ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
idLib : : Printf ( " %2d: %1.2f (GPU) %1.3f (CPU) = %s \n " , i , ev - > gpuTime / 1000000.0f , ev - > cpuTime / 1000.0f , ev - > name ) ;
totalGPU + = ev - > gpuTime ;
totalCPU + = ev - > cpuTime ;
}
idLib : : Printf ( " %2d: %1.2f (GPU) %1.3f (CPU) = total \n " , numPixEvents , totalGPU / 1000000.0f , totalCPU / 1000.0f ) ;
memset ( pixEvents , 0 , numPixLevels * sizeof ( pixEvents [ 0 ] ) ) ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
numPixEvents = 0 ;
numPixLevels = 0 ;
# endif
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
idRenderLog
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
idRenderLog renderLog ;
# if !defined( STUB_RENDER_LOG )
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idRenderLog : : idRenderLog
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idRenderLog : : idRenderLog ( )
{
2012-11-26 18:58:24 +00:00
activeLevel = 0 ;
indentString [ 0 ] = ' \0 ' ;
indentLevel = 0 ;
2014-05-10 12:40:01 +00:00
// logFile = NULL;
2012-11-26 18:58:24 +00:00
frameStartTime = 0 ;
closeBlockTime = 0 ;
logLevel = 0 ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idRenderLog : : StartFrame
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idRenderLog : : StartFrame ( )
{
if ( r_logFile . GetInteger ( ) = = 0 )
{
2012-11-26 18:58:24 +00:00
return ;
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
// open a new logfile
indentLevel = 0 ;
indentString [ 0 ] = ' \0 ' ;
activeLevel = r_logLevel . GetInteger ( ) ;
2019-11-11 19:27:44 +00:00
2014-05-11 15:24:24 +00:00
/*
2012-11-28 15:47:07 +00:00
struct tm * newtime ;
2012-11-26 18:58:24 +00:00
time_t aclock ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
char ospath [ MAX_OSPATH ] ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
char qpath [ 128 ] ;
sprintf ( qpath , " renderlogPC_%04i.txt " , r_logFile . GetInteger ( ) ) ;
2014-05-10 12:40:01 +00:00
//idStr finalPath = fileSystem->RelativePathToOSPath( qpath );
sprintf ( ospath , " %s " , qpath ) ;
2014-05-11 15:24:24 +00:00
*/
2012-11-26 18:58:24 +00:00
/*
for ( int i = 0 ; i < 9999 ; i + + ) {
char qpath [ 128 ] ;
sprintf ( qpath , " renderlog_%04i.txt " , r_logFile . GetInteger ( ) ) ;
idStr finalPath = fileSystem - > RelativePathToOSPath ( qpath ) ;
fileSystem - > RelativePathToOSPath ( qpath , ospath , MAX_OSPATH , FSPATH_BASE ) ;
if ( ! fileSystem - > FileExists ( finalPath . c_str ( ) ) ) {
break ; // use this name
}
}
*/
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
common - > SetRefreshOnPrint ( false ) ; // problems are caused if this print causes a refresh...
2019-11-11 19:27:44 +00:00
2014-05-10 12:40:01 +00:00
/*
2012-11-28 15:47:07 +00:00
if ( logFile ! = NULL )
{
2012-11-26 18:58:24 +00:00
fileSystem - > CloseFile ( logFile ) ;
logFile = NULL ;
}
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
logFile = fileSystem - > OpenFileWrite ( ospath ) ;
if ( logFile = = NULL )
{
2012-11-26 18:58:24 +00:00
idLib : : Warning ( " Failed to open logfile %s " , ospath ) ;
return ;
}
idLib : : Printf ( " Opened logfile %s \n " , ospath ) ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
// write the time out to the top of the file
time ( & aclock ) ;
newtime = localtime ( & aclock ) ;
2012-11-28 15:47:07 +00:00
const char * str = asctime ( newtime ) ;
2012-11-26 18:58:24 +00:00
logFile - > Printf ( " // %s " , str ) ;
logFile - > Printf ( " // %s \n \n " , com_version . GetString ( ) ) ;
2014-05-10 12:40:01 +00:00
*/
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
frameStartTime = Sys_Microseconds ( ) ;
closeBlockTime = frameStartTime ;
OpenBlock ( " Frame " ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idRenderLog : : EndFrame
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idRenderLog : : EndFrame ( )
{
2012-11-26 18:58:24 +00:00
PC_EndFrame ( ) ;
2019-11-11 19:27:44 +00:00
2014-05-10 12:40:01 +00:00
//if( logFile != NULL )
if ( r_logFile . GetInteger ( ) ! = 0 )
2012-11-28 15:47:07 +00:00
{
if ( r_logFile . GetInteger ( ) = = 1 )
{
2012-11-26 18:58:24 +00:00
Close ( ) ;
}
// log is open, so decrement r_logFile and stop if it is zero
2014-05-10 12:40:01 +00:00
//r_logFile.SetInteger( r_logFile.GetInteger() - 1 );
//idLib::Printf( "Frame logged.\n" );
2012-11-26 18:58:24 +00:00
return ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idRenderLog : : Close
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idRenderLog : : Close ( )
{
2014-05-10 12:40:01 +00:00
//if( logFile != NULL )
if ( r_logFile . GetInteger ( ) ! = 0 )
2012-11-28 15:47:07 +00:00
{
2012-11-26 18:58:24 +00:00
CloseBlock ( ) ;
2014-05-10 12:40:01 +00:00
//idLib::Printf( "Closing logfile\n" );
//fileSystem->CloseFile( logFile );
//logFile = NULL;
2012-11-26 18:58:24 +00:00
activeLevel = 0 ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idRenderLog : : OpenMainBlock
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idRenderLog : : OpenMainBlock ( renderLogMainBlock_t block )
{
2012-11-26 18:58:24 +00:00
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idRenderLog : : CloseMainBlock
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idRenderLog : : CloseMainBlock ( )
{
2012-11-26 18:58:24 +00:00
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idRenderLog : : OpenBlock
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idRenderLog : : OpenBlock ( const char * label )
{
2012-11-26 18:58:24 +00:00
// Allow the PIX functionality even when logFile is not running.
PC_BeginNamedEvent ( label ) ;
2019-11-11 19:27:44 +00:00
2014-05-10 12:40:01 +00:00
//if( logFile != NULL )
if ( r_logFile . GetInteger ( ) ! = 0 )
2012-11-28 15:47:07 +00:00
{
2014-05-10 14:00:18 +00:00
LogOpenBlock ( RENDER_LOG_INDENT_MAIN_BLOCK , " %s " , label ) ;
2012-11-26 18:58:24 +00:00
}
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idRenderLog : : CloseBlock
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idRenderLog : : CloseBlock ( )
{
2012-11-26 18:58:24 +00:00
PC_EndNamedEvent ( ) ;
2019-11-11 19:27:44 +00:00
2014-05-10 12:40:01 +00:00
//if( logFile != NULL )
if ( r_logFile . GetInteger ( ) ! = 0 )
2012-11-28 15:47:07 +00:00
{
2012-11-26 18:58:24 +00:00
LogCloseBlock ( RENDER_LOG_INDENT_MAIN_BLOCK ) ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idRenderLog : : Printf
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idRenderLog : : Printf ( const char * fmt , . . . )
{
2018-10-03 21:40:35 +00:00
# if !defined(USE_VULKAN)
2012-11-28 15:47:07 +00:00
if ( activeLevel < = LOG_LEVEL_BLOCKS_ONLY )
{
2012-11-26 18:58:24 +00:00
return ;
}
2019-11-11 19:27:44 +00:00
2014-05-10 12:40:01 +00:00
//if( logFile == NULL )
if ( r_logFile . GetInteger ( ) = = 0 | | ! glConfig . gremedyStringMarkerAvailable )
2012-11-28 15:47:07 +00:00
{
2012-11-26 18:58:24 +00:00
return ;
}
2019-11-11 19:27:44 +00:00
2014-05-10 12:40:01 +00:00
va_list marker ;
char msg [ 4096 ] ;
2019-11-11 19:27:44 +00:00
2014-05-10 12:40:01 +00:00
idStr out = indentString ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
va_start ( marker , fmt ) ;
2014-05-10 12:40:01 +00:00
idStr : : vsnPrintf ( msg , sizeof ( msg ) , fmt , marker ) ;
2012-11-26 18:58:24 +00:00
va_end ( marker ) ;
2019-11-11 19:27:44 +00:00
2014-05-10 12:40:01 +00:00
msg [ sizeof ( msg ) - 1 ] = ' \0 ' ;
2019-11-11 19:27:44 +00:00
2014-05-10 12:40:01 +00:00
out . Append ( msg ) ;
2019-11-11 19:27:44 +00:00
2014-05-10 12:40:01 +00:00
glStringMarkerGREMEDY ( out . Length ( ) , out . c_str ( ) ) ;
2019-11-11 19:27:44 +00:00
2014-05-10 12:40:01 +00:00
//logFile->Printf( "%s", indentString );
//va_start( marker, fmt );
//logFile->VPrintf( fmt, marker );
//va_end( marker );
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
// logFile->Flush(); this makes it take waaaay too long
2014-05-10 12:40:01 +00:00
# endif
2012-11-26 18:58:24 +00:00
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idRenderLog : : LogOpenBlock
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2014-05-10 13:29:59 +00:00
void idRenderLog : : LogOpenBlock ( renderLogIndentLabel_t label , const char * fmt , . . . )
2012-11-28 15:47:07 +00:00
{
2012-11-26 18:58:24 +00:00
uint64 now = Sys_Microseconds ( ) ;
2019-11-11 19:27:44 +00:00
2014-05-10 12:40:01 +00:00
//if( logFile != NULL )
if ( r_logFile . GetInteger ( ) ! = 0 )
2012-11-28 15:47:07 +00:00
{
2014-05-10 12:40:01 +00:00
//if( now - closeBlockTime >= 1000 )
//{
//logFile->Printf( "%s%1.1f msec gap from last closeblock\n", indentString, ( now - closeBlockTime ) * ( 1.0f / 1000.0f ) );
//}
2019-11-11 19:27:44 +00:00
2018-10-03 21:40:35 +00:00
# if !defined(USE_VULKAN)
2014-05-10 12:40:01 +00:00
if ( glConfig . gremedyStringMarkerAvailable )
2012-11-28 15:47:07 +00:00
{
2014-05-10 12:40:01 +00:00
//Printf( fmt, args );
//Printf( " {\n" );
2019-11-11 19:27:44 +00:00
2014-05-10 12:40:01 +00:00
//logFile->Printf( "%s", indentString );
//logFile->VPrintf( fmt, args );
//logFile->Printf( " {\n" );
2019-11-11 19:27:44 +00:00
2014-05-10 12:40:01 +00:00
va_list marker ;
char msg [ 4096 ] ;
2019-11-11 19:27:44 +00:00
2014-05-10 12:40:01 +00:00
idStr out = indentString ;
2019-11-11 19:27:44 +00:00
2014-05-10 12:40:01 +00:00
va_start ( marker , fmt ) ;
idStr : : vsnPrintf ( msg , sizeof ( msg ) , fmt , marker ) ;
va_end ( marker ) ;
2019-11-11 19:27:44 +00:00
2014-05-10 12:40:01 +00:00
msg [ sizeof ( msg ) - 1 ] = ' \0 ' ;
2019-11-11 19:27:44 +00:00
2014-05-10 12:40:01 +00:00
out . Append ( msg ) ;
out + = " { " ;
2019-11-11 19:27:44 +00:00
2014-05-10 12:40:01 +00:00
glStringMarkerGREMEDY ( out . Length ( ) , out . c_str ( ) ) ;
2012-11-26 18:58:24 +00:00
}
2014-05-10 12:40:01 +00:00
# endif
2012-11-26 18:58:24 +00:00
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
Indent ( label ) ;
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
if ( logLevel > = MAX_LOG_LEVELS )
{
2012-11-26 18:58:24 +00:00
idLib : : Warning ( " logLevel %d >= MAX_LOG_LEVELS " , logLevel ) ;
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
logLevel + + ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idRenderLog : : LogCloseBlock
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idRenderLog : : LogCloseBlock ( renderLogIndentLabel_t label )
{
2012-11-26 18:58:24 +00:00
closeBlockTime = Sys_Microseconds ( ) ;
2019-11-11 19:27:44 +00:00
2016-01-06 21:37:16 +00:00
//assert( logLevel > 0 );
2012-11-26 18:58:24 +00:00
logLevel - - ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
Outdent ( label ) ;
2019-11-11 19:27:44 +00:00
2014-05-10 12:40:01 +00:00
//if( logFile != NULL )
//{
//}
2012-11-26 18:58:24 +00:00
}
# else // !STUB_RENDER_LOG
2020-05-03 11:39:38 +00:00
// RB begin
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idRenderLog : : idRenderLog
= = = = = = = = = = = = = = = = = = = = = = = =
*/
idRenderLog : : idRenderLog ( )
{
}
2020-05-04 23:21:29 +00:00
# if 1
2020-05-03 11:39:38 +00:00
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idRenderLog : : OpenMainBlock
= = = = = = = = = = = = = = = = = = = = = = = =
*/
void idRenderLog : : OpenMainBlock ( renderLogMainBlock_t block )
{
2021-09-22 21:40:11 +00:00
// SRS - Use glConfig.timerQueryAvailable flag to control timestamp capture for all platforms
if ( glConfig . timerQueryAvailable )
{
mainBlock = block ;
2020-05-04 23:21:29 +00:00
2020-05-09 14:48:55 +00:00
# if defined( USE_VULKAN )
2021-09-22 21:40:11 +00:00
if ( vkcontext . queryIndex [ vkcontext . frameParity ] > = ( NUM_TIMESTAMP_QUERIES - 1 ) )
{
return ;
}
2020-05-04 23:21:29 +00:00
2021-09-22 21:40:11 +00:00
VkCommandBuffer commandBuffer = vkcontext . commandBuffer [ vkcontext . frameParity ] ;
VkQueryPool queryPool = vkcontext . queryPools [ vkcontext . frameParity ] ;
2020-05-04 23:21:29 +00:00
2021-09-22 21:40:11 +00:00
uint32 queryIndex = vkcontext . queryAssignedIndex [ vkcontext . frameParity ] [ mainBlock * 2 + 0 ] = vkcontext . queryIndex [ vkcontext . frameParity ] + + ;
vkCmdWriteTimestamp ( commandBuffer , VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT , queryPool , queryIndex ) ;
2020-05-09 14:48:55 +00:00
2021-04-19 18:31:15 +00:00
# elif defined(__APPLE__)
2021-09-22 21:40:11 +00:00
// 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 ] ) ;
}
glBeginQuery ( GL_TIME_ELAPSED_EXT , glcontext . renderLogMainBlockTimeQueryIds [ glcontext . frameParity ] [ mainBlock * 2 + 1 ] ) ;
}
2020-05-03 11:39:38 +00:00
# else
2021-04-19 18:31:15 +00:00
if ( glcontext . renderLogMainBlockTimeQueryIds [ glcontext . frameParity ] [ mainBlock * 2 ] = = 0 )
2020-05-03 11:39:38 +00:00
{
2021-04-19 18:31:15 +00:00
glCreateQueries ( GL_TIMESTAMP , 2 , & glcontext . renderLogMainBlockTimeQueryIds [ glcontext . frameParity ] [ mainBlock * 2 ] ) ;
2020-05-03 11:39:38 +00:00
}
2021-04-19 18:31:15 +00:00
glQueryCounter ( glcontext . renderLogMainBlockTimeQueryIds [ glcontext . frameParity ] [ mainBlock * 2 + 0 ] , GL_TIMESTAMP ) ;
glcontext . renderLogMainBlockTimeQueryIssued [ glcontext . frameParity ] [ mainBlock * 2 + 0 ] + + ;
2020-05-03 11:39:38 +00:00
# endif
2021-09-22 21:40:11 +00:00
}
2020-05-03 11:39:38 +00:00
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idRenderLog : : CloseMainBlock
= = = = = = = = = = = = = = = = = = = = = = = =
*/
void idRenderLog : : CloseMainBlock ( )
{
2021-09-22 21:40:11 +00:00
// SRS - Use glConfig.timerQueryAvailable flag to control timestamp capture for all platforms
if ( glConfig . timerQueryAvailable )
{
2020-05-04 23:21:29 +00:00
2021-09-22 21:40:11 +00:00
# if defined( USE_VULKAN )
if ( vkcontext . queryIndex [ vkcontext . frameParity ] > = ( NUM_TIMESTAMP_QUERIES - 1 ) )
{
return ;
}
2020-05-04 23:21:29 +00:00
2021-09-22 21:40:11 +00:00
VkCommandBuffer commandBuffer = vkcontext . commandBuffer [ vkcontext . frameParity ] ;
VkQueryPool queryPool = vkcontext . queryPools [ vkcontext . frameParity ] ;
2020-05-04 23:21:29 +00:00
2021-09-22 21:40:11 +00:00
uint32 queryIndex = vkcontext . queryAssignedIndex [ vkcontext . frameParity ] [ mainBlock * 2 + 1 ] = vkcontext . queryIndex [ vkcontext . frameParity ] + + ;
vkCmdWriteTimestamp ( commandBuffer , VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT , queryPool , queryIndex ) ;
2021-04-29 13:20:45 +00:00
2021-04-19 18:31:15 +00:00
# elif defined(__APPLE__)
2021-09-22 21:40:11 +00:00
// 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 ] + + ;
}
2021-04-29 13:20:45 +00:00
2020-05-03 11:39:38 +00:00
# else
2020-05-09 14:48:55 +00:00
glQueryCounter ( glcontext . renderLogMainBlockTimeQueryIds [ glcontext . frameParity ] [ mainBlock * 2 + 1 ] , GL_TIMESTAMP ) ;
glcontext . renderLogMainBlockTimeQueryIssued [ glcontext . frameParity ] [ mainBlock * 2 + 1 ] + + ;
2020-05-03 11:39:38 +00:00
# endif
2021-09-22 21:40:11 +00:00
}
2020-05-03 11:39:38 +00:00
}
# endif
2012-11-26 18:58:24 +00:00
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idRenderLog : : OpenBlock
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2020-05-03 11:39:38 +00:00
void idRenderLog : : OpenBlock ( const char * label , const idVec4 & color )
2012-11-28 15:47:07 +00:00
{
2020-05-03 11:39:38 +00:00
PC_BeginNamedEvent ( label , color ) ;
2012-11-26 18:58:24 +00:00
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idRenderLog : : CloseBlock
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idRenderLog : : CloseBlock ( )
{
2012-11-26 18:58:24 +00:00
PC_EndNamedEvent ( ) ;
}
2020-05-03 11:39:38 +00:00
// RB end
2012-11-26 18:58:24 +00:00
# endif // !STUB_RENDER_LOG