deleted 2-threads rendering support (SMP)

This commit is contained in:
myT 2017-11-03 19:34:32 +01:00
parent 4cd544217c
commit 9362d9bf53
9 changed files with 31 additions and 361 deletions

View file

@ -169,11 +169,11 @@ void Sys_GL_Init()
// @TODO: make a cvar defaulting to an empty string for this? e.g. value: "libGL.so.1"
if (SDL_GL_LoadLibrary(NULL) < 0)
ri.Error(ERR_FATAL, "GLimp_Init - SDL_GL_LoadLibrary failed: %s\n", SDL_GetError());
ri.Error(ERR_FATAL, "Sys_GL_Init - SDL_GL_LoadLibrary failed: %s\n", SDL_GetError());
glimp.window = SDL_CreateWindow("CNQ3", deskropRect.x, deskropRect.y, glConfig.vidWidth, glConfig.vidHeight, windowFlags);
if (glimp.window == NULL)
ri.Error(ERR_FATAL, "GLimp_Init - SDL_CreateWindow failed: %s\n", SDL_GetError());
ri.Error(ERR_FATAL, "Sys_GL_Init - SDL_CreateWindow failed: %s\n", SDL_GetError());
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
@ -187,16 +187,16 @@ void Sys_GL_Init()
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
glimp.glContext = SDL_GL_CreateContext(glimp.window);
if (glimp.glContext == NULL)
ri.Error(ERR_FATAL, "GLimp_Init - SDL_GL_CreateContext failed: %s\n", SDL_GetError());
ri.Error(ERR_FATAL, "Sys_GL_Init - SDL_GL_CreateContext failed: %s\n", SDL_GetError());
glConfig.colorBits = 32;
glConfig.depthBits = 24;
glConfig.stencilBits = 8;
if (SDL_GL_MakeCurrent(glimp.window, glimp.glContext) < 0)
ri.Error(ERR_FATAL, "GLimp_Init - SDL_GL_MakeCurrent failed: %s\n", SDL_GetError());
ri.Error(ERR_FATAL, "Sys_GL_Init - SDL_GL_MakeCurrent failed: %s\n", SDL_GetError());
if (!Lin_LoadGL())
ri.Error(ERR_FATAL, "GLimp_Init - failed to initialize core OpenGL\n");
ri.Error(ERR_FATAL, "Sys_GL_Init - failed to initialize core OpenGL\n");
}
@ -226,25 +226,3 @@ void Sys_GL_EndFrame()
SDL_GL_SwapWindow(glimp.window);
}
qbool GLimp_SpawnRenderThread( void (*function)() )
{
return qfalse;
}
void* GLimp_RendererSleep()
{
return NULL;
}
void GLimp_FrontEnderSleep()
{
}
void GLimp_WakeRenderer( void* data )
{
}

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;
@ -1045,23 +1045,12 @@ static const void* RB_SwapBuffers( const void* data )
====================
RB_ExecuteRenderCommands
This function will be called synchronously if running without
smp extensions, or asynchronously by another thread.
This function will always be called synchronously.
====================
*/
void RB_ExecuteRenderCommands( const void *data )
{
int ms = ri.Milliseconds();
#ifdef USE_R_SMP
if ( !r_smp->integer || data == backEndData[0]->commands.cmds ) {
backEnd.smpFrame = 0;
} else {
backEnd.smpFrame = 1;
}
#else
backEnd.smpFrame = 0;
#endif
while ( 1 ) {
data = PADP(data, sizeof(void *));
@ -1099,30 +1088,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

@ -21,42 +21,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "tr_local.h"
volatile qbool renderThreadActive;
void R_InitCommandBuffers()
{
glInfo.smpActive = qfalse;
#ifdef USE_R_SMP
if ( !r_smp->integer )
return;
ri.Printf( PRINT_ALL, "Trying SMP acceleration...\n" );
if ( GLimp_SpawnRenderThread( RB_RenderThread ) ) {
ri.Printf( PRINT_ALL, "...succeeded.\n" );
glInfo.smpActive = qtrue;
} else {
ri.Printf( PRINT_ALL, "...failed.\n" );
}
#endif
}
void R_ShutdownCommandBuffers()
{
// kill the rendering thread
#ifdef USE_R_SMP
if ( glInfo.smpActive ) {
GLimp_WakeRenderer( NULL );
}
#endif
glInfo.smpActive = qfalse;
}
static void R_IssueRenderCommands()
{
renderCommandList_t* cmdList = &backEndData[tr.smpFrame]->commands;
renderCommandList_t* cmdList = &backEndData->commands;
// add an end-of-list command
*(int *)(cmdList->cmds + cmdList->used) = RC_END_OF_LIST;
@ -64,38 +32,7 @@ static void R_IssueRenderCommands()
// clear it out, in case this is a sync and not a buffer flip
cmdList->used = 0;
#ifdef USE_R_SMP
if ( glInfo.smpActive ) {
static int c_blockedOnRender, c_blockedOnMain;
// 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();
}
// actually start the commands going
if ( !r_skipBackEnd->integer ) {
// let it start on the new batch
if ( !glInfo.smpActive ) {
RB_ExecuteRenderCommands( cmdList->cmds );
} else {
GLimp_WakeRenderer( cmdList );
}
}
#else
RB_ExecuteRenderCommands( cmdList->cmds );
#endif
}
@ -114,13 +51,6 @@ void R_SyncRenderThread( void ) {
return;
}
R_IssueRenderCommands();
#ifdef USE_R_SMP
if ( !glInfo.smpActive ) {
return;
}
GLimp_FrontEndSleep();
#endif
}
/*
@ -134,7 +64,7 @@ render thread if needed.
void *R_GetCommandBuffer( int bytes ) {
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
@ -288,9 +218,7 @@ void RE_EndFrame( int* pcFE, int* pc2D, int* pc3D )
R_IssueRenderCommands();
// use the other buffers next frame, because another CPU
// may still be rendering into the current ones
R_ToggleSmpFrame();
R_ClearFrame();
if (pcFE)
Com_Memcpy( pcFE, &tr.pc, sizeof( tr.pc ) );

View file

@ -37,12 +37,6 @@ cvar_t *r_displayRefresh;
cvar_t *r_detailTextures;
#ifdef USE_R_SMP
cvar_t *r_smp;
cvar_t *r_showSmp;
cvar_t *r_skipBackEnd;
#endif
cvar_t *r_intensity;
cvar_t *r_gamma;
cvar_t *r_greyscale;
@ -241,9 +235,6 @@ static void InitOpenGL()
r_swapInterval->modified = qtrue;
}
// init command buffers and SMP
R_InitCommandBuffers();
GfxInfo_f();
GL_SetDefaultState();
@ -459,11 +450,6 @@ void GfxInfo_f( void )
}
ri.Printf( PRINT_DEVELOPER, "CPU: %s\n", sys_cpustring->string );
#ifdef USE_R_SMP
if ( glInfo.smpActive ) {
ri.Printf( PRINT_ALL, "Using dual processor acceleration\n" );
}
#endif
}
@ -502,11 +488,6 @@ static const cvarTableItem_t r_cvars[] =
{ &r_vertexLight, "r_vertexLight", "0", CVAR_ARCHIVE | CVAR_LATCH, CVART_BOOL, NULL, NULL, "disables lightmap texture blending" },
// note that r_subdivisions > 64 will create rendering artefacts because you'll see the other side of a curved surface when against it
{ &r_subdivisions, "r_subdivisions", "1", CVAR_ARCHIVE | CVAR_LATCH, CVART_FLOAT, "1", "64", help_r_subdivisions },
#ifdef USE_R_SMP
{ &r_smp, "r_smp", "0", CVAR_ARCHIVE | CVAR_LATCH },
{ &r_showSmp, "r_showSmp", "0", CVAR_CHEAT },
{ &r_skipBackEnd, "r_skipBackEnd", "0", CVAR_CHEAT },
#endif
//
// latched variables that can only change over a restart
@ -617,23 +598,12 @@ void R_Init()
max_polys = max( r_maxpolys->integer, DEFAULT_MAX_POLYS );
max_polyverts = max( r_maxpolyverts->integer, DEFAULT_MAX_POLYVERTS );
byte* ptr = (byte*)ri.Hunk_Alloc( sizeof( *backEndData[0] ) + sizeof(srfPoly_t) * max_polys + sizeof(polyVert_t) * max_polyverts, h_low );
backEndData[0] = (backEndData_t*)ptr;
backEndData[0]->polys = (srfPoly_t *) (ptr + sizeof( *backEndData[0] ));
backEndData[0]->polyVerts = (polyVert_t *) (ptr + sizeof( *backEndData[0] ) + sizeof(srfPoly_t) * max_polys);
byte* ptr = (byte*)ri.Hunk_Alloc( sizeof(backEndData_t) + sizeof(srfPoly_t) * max_polys + sizeof(polyVert_t) * max_polyverts, h_low );
backEndData = (backEndData_t*)ptr;
backEndData->polys = (srfPoly_t*)(ptr + sizeof(backEndData_t));
backEndData->polyVerts = (polyVert_t*)(ptr + sizeof(backEndData_t) + sizeof(srfPoly_t) * max_polys);
backEndData[1] = NULL;
#ifdef USE_R_SMP
if (r_smp->integer) {
ptr = (byte*)ri.Hunk_Alloc( sizeof( *backEndData[1] ) + sizeof(srfPoly_t) * max_polys + sizeof(polyVert_t) * max_polyverts, h_low );
backEndData[1] = (backEndData_t*)ptr;
backEndData[1]->polys = (srfPoly_t *) (ptr + sizeof( *backEndData[1] ));
backEndData[1]->polyVerts = (polyVert_t *) (ptr + sizeof( *backEndData[1] ) + sizeof(srfPoly_t) * max_polys);
}
#endif
R_ToggleSmpFrame();
R_ClearFrame();
InitOpenGL();
@ -662,7 +632,6 @@ static void RE_Shutdown( qbool destroyWindow )
if ( tr.registered ) {
ri.Cmd_UnregisterModule();
R_SyncRenderThread();
R_ShutdownCommandBuffers();
R_DeleteTextures();
}

View file

@ -54,12 +54,6 @@ typedef struct {
//endif
// everything that is needed by the backend needs
// to be double buffered to allow it to run in
// parallel on a dual cpu machine
#define SMP_FRAMES 2
// a trRefEntity_t has all the information passed in by the cgame
// as well as some locally derived info
@ -812,7 +806,6 @@ typedef struct {
// all state modified by the back end is separated from the front end state
typedef struct {
int smpFrame;
trRefdef_t refdef;
viewParms_t viewParms;
orientationr_t orient;
@ -851,8 +844,6 @@ typedef struct {
int viewCount; // incremented every view (twice a scene if portaled) and every R_MarkFragments call
int lightCount; // incremented for each dlight in the view
int smpFrame; // toggles from 0 to 1 every EndFrame
int frameSceneNum; // zeroed at RE_BeginFrame
qbool worldMapLoaded;
@ -989,12 +980,6 @@ extern cvar_t *r_portalOnly;
extern cvar_t *r_subdivisions;
extern cvar_t *r_lodCurveError;
#ifdef USE_R_SMP
extern cvar_t *r_smp;
extern cvar_t *r_showSmp;
extern cvar_t *r_skipBackEnd;
#endif
extern cvar_t *r_ignoreGLErrors;
extern cvar_t *r_overBrightBits;
@ -1158,12 +1143,6 @@ void Sys_GL_Shutdown();
// Swaps buffers and applies r_swapInterval.
void Sys_GL_EndFrame();
// SMP
qbool GLimp_SpawnRenderThread( void (*function)( void ) );
void* GLimp_RendererSleep( void );
void GLimp_FrontEndSleep( void );
void GLimp_WakeRenderer( void *data );
/*
====================================================================
@ -1313,7 +1292,8 @@ SCENE GENERATION
============================================================
*/
void R_ToggleSmpFrame();
// clears counters and back-end commands
void R_ClearFrame();
void RE_ClearScene();
void RE_AddRefEntityToScene( const refEntity_t *ent, qbool intShaderTime );
@ -1364,7 +1344,6 @@ RENDERER BACK END FUNCTIONS
=============================================================
*/
void RB_RenderThread( void );
void RB_ExecuteRenderCommands( const void *data );
/*
@ -1461,10 +1440,8 @@ typedef enum {
#define MAX_DLIGHTS 32 // completely arbitrary now :D
#define MAX_REFENTITIES 1023 // can't be increased without changing drawsurf bit packing
// all of the information needed by the back end must be
// contained in a backEndData_t. This entire structure is
// duplicated so the front and back end can run in parallel
// on an SMP machine
// all of the information needed by the back-end must be
// contained in a backEndData_t instance
typedef struct {
drawSurf_t drawSurfs[MAX_DRAWSURFS];
litSurf_t litSurfs[MAX_DRAWSURFS];
@ -1478,17 +1455,12 @@ typedef struct {
extern int max_polys;
extern int max_polyverts;
extern backEndData_t *backEndData[SMP_FRAMES]; // the second one may not be allocated
extern volatile qbool renderThreadActive;
extern backEndData_t *backEndData;
void *R_GetCommandBuffer( int bytes );
void RB_ExecuteRenderCommands( const void *data );
void R_InitCommandBuffers();
void R_ShutdownCommandBuffers();
void R_SyncRenderThread( void );
void R_AddDrawSurfCmd( drawSurf_t* drawSurfs, int numDrawSurfs );
@ -1516,9 +1488,6 @@ struct glinfo_t {
qbool isFullscreen;
int displayFrequency;
// used by platform layer and renderer
qbool smpActive;
// used by renderer
GLint maxTextureSize;
GLint maxDrawElementsI;

View file

@ -710,12 +710,6 @@ static qbool SurfIsOffscreen( const drawSurf_t* drawSurf )
int i;
unsigned int pointAnd = (unsigned int)~0;
#ifdef USE_R_SMP
if ( glInfo.smpActive ) { // FIXME! we can't do RB_BeginSurface/RB_EndSurface stuff with smp!
return qfalse;
}
#endif
R_RotateForViewer();
R_DecomposeSort( drawSurf->sort, &entityNum, &shader, &fogNum );

View file

@ -38,21 +38,9 @@ static int r_firstScenePoly;
static int r_numpolyverts;
void R_ToggleSmpFrame()
void R_ClearFrame()
{
#ifdef USE_R_SMP
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
#endif
{
tr.smpFrame = 0;
}
backEndData[tr.smpFrame]->commands.used = 0;
backEndData->commands.used = 0;
r_firstSceneDrawSurf = 0;
r_firstSceneLitSurf = 0;
@ -124,11 +112,11 @@ void RE_AddPolyToScene( qhandle_t hShader, int numVerts, const polyVert_t* verts
}
for ( j = 0; j < numPolys; j++ ) {
srfPoly_t* poly = &backEndData[tr.smpFrame]->polys[r_numpolys];
srfPoly_t* 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];
Com_Memcpy( poly->verts, &verts[numVerts*j], numVerts * sizeof( *verts ) );
@ -177,7 +165,7 @@ void RE_AddRefEntityToScene( const refEntity_t* ent, qbool intShaderTime )
ri.Error( ERR_DROP, "RE_AddRefEntityToScene: bad reType %i", ent->reType );
}
trRefEntity_t* const trEnt = &backEndData[tr.smpFrame]->entities[r_numentities];
trRefEntity_t* const trEnt = &backEndData->entities[r_numentities];
trEnt->e = *ent;
trEnt->lightingCalculated = qfalse;
trEnt->intShaderTime = intShaderTime;
@ -197,7 +185,7 @@ void RE_AddLightToScene( const vec3_t org, float radius, float r, float g, float
return;
}
dlight_t* dl = &backEndData[tr.smpFrame]->dlights[r_numdlights++];
dlight_t* dl = &backEndData->dlights[r_numdlights++];
VectorCopy( org, dl->origin );
dl->radius = radius;
dl->color[0] = r;
@ -263,19 +251,19 @@ void RE_RenderScene( const refdef_t* fd )
tr.refdef.floatTime = (double)tr.refdef.time / 1000.0;
tr.refdef.numDrawSurfs = r_firstSceneDrawSurf;
tr.refdef.drawSurfs = backEndData[tr.smpFrame]->drawSurfs;
tr.refdef.drawSurfs = backEndData->drawSurfs;
tr.refdef.numLitSurfs = r_firstSceneLitSurf;
tr.refdef.litSurfs = backEndData[tr.smpFrame]->litSurfs;
tr.refdef.litSurfs = backEndData->litSurfs;
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_dlights = r_numdlights - r_firstSceneDlight;
tr.refdef.dlights = &backEndData[tr.smpFrame]->dlights[r_firstSceneDlight];
tr.refdef.dlights = &backEndData->dlights[r_firstSceneDlight];
tr.refdef.numPolys = r_numpolys - r_firstScenePoly;
tr.refdef.polys = &backEndData[tr.smpFrame]->polys[r_firstScenePoly];
tr.refdef.polys = &backEndData->polys[r_firstScenePoly];
// turn off dynamic lighting globally by clearing all the dlights if it needs to be disabled
if (!r_dynamiclight->integer) {

View file

@ -2150,15 +2150,6 @@ shader_t* R_FindShader( const char *name, int lightmapIndex, qbool mipRawImage )
}
}
// no, uploading is done by, duh, UPLOAD, so let that worry about it
#ifdef USE_R_SMP
// make sure the render thread is stopped, because we are probably
// going to have to upload an image
if (r_smp->integer) {
R_SyncRenderThread();
}
#endif
// clear the global shader
Com_Memset( &shader, 0, sizeof( shader ) );
Com_Memset( &stages, 0, sizeof( stages ) );
@ -2266,14 +2257,6 @@ qhandle_t RE_RegisterShaderFromImage( const char* name, const image_t* image )
}
}
// make sure the render thread is stopped, because we are probably
// going to have to upload an image
#ifdef USE_R_SMP
if (r_smp->integer) {
R_SyncRenderThread();
}
#endif
// clear the global shader
Com_Memset( &shader, 0, sizeof( shader ) );
Com_Memset( &stages, 0, sizeof( stages ) );

View file

@ -633,9 +633,6 @@ void Sys_GL_EndFrame()
}
///////////////////////////////////////////////////////////////
void Sys_GL_Init()
{
ri.Printf( PRINT_DEVELOPER, "Initializing OpenGL subsystem\n" );
@ -709,104 +706,6 @@ void Sys_GL_Shutdown()
}
/*
===========================================================
SMP acceleration
===========================================================
*/
static HANDLE renderCommandsEvent;
static HANDLE renderCompletedEvent;
static HANDLE renderActiveEvent;
static void (*glimpRenderThread)( void );
static void GLimp_RenderThreadWrapper()
{
glimpRenderThread();
// unbind the context before we die
qwglMakeCurrent( glw_state.hDC, NULL );
}
qbool GLimp_SpawnRenderThread( void (*function)( void ) )
{
renderCommandsEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
renderCompletedEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
renderActiveEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
glimpRenderThread = function;
DWORD renderThreadId;
HANDLE renderThreadHandle = CreateThread(
NULL, // LPSECURITY_ATTRIBUTES lpsa,
0, // DWORD cbStack,
(LPTHREAD_START_ROUTINE)GLimp_RenderThreadWrapper, // LPTHREAD_START_ROUTINE lpStartAddr,
0, // LPVOID lpvThreadParm,
0, // DWORD fdwCreate,
&renderThreadId );
return (renderThreadHandle != NULL);
}
static void *smpData;
static int wglErrors;
void *GLimp_RendererSleep( void ) {
void *data;
if ( !qwglMakeCurrent( glw_state.hDC, NULL ) ) {
wglErrors++;
}
ResetEvent( renderActiveEvent );
// after this, the front end can exit GLimp_FrontEndSleep
SetEvent( renderCompletedEvent );
WaitForSingleObject( renderCommandsEvent, INFINITE );
if ( !qwglMakeCurrent( glw_state.hDC, glw_state.hGLRC ) ) {
wglErrors++;
}
ResetEvent( renderCompletedEvent );
ResetEvent( renderCommandsEvent );
data = smpData;
// after this, the main thread can exit GLimp_WakeRenderer
SetEvent( renderActiveEvent );
return data;
}
void GLimp_FrontEndSleep( void ) {
WaitForSingleObject( renderCompletedEvent, INFINITE );
if ( !qwglMakeCurrent( glw_state.hDC, glw_state.hGLRC ) ) {
wglErrors++;
}
}
void GLimp_WakeRenderer( void *data ) {
smpData = data;
if ( !qwglMakeCurrent( glw_state.hDC, NULL ) ) {
wglErrors++;
}
// after this, the renderer can continue through GLimp_RendererSleep
SetEvent( renderCommandsEvent );
WaitForSingleObject( renderActiveEvent, INFINITE );
}
void WIN_UpdateResolution( int width, int height )
{
glConfig.vidWidth = width;