#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
#define MEMORY_BARRIER ((void)0)
#endif
-#ifndef USETHREADS
+#if !defined(USE_THREADS) || !defined(SSE2_PRESENT)
#undef MEMORY_BARRIER
#define MEMORY_BARRIER ((void)0)
#endif
typedef ATOMIC(struct DPSOFTRAST_State_Thread_s
{
-#ifdef USETHREADS
+#ifdef USE_THREADS
SDL_Thread *thread;
#endif
int index;
int triangleoffset;
bool waiting;
-#ifdef USETHREADS
+#ifdef USE_THREADS
SDL_cond *waitcond;
#endif
int numthreads;
DPSOFTRAST_State_Thread *threads;
-#ifdef USETHREADS
+#ifdef USE_THREADS
SDL_mutex *trianglemutex;
SDL_cond *trianglecond;
#endif
int usedtriangles = dpsoftrast.trianglepool.usedtriangles;
if (usedtriangles <= DPSOFTRAST_DRAW_MAXTRIANGLEPOOL-space)
return;
-#ifdef USETHREADS
+#ifdef USE_THREADS
SDL_LockMutex(dpsoftrast.trianglemutex);
#endif
for(;;)
}
if (usedtriangles <= DPSOFTRAST_DRAW_MAXTRIANGLEPOOL-space || waitindex < 0)
break;
-#ifdef USETHREADS
+#ifdef USE_THREADS
thread = &dpsoftrast.threads[waitindex];
thread->waiting = true;
SDL_CondBroadcast(dpsoftrast.trianglecond);
thread->waiting = false;
#endif
}
-#ifdef USETHREADS
+#ifdef USE_THREADS
SDL_UnlockMutex(dpsoftrast.trianglemutex);
#endif
dpsoftrast.trianglepool.usedtriangles = usedtriangles;
{
DPSOFTRAST_State_Triangle *triangle;
if (dpsoftrast.trianglepool.usedtriangles >= DPSOFTRAST_DRAW_MAXTRIANGLEPOOL-1)
-#ifdef USETHREADS
+#ifdef USE_THREADS
DPSOFTRAST_Draw_FreeTrianglePool(DPSOFTRAST_DRAW_MAXTRIANGLEPOOL/8);
#else
DPSOFTRAST_Draw_FlushThreads();
if (usedcommands <= DPSOFTRAST_DRAW_MAXCOMMANDPOOL-space)
return;
DPSOFTRAST_Draw_SyncCommands();
-#ifdef USETHREADS
+#ifdef USE_THREADS
SDL_LockMutex(dpsoftrast.trianglemutex);
#endif
for(;;)
}
if (usedcommands <= DPSOFTRAST_DRAW_MAXCOMMANDPOOL-space || waitindex < 0)
break;
-#ifdef USETHREADS
+#ifdef USE_THREADS
thread = &dpsoftrast.threads[waitindex];
thread->waiting = true;
SDL_CondBroadcast(dpsoftrast.trianglecond);
thread->waiting = false;
#endif
}
-#ifdef USETHREADS
+#ifdef USE_THREADS
SDL_UnlockMutex(dpsoftrast.trianglemutex);
#endif
dpsoftrast.commandpool.usedcommands = usedcommands;
extra += DPSOFTRAST_DRAW_MAXCOMMANDPOOL - freecommand;
if(usedcommands > DPSOFTRAST_DRAW_MAXCOMMANDPOOL - (size + extra))
{
-#ifdef USETHREADS
+#ifdef USE_THREADS
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)
{
+#ifdef SSE2_PRESENT
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);
+#endif
}
void DPSOFTRAST_Draw_GenerateSpans(DPSOFTRAST_State_Thread *thread, int freetriangle)
{
+#ifdef SSE2_PRESENT
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;
+#endif
}
void DPSOFTRAST_Draw_FlushThreads(void)
MEMORY_BARRIER;
dpsoftrast.drawtriangle = dpsoftrast.trianglepool.freetriangle;
}
-#ifdef USETHREADS
+#ifdef USE_THREADS
SDL_LockMutex(dpsoftrast.trianglemutex);
#endif
for (i = 0; i < dpsoftrast.numthreads; i++)
{
thread = &dpsoftrast.threads[i];
-#ifdef USETHREADS
+#ifdef USE_THREADS
while (thread->triangleoffset != dpsoftrast.drawtriangle)
{
thread->waiting = true;
DPSOFTRAST_Draw_GenerateSpans(thread, dpsoftrast.drawtriangle);
#endif
}
-#ifdef USETHREADS
+#ifdef USE_THREADS
SDL_UnlockMutex(dpsoftrast.trianglemutex);
#endif
dpsoftrast.trianglepool.usedtriangles = 0;
dpsoftrast.commandpool.usedcommands = 0;
}
-#ifdef USETHREADS
+#ifdef USE_THREADS
static int DPSOFTRAST_Draw_Thread(void *data)
{
DPSOFTRAST_State_Thread *thread = (DPSOFTRAST_State_Thread *)data;
}
if (dpsoftrast.trianglepool.usedtriangles >= DPSOFTRAST_DRAW_MAXTRIANGLEPOOL-1)
-#ifdef USETHREADS
+#ifdef USE_THREADS
DPSOFTRAST_Draw_FreeTrianglePool(DPSOFTRAST_DRAW_MAXTRIANGLEPOOL/8);
#else
DPSOFTRAST_Draw_FlushThreads();
MEMORY_BARRIER;
dpsoftrast.drawtriangle = dpsoftrast.trianglepool.freetriangle;
-#ifdef USETHREADS
+#ifdef USE_THREADS
SDL_LockMutex(dpsoftrast.trianglemutex);
SDL_CondBroadcast(dpsoftrast.trianglecond);
SDL_UnlockMutex(dpsoftrast.trianglemutex);
MEMORY_BARRIER;
dpsoftrast.drawtriangle = dpsoftrast.trianglepool.freetriangle;
-#ifdef USETHREADS
+#ifdef USE_THREADS
SDL_LockMutex(dpsoftrast.trianglemutex);
SDL_CondBroadcast(dpsoftrast.trianglecond);
SDL_UnlockMutex(dpsoftrast.trianglemutex);
dpsoftrast.color[2] = 1;
dpsoftrast.color[3] = 1;
dpsoftrast.cullface = GL_BACK;
-#ifdef USETHREADS
+#ifdef USE_THREADS
dpsoftrast.numthreads = bound(1, numthreads, 64);
dpsoftrast.trianglemutex = SDL_CreateMutex();
dpsoftrast.trianglecond = SDL_CreateCond();
thread->triangleoffset = 0;
thread->commandoffset = 0;
thread->waiting = false;
-#ifdef USETHREADS
+#ifdef USE_THREADS
thread->waitcond = SDL_CreateCond();
#endif
thread->validate = -1;
DPSOFTRAST_Validate(thread, -1);
-#ifdef USETHREADS
+#ifdef USE_THREADS
thread->thread = SDL_CreateThread(DPSOFTRAST_Draw_Thread, thread);
#endif
}
void DPSOFTRAST_Shutdown(void)
{
int i;
-#ifdef USETHREADS
+#ifdef USE_THREADS
if(dpsoftrast.numthreads > 0)
{
DPSOFTRAST_State_Thread *thread;
csprogs.o \
curves.o \
cvar.o \
- dpsoftrast.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
-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
# Compilation
CFLAGS_PROFILE=-g -pg -ggdb -fprofile-arcs
CFLAGS_RELEASE=
CFLAGS_RELEASE_PROFILE=-fbranch-probabilities
-CFLAGS_SDL=$(SDLCONFIG_CFLAGS)
+CFLAGS_SDL=$(SDLCONFIG_CFLAGS) -DUSE_SDL
CFLAGS_SSE=-msse
##### 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)
$(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)
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"};