removed screenshot/videoframe requests from the render command list

This commit is contained in:
myT 2023-11-23 19:59:39 +01:00
parent b91e20a1b9
commit 9a6e253dc3
5 changed files with 57 additions and 106 deletions

View file

@ -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); }

View file

@ -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");

View file

@ -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<screenshotCommand_t>( 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<swapBuffersCommand_t>( RC_SWAP_BUFFERS, qtrue );
if ( delayScreenshot ) {
screenshotCommand_t* const cmd = AllocateRenderCommand<screenshotCommand_t>( 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<videoFrameCommand_t>( RC_VIDEOFRAME );
Q_assert( cmd );
videoFrameCommand_t* const cmd = &backEndData->readbackCommands.videoFrame;
cmd->requested = qtrue;
cmd->width = width;
cmd->height = height;
cmd->captureBuffer = captureBuffer;

View file

@ -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);
}

View file

@ -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;