Permalink
Browse files

autodetect renderer

The renderer may return qfalse in BeginRegistration to indicate that
it cannot run, cl_renderers is a comma separated list of renderers to
try until one returns qtrue.
  • Loading branch information...
1 parent 9c519e2 commit c6c4bf43307dc209a29a12206e110812ea5a5572 @gimhael gimhael committed Mar 4, 2012
@@ -183,6 +183,9 @@ struct rsa_private_key private_key;
cvar_t *cl_gamename;
cvar_t *cl_altTab;
+static cvar_t *cl_renderer = NULL;
+static void *rendererLib = NULL;
+
// XreaL BEGIN
cvar_t *cl_aviMotionJpeg;
// XreaL END
@@ -2468,9 +2471,6 @@ void CL_Vid_Restart_f(void)
CL_InitOpenGLExt();
#endif
- // initialize the renderer interface
- CL_InitRef();
-
// startup all the client stuff
CL_StartHunkUsers();
@@ -4131,11 +4131,14 @@ void QDECL CL_RefPrintf(int print_level, const char *fmt, ...)
CL_InitRenderer
============
*/
-void CL_InitRenderer(void)
+qboolean CL_InitRenderer(void)
{
fileHandle_t f;
// this sets up the renderer and calls R_Init
- re.BeginRegistration(&cls.glconfig, &cls.glconfig2);
+ if( !re.BeginRegistration(&cls.glconfig, &cls.glconfig2) ) {
+
+ return qfalse;
+ }
// load character sets
cls.charSetShader = re.RegisterShader("gfx/2d/bigchars");
@@ -4166,6 +4169,8 @@ void CL_InitRenderer(void)
, cls.glconfig.renderer_string
, cls.glconfig.version_string );
#endif
+
+ return qtrue;
}
/*
@@ -4188,10 +4193,28 @@ void CL_StartHunkUsers(void)
return;
}
- if(!cls.rendererStarted)
- {
- cls.rendererStarted = qtrue;
- CL_InitRenderer();
+ if( rendererLib == NULL ) {
+ // initialize the renderer interface
+ char renderers[MAX_QPATH];
+ char *from, *to;
+
+ Q_strncpyz( renderers, cl_renderer->string, sizeof(renderers) );
+ from = renderers;
+ while( from ) {
+ to = strchr(from, ',');
+ if( to )
+ *to++ = '\0';
+ CL_InitRef( from );
+ if( CL_InitRenderer() ) {
+ cls.rendererStarted = qtrue;
+ break;
+ }
+ CL_ShutdownRef();
+ from = to;
+ }
+ } else if(!cls.rendererStarted) {
+ if( CL_InitRenderer() )
+ cls.rendererStarted = qtrue;
}
if(!cls.soundStarted)
@@ -4414,9 +4437,6 @@ int CL_ScaledMilliseconds(void)
-static cvar_t *cl_renderer = NULL;
-static void *rendererLib = NULL;
-
#if defined(REF_HARD_LINKED)
extern refexport_t* GetRefAPI(int apiVersion, refimport_t * rimp);
#endif
@@ -4428,7 +4448,7 @@ CL_InitRef
RB: changed to load the renderer from a .dll
============
*/
-void CL_InitRef(void)
+void CL_InitRef(const char *renderer)
{
refimport_t ri;
refexport_t *ret;
@@ -4440,11 +4460,9 @@ void CL_InitRef(void)
Com_Printf("----- Initializing Renderer ----\n");
- cl_renderer = Cvar_Get("cl_renderer", "GL3", CVAR_ARCHIVE | CVAR_LATCH);
-
#if !defined(REF_HARD_LINKED)
- Com_sprintf(dllName, sizeof(dllName), DLL_PREFIX "renderer%s" ARCH_STRING DLL_EXT, cl_renderer->string);
+ Com_sprintf(dllName, sizeof(dllName), DLL_PREFIX "renderer%s" ARCH_STRING DLL_EXT, renderer);
Com_Printf("Loading \"%s\"...", dllName);
if((rendererLib = Sys_LoadLibrary(dllName)) == 0)
@@ -4896,6 +4914,8 @@ void CL_Init(void)
//
// register our variables
//
+ cl_renderer = Cvar_Get("cl_renderer", "GL3,GL", CVAR_ARCHIVE|CVAR_LATCH);
+
cl_noprint = Cvar_Get("cl_noprint", "0", 0);
cl_motd = Cvar_Get("cl_motd", "1", 0);
cl_autoupdate = Cvar_Get("cl_autoupdate", "1", CVAR_ARCHIVE);
@@ -5217,8 +5237,6 @@ void CL_Init(void)
CL_InitOpenGLExt();
#endif
- CL_InitRef();
-
SCR_Init();
Cbuf_Execute();
@@ -611,7 +611,7 @@ void CL_ClearPing(int n);
int CL_GetPingQueueCount(void);
void CL_ShutdownRef(void);
-void CL_InitRef(void);
+void CL_InitRef(const char *renderer);
void CL_InitOpenGLExt(void);
void CL_InitPNG(void);
void CL_InitZLIB(void);
@@ -1823,7 +1823,7 @@ void RE_StretchRaw(int x, int y, int w, int h, int cols, int rows, co
void RE_UploadCinematic(int w, int h, int cols, int rows, const byte * data, int client, qboolean dirty);
void RE_BeginFrame(stereoFrame_t stereoFrame);
-void RE_BeginRegistration(glconfig_t * glconfig, glconfig2_t * glconfig2);
+qboolean RE_BeginRegistration(glconfig_t * glconfig, glconfig2_t * glconfig2);
void RE_LoadWorldMap(const char *mapname);
void RE_SetWorldVisData(const byte * vis);
qhandle_t RE_RegisterModel(const char *name);
@@ -1910,7 +1910,7 @@ IMPLEMENTATION SPECIFIC FUNCTIONS
extern int gl_NormalFontBase;
-void GLimp_Init(void);
+qboolean GLimp_Init(void);
#ifdef IPHONE
void GLimp_SetMode(float rotation);
#endif // IPHONE
@@ -1833,7 +1833,7 @@ static qboolean R_LoadMDX(model_t * mod, void *buffer, const char *mod_name)
/*
** RE_BeginRegistration
*/
-void RE_BeginRegistration(glconfig_t * glconfigOut, glconfig2_t * glconfigOut2)
+qboolean RE_BeginRegistration(glconfig_t * glconfigOut, glconfig2_t * glconfigOut2)
{
ri.Hunk_Clear(); // (SA) MEM NOTE: not in missionpack
@@ -1854,6 +1854,8 @@ void RE_BeginRegistration(glconfig_t * glconfigOut, glconfig2_t * glconfigOut2)
// without this we'd see a white flash on a level load because the very
// first time the level shot would not be drawn
RE_StretchPic(0, 0, 0, 0, 0, 0, 1, 1, 0);
+
+ return qtrue;
}
/*
@@ -60,8 +60,9 @@ typedef struct
// BeginRegistration makes any existing media pointers invalid
// and returns the current gl configuration, including screen width
// and height, which can be used by the client to intelligently
- // size display elements
- void (*BeginRegistration) (glconfig_t * config, glconfig2_t * glconfig2);
+ // size display elements. Returns false if the renderer couldn't
+ // be initialized.
+ qboolean (*BeginRegistration) (glconfig_t * config, glconfig2_t * glconfig2);
qhandle_t (*RegisterModel) (const char *name);
//qhandle_t (*RegisterModelAllLODs) (const char *name);
qhandle_t (*RegisterSkin) (const char *name);
@@ -40,9 +40,10 @@ float displayAspect = 0.0f;
static void GfxInfo_f(void);
+cvar_t *r_glMajorVersion;
+cvar_t *r_glMinorVersion;
cvar_t *r_glCoreProfile;
-cvar_t *r_glMinMajorVersion;
-cvar_t *r_glMinMinorVersion;
+cvar_t *r_glDebugProfile;
cvar_t *r_flares;
cvar_t *r_flareSize;
@@ -353,7 +354,7 @@ static void AssertCvarRange(cvar_t * cv, float minVal, float maxVal, qboolean sh
** to the user.
*/
#if !defined(USE_D3D10)
-static void InitOpenGL(void)
+static qboolean InitOpenGL(void)
{
char renderer_buffer[1024];
@@ -373,7 +374,8 @@ static void InitOpenGL(void)
{
GLint temp;
- GLimp_Init();
+ if( !GLimp_Init() )
+ return qfalse;
GL_CheckErrors();
@@ -408,6 +410,8 @@ static void InitOpenGL(void)
// set default state
GL_SetDefaultState();
GL_CheckErrors();
+
+ return qtrue;
}
#endif
@@ -1327,10 +1331,11 @@ R_Register
*/
void R_Register(void)
{
- r_glCoreProfile = ri.Cvar_Get("r_glCoreProfile", "1", CVAR_INIT);
-
- r_glMinMajorVersion = ri.Cvar_Get("r_glMinMajorVersion", "3", CVAR_LATCH);
- r_glMinMinorVersion = ri.Cvar_Get("r_glMinMinorVersion", "2", CVAR_LATCH);
+ // OpenGL context selection
+ r_glMajorVersion = ri.Cvar_Get("r_glMajorVersion", "", CVAR_LATCH);
+ r_glMinorVersion = ri.Cvar_Get("r_glMinorVersion", "", CVAR_LATCH);
+ r_glCoreProfile = ri.Cvar_Get("r_glCoreProfile", "", CVAR_LATCH);
+ r_glDebugProfile = ri.Cvar_Get("r_glDebugProfile", "", CVAR_LATCH);
// latched and archived variables
r_ext_compressed_textures = ri.Cvar_Get("r_ext_compressed_textures", "0", CVAR_ARCHIVE | CVAR_LATCH);
@@ -1436,7 +1441,7 @@ void R_Register(void)
r_lodBias = ri.Cvar_Get("r_lodBias", "0", CVAR_ARCHIVE);
r_flares = ri.Cvar_Get("r_flares", "0", CVAR_ARCHIVE);
r_znear = ri.Cvar_Get("r_znear", "4", CVAR_CHEAT);
- r_zfar = ri.Cvar_Get("r_zfar", "1024", CVAR_CHEAT);
+ r_zfar = ri.Cvar_Get("r_zfar", "0", CVAR_CHEAT);
r_ignoreGLErrors = ri.Cvar_Get("r_ignoreGLErrors", "1", CVAR_ARCHIVE);
r_fastsky = ri.Cvar_Get("r_fastsky", "0", CVAR_ARCHIVE);
r_inGameVideo = ri.Cvar_Get("r_inGameVideo", "1", CVAR_ARCHIVE);
@@ -1709,7 +1714,7 @@ void R_Register(void)
R_Init
===============
*/
-void R_Init(void)
+qboolean R_Init(void)
{
int err;
int i;
@@ -1755,25 +1760,6 @@ void R_Init(void)
R_Register();
- backEndData[0] = (backEndData_t *) ri.Hunk_Alloc(sizeof(*backEndData[0]), h_low);
- backEndData[0]->polys = (srfPoly_t *) ri.Hunk_Alloc(r_maxPolys->integer * sizeof(srfPoly_t), h_low);
- backEndData[0]->polyVerts = (polyVert_t *) ri.Hunk_Alloc(r_maxPolyVerts->integer * sizeof(polyVert_t), h_low);
- backEndData[0]->polybuffers = (srfPolyBuffer_t *) ri.Hunk_Alloc(r_maxPolys->integer * sizeof(srfPolyBuffer_t), h_low);
-
- if(r_smp->integer)
- {
- backEndData[1] = (backEndData_t *) ri.Hunk_Alloc(sizeof(*backEndData[1]), h_low);
- backEndData[1]->polys = (srfPoly_t *) ri.Hunk_Alloc(r_maxPolys->integer * sizeof(srfPoly_t), h_low);
- backEndData[1]->polyVerts = (polyVert_t *) ri.Hunk_Alloc(r_maxPolyVerts->integer * sizeof(polyVert_t), h_low);
- backEndData[1]->polybuffers = (srfPolyBuffer_t *) ri.Hunk_Alloc(r_maxPolys->integer * sizeof(srfPolyBuffer_t), h_low);
- }
- else
- {
- backEndData[1] = NULL;
- }
-
- R_ToggleSmpFrame();
-
#if defined(USE_D3D10)
if(glConfig.vidWidth == 0)
{
@@ -2002,14 +1988,35 @@ void R_Init(void)
// set default state
//D3D10_SetDefaultState();
#else
- InitOpenGL();
+ if( !InitOpenGL() ) {
+ return qfalse;
+ }
#if !defined(GLSL_COMPILE_STARTUP_ONLY)
GLSL_InitGPUShaders();
#endif
#endif
+ backEndData[0] = (backEndData_t *) ri.Hunk_Alloc(sizeof(*backEndData[0]), h_low);
+ backEndData[0]->polys = (srfPoly_t *) ri.Hunk_Alloc(r_maxPolys->integer * sizeof(srfPoly_t), h_low);
+ backEndData[0]->polyVerts = (polyVert_t *) ri.Hunk_Alloc(r_maxPolyVerts->integer * sizeof(polyVert_t), h_low);
+ backEndData[0]->polybuffers = (srfPolyBuffer_t *) ri.Hunk_Alloc(r_maxPolys->integer * sizeof(srfPolyBuffer_t), h_low);
+
+ if(r_smp->integer)
+ {
+ backEndData[1] = (backEndData_t *) ri.Hunk_Alloc(sizeof(*backEndData[1]), h_low);
+ backEndData[1]->polys = (srfPoly_t *) ri.Hunk_Alloc(r_maxPolys->integer * sizeof(srfPoly_t), h_low);
+ backEndData[1]->polyVerts = (polyVert_t *) ri.Hunk_Alloc(r_maxPolyVerts->integer * sizeof(polyVert_t), h_low);
+ backEndData[1]->polybuffers = (srfPolyBuffer_t *) ri.Hunk_Alloc(r_maxPolys->integer * sizeof(srfPolyBuffer_t), h_low);
+ }
+ else
+ {
+ backEndData[1] = NULL;
+ }
+
+ R_ToggleSmpFrame();
+
R_InitImages();
R_InitFBOs();
@@ -2048,6 +2055,8 @@ void R_Init(void)
GL_CheckErrors();
ri.Printf(PRINT_ALL, "----- finished R_Init -----\n");
+
+ return qtrue;
}
/*
@@ -3913,9 +3913,10 @@ extern float displayAspect; // FIXME
//
// cvars
//
+extern cvar_t *r_glMajorVersion; // override GL version autodetect (for testing)
+extern cvar_t *r_glMinorVersion;
extern cvar_t *r_glCoreProfile;
-extern cvar_t *r_glMinMajorVersion;
-extern cvar_t *r_glMinMinorVersion;
+extern cvar_t *r_glDebugProfile;
extern cvar_t *r_flares; // light flares
extern cvar_t *r_flareSize;
@@ -4347,7 +4348,7 @@ void RE_StretchRaw(int x, int y, int w, int h, int cols, int rows, co
void RE_UploadCinematic(int w, int h, int cols, int rows, const byte * data, int client, qboolean dirty);
void RE_BeginFrame(stereoFrame_t stereoFrame);
-void RE_BeginRegistration(glconfig_t * glconfig, glconfig2_t * glconfig2);
+qboolean RE_BeginRegistration(glconfig_t * glconfig, glconfig2_t * glconfig2);
void RE_LoadWorldMap(const char *mapname);
void RE_SetWorldVisData(const byte * vis);
qhandle_t RE_RegisterModel(const char *name);
@@ -4365,7 +4366,7 @@ float R_ProcessLightmap(byte ** pic, int in_padding, int width, int he
model_t *R_AllocModel(void);
-void R_Init(void);
+qboolean R_Init(void);
qboolean R_GetModeInfo(int *width, int *height, float *windowAspect, int mode);
@@ -4449,7 +4450,7 @@ IMPLEMENTATION SPECIFIC FUNCTIONS
====================================================================
*/
-void GLimp_Init(void);
+qboolean GLimp_Init(void);
void GLimp_Shutdown(void);
void GLimp_EndFrame(void);
@@ -479,9 +479,10 @@ static qboolean R_LoadDAE(model_t * mod, void *buffer, int bufferLen, const char
/*
** RE_BeginRegistration
*/
-void RE_BeginRegistration(glconfig_t * glconfigOut, glconfig2_t *glconfig2Out)
+qboolean RE_BeginRegistration(glconfig_t * glconfigOut, glconfig2_t *glconfig2Out)
{
- R_Init();
+ if( !R_Init() )
+ return qfalse;
*glconfigOut = glConfig;
*glconfig2Out = glConfig2;
Oops, something went wrong.

0 comments on commit c6c4bf4

Please sign in to comment.