/* ==================== R_IssueRenderCommands ==================== */ void R_IssueRenderCommands( qboolean runPerformanceCounters ) { renderCommandList_t *cmdList; if ( refHeadless ) { return; } cmdList = &backEndData->commands; assert(cmdList); // add an end-of-list command *(int *)(cmdList->cmds + cmdList->used) = RC_END_OF_LIST; // clear it out, in case this is a sync and not a buffer flip cmdList->used = 0; if ( runPerformanceCounters ) { R_PerformanceCounters(); } // actually start the commands going if ( !r_skipBackEnd->integer ) { // let it start on the new batch RB_ExecuteRenderCommands( cmdList->cmds ); } }
/** * @brief R_IssueRenderCommands * @param[in] runPerformanceCounters */ void R_IssueRenderCommands(qboolean runPerformanceCounters) { renderCommandList_t *cmdList = &backEndData->commands; etl_assert(cmdList != NULL); // add an end-of-list command *(int *)(cmdList->cmds + cmdList->used) = RC_END_OF_LIST; // clear it out, in case this is a sync and not a buffer flip cmdList->used = 0; // at this point, the back end thread is idle, so it is ok // to look at it's performance counters if (runPerformanceCounters) { R_PerformanceCounters(); } // actually start the commands going if (!r_skipBackEnd->integer) { // let it start on the new batch RB_ExecuteRenderCommands(cmdList->cmds); } }
void R_IssueRenderCommands( qboolean runPerformanceCounters ) { renderCommandList_t *cmdList; cmdList = &backEndData[ tr.smpFrame ]->commands; assert( cmdList ); // bk001205 // add an end-of-list command * ( int * )( cmdList->cmds + cmdList->used ) = RC_END_OF_LIST; // clear it out, in case this is a sync and not a buffer flip cmdList->used = 0; if ( glConfig.smpActive ) { // if the render thread is not idle, wait for it if ( renderThreadActive ) { c_blockedOnRender++; if ( r_showSmp->integer ) { ri.Printf( PRINT_ALL, "R" ); } } else { c_blockedOnMain++; if ( r_showSmp->integer ) { ri.Printf( PRINT_ALL, "." ); } } // sleep until the renderer has completed GLimp_FrontEndSleep(); } // at this point, the back end thread is idle, so it is ok // to look at its performance counters if ( runPerformanceCounters ) { R_PerformanceCounters(); } // actually start the commands going if ( !r_skipBackEnd->integer ) { // let it start on the new batch if ( !glConfig.smpActive ) { RB_ExecuteRenderCommands( cmdList->cmds ); } else { GLimp_WakeRenderer( cmdList->cmds ); } } }
void R_IssueRenderCommands( bool runPerformanceCounters ) { renderCommandList_t *cmdList; cmdList = &backEndData[ tr.smpFrame ]->commands; ASSERT(cmdList != nullptr); // add an end-of-list command *reinterpret_cast<renderCommand_t*>(&cmdList->cmds[cmdList->used]) = renderCommand_t::RC_END_OF_LIST; // clear it out, in case this is a sync and not a buffer flip cmdList->used = 0; if ( glConfig.smpActive ) { // if the render thread is not idle, wait for it if ( renderThreadActive ) { c_blockedOnRender++; if ( r_showSmp->integer ) { Log::Notice("R"); } } else { c_blockedOnMain++; if ( r_showSmp->integer ) { Log::Notice("."); } } // sleep until the renderer has completed GLimp_FrontEndSleep(); } // at this point, the back end thread is idle, so it is ok // to look at its performance counters if ( runPerformanceCounters ) { R_PerformanceCounters(); } // actually start the commands going if ( !r_skipBackEnd->integer ) { // let it start on the new batch if ( !glConfig.smpActive ) { RB_ExecuteRenderCommands( cmdList->cmds ); } else { GLimp_WakeRenderer( cmdList->cmds ); } } }
/* ===================== idRenderSystemLocal::SwapCommandBuffers_FinishRendering ===================== */ void idRenderSystemLocal::SwapCommandBuffers_FinishRendering( uint64 * frontEndMicroSec, uint64 * backEndMicroSec, uint64 * shadowMicroSec, uint64 * gpuMicroSec ) { SCOPED_PROFILE_EVENT( "SwapCommandBuffers" ); if ( gpuMicroSec != NULL ) { *gpuMicroSec = 0; // until shown otherwise } if ( !R_IsInitialized() ) { return; } // After coming back from an autoswap, we won't have anything to render if ( frameData->cmdHead->next != NULL ) { // wait for our fence to hit, which means the swap has actually happened // We must do this before clearing any resources the GPU may be using void GL_BlockingSwapBuffers(); GL_BlockingSwapBuffers(); } // read back the start and end timer queries from the previous frame if ( glConfig.timerQueryAvailable ) { uint64 drawingTimeNanoseconds = 0; if ( tr.timerQueryId != 0 ) { qglGetQueryObjectui64vEXT( tr.timerQueryId, GL_QUERY_RESULT, &drawingTimeNanoseconds ); } if ( gpuMicroSec != NULL ) { *gpuMicroSec = drawingTimeNanoseconds / 1000; } } //------------------------------ // save out timing information if ( frontEndMicroSec != NULL ) { *frontEndMicroSec = pc.frontEndMicroSec; } if ( backEndMicroSec != NULL ) { *backEndMicroSec = backEnd.pc.totalMicroSec; } if ( shadowMicroSec != NULL ) { *shadowMicroSec = backEnd.pc.shadowMicroSec; } // print any other statistics and clear all of them R_PerformanceCounters(); // check for dynamic changes that require some initialization R_CheckCvars(); // check for errors GL_CheckErrors(); }
/* ============= EndFrame Returns the number of msec spent in the back end ============= */ void idRenderSystemLocal::EndFrame( int *frontEndMsec, int *backEndMsec, bool swapFrontBack ) { emptyCommand_t *cmd; if ( !glConfig.isInitialized ) { return; } // close any gui drawing guiModel->EmitFullScreen(); guiModel->Clear(); // save out timing information if ( frontEndMsec ) { *frontEndMsec = pc.frontEndMsec; } if ( backEndMsec ) { *backEndMsec = backEnd.pc.msec; } // print any other statistics and clear all of them R_PerformanceCounters(); // check for dynamic changes that require some initialization R_CheckCvars(); // check for errors GL_CheckErrors(); // add the swapbuffers command if(swapFrontBack) { cmd = (emptyCommand_t *)R_GetCommandBuffer( sizeof( *cmd ) ); cmd->commandId = RC_SWAP_BUFFERS; } // start the back end up again with the new command list R_IssueRenderCommands(); // use the other buffers next frame, because another CPU // may still be rendering into the current buffers R_ToggleSmpFrame(); // we can now release the vertexes used this frame vertexCache.EndFrame(); if ( session->writeDemo ) { session->writeDemo->WriteInt( DS_RENDER ); session->writeDemo->WriteInt( DC_END_FRAME ); if ( r_showDemo.GetBool() ) { common->Printf( "write DC_END_FRAME\n" ); } } }
frameInfo_t idRenderSystemLocal::LocalEndFrame() { frameInfo_t info; memset(&info, 0, sizeof(info)); if (!glConfig.isInitialized) { return info; } // close any gui drawing guiModel->EmitFullScreen(); guiModel->Clear(); // save out timing information info.time.frontEndMsec = pc.frontEndMsec; info.time.backEndMsec = backEnd.pc.msec; // print any other statistics and clear all of them R_PerformanceCounters(); // check for errors GL_CheckErrors(false); // add the swapbuffers command auto cmd = R_GetCommandBuffer<emptyCommand_t>(); cmd->commandId = RC_SWAP_BUFFERS; // start the back end up again with the new command list info.framebuffer = R_IssueRenderCommands(); // use the other buffers next frame, because another CPU // may still be rendering into the current buffers R_ToggleSmpFrame(); // we can now release the vertexes used this frame vertexCache.EndFrame(); if (session->writeDemo) { session->writeDemo->WriteInt(DS_RENDER); session->writeDemo->WriteInt(DC_END_FRAME); if (r_showDemo.GetBool()) { common->Printf("write DC_END_FRAME\n"); } } return info; }
void R_IssueRenderCommands( qboolean runPerformanceCounters ) { R_GetCommandBuffer( RC_END_OF_LIST, 0 ); // clear it out, in case this is a sync and not a buffer flip trScene.backEnd->used = 0; if ( glConfig.smpActive ) { // if the render thread is not idle, wait for it if ( renderThreadActive ) { c_blockedOnRender++; if ( r_showSmp->integer ) { ri.Printf( PRINT_ALL, "R" ); } } else { c_blockedOnMain++; if ( r_showSmp->integer ) { ri.Printf( PRINT_ALL, "." ); } } // sleep until the renderer has completed GLimp_FrontEndSleep(); } // at this point, the back end thread is idle, so it is ok // to look at it's performance counters if ( runPerformanceCounters ) { R_PerformanceCounters(); } // actually start the commands going if ( !r_skipBackEnd->integer ) { // let it start on the new batch if ( !glConfig.smpActive ) { RB_ExecuteRenderCommands( trScene.backEnd->data ); } else { GLimp_WakeRenderer( trScene.backEnd->data ); } } }