Remove SMP and render thread code, as they're unused

This commit is contained in:
smallmodel 2024-12-01 16:26:26 +01:00
parent d884512a76
commit 7e6b0a1c2b
No known key found for this signature in database
GPG key ID: 9F2D623CEDF08512
16 changed files with 441 additions and 283 deletions

View file

@ -317,7 +317,7 @@ functions exported to the main executable
refEntity_t *(*R_GetRenderEntity)(int entityNumber);
void (*R_ModelBounds)(clipHandle_t model, vec3_t mins, vec3_t maxs);
float (*R_ModelRadius)(clipHandle_t model);
float (*R_Noise)(float x, float y, float z, float t);
float (*R_Noise)(float x, float y, float z, double t);
void (*R_DebugLine)(const vec3_t start, const vec3_t end, float r, float g, float b, float alpha);
baseshader_t *(*GetShader)(int shaderNum);
// =========== Swipes =============

View file

@ -65,6 +65,16 @@ typedef struct image_s {
imgFlags_t flags;
struct image_s* next;
int bytesUsed;
int numMipmaps;
qboolean dynamicallyUpdated;
qboolean allowPicmip;
qboolean force32bit;
int wrapClampModeX;
int wrapClampModeY;
int r_sequence;
int UseCount;
} image_t;
// any change in the LIGHTMAP_* defines here MUST be reflected in
@ -124,8 +134,22 @@ qboolean R_GetModeInfo( int *width, int *height, float *windowAspect, int mode )
float R_NoiseGet4f( float x, float y, float z, double t );
void R_NoiseInit( void );
image_t *R_FindImageFile( const char *name, imgType_t type, imgFlags_t flags );
image_t *R_CreateImage( const char *name, byte *pic, int width, int height, imgType_t type, imgFlags_t flags, int internalFormat );
image_t *R_FindImageFile(const char* name, qboolean mipmap, qboolean allowPicmip, qboolean force32bit, int glWrapClampModeX, int glWrapClampModeY);
image_t *R_RefreshImageFile(const char* name, qboolean mipmap, qboolean allowPicmip, qboolean force32bit, int glWrapClampModeX, int glWrapClampModeY);
image_t* R_CreateImage(
const char* name,
byte* pic,
int width,
int height,
int numMipmaps,
int iMipmapsAvailable,
qboolean allowPicmip,
qboolean force32bit,
qboolean hasAlpha,
int glCompressMode,
int glWrapClampModeX,
int glWrapClampModeY
);
void R_IssuePendingRenderCommands( void );
qhandle_t RE_RegisterShaderLightMap( const char *name, int lightmapIndex );

View file

@ -160,7 +160,7 @@ typedef struct {
void (*SwipePoint)(vec3_t point1, vec3_t point2, float time);
void (*SwipeEnd)();
void (*SetRenderTime)(int t);
float (*Noise)(float x, float y, float z, float t);
float (*Noise)(float x, float y, float z, double t);
qboolean (*SetMode)(int mode, const glconfig_t* glConfig);
void (*SetFullscreen)(qboolean fullScreen);
int (*GetShaderWidth)(qhandle_t hShader);

View file

@ -21,7 +21,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "tr_local.h"
backEndData_t *backEndData[SMP_FRAMES];
backEndData_t *backEndData;
backEndState_t backEnd;
@ -1012,7 +1012,7 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, int componen
if ( !tr.registered ) {
return;
}
R_SyncRenderThread();
R_IssuePendingRenderCommands();
// we definately want to sync every frame for the cinematics
qglFinish();
@ -1325,6 +1325,43 @@ void RB_ShowImages( qboolean quiet ) {
}
}
/*
=============
RB_ColorMask
=============
*/
const void *RB_ColorMask(const void *data)
{
const colorMaskCommand_t *cmd = data;
qglColorMask(cmd->rgba[0], cmd->rgba[1], cmd->rgba[2], cmd->rgba[3]);
return (const void *)(cmd + 1);
}
/*
=============
RB_ClearDepth
=============
*/
const void *RB_ClearDepth(const void *data)
{
const clearDepthCommand_t *cmd = data;
if(tess.numIndexes)
RB_EndSurface();
// texture swapping test
if (r_showImages->integer)
RB_ShowImages(qtrue);
qglClear(GL_DEPTH_BUFFER_BIT);
return (const void *)(cmd + 1);
}
/*
=============
@ -1392,13 +1429,9 @@ void RB_ExecuteRenderCommands( const void *data ) {
t1 = ri.Milliseconds ();
if ( !r_smp->integer || data == backEndData[0]->commands.cmds ) {
backEnd.smpFrame = 0;
} else {
backEnd.smpFrame = 1;
}
while ( 1 ) {
data = PADP(data, sizeof(void *));
switch ( *(const int *)data ) {
case RC_SET_COLOR:
data = RB_SetColor( data );
@ -1421,10 +1454,18 @@ void RB_ExecuteRenderCommands( const void *data ) {
case RC_SCREENSHOT:
data = RB_TakeScreenshotCmd( data );
break;
case RC_VIDEOFRAME:
data = RB_TakeVideoFrameCmd( data );
break;
case RC_COLORMASK:
data = RB_ColorMask(data);
break;
case RC_CLEARDEPTH:
data = RB_ClearDepth(data);
break;
case RC_END_OF_LIST:
default:
// stop rendering on this thread
// stop rendering
t2 = ri.Milliseconds ();
backEnd.pc.msec = t2 - t1;
return;
@ -1432,30 +1473,3 @@ void RB_ExecuteRenderCommands( const void *data ) {
}
}
/*
================
RB_RenderThread
================
*/
void RB_RenderThread( void ) {
const void *data;
// wait for either a rendering command or a quit command
while ( 1 ) {
// sleep until we have work to do
data = GLimp_RendererSleep();
if ( !data ) {
return; // all done, renderer is shutting down
}
renderThreadActive = qtrue;
RB_ExecuteRenderCommands( data );
renderThreadActive = qfalse;
}
}

View file

@ -206,7 +206,7 @@ static void R_LoadLightmaps(gamelump_t* l) {
buf = l->buffer;
// we are about to upload textures
R_SyncRenderThread();
R_IssuePendingRenderCommands();
// create all the lightmaps
tr.numLightmaps = len / (LIGHTMAP_SIZE * LIGHTMAP_SIZE * 3);

View file

@ -15,16 +15,12 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Foobar; if not, write to the Free Software
along with Quake III Arena source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "tr_local.h"
volatile renderCommandList_t *renderCommandList;
volatile qboolean renderThreadActive;
static backEndCounters_t pc_save;
/*
@ -95,76 +91,22 @@ void R_PerformanceCounters( void ) {
}
/*
====================
R_InitCommandBuffers
====================
*/
void R_InitCommandBuffers( void ) {
glConfig.smpActive = qfalse;
if ( r_smp->integer ) {
ri.Printf( PRINT_ALL, "Trying SMP acceleration...\n" );
if ( GLimp_SpawnRenderThread( RB_RenderThread ) ) {
ri.Printf( PRINT_ALL, "...succeeded.\n" );
glConfig.smpActive = qtrue;
} else {
ri.Printf( PRINT_ALL, "...failed.\n" );
}
}
}
/*
====================
R_ShutdownCommandBuffers
====================
*/
void R_ShutdownCommandBuffers( void ) {
// kill the rendering thread
if ( glConfig.smpActive ) {
GLimp_WakeRenderer( NULL );
glConfig.smpActive = qfalse;
}
}
/*
====================
R_IssueRenderCommands
====================
*/
int c_blockedOnRender;
int c_blockedOnMain;
void R_IssueRenderCommands( qboolean runPerformanceCounters ) {
renderCommandList_t *cmdList;
cmdList = &backEndData[tr.smpFrame]->commands;
assert(cmdList); // bk001205
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 ( 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();
}
@ -172,53 +114,41 @@ void R_IssueRenderCommands( qboolean runPerformanceCounters ) {
// 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 );
}
RB_ExecuteRenderCommands( cmdList->cmds );
}
}
/*
====================
R_SyncRenderThread
R_IssuePendingRenderCommands
Issue any pending commands and wait for them to complete.
After exiting, the render thread will have completed its work
and will remain idle and the main thread is free to issue
OpenGL calls until R_IssueRenderCommands is called.
====================
*/
void R_SyncRenderThread( void ) {
void R_IssuePendingRenderCommands( void ) {
if ( !tr.registered ) {
return;
}
R_IssueRenderCommands( qfalse );
if ( !glConfig.smpActive ) {
return;
}
GLimp_FrontEndSleep();
}
/*
============
R_GetCommandBuffer
R_GetCommandBufferReserved
make sure there is enough command space, waiting on the
render thread if needed.
make sure there is enough command space
============
*/
void *R_GetCommandBuffer( int bytes ) {
void *R_GetCommandBufferReserved( int bytes, int reservedBytes ) {
renderCommandList_t *cmdList;
cmdList = &backEndData[tr.smpFrame]->commands;
cmdList = &backEndData->commands;
bytes = PAD(bytes, sizeof(void *));
// always leave room for the end of list command
if ( cmdList->used + bytes + 4 > MAX_RENDER_COMMANDS ) {
if ( bytes > MAX_RENDER_COMMANDS - 4 ) {
if ( cmdList->used + bytes + sizeof( int ) + reservedBytes > MAX_RENDER_COMMANDS ) {
if ( bytes > MAX_RENDER_COMMANDS - sizeof( int ) ) {
ri.Error( ERR_FATAL, "R_GetCommandBuffer: bad size %i", bytes );
}
// if we run out of room, just start dropping commands
@ -230,6 +160,17 @@ void *R_GetCommandBuffer( int bytes ) {
return cmdList->cmds + cmdList->used - bytes;
}
/*
=============
R_GetCommandBuffer
returns NULL if there is not enough space for important commands
=============
*/
void *R_GetCommandBuffer( int bytes ) {
return R_GetCommandBufferReserved( bytes, PAD( sizeof( swapBuffersCommand_t ), sizeof(void *) ) );
}
/*
=============
@ -336,6 +277,49 @@ void RE_StretchPic ( float x, float y, float w, float h,
cmd->t2 = t2;
}
#define MODE_RED_CYAN 1
#define MODE_RED_BLUE 2
#define MODE_RED_GREEN 3
#define MODE_GREEN_MAGENTA 4
#define MODE_MAX MODE_GREEN_MAGENTA
void R_SetColorMode(GLboolean *rgba, stereoFrame_t stereoFrame, int colormode)
{
rgba[0] = rgba[1] = rgba[2] = rgba[3] = GL_TRUE;
if(colormode > MODE_MAX)
{
if(stereoFrame == STEREO_LEFT)
stereoFrame = STEREO_RIGHT;
else if(stereoFrame == STEREO_RIGHT)
stereoFrame = STEREO_LEFT;
colormode -= MODE_MAX;
}
if(colormode == MODE_GREEN_MAGENTA)
{
if(stereoFrame == STEREO_LEFT)
rgba[0] = rgba[2] = GL_FALSE;
else if(stereoFrame == STEREO_RIGHT)
rgba[1] = GL_FALSE;
}
else
{
if(stereoFrame == STEREO_LEFT)
rgba[1] = rgba[2] = GL_FALSE;
else if(stereoFrame == STEREO_RIGHT)
{
rgba[0] = GL_FALSE;
if(colormode == MODE_RED_BLUE)
rgba[1] = GL_FALSE;
else if(colormode == MODE_RED_GREEN)
rgba[2] = GL_FALSE;
}
}
}
/*
====================
@ -346,7 +330,8 @@ for each RE_EndFrame
====================
*/
void RE_BeginFrame( stereoFrame_t stereoFrame ) {
drawBufferCommand_t *cmd;
drawBufferCommand_t *cmd = NULL;
colorMaskCommand_t *colcmd = NULL;
if ( !tr.registered ) {
return;
@ -376,7 +361,7 @@ void RE_BeginFrame( stereoFrame_t stereoFrame ) {
}
else
{
R_SyncRenderThread();
R_IssuePendingRenderCommands();
qglEnable( GL_STENCIL_TEST );
qglStencilMask( ~0U );
qglClearStencil( 0U );
@ -389,7 +374,7 @@ void RE_BeginFrame( stereoFrame_t stereoFrame ) {
{
// this is only reached if it was on and is now off
if ( r_measureOverdraw->modified ) {
R_SyncRenderThread();
R_IssuePendingRenderCommands();
qglDisable( GL_STENCIL_TEST );
}
r_measureOverdraw->modified = qfalse;
@ -399,7 +384,7 @@ void RE_BeginFrame( stereoFrame_t stereoFrame ) {
// texturemode stuff
//
if ( r_textureMode->modified ) {
R_SyncRenderThread();
R_IssuePendingRenderCommands();
GL_TextureMode( r_textureMode->string );
r_textureMode->modified = qfalse;
}
@ -410,30 +395,26 @@ void RE_BeginFrame( stereoFrame_t stereoFrame ) {
if ( r_gamma->modified ) {
r_gamma->modified = qfalse;
R_SyncRenderThread();
R_IssuePendingRenderCommands();
R_SetColorMappings();
}
// check for errors
if ( !r_ignoreGLErrors->integer ) {
int err;
// check for errors
if ( !r_ignoreGLErrors->integer )
{
int err;
R_SyncRenderThread();
if ( ( err = qglGetError() ) != GL_NO_ERROR ) {
ri.Error( ERR_FATAL, "RE_BeginFrame() - glGetError() failed (0x%x)!\n", err );
}
}
//
// draw buffer stuff
//
cmd = R_GetCommandBuffer( sizeof( *cmd ) );
if ( !cmd ) {
return;
R_IssuePendingRenderCommands();
if ((err = qglGetError()) != GL_NO_ERROR)
ri.Error(ERR_FATAL, "RE_BeginFrame() - glGetError() failed (0x%x)!", err);
}
cmd->commandId = RC_DRAW_BUFFER;
if ( glConfig.stereoEnabled ) {
if (glConfig.stereoEnabled) {
if( !(cmd = R_GetCommandBuffer(sizeof(*cmd))) )
return;
cmd->commandId = RC_DRAW_BUFFER;
if ( stereoFrame == STEREO_LEFT ) {
cmd->buffer = (int)GL_BACK_LEFT;
} else if ( stereoFrame == STEREO_RIGHT ) {
@ -441,16 +422,78 @@ void RE_BeginFrame( stereoFrame_t stereoFrame ) {
} else {
ri.Error( ERR_FATAL, "RE_BeginFrame: Stereo is enabled, but stereoFrame was %i", stereoFrame );
}
} else {
if ( stereoFrame != STEREO_CENTER ) {
ri.Error( ERR_FATAL, "RE_BeginFrame: Stereo is disabled, but stereoFrame was %i", stereoFrame );
}
else
{
if(r_anaglyphMode->integer)
{
if(r_anaglyphMode->modified)
{
// clear both, front and backbuffer.
qglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
qglClearColor(0.0f, 0.0f, 0.0f, 1.0f);
qglDrawBuffer(GL_FRONT);
qglClear(GL_COLOR_BUFFER_BIT);
qglDrawBuffer(GL_BACK);
qglClear(GL_COLOR_BUFFER_BIT);
r_anaglyphMode->modified = qfalse;
}
if(stereoFrame == STEREO_LEFT)
{
if( !(cmd = R_GetCommandBuffer(sizeof(*cmd))) )
return;
if( !(colcmd = R_GetCommandBuffer(sizeof(*colcmd))) )
return;
}
else if(stereoFrame == STEREO_RIGHT)
{
clearDepthCommand_t *cldcmd;
if( !(cldcmd = R_GetCommandBuffer(sizeof(*cldcmd))) )
return;
cldcmd->commandId = RC_CLEARDEPTH;
if( !(colcmd = R_GetCommandBuffer(sizeof(*colcmd))) )
return;
}
else
ri.Error( ERR_FATAL, "RE_BeginFrame: Stereo is enabled, but stereoFrame was %i", stereoFrame );
R_SetColorMode(colcmd->rgba, stereoFrame, r_anaglyphMode->integer);
colcmd->commandId = RC_COLORMASK;
}
if ( !Q_stricmp( r_drawBuffer->string, "GL_FRONT" ) ) {
cmd->buffer = (int)GL_FRONT;
} else {
cmd->buffer = (int)GL_BACK;
else
{
if(stereoFrame != STEREO_CENTER)
ri.Error( ERR_FATAL, "RE_BeginFrame: Stereo is disabled, but stereoFrame was %i", stereoFrame );
if( !(cmd = R_GetCommandBuffer(sizeof(*cmd))) )
return;
}
if(cmd)
{
cmd->commandId = RC_DRAW_BUFFER;
if(r_anaglyphMode->modified)
{
qglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
r_anaglyphMode->modified = qfalse;
}
if (!Q_stricmp(r_drawBuffer->string, "GL_FRONT"))
cmd->buffer = (int)GL_FRONT;
else
cmd->buffer = (int)GL_BACK;
}
}
tr.refdef.stereoFrame = stereoFrame;
}
@ -467,7 +510,7 @@ void RE_EndFrame( int *frontEndMsec, int *backEndMsec ) {
if ( !tr.registered ) {
return;
}
cmd = R_GetCommandBuffer( sizeof( *cmd ) );
cmd = R_GetCommandBufferReserved( sizeof( *cmd ), 0 );
if ( !cmd ) {
return;
}
@ -475,9 +518,7 @@ void RE_EndFrame( int *frontEndMsec, int *backEndMsec ) {
R_IssueRenderCommands( qtrue );
// use the other buffers next frame, because another CPU
// may still be rendering into the current ones
R_ToggleSmpFrame();
R_InitNextFrame();
if ( frontEndMsec ) {
*frontEndMsec = tr.frontEndMsec;
@ -489,3 +530,30 @@ void RE_EndFrame( int *frontEndMsec, int *backEndMsec ) {
backEnd.pc.msec = 0;
}
/*
=============
RE_TakeVideoFrame
=============
*/
void RE_TakeVideoFrame( int width, int height,
byte *captureBuffer, byte *encodeBuffer, qboolean motionJpeg )
{
videoFrameCommand_t *cmd;
if( !tr.registered ) {
return;
}
cmd = R_GetCommandBuffer( sizeof( *cmd ) );
if( !cmd ) {
return;
}
cmd->commandId = RC_VIDEOFRAME;
cmd->width = width;
cmd->height = height;
cmd->captureBuffer = captureBuffer;
cmd->encodeBuffer = encodeBuffer;
cmd->motionJpeg = motionJpeg;
}

View file

@ -55,7 +55,7 @@ void Draw_StretchPic(float x, float y, float w, float h, float s1, float t1, flo
#if 1
shader_t* shader;
R_SyncRenderThread();
R_IssuePendingRenderCommands();
if (hShader) {
shader = R_GetShaderByHandle(hShader);
@ -102,7 +102,7 @@ void Draw_StretchPic2(float x, float y, float w, float h, float s1, float t1, fl
float scaledWidth1, scaledHeight1;
float scaledWidth2, scaledHeight2;
R_SyncRenderThread();
R_IssuePendingRenderCommands();
if (hShader) {
shader = R_GetShaderByHandle(hShader);
@ -152,7 +152,7 @@ void Draw_TilePic(float x, float y, float w, float h, qhandle_t hShader) {
shader_t* shader;
float picw, pich;
R_SyncRenderThread();
R_IssuePendingRenderCommands();
if (hShader) {
shader = R_GetShaderByHandle(hShader);
@ -198,7 +198,7 @@ void Draw_TilePicOffset(float x, float y, float w, float h, qhandle_t hShader, i
shader_t* shader;
float picw, pich;
R_SyncRenderThread();
R_IssuePendingRenderCommands();
if (hShader) {
shader = R_GetShaderByHandle(hShader);
@ -244,7 +244,7 @@ void Draw_TrianglePic(const vec2_t vPoints[3], const vec2_t vTexCoords[3], qhand
int i;
shader_t* shader;
R_SyncRenderThread();
R_IssuePendingRenderCommands();
if (hShader) {
shader = R_GetShaderByHandle(hShader);
@ -278,7 +278,7 @@ void RE_DrawBackground_TexSubImage(int cols, int rows, int bgr, byte* data) {
w = glConfig.vidWidth;
h = glConfig.vidHeight;
R_SyncRenderThread();
R_IssuePendingRenderCommands();
qglFinish();
if (bgr) {
@ -331,7 +331,7 @@ RE_DrawBackground_DrawPixels
================
*/
void RE_DrawBackground_DrawPixels(int cols, int rows, int bgr, byte* data) {
R_SyncRenderThread();
R_IssuePendingRenderCommands();
GL_State(0);
qglDisable(GL_TEXTURE_2D);
@ -355,7 +355,7 @@ AddBox
================
*/
void AddBox(float x, float y, float w, float h) {
R_SyncRenderThread();
R_IssuePendingRenderCommands();
qglColor4ubv(backEnd.color2D);
qglDisable(GL_TEXTURE_2D);
@ -379,7 +379,7 @@ DrawBox
================
*/
void DrawBox(float x, float y, float w, float h) {
R_SyncRenderThread();
R_IssuePendingRenderCommands();
qglColor4ubv(backEnd.color2D);
qglDisable(GL_TEXTURE_2D);
@ -405,7 +405,7 @@ DrawLineLoop
void DrawLineLoop(const vec2_t* points, int count, int stipple_factor, int stipple_mask) {
int i;
R_SyncRenderThread();
R_IssuePendingRenderCommands();
qglDisable(GL_TEXTURE_2D);
@ -435,7 +435,7 @@ Set2DWindow
================
*/
void Set2DWindow(int x, int y, int w, int h, float left, float right, float bottom, float top, float n, float f) {
R_SyncRenderThread();
R_IssuePendingRenderCommands();
qglViewport(x, y, w, h);
qglScissor(x, y, w, h);
qglMatrixMode(GL_PROJECTION);

View file

@ -552,7 +552,7 @@ void R_DrawString_sgl(fontheader_sgl_t* font, const char* text, float x, float y
return;
}
R_SyncRenderThread();
R_IssuePendingRenderCommands();
if (font->trhandle != r_sequencenumber) {
font->shader = NULL;
@ -771,7 +771,7 @@ void R_DrawFloatingString_sgl(fontheader_sgl_t* font, const char* text, const ve
return;
}
R_SyncRenderThread();
R_IssuePendingRenderCommands();
if (font->trhandle != r_sequencenumber) {
font->shader = NULL;
}

View file

@ -3173,7 +3173,7 @@ qhandle_t RE_RegisterSkin( const char *name ) {
skin->numSurfaces = 0;
// make sure the render thread is stopped
R_SyncRenderThread();
R_IssuePendingRenderCommands();
// If not a .skin file, load as a single shader
if ( strcmp( name + strlen( name ) - 5, ".skin" ) ) {

View file

@ -45,8 +45,6 @@ cvar_t *r_displayRefresh;
cvar_t *r_znear;
cvar_t *r_smp;
cvar_t *r_showSmp;
cvar_t *r_skipBackEnd;
cvar_t *r_ignorehwgamma;
@ -265,7 +263,9 @@ cvar_t* r_ext_multisample;
cvar_t* r_noborder;
cvar_t* r_ext_texture_filter_anisotropic;
cvar_t* r_stereoEnabled;
cvar_t* r_anaglyphMode;
cvar_t* r_aviMotionJpegQuality;
cvar_t* r_screenshotJpegQuality;
static char infostring[8192];
@ -342,9 +342,6 @@ static void InitOpenGL( void )
}
}
// init command buffers and SMP
R_InitCommandBuffers();
// print info
GfxInfo_f();
@ -972,6 +969,85 @@ void R_ScreenShotJPEG_f (void) {
//============================================================================
/*
==================
RB_TakeVideoFrameCmd
==================
*/
const void *RB_TakeVideoFrameCmd( const void *data )
{
const videoFrameCommand_t *cmd;
byte *cBuf;
size_t memcount, linelen;
int padwidth, avipadwidth, padlen, avipadlen;
GLint packAlign;
cmd = (const videoFrameCommand_t *)data;
qglGetIntegerv(GL_PACK_ALIGNMENT, &packAlign);
linelen = cmd->width * 3;
// Alignment stuff for glReadPixels
padwidth = PAD(linelen, packAlign);
padlen = padwidth - linelen;
// AVI line padding
avipadwidth = PAD(linelen, AVI_LINE_PADDING);
avipadlen = avipadwidth - linelen;
cBuf = PADP(cmd->captureBuffer, packAlign);
qglReadPixels(0, 0, cmd->width, cmd->height, GL_RGB,
GL_UNSIGNED_BYTE, cBuf);
memcount = padwidth * cmd->height;
// gamma correct
if(glConfig.deviceSupportsGamma)
R_GammaCorrect(cBuf, memcount);
if(cmd->motionJpeg)
{
memcount = RE_SaveJPGToBuffer(cmd->encodeBuffer, linelen * cmd->height,
r_aviMotionJpegQuality->integer,
cmd->width, cmd->height, cBuf, padlen);
ri.CL_WriteAVIVideoFrame(cmd->encodeBuffer, memcount);
}
else
{
byte *lineend, *memend;
byte *srcptr, *destptr;
srcptr = cBuf;
destptr = cmd->encodeBuffer;
memend = srcptr + memcount;
// swap R and B and remove line paddings
while(srcptr < memend)
{
lineend = srcptr + linelen;
while(srcptr < lineend)
{
*destptr++ = srcptr[2];
*destptr++ = srcptr[1];
*destptr++ = srcptr[0];
srcptr += 3;
}
Com_Memset(destptr, '\0', avipadlen);
destptr += avipadlen;
srcptr += padlen;
}
ri.CL_WriteAVIVideoFrame(cmd->encodeBuffer, avipadwidth * cmd->height);
}
return (const void *)(cmd + 1);
}
//============================================================================
/*
** GL_SetDefaultState
*/
@ -1303,12 +1379,6 @@ void R_Register( void )
r_customheight = ri.Cvar_Get( "r_customheight", "1024", CVAR_ARCHIVE | CVAR_LATCH );
r_customaspect = ri.Cvar_Get( "r_customaspect", "1", CVAR_ARCHIVE | CVAR_LATCH );
r_vertexLight = ri.Cvar_Get("r_vertexLight", "0", CVAR_ARCHIVE | CVAR_LATCH);
#if (defined(MACOS_X) || defined(__linux__)) && defined(SMP)
// Default to using SMP on Mac OS X or Linux if we have multiple processors
r_smp = ri.Cvar_Get( "r_smp", Sys_ProcessorCount() > 1 ? "1" : "0", CVAR_ARCHIVE | CVAR_LATCH);
#else
r_smp = ri.Cvar_Get( "r_smp", "0", CVAR_ARCHIVE | CVAR_LATCH);
#endif
r_ignoreFastPath = ri.Cvar_Get("r_ignoreFastPath", "0", CVAR_ARCHIVE | CVAR_LATCH);
r_subdivisions = ri.Cvar_Get("r_subdivisions", "4", CVAR_ARCHIVE | CVAR_LATCH);
@ -1347,6 +1417,8 @@ void R_Register( void )
r_ambientScale = ri.Cvar_Get( "r_ambientScale", "0.6", CVAR_CHEAT );
r_directedScale = ri.Cvar_Get( "r_directedScale", "1", CVAR_CHEAT );
r_anaglyphMode = ri.Cvar_Get("r_anaglyphMode", "0", CVAR_ARCHIVE);
//
// temporary variables that can change at any time
//
@ -1395,7 +1467,6 @@ void R_Register( void )
r_flareSize = ri.Cvar_Get ("r_flareSize", "40", CVAR_CHEAT);
r_flareFade = ri.Cvar_Get ("r_flareFade", "7", CVAR_CHEAT);
r_showSmp = ri.Cvar_Get ("r_showSmp", "0", CVAR_CHEAT);
r_skipBackEnd = ri.Cvar_Get ("r_skipBackEnd", "0", CVAR_CHEAT);
r_measureOverdraw = ri.Cvar_Get( "r_measureOverdraw", "0", CVAR_CHEAT );
@ -1516,6 +1587,7 @@ void R_Register( void )
//
r_showSkeleton = ri.Cvar_Get("r_showSkeleton", "0", CVAR_CHEAT);
r_aviMotionJpegQuality = ri.Cvar_Get("r_aviMotionJpegQuality", "90", CVAR_ARCHIVE);
r_screenshotJpegQuality = ri.Cvar_Get("r_screenshotJpegQuality", "90", CVAR_ARCHIVE);
ri.Cmd_AddCommand( "ter_crater", R_TerrainCrater_f );
@ -1616,26 +1688,14 @@ void R_Init( void ) {
if (max_termarks < MAX_TERMARKS)
max_termarks = MAX_TERMARKS;
ptr = ri.Malloc(sizeof(*backEndData[0]) + sizeof(srfPoly_t) * max_polys + sizeof(polyVert_t) * max_polyverts + sizeof(srfMarkFragment_t) * max_termarks);
backEndData[0] = (backEndData_t*)ptr;
backEndData[0]->polys = (srfPoly_t*)((char*)ptr + sizeof(*backEndData[0]));
backEndData[0]->polyVerts = (polyVert_t*)((char*)ptr + sizeof(*backEndData[0]) + sizeof(srfPoly_t) * max_polys);
backEndData[0]->terMarks = (srfMarkFragment_t*)((char*)ptr + sizeof(*backEndData[0]) + sizeof(srfPoly_t) * max_polys + sizeof(polyVert_t) * max_polyverts);
backEndData[0]->staticModels = NULL;
backEndData[0]->staticModelData = NULL;
if (r_smp->integer) {
ptr = ri.Malloc(sizeof(*backEndData[1]) + sizeof(srfPoly_t) * max_polys + sizeof(polyVert_t) * max_polyverts);
backEndData[1] = (backEndData_t*)ptr;
backEndData[1]->polys = (srfPoly_t*)((char*)ptr + sizeof(*backEndData[1]));
backEndData[1]->polyVerts = (polyVert_t*)((char*)ptr + sizeof(*backEndData[1]) + sizeof(srfPoly_t) * max_polys);
backEndData[1]->terMarks = (srfMarkFragment_t*)((char*)ptr + sizeof(*backEndData[1]) + sizeof(srfPoly_t) * max_polys + sizeof(polyVert_t) * max_polyverts);
backEndData[1]->staticModels = NULL;
backEndData[1]->staticModelData = NULL;
}
else {
backEndData[1] = NULL;
}
R_ToggleSmpFrame();
ptr = ri.Malloc(sizeof(*backEndData) + sizeof(srfPoly_t) * max_polys + sizeof(polyVert_t) * max_polyverts + sizeof(srfMarkFragment_t) * max_termarks);
backEndData = (backEndData_t*)ptr;
backEndData->polys = (srfPoly_t*)((char*)ptr + sizeof(*backEndData));
backEndData->polyVerts = (polyVert_t*)((char*)ptr + sizeof(*backEndData) + sizeof(srfPoly_t) * max_polys);
backEndData->terMarks = (srfMarkFragment_t*)((char*)ptr + sizeof(*backEndData) + sizeof(srfPoly_t) * max_polys + sizeof(polyVert_t) * max_polyverts);
backEndData->staticModels = NULL;
backEndData->staticModelData = NULL;
R_InitNextFrame();
InitOpenGL();
@ -1680,8 +1740,7 @@ void RE_Shutdown( qboolean destroyWindow ) {
if ( tr.registered ) {
R_SyncRenderThread();
R_ShutdownCommandBuffers();
R_IssuePendingRenderCommands();
R_DeleteTextures();
}
@ -1711,7 +1770,7 @@ void RE_BeginRegistration(glconfig_t* glconfigOut) {
UI_LoadResource("*123");
scr_initialized = 0;
R_SyncRenderThread();
R_IssuePendingRenderCommands();
R_LevelMarksFree();
ri.Hunk_Clear();
@ -1747,7 +1806,7 @@ Touch all images to make sure they are resident
=============
*/
void RE_EndRegistration( void ) {
R_SyncRenderThread();
R_IssuePendingRenderCommands();
if (r_precacheimages->integer) {
int start, end;

View file

@ -27,6 +27,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "../qcommon/qcommon.h"
#include "tr_public.h"
#include "../renderercommon/qgl.h"
#include "../renderercommon/tr_common.h"
#include "qgl.h"
#ifdef __cplusplus
@ -217,6 +218,7 @@ typedef struct {
float modelMatrix[16];
} orientationr_t;
/*
typedef struct image_s {
char imgName[MAX_QPATH]; // game path, including extension
int width, height; // source image
@ -240,6 +242,7 @@ typedef struct image_s {
struct image_s* next;
} image_t;
*/
//===============================================================================
@ -633,6 +636,8 @@ typedef struct {
vec3_t vieworg;
vec3_t viewaxis[3]; // transformation matrix
stereoFrame_t stereoFrame;
int time; // time in milliseconds for shader effects and other time dependent rendering issues
int rdflags; // RDF_NOWORLDMODEL, etc
@ -1540,10 +1545,10 @@ extern cvar_t *r_portalOnly;
extern cvar_t *r_subdivisions;
extern cvar_t *r_lodCurveError;
extern cvar_t *r_smp;
extern cvar_t *r_showSmp;
extern cvar_t *r_skipBackEnd;
extern cvar_t *r_anaglyphMode;
extern cvar_t *r_ignoreGLErrors;
extern cvar_t *r_overBrightBits;
@ -1641,11 +1646,8 @@ extern cvar_t* r_showSkeleton;
//====================================================================
float R_NoiseGet4f( float x, float y, float z, float t );
void R_NoiseInit( void );
void R_SwapBuffers( int );
void R_DebugCircle(const vec3_t org, float radius, float r, float g, float b, float alpha, qboolean horizontal);
void R_DebugLine(const vec3_t start, const vec3_t end, float r, float g, float b, float alpha);
void R_RenderView( viewParms_t *parms );
@ -1775,23 +1777,7 @@ qboolean R_GetEntityToken( char *buffer, int size );
model_t *R_AllocModel( void );
void R_Init( void );
image_t *R_FindImageFile(const char* name, qboolean mipmap, qboolean allowPicmip, qboolean force32bit, int glWrapClampModeX, int glWrapClampModeY);
image_t *R_RefreshImageFile(const char* name, qboolean mipmap, qboolean allowPicmip, qboolean force32bit, int glWrapClampModeX, int glWrapClampModeY);
image_t* R_CreateImage(
const char* name,
byte* pic,
int width,
int height,
int numMipmaps,
int iMipmapsAvailable,
qboolean allowPicmip,
qboolean force32bit,
qboolean hasAlpha,
int glCompressMode,
int glWrapClampModeX,
int glWrapClampModeY
);
qboolean R_GetModeInfo( int *width, int *height, float *windowAspect, int mode );
void R_SetColorMappings( void );
@ -1810,6 +1796,7 @@ void R_FreeUnusedImages( void );
int R_SumOfUsedImages( void );
skin_t *R_GetSkinByHandle( qhandle_t hSkin );
const void *RB_TakeVideoFrameCmd( const void *data );
//
// tr_shader.c
@ -2052,7 +2039,7 @@ SCENE GENERATION
============================================================
*/
void R_ToggleSmpFrame( void );
void R_InitNextFrame( void );
void RE_ClearScene( void );
void RE_AddRefEntityToScene( const refEntity_t *ent, int parentEntityNumber);
@ -2389,6 +2376,27 @@ typedef struct {
qboolean jpeg;
} screenshotCommand_t;
typedef struct {
int commandId;
int width;
int height;
byte *captureBuffer;
byte *encodeBuffer;
qboolean motionJpeg;
} videoFrameCommand_t;
typedef struct
{
int commandId;
GLboolean rgba[4];
} colorMaskCommand_t;
typedef struct
{
int commandId;
} clearDepthCommand_t;
typedef enum {
RC_END_OF_LIST,
RC_SET_COLOR,
@ -2397,7 +2405,10 @@ typedef enum {
RC_SPRITE_SURFS,
RC_DRAW_BUFFER,
RC_SWAP_BUFFERS,
RC_SCREENSHOT
RC_SCREENSHOT,
RC_VIDEOFRAME,
RC_COLORMASK,
RC_CLEARDEPTH
} renderCommand_t;
@ -2430,7 +2441,7 @@ extern int max_polys;
extern int max_polyverts;
extern int max_termarks;
extern backEndData_t *backEndData[SMP_FRAMES]; // the second one may not be allocated
extern backEndData_t *backEndData; // the second one may not be allocated
extern volatile renderCommandList_t *renderCommandList;

View file

@ -1678,7 +1678,7 @@ void R_DebugGraphics( void ) {
}
// the render thread can't make callbacks to the main thread
R_SyncRenderThread();
R_IssuePendingRenderCommands();
GL_Bind( tr.whiteImage);
GL_Cull( CT_FRONT_SIDED );
@ -1804,7 +1804,7 @@ void R_DrawDebugLines(void) {
return;
}
R_SyncRenderThread();
R_IssuePendingRenderCommands();
GL_Bind(tr.whiteImage);
if (r_debuglines_depthmask->integer) {
GL_State(GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE);

View file

@ -203,7 +203,7 @@ static qhandle_t R_RegisterModelInternal( const char *name, qboolean bBeginTiki,
// make sure the render thread is stopped
R_SyncRenderThread();
R_IssuePendingRenderCommands();
mod->serveronly = qtrue;
@ -1607,13 +1607,13 @@ void RB_StaticMesh(staticSurface_t *staticSurf)
tess.texCoords[baseVertex + j][1][1] = surf->pStaticTexCoords[j][1][1];
}
if (backEndData[backEnd.smpFrame]->staticModelData) {
if (backEndData->staticModelData) {
const size_t offset =
backEnd.currentStaticModel->firstVertexData + staticSurf->ofsStaticData * sizeof(color4ub_t);
assert(offset < tr.world->numStaticModelData * sizeof(color4ub_t));
assert(offset + render_count * sizeof(color4ub_t) <= tr.world->numStaticModelData * sizeof(color4ub_t));
const color4ub_t *in = (const color4ub_t *)&backEndData[backEnd.smpFrame]->staticModelData[offset];
const color4ub_t *in = (const color4ub_t *)&backEndData->staticModelData[offset];
for (i = 0; i < render_count; i++) {
tess.vertexColors[baseVertex + i][0] = in[i][0];
@ -1789,7 +1789,7 @@ void R_DebugSkeleton(void) {
return;
}
R_SyncRenderThread();
R_IssuePendingRenderCommands();
GL_Bind( tr.whiteImage );
GL_State( GLS_POLYMODE_LINE );

View file

@ -51,16 +51,8 @@ R_ToggleSmpFrame
====================
*/
void R_ToggleSmpFrame( void ) {
if ( r_smp->integer ) {
// use the other buffers next frame, because another CPU
// may still be rendering into the current ones
tr.smpFrame ^= 1;
} else {
tr.smpFrame = 0;
}
backEndData[tr.smpFrame]->commands.used = 0;
void R_InitNextFrame( void ) {
backEndData->commands.used = 0;
r_firstSceneDrawSurf = 0;
r_firstSceneSpriteSurf = 0;
@ -145,11 +137,11 @@ qboolean RE_AddPolyToScene(qhandle_t hShader, int numVerts, const polyVert_t* ve
return qfalse;
}
poly = &backEndData[tr.smpFrame]->polys[r_numpolys];
poly = &backEndData->polys[r_numpolys];
poly->surfaceType = SF_POLY;
poly->hShader = hShader;
poly->numVerts = numVerts;
poly->verts = &backEndData[tr.smpFrame]->polyVerts[r_numpolyverts];
poly->verts = &backEndData->polyVerts[r_numpolyverts];
poly->renderfx = renderfx;
Com_Memcpy(poly->verts, verts, sizeof(polyVert_t) * numVerts);
@ -196,11 +188,11 @@ void RE_AddTerrainMarkToScene(int iTerrainIndex, qhandle_t hShader, int numVerts
return;
}
terMark = &backEndData[tr.smpFrame]->terMarks[r_numtermarks];
terMark = &backEndData->terMarks[r_numtermarks];
terMark->surfaceType = hShader;
terMark->iIndex = iTerrainIndex;
terMark->numVerts = numVerts;
terMark->verts = &backEndData[tr.smpFrame]->polyVerts[r_numpolyverts];
terMark->verts = &backEndData->polyVerts[r_numpolyverts];
memcpy(terMark->verts, verts, sizeof(polyVert_t) * numVerts);
r_numtermarks++;
@ -218,8 +210,8 @@ refEntity_t* RE_GetRenderEntity(int entityNumber) {
int i;
for (i = 0; i < r_numentities; i++) {
if (backEndData[0]->entities[i].e.entityNumber == entityNumber) {
return &backEndData[0]->entities[i].e;
if (backEndData->entities[i].e.entityNumber == entityNumber) {
return &backEndData->entities[i].e;
}
}
@ -244,9 +236,9 @@ void RE_AddRefEntityToScene( const refEntity_t *ent, int parentEntityNumber) {
ri.Error( ERR_DROP, "RE_AddRefEntityToScene: bad reType %i", ent->reType );
}
backEndData[tr.smpFrame]->entities[r_numentities].e = *ent;
backEndData[tr.smpFrame]->entities[r_numentities].bLightGridCalculated = qfalse;
backEndData[tr.smpFrame]->entities[r_numentities].sphereCalculated = qfalse;
backEndData->entities[r_numentities].e = *ent;
backEndData->entities[r_numentities].bLightGridCalculated = qfalse;
backEndData->entities[r_numentities].sphereCalculated = qfalse;
if (parentEntityNumber != ENTITYNUM_NONE)
{
@ -257,20 +249,20 @@ void RE_AddRefEntityToScene( const refEntity_t *ent, int parentEntityNumber) {
//
for (i = r_firstSceneEntity; i < r_numentities; i++)
{
if (backEndData[tr.smpFrame]->entities[i].e.entityNumber == parentEntityNumber)
if (backEndData->entities[i].e.entityNumber == parentEntityNumber)
{
backEndData[tr.smpFrame]->entities[r_numentities].e.parentEntity = i - r_firstSceneEntity;
backEndData->entities[r_numentities].e.parentEntity = i - r_firstSceneEntity;
break;
}
}
if (i == r_numentities) {
backEndData[tr.smpFrame]->entities[i].e.parentEntity = ENTITYNUM_NONE;
backEndData->entities[i].e.parentEntity = ENTITYNUM_NONE;
}
}
else
{
backEndData[tr.smpFrame]->entities[r_numentities].e.parentEntity = ENTITYNUM_NONE;
backEndData->entities[r_numentities].e.parentEntity = ENTITYNUM_NONE;
}
r_numentities++;
@ -288,7 +280,7 @@ void RE_AddRefSpriteToScene(const refEntity_t* ent) {
return;
}
spr = &backEndData[tr.smpFrame]->sprites[r_numsprites];
spr = &backEndData->sprites[r_numsprites];
VectorCopy(ent->origin, spr->origin);
spr->surftype = SF_SPRITE;
spr->hModel = ent->hModel;
@ -322,7 +314,7 @@ void RE_AddDynamicLightToScene( const vec3_t org, float intensity, float r, floa
if ( intensity <= 0 ) {
return;
}
dl = &backEndData[tr.smpFrame]->dlights[r_numdlights++];
dl = &backEndData->dlights[r_numdlights++];
VectorCopy (org, dl->origin);
dl->radius = intensity;
dl->color[0] = r;
@ -523,27 +515,27 @@ void RE_RenderScene( const refdef_t *fd ) {
tr.refdef.floatTime = tr.refdef.time * 0.001f;
tr.refdef.numDrawSurfs = r_firstSceneDrawSurf;
tr.refdef.drawSurfs = backEndData[tr.smpFrame]->drawSurfs;
tr.refdef.drawSurfs = backEndData->drawSurfs;
tr.refdef.numSpriteSurfs = r_firstSceneSpriteSurf;
tr.refdef.spriteSurfs = backEndData[tr.smpFrame]->spriteSurfs;
tr.refdef.spriteSurfs = backEndData->spriteSurfs;
tr.refdef.num_entities = r_numentities - r_firstSceneEntity;
tr.refdef.entities = &backEndData[tr.smpFrame]->entities[r_firstSceneEntity];
tr.refdef.entities = &backEndData->entities[r_firstSceneEntity];
tr.refdef.num_sprites = r_numsprites - r_firstSceneSprite;
tr.refdef.sprites = &backEndData[tr.smpFrame]->sprites[r_firstSceneSprite];
tr.refdef.sprites = &backEndData->sprites[r_firstSceneSprite];
tr.refdef.num_dlights = r_numdlights - r_firstSceneDlight;
tr.refdef.dlights = &backEndData[tr.smpFrame]->dlights[r_firstSceneDlight];
tr.refdef.dlights = &backEndData->dlights[r_firstSceneDlight];
tr.refdef.numTerMarks = r_numtermarks - r_firstSceneTerMark;
tr.refdef.terMarks = &backEndData[tr.smpFrame]->terMarks[r_firstSceneTerMark];
tr.refdef.terMarks = &backEndData->terMarks[r_firstSceneTerMark];
tr.refdef.numPolys = r_numpolys - r_firstScenePoly;
tr.refdef.polys = &backEndData[tr.smpFrame]->polys[r_firstScenePoly];
tr.refdef.polys = &backEndData->polys[r_firstScenePoly];
backEndData[tr.smpFrame]->staticModelData = tr.refdef.staticModelData;
backEndData->staticModelData = tr.refdef.staticModelData;
// turn off dynamic lighting globally by clearing all the
// dlights if it needs to be disabled or if vertex lighting is enabled

View file

@ -2800,7 +2800,7 @@ sortedIndex.
==============
*/
static void FixRenderCommandList( int newShader ) {
renderCommandList_t *cmdList = &backEndData[tr.smpFrame]->commands;
renderCommandList_t *cmdList = &backEndData->commands;
if( cmdList ) {
const void *curCmd = cmdList->cmds;
@ -3310,12 +3310,6 @@ shader_t* R_FindShader(const char* name, int lightmapIndex, qboolean mipRawImage
currentShader = AddShaderTextToHash(strippedName, hash);
}
// make sure the render thread is stopped, because we are probably
// going to have to upload an image
if (r_smp->integer) {
R_SyncRenderThread();
}
// clear the global shader
Com_Memset( &shader, 0, sizeof( shader ) );
Com_Memset(&unfoggedStages, 0, sizeof(unfoggedStages));

View file

@ -681,7 +681,7 @@ static void R_PreTessellateTerrain()
return;
}
R_SyncRenderThread();
R_IssuePendingRenderCommands();
if (ter_maxtris->integer < 4 * numTerrainPatches) {
Cvar_SetValue("ter_maxtris", 4 * numTerrainPatches);
@ -1167,10 +1167,6 @@ R_TessellateTerrain
*/
void R_TessellateTerrain()
{
if (glConfig.smpActive) {
R_SyncRenderThread();
}
R_DoTriSplitting();
// Morph geometry according to the view
R_DoGeomorphs();