git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@10794
d7cf8633-e32d-0410-b094-
e92efae38249
#include "quakedef.h"
#include "dpsoftrast.h"
#include "quakedef.h"
#include "dpsoftrast.h"
-//#define USETHREADS
-#ifdef USETHREADS
+#ifdef USE_SDL
+#define USE_THREADS
+#endif
+
+#ifdef USE_THREADS
#include <SDL.h>
#include <SDL_thread.h>
#endif
#include <SDL.h>
#include <SDL_thread.h>
#endif
#define MEMORY_BARRIER ((void)0)
#endif
#define MEMORY_BARRIER ((void)0)
#endif
+#if !defined(USE_THREADS) || !defined(SSE2_PRESENT)
#undef MEMORY_BARRIER
#define MEMORY_BARRIER ((void)0)
#endif
#undef MEMORY_BARRIER
#define MEMORY_BARRIER ((void)0)
#endif
typedef ATOMIC(struct DPSOFTRAST_State_Thread_s
{
typedef ATOMIC(struct DPSOFTRAST_State_Thread_s
{
SDL_Thread *thread;
#endif
int index;
SDL_Thread *thread;
#endif
int index;
int triangleoffset;
bool waiting;
int triangleoffset;
bool waiting;
SDL_cond *waitcond;
#endif
SDL_cond *waitcond;
#endif
int numthreads;
DPSOFTRAST_State_Thread *threads;
int numthreads;
DPSOFTRAST_State_Thread *threads;
SDL_mutex *trianglemutex;
SDL_cond *trianglecond;
#endif
SDL_mutex *trianglemutex;
SDL_cond *trianglecond;
#endif
int usedtriangles = dpsoftrast.trianglepool.usedtriangles;
if (usedtriangles <= DPSOFTRAST_DRAW_MAXTRIANGLEPOOL-space)
return;
int usedtriangles = dpsoftrast.trianglepool.usedtriangles;
if (usedtriangles <= DPSOFTRAST_DRAW_MAXTRIANGLEPOOL-space)
return;
SDL_LockMutex(dpsoftrast.trianglemutex);
#endif
for(;;)
SDL_LockMutex(dpsoftrast.trianglemutex);
#endif
for(;;)
}
if (usedtriangles <= DPSOFTRAST_DRAW_MAXTRIANGLEPOOL-space || waitindex < 0)
break;
}
if (usedtriangles <= DPSOFTRAST_DRAW_MAXTRIANGLEPOOL-space || waitindex < 0)
break;
thread = &dpsoftrast.threads[waitindex];
thread->waiting = true;
SDL_CondBroadcast(dpsoftrast.trianglecond);
thread = &dpsoftrast.threads[waitindex];
thread->waiting = true;
SDL_CondBroadcast(dpsoftrast.trianglecond);
thread->waiting = false;
#endif
}
thread->waiting = false;
#endif
}
SDL_UnlockMutex(dpsoftrast.trianglemutex);
#endif
dpsoftrast.trianglepool.usedtriangles = usedtriangles;
SDL_UnlockMutex(dpsoftrast.trianglemutex);
#endif
dpsoftrast.trianglepool.usedtriangles = usedtriangles;
{
DPSOFTRAST_State_Triangle *triangle;
if (dpsoftrast.trianglepool.usedtriangles >= DPSOFTRAST_DRAW_MAXTRIANGLEPOOL-1)
{
DPSOFTRAST_State_Triangle *triangle;
if (dpsoftrast.trianglepool.usedtriangles >= DPSOFTRAST_DRAW_MAXTRIANGLEPOOL-1)
DPSOFTRAST_Draw_FreeTrianglePool(DPSOFTRAST_DRAW_MAXTRIANGLEPOOL/8);
#else
DPSOFTRAST_Draw_FlushThreads();
DPSOFTRAST_Draw_FreeTrianglePool(DPSOFTRAST_DRAW_MAXTRIANGLEPOOL/8);
#else
DPSOFTRAST_Draw_FlushThreads();
if (usedcommands <= DPSOFTRAST_DRAW_MAXCOMMANDPOOL-space)
return;
DPSOFTRAST_Draw_SyncCommands();
if (usedcommands <= DPSOFTRAST_DRAW_MAXCOMMANDPOOL-space)
return;
DPSOFTRAST_Draw_SyncCommands();
SDL_LockMutex(dpsoftrast.trianglemutex);
#endif
for(;;)
SDL_LockMutex(dpsoftrast.trianglemutex);
#endif
for(;;)
}
if (usedcommands <= DPSOFTRAST_DRAW_MAXCOMMANDPOOL-space || waitindex < 0)
break;
}
if (usedcommands <= DPSOFTRAST_DRAW_MAXCOMMANDPOOL-space || waitindex < 0)
break;
thread = &dpsoftrast.threads[waitindex];
thread->waiting = true;
SDL_CondBroadcast(dpsoftrast.trianglecond);
thread = &dpsoftrast.threads[waitindex];
thread->waiting = true;
SDL_CondBroadcast(dpsoftrast.trianglecond);
thread->waiting = false;
#endif
}
thread->waiting = false;
#endif
}
SDL_UnlockMutex(dpsoftrast.trianglemutex);
#endif
dpsoftrast.commandpool.usedcommands = usedcommands;
SDL_UnlockMutex(dpsoftrast.trianglemutex);
#endif
dpsoftrast.commandpool.usedcommands = usedcommands;
extra += DPSOFTRAST_DRAW_MAXCOMMANDPOOL - freecommand;
if(usedcommands > DPSOFTRAST_DRAW_MAXCOMMANDPOOL - (size + extra))
{
extra += DPSOFTRAST_DRAW_MAXCOMMANDPOOL - freecommand;
if(usedcommands > DPSOFTRAST_DRAW_MAXCOMMANDPOOL - (size + extra))
{
DPSOFTRAST_Draw_FreeCommandPool(size + extra);
#else
DPSOFTRAST_Draw_FlushThreads();
DPSOFTRAST_Draw_FreeCommandPool(size + extra);
#else
DPSOFTRAST_Draw_FlushThreads();
void DPSOFTRAST_PixelShader_LightSource(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span)
{
void DPSOFTRAST_PixelShader_LightSource(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span)
{
float buffer_z[DPSOFTRAST_DRAW_MAXSPANLENGTH];
unsigned char buffer_texture_colorbgra8[DPSOFTRAST_DRAW_MAXSPANLENGTH*4];
unsigned char buffer_texture_normalbgra8[DPSOFTRAST_DRAW_MAXSPANLENGTH*4];
float buffer_z[DPSOFTRAST_DRAW_MAXSPANLENGTH];
unsigned char buffer_texture_colorbgra8[DPSOFTRAST_DRAW_MAXSPANLENGTH*4];
unsigned char buffer_texture_normalbgra8[DPSOFTRAST_DRAW_MAXSPANLENGTH*4];
}
}
DPSOFTRAST_Draw_Span_FinishBGRA8(thread, triangle, span, buffer_FragColorbgra8);
}
}
DPSOFTRAST_Draw_Span_FinishBGRA8(thread, triangle, span, buffer_FragColorbgra8);
void DPSOFTRAST_Draw_GenerateSpans(DPSOFTRAST_State_Thread *thread, int freetriangle)
{
void DPSOFTRAST_Draw_GenerateSpans(DPSOFTRAST_State_Thread *thread, int freetriangle)
{
int miny = (thread->index*dpsoftrast.fb_height)/dpsoftrast.numthreads;
int maxy = ((thread->index+1)*dpsoftrast.fb_height)/dpsoftrast.numthreads;
int commandoffset = thread->commandoffset;
int miny = (thread->index*dpsoftrast.fb_height)/dpsoftrast.numthreads;
int maxy = ((thread->index+1)*dpsoftrast.fb_height)/dpsoftrast.numthreads;
int commandoffset = thread->commandoffset;
thread->commandoffset = commandoffset;
thread->triangleoffset = triangleoffset;
thread->commandoffset = commandoffset;
thread->triangleoffset = triangleoffset;
}
void DPSOFTRAST_Draw_FlushThreads(void)
}
void DPSOFTRAST_Draw_FlushThreads(void)
MEMORY_BARRIER;
dpsoftrast.drawtriangle = dpsoftrast.trianglepool.freetriangle;
}
MEMORY_BARRIER;
dpsoftrast.drawtriangle = dpsoftrast.trianglepool.freetriangle;
}
SDL_LockMutex(dpsoftrast.trianglemutex);
#endif
for (i = 0; i < dpsoftrast.numthreads; i++)
{
thread = &dpsoftrast.threads[i];
SDL_LockMutex(dpsoftrast.trianglemutex);
#endif
for (i = 0; i < dpsoftrast.numthreads; i++)
{
thread = &dpsoftrast.threads[i];
while (thread->triangleoffset != dpsoftrast.drawtriangle)
{
thread->waiting = true;
while (thread->triangleoffset != dpsoftrast.drawtriangle)
{
thread->waiting = true;
DPSOFTRAST_Draw_GenerateSpans(thread, dpsoftrast.drawtriangle);
#endif
}
DPSOFTRAST_Draw_GenerateSpans(thread, dpsoftrast.drawtriangle);
#endif
}
SDL_UnlockMutex(dpsoftrast.trianglemutex);
#endif
dpsoftrast.trianglepool.usedtriangles = 0;
dpsoftrast.commandpool.usedcommands = 0;
}
SDL_UnlockMutex(dpsoftrast.trianglemutex);
#endif
dpsoftrast.trianglepool.usedtriangles = 0;
dpsoftrast.commandpool.usedcommands = 0;
}
static int DPSOFTRAST_Draw_Thread(void *data)
{
DPSOFTRAST_State_Thread *thread = (DPSOFTRAST_State_Thread *)data;
static int DPSOFTRAST_Draw_Thread(void *data)
{
DPSOFTRAST_State_Thread *thread = (DPSOFTRAST_State_Thread *)data;
}
if (dpsoftrast.trianglepool.usedtriangles >= DPSOFTRAST_DRAW_MAXTRIANGLEPOOL-1)
}
if (dpsoftrast.trianglepool.usedtriangles >= DPSOFTRAST_DRAW_MAXTRIANGLEPOOL-1)
DPSOFTRAST_Draw_FreeTrianglePool(DPSOFTRAST_DRAW_MAXTRIANGLEPOOL/8);
#else
DPSOFTRAST_Draw_FlushThreads();
DPSOFTRAST_Draw_FreeTrianglePool(DPSOFTRAST_DRAW_MAXTRIANGLEPOOL/8);
#else
DPSOFTRAST_Draw_FlushThreads();
MEMORY_BARRIER;
dpsoftrast.drawtriangle = dpsoftrast.trianglepool.freetriangle;
MEMORY_BARRIER;
dpsoftrast.drawtriangle = dpsoftrast.trianglepool.freetriangle;
SDL_LockMutex(dpsoftrast.trianglemutex);
SDL_CondBroadcast(dpsoftrast.trianglecond);
SDL_UnlockMutex(dpsoftrast.trianglemutex);
SDL_LockMutex(dpsoftrast.trianglemutex);
SDL_CondBroadcast(dpsoftrast.trianglecond);
SDL_UnlockMutex(dpsoftrast.trianglemutex);
MEMORY_BARRIER;
dpsoftrast.drawtriangle = dpsoftrast.trianglepool.freetriangle;
MEMORY_BARRIER;
dpsoftrast.drawtriangle = dpsoftrast.trianglepool.freetriangle;
SDL_LockMutex(dpsoftrast.trianglemutex);
SDL_CondBroadcast(dpsoftrast.trianglecond);
SDL_UnlockMutex(dpsoftrast.trianglemutex);
SDL_LockMutex(dpsoftrast.trianglemutex);
SDL_CondBroadcast(dpsoftrast.trianglecond);
SDL_UnlockMutex(dpsoftrast.trianglemutex);
dpsoftrast.color[2] = 1;
dpsoftrast.color[3] = 1;
dpsoftrast.cullface = GL_BACK;
dpsoftrast.color[2] = 1;
dpsoftrast.color[3] = 1;
dpsoftrast.cullface = GL_BACK;
dpsoftrast.numthreads = bound(1, numthreads, 64);
dpsoftrast.trianglemutex = SDL_CreateMutex();
dpsoftrast.trianglecond = SDL_CreateCond();
dpsoftrast.numthreads = bound(1, numthreads, 64);
dpsoftrast.trianglemutex = SDL_CreateMutex();
dpsoftrast.trianglecond = SDL_CreateCond();
thread->triangleoffset = 0;
thread->commandoffset = 0;
thread->waiting = false;
thread->triangleoffset = 0;
thread->commandoffset = 0;
thread->waiting = false;
thread->waitcond = SDL_CreateCond();
#endif
thread->validate = -1;
DPSOFTRAST_Validate(thread, -1);
thread->waitcond = SDL_CreateCond();
#endif
thread->validate = -1;
DPSOFTRAST_Validate(thread, -1);
thread->thread = SDL_CreateThread(DPSOFTRAST_Draw_Thread, thread);
#endif
}
thread->thread = SDL_CreateThread(DPSOFTRAST_Draw_Thread, thread);
#endif
}
void DPSOFTRAST_Shutdown(void)
{
int i;
void DPSOFTRAST_Shutdown(void)
{
int i;
if(dpsoftrast.numthreads > 0)
{
DPSOFTRAST_State_Thread *thread;
if(dpsoftrast.numthreads > 0)
{
DPSOFTRAST_State_Thread *thread;
csprogs.o \
curves.o \
cvar.o \
csprogs.o \
curves.o \
cvar.o \
dpvsimpledecode.o \
filematch.o \
fractalnoise.o \
dpvsimpledecode.o \
filematch.o \
fractalnoise.o \
# note that builddate.c is very intentionally not compiled to a .o before
# being linked, because it should be recompiled every time an executable is
# built to give the executable a proper date string
# note that builddate.c is very intentionally not compiled to a .o before
# being linked, because it should be recompiled every time an executable is
# built to give the executable a proper date string
-OBJ_SV= builddate.c sys_linux.o vid_null.o $(OBJ_SND_NULL) $(OBJ_NOCD) $(OBJ_COMMON)
-OBJ_SDL= builddate.c sys_sdl.o vid_sdl.o $(OBJ_SND_COMMON) snd_sdl.o cd_sdl.o $(OBJ_COMMON)
+OBJ_SV= builddate.c sys_linux.o vid_null.o $(OBJ_SND_NULL) $(OBJ_NOCD) $(OBJ_COMMON) dpsoftrast.o
+OBJ_SDL= builddate.c sys_sdl.o vid_sdl.o $(OBJ_SND_COMMON) snd_sdl.o cd_sdl.o $(OBJ_COMMON) dpsoftrast_sdl.o
CFLAGS_PROFILE=-g -pg -ggdb -fprofile-arcs
CFLAGS_RELEASE=
CFLAGS_RELEASE_PROFILE=-fbranch-probabilities
CFLAGS_PROFILE=-g -pg -ggdb -fprofile-arcs
CFLAGS_RELEASE=
CFLAGS_RELEASE_PROFILE=-fbranch-probabilities
-CFLAGS_SDL=$(SDLCONFIG_CFLAGS)
+CFLAGS_SDL=$(SDLCONFIG_CFLAGS) -DUSE_SDL
##### UNIX specific variables #####
##### UNIX specific variables #####
-OBJ_GLX= builddate.c sys_linux.o vid_glx.o keysym2ucs.o $(OBJ_SOUND) $(OBJ_CD) $(OBJ_COMMON)
+OBJ_GLX= builddate.c sys_linux.o vid_glx.o keysym2ucs.o $(OBJ_SOUND) $(OBJ_CD) $(OBJ_COMMON) dpsoftrast.o
LDFLAGS_UNIXCOMMON=-lm $(LIB_ODE) $(LIB_CG) $(LIB_JPEG) $(LIB_CRYPTO) $(LIB_CRYPTO_RIJNDAEL)
LDFLAGS_UNIXCL=-L$(UNIX_X11LIBPATH) -lX11 -lXpm -lXext -lXxf86dga -lXxf86vm $(LIB_SOUND)
LDFLAGS_UNIXCOMMON=-lm $(LIB_ODE) $(LIB_CG) $(LIB_JPEG) $(LIB_CRYPTO) $(LIB_CRYPTO_RIJNDAEL)
LDFLAGS_UNIXCL=-L$(UNIX_X11LIBPATH) -lX11 -lXpm -lXext -lXxf86dga -lXxf86vm $(LIB_SOUND)
$(CHECKLEVEL2)
$(DO_CC) $(CFLAGS_SDL)
$(CHECKLEVEL2)
$(DO_CC) $(CFLAGS_SDL)
+dpsoftrast_sdl.o: dpsoftrast.c
+ $(CHECKLEVEL2)
+ $(DO_CC) $(CFLAGS_SDL)
+
crypto.o: crypto.c
$(CHECKLEVEL2)
$(DO_CC) $(CFLAGS_CRYPTO) $(CFLAGS_CRYPTO_RIJNDAEL)
crypto.o: crypto.c
$(CHECKLEVEL2)
$(DO_CC) $(CFLAGS_CRYPTO) $(CFLAGS_CRYPTO_RIJNDAEL)
qboolean vid_supportrefreshrate = false;
cvar_t vid_soft = {CVAR_SAVE, "vid_soft", "0", "enables use of the DarkPlaces Software Rasterizer rather than OpenGL or Direct3D"};
qboolean vid_supportrefreshrate = false;
cvar_t vid_soft = {CVAR_SAVE, "vid_soft", "0", "enables use of the DarkPlaces Software Rasterizer rather than OpenGL or Direct3D"};
-cvar_t vid_soft_threads = {CVAR_SAVE, "vid_soft_threads", "1", "the number of threads the DarkPlaces Software Rasterizer should use"};
+cvar_t vid_soft_threads = {CVAR_SAVE, "vid_soft_threads", "2", "the number of threads the DarkPlaces Software Rasterizer should use"};
cvar_t joy_detected = {CVAR_READONLY, "joy_detected", "0", "number of joysticks detected by engine"};
cvar_t joy_enable = {CVAR_SAVE, "joy_enable", "0", "enables joystick support"};
cvar_t joy_index = {0, "joy_index", "0", "selects which joystick to use if you have multiple"};
cvar_t joy_detected = {CVAR_READONLY, "joy_detected", "0", "number of joysticks detected by engine"};
cvar_t joy_enable = {CVAR_SAVE, "joy_enable", "0", "enables joystick support"};
cvar_t joy_index = {0, "joy_index", "0", "selects which joystick to use if you have multiple"};