mirror of
https://bitbucket.org/CPMADevs/cnq3
synced 2025-02-18 09:51:14 +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 ProcessModel(model_t& model) override;
|
||||||
void ProcessShader(shader_t& shader) 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 UISetColor(const uiSetColorCommand_t& cmd) override { ui.UISetColor(cmd); }
|
||||||
void UIDrawQuad(const uiDrawQuadCommand_t& cmd) override { ui.UIDrawQuad(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;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GRP::ExecuteRenderCommands(const byte* data)
|
void GRP::ExecuteRenderCommands(const byte* data, bool readbackRequested)
|
||||||
{
|
{
|
||||||
updateReadbackTexture =
|
updateReadbackTexture = readbackRequested;
|
||||||
R_FindRenderCommand(RC_SCREENSHOT) != NULL ||
|
|
||||||
R_FindRenderCommand(RC_VIDEOFRAME) != NULL;
|
|
||||||
|
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
|
@ -940,12 +938,6 @@ void GRP::ExecuteRenderCommands(const byte* data)
|
||||||
case RC_END_SCENE:
|
case RC_END_SCENE:
|
||||||
smaa.Draw(((const endSceneCommand_t*)data)->viewParms);
|
smaa.Draw(((const endSceneCommand_t*)data)->viewParms);
|
||||||
break;
|
break;
|
||||||
case RC_SCREENSHOT:
|
|
||||||
RB_TakeScreenshotCmd((const screenshotCommand_t*)data);
|
|
||||||
break;
|
|
||||||
case RC_VIDEOFRAME:
|
|
||||||
RB_TakeVideoFrameCmd((const videoFrameCommand_t*)data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Q_assert(!"Unsupported render command type");
|
Q_assert(!"Unsupported render command type");
|
||||||
|
|
|
@ -30,63 +30,42 @@ const int renderCommandSizes[RC_COUNT + 1] =
|
||||||
};
|
};
|
||||||
#undef RC
|
#undef RC
|
||||||
|
|
||||||
|
|
||||||
// we reserve space for frame ending commands as well as transition commands (begin/end 2D/3D rendering)
|
// 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 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()
|
void R_IssueRenderCommands()
|
||||||
{
|
{
|
||||||
renderCommandList_t* cmdList = &backEndData->commands;
|
|
||||||
|
|
||||||
// add an end-of-list command
|
// add an end-of-list command
|
||||||
|
renderCommandList_t* cmdList = &backEndData->commands;
|
||||||
((renderCommandBase_t*)(cmdList->cmds + cmdList->used))->commandId = RC_END_OF_LIST;
|
((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
|
// clear it out, in case this is a sync and not a buffer flip
|
||||||
cmdList->used = 0;
|
cmdList->used = 0;
|
||||||
|
|
||||||
renderPipeline->ExecuteRenderCommands( cmdList->cmds );
|
// process render commands
|
||||||
}
|
readbackCommands_t* const readback = &backEndData->readbackCommands;
|
||||||
|
renderPipeline->ExecuteRenderCommands( cmdList->cmds, R_IsReadbackRequested( readback ) );
|
||||||
|
|
||||||
|
// process readback commands
|
||||||
byte* R_FindRenderCommand( renderCommand_t type )
|
if ( readback->screenshot.requested ) {
|
||||||
{
|
RB_TakeScreenshotCmd( &readback->screenshot );
|
||||||
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];
|
|
||||||
}
|
}
|
||||||
}
|
if ( readback->videoFrame.requested ) {
|
||||||
|
RB_TakeVideoFrameCmd( &readback->videoFrame );
|
||||||
|
}
|
||||||
static void RemoveRenderCommand( byte* cmd, int cmdSize )
|
readback->screenshot.requested = qfalse;
|
||||||
{
|
readback->videoFrame.requested = qfalse;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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 )
|
void RE_BeginFrame( stereoFrame_t stereoFrame )
|
||||||
{
|
{
|
||||||
if (!tr.registered)
|
if ( !tr.registered )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tr.frameCount++;
|
tr.frameCount++;
|
||||||
|
@ -311,13 +290,11 @@ void RE_BeginFrame( stereoFrame_t stereoFrame )
|
||||||
// delayed screenshot
|
// delayed screenshot
|
||||||
if ( r_delayedScreenshotPending ) {
|
if ( r_delayedScreenshotPending ) {
|
||||||
r_delayedScreenshotFrame++;
|
r_delayedScreenshotFrame++;
|
||||||
if ( r_delayedScreenshotFrame >= 2 ) {
|
if ( r_delayedScreenshotFrame >= 1 ) {
|
||||||
screenshotCommand_t* const cmd = AllocateRenderCommand<screenshotCommand_t>( RC_SCREENSHOT );
|
backEndData->readbackCommands.screenshot = r_delayedScreenshot;
|
||||||
if ( cmd ) {
|
backEndData->readbackCommands.screenshot.requested = qtrue;
|
||||||
*cmd = r_delayedScreenshot;
|
r_delayedScreenshotPending = qfalse;
|
||||||
r_delayedScreenshotPending = qfalse;
|
r_delayedScreenshotFrame = 0;
|
||||||
r_delayedScreenshotFrame = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,26 +307,16 @@ void RE_BeginFrame( stereoFrame_t stereoFrame )
|
||||||
|
|
||||||
void RE_EndFrame( qbool render )
|
void RE_EndFrame( qbool render )
|
||||||
{
|
{
|
||||||
if (!tr.registered)
|
if ( !tr.registered )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
qbool delayScreenshot = qfalse;
|
|
||||||
if ( !render && r_delayedScreenshotPending )
|
if ( !render && r_delayedScreenshotPending )
|
||||||
render = qtrue;
|
render = qtrue;
|
||||||
|
|
||||||
if ( !render ) {
|
if ( !render ) {
|
||||||
screenshotCommand_t* ssCmd = (screenshotCommand_t*)R_FindRenderCommand( RC_SCREENSHOT );
|
readbackCommands_t* const readback = &backEndData->readbackCommands;
|
||||||
|
if ( R_IsReadbackRequested( readback ) )
|
||||||
if ( ssCmd )
|
|
||||||
render = qtrue;
|
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;
|
backEnd.renderFrame = render;
|
||||||
|
@ -359,10 +326,6 @@ void RE_EndFrame( qbool render )
|
||||||
|
|
||||||
if ( render ) {
|
if ( render ) {
|
||||||
AllocateRenderCommand<swapBuffersCommand_t>( RC_SWAP_BUFFERS, qtrue );
|
AllocateRenderCommand<swapBuffersCommand_t>( RC_SWAP_BUFFERS, qtrue );
|
||||||
if ( delayScreenshot ) {
|
|
||||||
screenshotCommand_t* const cmd = AllocateRenderCommand<screenshotCommand_t>( RC_SCREENSHOT, qtrue );
|
|
||||||
*cmd = r_delayedScreenshot;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
R_ClearFrame();
|
R_ClearFrame();
|
||||||
}
|
}
|
||||||
|
@ -385,9 +348,8 @@ void RE_TakeVideoFrame( int width, int height, byte *captureBuffer, byte *encode
|
||||||
End2D();
|
End2D();
|
||||||
End3D();
|
End3D();
|
||||||
|
|
||||||
videoFrameCommand_t* const cmd = AllocateRenderCommand<videoFrameCommand_t>( RC_VIDEOFRAME );
|
videoFrameCommand_t* const cmd = &backEndData->readbackCommands.videoFrame;
|
||||||
Q_assert( cmd );
|
cmd->requested = qtrue;
|
||||||
|
|
||||||
cmd->width = width;
|
cmd->width = width;
|
||||||
cmd->height = height;
|
cmd->height = height;
|
||||||
cmd->captureBuffer = captureBuffer;
|
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) {
|
switch (cmd->type) {
|
||||||
case screenshotCommand_t::SS_JPG:
|
case screenshotCommand_t::SS_JPG:
|
||||||
|
@ -202,8 +202,6 @@ const byte* RB_TakeScreenshotCmd( const screenshotCommand_t* cmd )
|
||||||
r_delayedScreenshotPending = qfalse;
|
r_delayedScreenshotPending = qfalse;
|
||||||
r_delayedScreenshotFrame = 0;
|
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;
|
cmd = &r_delayedScreenshot;
|
||||||
r_delayedScreenshotPending = qtrue;
|
r_delayedScreenshotPending = qtrue;
|
||||||
r_delayedScreenshotFrame = 0;
|
r_delayedScreenshotFrame = 0;
|
||||||
cmd->delayed = qtrue;
|
|
||||||
} else {
|
} else {
|
||||||
if ( R_FindRenderCommand( RC_SCREENSHOT ) )
|
cmd = &backEndData->readbackCommands.screenshot;
|
||||||
|
if ( cmd->requested )
|
||||||
return;
|
return;
|
||||||
cmd = (screenshotCommand_t*)R_AllocateRenderCommand( sizeof(screenshotCommand_t), RC_SCREENSHOT, qfalse );
|
|
||||||
if ( !cmd )
|
|
||||||
return;
|
|
||||||
cmd->delayed = qfalse;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ri.Cmd_Argc() == 2) {
|
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 );
|
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->width = glConfig.vidWidth;
|
||||||
cmd->height = glConfig.vidHeight;
|
cmd->height = glConfig.vidHeight;
|
||||||
cmd->fileName = s;
|
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 )
|
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;
|
const int frameSize = PAD( cmd->width, 4 ) * cmd->height * 3;
|
||||||
ri.CL_WriteAVIVideoFrame( cmd->captureBuffer, frameSize );
|
ri.CL_WriteAVIVideoFrame( cmd->captureBuffer, frameSize );
|
||||||
}
|
}
|
||||||
|
|
||||||
return (const byte *)(cmd + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1490,18 +1490,20 @@ struct endSceneCommand_t : renderCommandBase_t {
|
||||||
uint32_t padding2;
|
uint32_t padding2;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct screenshotCommand_t : renderCommandBase_t {
|
struct readbackCommandBase_t {
|
||||||
|
qbool requested;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct screenshotCommand_t : readbackCommandBase_t {
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
const char* fileName;
|
const char* fileName;
|
||||||
enum ss_type { SS_TGA, SS_JPG } type;
|
enum ss_type { SS_TGA, SS_JPG } type;
|
||||||
float conVis; // if > 0, this is a delayed screenshot and we need to
|
float conVis; // if > 0, this is a delayed screenshot and we need to
|
||||||
// restore the console visibility to that value
|
// restore the console visibility to that value
|
||||||
qbool delayed;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct videoFrameCommand_t : renderCommandBase_t {
|
struct videoFrameCommand_t : readbackCommandBase_t {
|
||||||
int commandId;
|
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
byte *captureBuffer;
|
byte *captureBuffer;
|
||||||
|
@ -1509,6 +1511,11 @@ struct videoFrameCommand_t : renderCommandBase_t {
|
||||||
qbool motionJpeg;
|
qbool motionJpeg;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct readbackCommands_t {
|
||||||
|
screenshotCommand_t screenshot;
|
||||||
|
videoFrameCommand_t videoFrame;
|
||||||
|
};
|
||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
#define RENDER_COMMAND_LIST(Cmd) \
|
#define RENDER_COMMAND_LIST(Cmd) \
|
||||||
|
@ -1523,9 +1530,7 @@ struct videoFrameCommand_t : renderCommandBase_t {
|
||||||
Cmd(RC_DRAW_SCENE_VIEW, drawSceneViewCommand_t) \
|
Cmd(RC_DRAW_SCENE_VIEW, drawSceneViewCommand_t) \
|
||||||
Cmd(RC_END_SCENE, endSceneCommand_t) \
|
Cmd(RC_END_SCENE, endSceneCommand_t) \
|
||||||
Cmd(RC_BEGIN_FRAME, beginFrameCommand_t) \
|
Cmd(RC_BEGIN_FRAME, beginFrameCommand_t) \
|
||||||
Cmd(RC_SWAP_BUFFERS, swapBuffersCommand_t) \
|
Cmd(RC_SWAP_BUFFERS, swapBuffersCommand_t)
|
||||||
Cmd(RC_SCREENSHOT, screenshotCommand_t) \
|
|
||||||
Cmd(RC_VIDEOFRAME, videoFrameCommand_t)
|
|
||||||
|
|
||||||
#define RC(Enum, Type) Enum,
|
#define RC(Enum, Type) Enum,
|
||||||
enum renderCommand_t {
|
enum renderCommand_t {
|
||||||
|
@ -1550,6 +1555,7 @@ typedef struct {
|
||||||
srfPoly_t *polys;
|
srfPoly_t *polys;
|
||||||
polyVert_t *polyVerts;
|
polyVert_t *polyVerts;
|
||||||
renderCommandList_t commands;
|
renderCommandList_t commands;
|
||||||
|
readbackCommands_t readbackCommands;
|
||||||
} backEndData_t;
|
} backEndData_t;
|
||||||
|
|
||||||
#define SKY_SUBDIVISIONS 8
|
#define SKY_SUBDIVISIONS 8
|
||||||
|
@ -1566,8 +1572,8 @@ extern int max_polyverts;
|
||||||
|
|
||||||
extern backEndData_t* backEndData;
|
extern backEndData_t* backEndData;
|
||||||
|
|
||||||
const byte* RB_TakeScreenshotCmd( const screenshotCommand_t* cmd );
|
void RB_TakeScreenshotCmd( const screenshotCommand_t* cmd );
|
||||||
const byte* RB_TakeVideoFrameCmd( const videoFrameCommand_t* cmd );
|
void RB_TakeVideoFrameCmd( const videoFrameCommand_t* cmd );
|
||||||
|
|
||||||
void RB_PushSingleStageShader( int stateBits, cullType_t cullType );
|
void RB_PushSingleStageShader( int stateBits, cullType_t cullType );
|
||||||
void RB_PopShader();
|
void RB_PopShader();
|
||||||
|
@ -1578,7 +1584,6 @@ void RB_DrawSky();
|
||||||
void R_BuildCloudData();
|
void R_BuildCloudData();
|
||||||
|
|
||||||
void R_IssueRenderCommands();
|
void R_IssueRenderCommands();
|
||||||
byte* R_FindRenderCommand( renderCommand_t type );
|
|
||||||
byte* R_AllocateRenderCommand( int bytes, int commandId, qbool endFrame );
|
byte* R_AllocateRenderCommand( int bytes, int commandId, qbool endFrame );
|
||||||
|
|
||||||
void R_AddDrawSurfCmd( drawSurf_t* drawSurfs, int numDrawSurfs, int numTranspSurfs );
|
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 BeginTextureUpload(RHI::MappedTexture& mappedTexture, image_t* image) = 0;
|
||||||
virtual void EndTextureUpload() = 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 UISetColor(const uiSetColorCommand_t& cmd) = 0;
|
||||||
virtual void UIDrawQuad(const uiDrawQuadCommand_t& cmd) = 0;
|
virtual void UIDrawQuad(const uiDrawQuadCommand_t& cmd) = 0;
|
||||||
|
|
Loading…
Reference in a new issue