mirror of
https://github.com/DrBeef/ioq3quest.git
synced 2024-11-27 06:13:01 +00:00
First shot at SMP renderer with sdl_glimp. Does not work yet!
This commit is contained in:
parent
4517e7a34b
commit
6c0079508c
2 changed files with 116 additions and 47 deletions
|
@ -326,8 +326,8 @@ ifeq ($(PLATFORM),darwin)
|
||||||
$(B)/baseq3/vm/ui.qvm \
|
$(B)/baseq3/vm/ui.qvm \
|
||||||
$(B)/missionpack/vm/qagame.qvm \
|
$(B)/missionpack/vm/qagame.qvm \
|
||||||
$(B)/missionpack/vm/cgame.qvm \
|
$(B)/missionpack/vm/cgame.qvm \
|
||||||
$(B)/missionpack/vm/ui.qvm
|
$(B)/missionpack/vm/ui.qvm \
|
||||||
# $(B)/$(PLATFORM)quake3-smp \
|
$(B)/$(PLATFORM)quake3-smp \
|
||||||
|
|
||||||
else # ifeq darwin
|
else # ifeq darwin
|
||||||
|
|
||||||
|
@ -997,6 +997,18 @@ ifeq ($(PLATFORM),darwin)
|
||||||
$(B)/client/linux_snd.o \
|
$(B)/client/linux_snd.o \
|
||||||
$(B)/client/sdl_snd.o \
|
$(B)/client/sdl_snd.o \
|
||||||
|
|
||||||
|
Q3POBJ_SMP=\
|
||||||
|
$(B)/client/unix_main.o \
|
||||||
|
$(B)/client/unix_net.o \
|
||||||
|
$(B)/client/unix_shared.o \
|
||||||
|
$(B)/client/linux_signals.o \
|
||||||
|
$(B)/client/linux_common.o \
|
||||||
|
$(B)/client/linux_qgl.o \
|
||||||
|
$(B)/client/sdl_glimp_smp.o \
|
||||||
|
$(B)/client/linux_joystick.o \
|
||||||
|
$(B)/client/linux_snd.o \
|
||||||
|
$(B)/client/sdl_snd.o \
|
||||||
|
|
||||||
ifeq ($(ARCH),i386)
|
ifeq ($(ARCH),i386)
|
||||||
I386OBJS := \
|
I386OBJS := \
|
||||||
$(B)/client/ftola.o \
|
$(B)/client/ftola.o \
|
||||||
|
@ -1212,6 +1224,7 @@ $(B)/client/linux_common.o : $(UDIR)/linux_common.c; $(DO_CC)
|
||||||
$(B)/client/linux_glimp.o : $(UDIR)/linux_glimp.c; $(DO_CC) $(GL_CFLAGS)
|
$(B)/client/linux_glimp.o : $(UDIR)/linux_glimp.c; $(DO_CC) $(GL_CFLAGS)
|
||||||
$(B)/client/sdl_glimp.o : $(UDIR)/sdl_glimp.c; $(DO_CC) $(GL_CFLAGS)
|
$(B)/client/sdl_glimp.o : $(UDIR)/sdl_glimp.c; $(DO_CC) $(GL_CFLAGS)
|
||||||
$(B)/client/linux_glimp_smp.o : $(UDIR)/linux_glimp.c; $(DO_SMP_CC) $(GL_CFLAGS)
|
$(B)/client/linux_glimp_smp.o : $(UDIR)/linux_glimp.c; $(DO_SMP_CC) $(GL_CFLAGS)
|
||||||
|
$(B)/client/sdl_glimp_smp.o : $(UDIR)/sdl_glimp.c; $(DO_SMP_CC) $(GL_CFLAGS)
|
||||||
$(B)/client/linux_joystick.o : $(UDIR)/linux_joystick.c; $(DO_CC)
|
$(B)/client/linux_joystick.o : $(UDIR)/linux_joystick.c; $(DO_CC)
|
||||||
$(B)/client/linux_qgl.o : $(UDIR)/linux_qgl.c; $(DO_CC) $(GL_CFLAGS)
|
$(B)/client/linux_qgl.o : $(UDIR)/linux_qgl.c; $(DO_CC) $(GL_CFLAGS)
|
||||||
$(B)/client/linux_input.o : $(UDIR)/linux_input.c; $(DO_CC)
|
$(B)/client/linux_input.o : $(UDIR)/linux_input.c; $(DO_CC)
|
||||||
|
|
|
@ -60,6 +60,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
#include "SDL.h"
|
#include "SDL.h"
|
||||||
|
|
||||||
|
#ifdef SMP
|
||||||
|
#include "SDL_thread.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -1024,8 +1028,9 @@ void GLimp_EndFrame (void)
|
||||||
QGL_EnableLogging( (qboolean)r_logFile->integer ); // bk001205 - was ->value
|
QGL_EnableLogging( (qboolean)r_logFile->integer ); // bk001205 - was ->value
|
||||||
}
|
}
|
||||||
|
|
||||||
// Figure out something to do with this...
|
|
||||||
#if 0 //def SMP
|
|
||||||
|
#ifdef SMP
|
||||||
/*
|
/*
|
||||||
===========================================================
|
===========================================================
|
||||||
|
|
||||||
|
@ -1034,53 +1039,104 @@ SMP acceleration
|
||||||
===========================================================
|
===========================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static pthread_mutex_t smpMutex = PTHREAD_MUTEX_INITIALIZER;
|
/*
|
||||||
|
* I have no idea if this will even work...most platforms don't offer
|
||||||
|
* thread-safe OpenGL libraries, and it looks like the original Linux
|
||||||
|
* code counted on each thread claiming the GL context with glXMakeCurrent(),
|
||||||
|
* which you can't currently do in SDL. We'll just have to hope for the best.
|
||||||
|
*/
|
||||||
|
|
||||||
static pthread_cond_t renderCommandsEvent = PTHREAD_COND_INITIALIZER;
|
static SDL_mutex *smpMutex = NULL;
|
||||||
static pthread_cond_t renderCompletedEvent = PTHREAD_COND_INITIALIZER;
|
static SDL_cond *renderCommandsEvent = NULL;
|
||||||
|
static SDL_cond *renderCompletedEvent = NULL;
|
||||||
|
static void (*glimpRenderThread)( void ) = NULL;
|
||||||
|
static SDL_Thread *renderThread = NULL;
|
||||||
|
|
||||||
static void (*glimpRenderThread)( void );
|
static void GLimp_ShutdownRenderThread(void)
|
||||||
|
{
|
||||||
|
if (smpMutex != NULL)
|
||||||
|
{
|
||||||
|
SDL_DestroyMutex(smpMutex);
|
||||||
|
smpMutex = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void *GLimp_RenderThreadWrapper( void *arg )
|
if (renderCommandsEvent != NULL)
|
||||||
|
{
|
||||||
|
SDL_DestroyCond(renderCommandsEvent);
|
||||||
|
renderCommandsEvent = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (renderCompletedEvent != NULL)
|
||||||
|
{
|
||||||
|
SDL_DestroyCond(renderCompletedEvent);
|
||||||
|
renderCompletedEvent = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
glimpRenderThread = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int GLimp_RenderThreadWrapper( void *arg )
|
||||||
{
|
{
|
||||||
Com_Printf( "Render thread starting\n" );
|
Com_Printf( "Render thread starting\n" );
|
||||||
|
|
||||||
glimpRenderThread();
|
glimpRenderThread();
|
||||||
|
|
||||||
qglXMakeCurrent( dpy, None, NULL );
|
//qglXMakeCurrent( dpy, None, NULL );
|
||||||
|
|
||||||
Com_Printf( "Render thread terminating\n" );
|
Com_Printf( "Render thread terminating\n" );
|
||||||
|
|
||||||
return arg;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
qboolean GLimp_SpawnRenderThread( void (*function)( void ) )
|
qboolean GLimp_SpawnRenderThread( void (*function)( void ) )
|
||||||
{
|
{
|
||||||
pthread_t renderThread;
|
if (renderThread != NULL) /* hopefully just a zombie at this point... */
|
||||||
int ret;
|
{
|
||||||
|
Com_Printf("Already a render thread? Trying to clean it up...\n");
|
||||||
|
SDL_WaitThread(renderThread, NULL);
|
||||||
|
renderThread = NULL;
|
||||||
|
GLimp_ShutdownRenderThread();
|
||||||
|
}
|
||||||
|
|
||||||
pthread_mutex_init( &smpMutex, NULL );
|
smpMutex = SDL_CreateMutex();
|
||||||
|
if (smpMutex == NULL)
|
||||||
|
{
|
||||||
|
Com_Printf( "smpMutex creation failed: %s\n", SDL_GetError() );
|
||||||
|
GLimp_ShutdownRenderThread();
|
||||||
|
return qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
pthread_cond_init( &renderCommandsEvent, NULL );
|
renderCommandsEvent = SDL_CreateCond();
|
||||||
pthread_cond_init( &renderCompletedEvent, NULL );
|
if (renderCommandsEvent == NULL)
|
||||||
|
{
|
||||||
|
Com_Printf( "renderCommandsEvent creation failed: %s\n", SDL_GetError() );
|
||||||
|
GLimp_ShutdownRenderThread();
|
||||||
|
return qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
glimpRenderThread = function;
|
renderCompletedEvent = SDL_CreateCond();
|
||||||
|
if (renderCompletedEvent == NULL)
|
||||||
|
{
|
||||||
|
Com_Printf( "renderCompletedEvent creation failed: %s\n", SDL_GetError() );
|
||||||
|
GLimp_ShutdownRenderThread();
|
||||||
|
return qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
ret = pthread_create( &renderThread,
|
glimpRenderThread = function;
|
||||||
NULL, // attributes
|
renderThread = SDL_CreateThread(GLimp_RenderThreadWrapper, NULL);
|
||||||
GLimp_RenderThreadWrapper,
|
if ( renderThread == NULL ) {
|
||||||
NULL ); // argument
|
ri.Printf( PRINT_ALL, "SDL_CreateThread() returned %s", SDL_GetError() );
|
||||||
if ( ret ) {
|
GLimp_ShutdownRenderThread();
|
||||||
ri.Printf( PRINT_ALL, "pthread_create returned %d: %s", ret, strerror( ret ) );
|
return qfalse;
|
||||||
return qfalse;
|
|
||||||
} else {
|
} else {
|
||||||
ret = pthread_detach( renderThread );
|
// !!! FIXME: No detach API available in SDL!
|
||||||
if ( ret ) {
|
//ret = pthread_detach( renderThread );
|
||||||
ri.Printf( PRINT_ALL, "pthread_detach returned %d: %s", ret, strerror( ret ) );
|
//if ( ret ) {
|
||||||
}
|
//ri.Printf( PRINT_ALL, "pthread_detach returned %d: %s", ret, strerror( ret ) );
|
||||||
}
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
return qtrue;
|
return qtrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
static volatile void *smpData = NULL;
|
static volatile void *smpData = NULL;
|
||||||
|
@ -1088,58 +1144,58 @@ static volatile qboolean smpDataReady;
|
||||||
|
|
||||||
void *GLimp_RendererSleep( void )
|
void *GLimp_RendererSleep( void )
|
||||||
{
|
{
|
||||||
void *data;
|
void *data = NULL;
|
||||||
|
|
||||||
qglXMakeCurrent( dpy, None, NULL );
|
//qglXMakeCurrent( dpy, None, NULL );
|
||||||
|
|
||||||
pthread_mutex_lock( &smpMutex );
|
SDL_LockMutex(smpMutex);
|
||||||
{
|
{
|
||||||
smpData = NULL;
|
smpData = NULL;
|
||||||
smpDataReady = qfalse;
|
smpDataReady = qfalse;
|
||||||
|
|
||||||
// after this, the front end can exit GLimp_FrontEndSleep
|
// after this, the front end can exit GLimp_FrontEndSleep
|
||||||
pthread_cond_signal( &renderCompletedEvent );
|
SDL_CondSignal(renderCompletedEvent);
|
||||||
|
|
||||||
while ( !smpDataReady ) {
|
while ( !smpDataReady ) {
|
||||||
pthread_cond_wait( &renderCommandsEvent, &smpMutex );
|
SDL_CondWait(renderCommandsEvent, smpMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
data = (void *)smpData;
|
data = (void *)smpData;
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock( &smpMutex );
|
SDL_UnlockMutex(smpMutex);
|
||||||
|
|
||||||
qglXMakeCurrent( dpy, win, ctx );
|
//qglXMakeCurrent( dpy, win, ctx );
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLimp_FrontEndSleep( void )
|
void GLimp_FrontEndSleep( void )
|
||||||
{
|
{
|
||||||
pthread_mutex_lock( &smpMutex );
|
SDL_LockMutex(smpMutex);
|
||||||
{
|
{
|
||||||
while ( smpData ) {
|
while ( smpData ) {
|
||||||
pthread_cond_wait( &renderCompletedEvent, &smpMutex );
|
SDL_CondWait(renderCompletedEvent, smpMutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock( &smpMutex );
|
SDL_UnlockMutex(smpMutex);
|
||||||
|
|
||||||
qglXMakeCurrent( dpy, win, ctx );
|
//qglXMakeCurrent( dpy, win, ctx );
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLimp_WakeRenderer( void *data )
|
void GLimp_WakeRenderer( void *data )
|
||||||
{
|
{
|
||||||
qglXMakeCurrent( dpy, None, NULL );
|
//qglXMakeCurrent( dpy, None, NULL );
|
||||||
|
|
||||||
pthread_mutex_lock( &smpMutex );
|
SDL_LockMutex(smpMutex);
|
||||||
{
|
{
|
||||||
assert( smpData == NULL );
|
assert( smpData == NULL );
|
||||||
smpData = data;
|
smpData = data;
|
||||||
smpDataReady = qtrue;
|
smpDataReady = qtrue;
|
||||||
|
|
||||||
// after this, the renderer can continue through GLimp_RendererSleep
|
// after this, the renderer can continue through GLimp_RendererSleep
|
||||||
pthread_cond_signal( &renderCommandsEvent );
|
SDL_CondSignal(renderCommandsEvent);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock( &smpMutex );
|
SDL_UnlockMutex(smpMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
Loading…
Reference in a new issue