mirror of
https://bitbucket.org/CPMADevs/cnq3
synced 2024-11-26 05:50:57 +00:00
removed screenshot/videoframe requests from the render command list
This commit is contained in:
parent
b91e20a1b9
commit
9a6e253dc3
5 changed files with 57 additions and 106 deletions
|
@ -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); }
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue