From 9a6e253dc3cd27bfaa5e327350ec2274a08eb510 Mon Sep 17 00:00:00 2001 From: myT <> Date: Thu, 23 Nov 2023 19:59:39 +0100 Subject: [PATCH] removed screenshot/videoframe requests from the render command list --- code/renderer/grp_local.h | 2 +- code/renderer/grp_main.cpp | 12 +---- code/renderer/tr_cmds.cpp | 104 ++++++++++++------------------------- code/renderer/tr_init.cpp | 18 ++----- code/renderer/tr_local.h | 27 ++++++---- 5 files changed, 57 insertions(+), 106 deletions(-) diff --git a/code/renderer/grp_local.h b/code/renderer/grp_local.h index 028da4e..232b3af 100644 --- a/code/renderer/grp_local.h +++ b/code/renderer/grp_local.h @@ -656,7 +656,7 @@ struct GRP : IRenderPipeline void ProcessModel(model_t& model) override; void ProcessShader(shader_t& shader) override; - void ExecuteRenderCommands(const byte* data) override; + void ExecuteRenderCommands(const byte* data, bool readbackRequested) override; void UISetColor(const uiSetColorCommand_t& cmd) override { ui.UISetColor(cmd); } void UIDrawQuad(const uiDrawQuadCommand_t& cmd) override { ui.UIDrawQuad(cmd); } diff --git a/code/renderer/grp_main.cpp b/code/renderer/grp_main.cpp index 78ddce9..3c6aa61 100644 --- a/code/renderer/grp_main.cpp +++ b/code/renderer/grp_main.cpp @@ -884,11 +884,9 @@ uint32_t GRP::CreatePSO(CachedPSO& cache, const char* name) return index; } -void GRP::ExecuteRenderCommands(const byte* data) +void GRP::ExecuteRenderCommands(const byte* data, bool readbackRequested) { - updateReadbackTexture = - R_FindRenderCommand(RC_SCREENSHOT) != NULL || - R_FindRenderCommand(RC_VIDEOFRAME) != NULL; + updateReadbackTexture = readbackRequested; for(;;) { @@ -940,12 +938,6 @@ void GRP::ExecuteRenderCommands(const byte* data) case RC_END_SCENE: smaa.Draw(((const endSceneCommand_t*)data)->viewParms); break; - case RC_SCREENSHOT: - RB_TakeScreenshotCmd((const screenshotCommand_t*)data); - break; - case RC_VIDEOFRAME: - RB_TakeVideoFrameCmd((const videoFrameCommand_t*)data); - break; default: Q_assert(!"Unsupported render command type"); diff --git a/code/renderer/tr_cmds.cpp b/code/renderer/tr_cmds.cpp index 6fd5724..6c10b49 100644 --- a/code/renderer/tr_cmds.cpp +++ b/code/renderer/tr_cmds.cpp @@ -30,63 +30,42 @@ const int renderCommandSizes[RC_COUNT + 1] = }; #undef RC - // we reserve space for frame ending commands as well as transition commands (begin/end 2D/3D rendering) static const int CmdListReservedBytes = (int)(sizeof(swapBuffersCommand_t) + sizeof(screenshotCommand_t) + 16 * sizeof(void*)); +static qbool R_IsReadbackRequested( readbackCommands_t* readback ) +{ + Q_assert( readback ); + + return + readback->screenshot.requested != 0 || + readback->videoFrame.requested != 0; +} + + void R_IssueRenderCommands() { - renderCommandList_t* cmdList = &backEndData->commands; - // add an end-of-list command + renderCommandList_t* cmdList = &backEndData->commands; ((renderCommandBase_t*)(cmdList->cmds + cmdList->used))->commandId = RC_END_OF_LIST; // clear it out, in case this is a sync and not a buffer flip cmdList->used = 0; - renderPipeline->ExecuteRenderCommands( cmdList->cmds ); -} + // process render commands + readbackCommands_t* const readback = &backEndData->readbackCommands; + renderPipeline->ExecuteRenderCommands( cmdList->cmds, R_IsReadbackRequested( readback ) ); - -byte* R_FindRenderCommand( renderCommand_t type ) -{ - renderCommandList_t* cmdList = &backEndData->commands; - byte* data = cmdList->cmds; - byte* end = cmdList->cmds + cmdList->used; - - for ( ;; ) { - const int commandId = ((const renderCommandBase_t*)data)->commandId; - - if( commandId == type ) - return (byte*)data; - - if ( data >= end ) - return NULL; - - if ( commandId < 0 || commandId >= RC_COUNT ) { - Q_assert( !"Invalid render command type" ); - return NULL; - } - - if ( commandId == RC_END_OF_LIST ) - return NULL; - - data += renderCommandSizes[commandId]; + // process readback commands + if ( readback->screenshot.requested ) { + RB_TakeScreenshotCmd( &readback->screenshot ); } -} - - -static void RemoveRenderCommand( byte* cmd, int cmdSize ) -{ - renderCommandList_t* cmdList = &backEndData->commands; - const int endOffset = (cmd + cmdSize) - cmdList->cmds; - const int endBytes = cmdList->used - endOffset; - Q_assert( cmd >= cmdList->cmds ); - Q_assert( cmd + cmdSize <= cmdList->cmds + cmdList->used ); - - memmove( cmd, cmd + cmdSize, endBytes ); - cmdList->used -= cmdSize; + if ( readback->videoFrame.requested ) { + RB_TakeVideoFrameCmd( &readback->videoFrame ); + } + readback->screenshot.requested = qfalse; + readback->videoFrame.requested = qfalse; } @@ -301,7 +280,7 @@ void RE_DrawTriangle( float x0, float y0, float x1, float y1, float x2, float y2 void RE_BeginFrame( stereoFrame_t stereoFrame ) { - if (!tr.registered) + if ( !tr.registered ) return; tr.frameCount++; @@ -311,13 +290,11 @@ void RE_BeginFrame( stereoFrame_t stereoFrame ) // delayed screenshot if ( r_delayedScreenshotPending ) { r_delayedScreenshotFrame++; - if ( r_delayedScreenshotFrame >= 2 ) { - screenshotCommand_t* const cmd = AllocateRenderCommand( RC_SCREENSHOT ); - if ( cmd ) { - *cmd = r_delayedScreenshot; - r_delayedScreenshotPending = qfalse; - r_delayedScreenshotFrame = 0; - } + if ( r_delayedScreenshotFrame >= 1 ) { + backEndData->readbackCommands.screenshot = r_delayedScreenshot; + backEndData->readbackCommands.screenshot.requested = qtrue; + r_delayedScreenshotPending = qfalse; + r_delayedScreenshotFrame = 0; } } @@ -330,26 +307,16 @@ void RE_BeginFrame( stereoFrame_t stereoFrame ) void RE_EndFrame( qbool render ) { - if (!tr.registered) + if ( !tr.registered ) return; - qbool delayScreenshot = qfalse; if ( !render && r_delayedScreenshotPending ) render = qtrue; if ( !render ) { - screenshotCommand_t* ssCmd = (screenshotCommand_t*)R_FindRenderCommand( RC_SCREENSHOT ); - - if ( ssCmd ) + readbackCommands_t* const readback = &backEndData->readbackCommands; + if ( R_IsReadbackRequested( readback ) ) render = qtrue; - - if ( ssCmd && !ssCmd->delayed ) { - // save and remove the command so we can push it back after the frame's done - r_delayedScreenshot = *ssCmd; - r_delayedScreenshot.delayed = qtrue; - RemoveRenderCommand( (byte*)ssCmd, sizeof(screenshotCommand_t) ); - delayScreenshot = qtrue; - } } backEnd.renderFrame = render; @@ -359,10 +326,6 @@ void RE_EndFrame( qbool render ) if ( render ) { AllocateRenderCommand( RC_SWAP_BUFFERS, qtrue ); - if ( delayScreenshot ) { - screenshotCommand_t* const cmd = AllocateRenderCommand( RC_SCREENSHOT, qtrue ); - *cmd = r_delayedScreenshot; - } } else { R_ClearFrame(); } @@ -385,9 +348,8 @@ void RE_TakeVideoFrame( int width, int height, byte *captureBuffer, byte *encode End2D(); End3D(); - videoFrameCommand_t* const cmd = AllocateRenderCommand( RC_VIDEOFRAME ); - Q_assert( cmd ); - + videoFrameCommand_t* const cmd = &backEndData->readbackCommands.videoFrame; + cmd->requested = qtrue; cmd->width = width; cmd->height = height; cmd->captureBuffer = captureBuffer; diff --git a/code/renderer/tr_init.cpp b/code/renderer/tr_init.cpp index a11435b..e63eb0e 100644 --- a/code/renderer/tr_init.cpp +++ b/code/renderer/tr_init.cpp @@ -184,7 +184,7 @@ static void RB_TakeScreenshotJPG( int width, int height, const char* fileName ) } -const byte* RB_TakeScreenshotCmd( const screenshotCommand_t* cmd ) +void RB_TakeScreenshotCmd( const screenshotCommand_t* cmd ) { switch (cmd->type) { case screenshotCommand_t::SS_JPG: @@ -202,8 +202,6 @@ const byte* RB_TakeScreenshotCmd( const screenshotCommand_t* cmd ) r_delayedScreenshotPending = qfalse; r_delayedScreenshotFrame = 0; } - - return (const byte*)(cmd + 1); } @@ -220,14 +218,10 @@ static void R_TakeScreenshot( const char* ext, screenshotCommand_t::ss_type type cmd = &r_delayedScreenshot; r_delayedScreenshotPending = qtrue; r_delayedScreenshotFrame = 0; - cmd->delayed = qtrue; } else { - if ( R_FindRenderCommand( RC_SCREENSHOT ) ) + cmd = &backEndData->readbackCommands.screenshot; + if ( cmd->requested ) return; - cmd = (screenshotCommand_t*)R_AllocateRenderCommand( sizeof(screenshotCommand_t), RC_SCREENSHOT, qfalse ); - if ( !cmd ) - return; - cmd->delayed = qfalse; } if (ri.Cmd_Argc() == 2) { @@ -240,7 +234,7 @@ static void R_TakeScreenshot( const char* ext, screenshotCommand_t::ss_type type 1900+t.tm_year, 1+t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, ms, ext ); } - cmd->commandId = RC_SCREENSHOT; + cmd->requested = qtrue; cmd->width = glConfig.vidWidth; cmd->height = glConfig.vidHeight; cmd->fileName = s; @@ -276,7 +270,7 @@ static void R_ScreenShotNoConJPG_f() //============================================================================ -const byte *RB_TakeVideoFrameCmd( const videoFrameCommand_t *cmd ) +void RB_TakeVideoFrameCmd( const videoFrameCommand_t *cmd ) { if( cmd->motionJpeg ) { @@ -290,8 +284,6 @@ const byte *RB_TakeVideoFrameCmd( const videoFrameCommand_t *cmd ) const int frameSize = PAD( cmd->width, 4 ) * cmd->height * 3; ri.CL_WriteAVIVideoFrame( cmd->captureBuffer, frameSize ); } - - return (const byte *)(cmd + 1); } diff --git a/code/renderer/tr_local.h b/code/renderer/tr_local.h index 80fbbcb..6fd2f62 100644 --- a/code/renderer/tr_local.h +++ b/code/renderer/tr_local.h @@ -1490,18 +1490,20 @@ struct endSceneCommand_t : renderCommandBase_t { uint32_t padding2; }; -struct screenshotCommand_t : renderCommandBase_t { +struct readbackCommandBase_t { + qbool requested; +}; + +struct screenshotCommand_t : readbackCommandBase_t { int width; int height; const char* fileName; enum ss_type { SS_TGA, SS_JPG } type; float conVis; // if > 0, this is a delayed screenshot and we need to // restore the console visibility to that value - qbool delayed; }; -struct videoFrameCommand_t : renderCommandBase_t { - int commandId; +struct videoFrameCommand_t : readbackCommandBase_t { int width; int height; byte *captureBuffer; @@ -1509,6 +1511,11 @@ struct videoFrameCommand_t : renderCommandBase_t { qbool motionJpeg; }; +struct readbackCommands_t { + screenshotCommand_t screenshot; + videoFrameCommand_t videoFrame; +}; + #pragma pack(pop) #define RENDER_COMMAND_LIST(Cmd) \ @@ -1523,9 +1530,7 @@ struct videoFrameCommand_t : renderCommandBase_t { Cmd(RC_DRAW_SCENE_VIEW, drawSceneViewCommand_t) \ Cmd(RC_END_SCENE, endSceneCommand_t) \ Cmd(RC_BEGIN_FRAME, beginFrameCommand_t) \ - Cmd(RC_SWAP_BUFFERS, swapBuffersCommand_t) \ - Cmd(RC_SCREENSHOT, screenshotCommand_t) \ - Cmd(RC_VIDEOFRAME, videoFrameCommand_t) + Cmd(RC_SWAP_BUFFERS, swapBuffersCommand_t) #define RC(Enum, Type) Enum, enum renderCommand_t { @@ -1550,6 +1555,7 @@ typedef struct { srfPoly_t *polys; polyVert_t *polyVerts; renderCommandList_t commands; + readbackCommands_t readbackCommands; } backEndData_t; #define SKY_SUBDIVISIONS 8 @@ -1566,8 +1572,8 @@ extern int max_polyverts; extern backEndData_t* backEndData; -const byte* RB_TakeScreenshotCmd( const screenshotCommand_t* cmd ); -const byte* RB_TakeVideoFrameCmd( const videoFrameCommand_t* cmd ); +void RB_TakeScreenshotCmd( const screenshotCommand_t* cmd ); +void RB_TakeVideoFrameCmd( const videoFrameCommand_t* cmd ); void RB_PushSingleStageShader( int stateBits, cullType_t cullType ); void RB_PopShader(); @@ -1578,7 +1584,6 @@ void RB_DrawSky(); void R_BuildCloudData(); void R_IssueRenderCommands(); -byte* R_FindRenderCommand( renderCommand_t type ); byte* R_AllocateRenderCommand( int bytes, int commandId, qbool endFrame ); void R_AddDrawSurfCmd( drawSurf_t* drawSurfs, int numDrawSurfs, int numTranspSurfs ); @@ -1666,7 +1671,7 @@ struct IRenderPipeline virtual void BeginTextureUpload(RHI::MappedTexture& mappedTexture, image_t* image) = 0; virtual void EndTextureUpload() = 0; - virtual void ExecuteRenderCommands(const byte* data) = 0; + virtual void ExecuteRenderCommands(const byte* data, bool readbackRequested) = 0; virtual void UISetColor(const uiSetColorCommand_t& cmd) = 0; virtual void UIDrawQuad(const uiDrawQuadCommand_t& cmd) = 0;