#ifdef SSE_POSSIBLE
#include <emmintrin.h>
+#if defined(__GNUC__) && (__GNUC < 4 || __GNUC_MINOR__ < 6)
+ #define _mm_cvtss_f32(val) (__builtin_ia32_vec_ext_v4sf ((__v4sf)(val), 0))
+#endif
+
#define MM_MALLOC(size) _mm_malloc(size, ATOMIC_SIZE)
static void *MM_CALLOC(size_t nmemb, size_t size)
int startx; // usable range (according to pixelmask)
int endx; // usable range (according to pixelmask)
unsigned char *pixelmask; // true for pixels that passed depth test, false for others
+ int depthbase; // depthbuffer value at x (add depthslope*startx to get first pixel's depthbuffer value)
+ int depthslope; // depthbuffer value pixel delta
}
DPSOFTRAST_State_Span);
#define DPSOFTRAST_DRAW_MAXSPANS 1024
#define DPSOFTRAST_DRAW_MAXTRIANGLES 128
+#define DPSOFTRAST_DRAW_MAXSPANLENGTH 256
#define DPSOFTRAST_VALIDATE_FB 1
#define DPSOFTRAST_VALIDATE_DEPTHFUNC 2
int scissor[4];
float depthrange[2];
float polygonoffset[2];
- ALIGN(float clipplane[4]);
+ float clipplane[4];
+ ALIGN(float fb_clipplane[4]);
int shader_mode;
int shader_permutation;
int numtriangles;
DPSOFTRAST_State_Span spans[DPSOFTRAST_DRAW_MAXSPANS];
DPSOFTRAST_State_Triangle triangles[DPSOFTRAST_DRAW_MAXTRIANGLES];
+ unsigned char pixelmaskarray[DPSOFTRAST_DRAW_MAXSPANLENGTH+4]; // LordHavoc: padded to allow some termination bytes
}
DPSOFTRAST_State_Thread);
#define DPSOFTRAST_DEPTHOFFSET (128.0f)
#define DPSOFTRAST_BGRA8_FROM_RGBA32F(r,g,b,a) (((int)(r * 255.0f + 0.5f) << 16) | ((int)(g * 255.0f + 0.5f) << 8) | (int)(b * 255.0f + 0.5f) | ((int)(a * 255.0f + 0.5f) << 24))
#define DPSOFTRAST_DEPTH32_FROM_DEPTH32F(d) ((int)(DPSOFTRAST_DEPTHSCALE * (1-d)))
-#define DPSOFTRAST_DRAW_MAXSPANLENGTH 256
+
+static void DPSOFTRAST_Draw_DepthTest(DPSOFTRAST_State_Thread *thread, DPSOFTRAST_State_Span *span);
+static void DPSOFTRAST_Draw_DepthWrite(const DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Span *span);
static void DPSOFTRAST_RecalcViewport(const int *viewport, float *fb_viewportcenter, float *fb_viewportscale)
{
}
}
+static void DPSOFTRAST_RecalcClipPlane(DPSOFTRAST_State_Thread *thread)
+{
+ thread->fb_clipplane[0] = thread->clipplane[0] / thread->fb_viewportscale[1];
+ thread->fb_clipplane[1] = thread->clipplane[1] / thread->fb_viewportscale[2];
+ thread->fb_clipplane[2] = thread->clipplane[2] / thread->fb_viewportscale[3];
+ thread->fb_clipplane[3] = thread->clipplane[3] / thread->fb_viewportscale[0];
+ thread->fb_clipplane[3] -= thread->fb_viewportcenter[1]*thread->fb_clipplane[0] + thread->fb_viewportcenter[2]*thread->fb_clipplane[1] + thread->fb_viewportcenter[3]*thread->fb_clipplane[2] + thread->fb_viewportcenter[0]*thread->fb_clipplane[3];
+}
+
static void DPSOFTRAST_RecalcFB(DPSOFTRAST_State_Thread *thread)
{
// calculate framebuffer scissor, viewport, viewport clipped by scissor,
thread->fb_scissor[3] = y2 - y1;
DPSOFTRAST_RecalcViewport(thread->viewport, thread->fb_viewportcenter, thread->fb_viewportscale);
+ DPSOFTRAST_RecalcClipPlane(thread);
DPSOFTRAST_RecalcThread(thread);
}
static void DPSOFTRAST_Interpret_ClipPlane(DPSOFTRAST_State_Thread *thread, DPSOFTRAST_Command_ClipPlane *command)
{
memcpy(thread->clipplane, command->clipplane, 4*sizeof(float));
+ thread->validate |= DPSOFTRAST_VALIDATE_FB;
}
void DPSOFTRAST_ClipPlane(float x, float y, float z, float w)
{
DPSOFTRAST_Command_ClipPlane *command = DPSOFTRAST_ALLOCATECOMMAND(ClipPlane);
- x /= dpsoftrast.fb_viewportscale[1];
- y /= dpsoftrast.fb_viewportscale[2];
- z /= dpsoftrast.fb_viewportscale[3];
- w /= dpsoftrast.fb_viewportscale[0];
- w -= dpsoftrast.fb_viewportcenter[1]*x + dpsoftrast.fb_viewportcenter[2]*y + dpsoftrast.fb_viewportcenter[3]*z + dpsoftrast.fb_viewportcenter[0]*w;
command->clipplane[0] = x;
command->clipplane[1] = y;
command->clipplane[2] = z;
}
}
-void DPSOFTRAST_Draw_Span_Finish(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, const float * RESTRICT in4f)
-{
- int x;
- int startx = span->startx;
- int endx = span->endx;
- int d[4];
- float a, b;
- unsigned char * RESTRICT pixelmask = span->pixelmask;
- unsigned char * RESTRICT pixel = (unsigned char *)dpsoftrast.fb_colorpixels[0];
- if (!pixel)
- return;
- pixel += (span->y * dpsoftrast.fb_width + span->x) * 4;
- // handle alphatest now (this affects depth writes too)
- if (thread->alphatest)
- for (x = startx;x < endx;x++)
- if (in4f[x*4+3] < 0.5f)
- pixelmask[x] = false;
- // FIXME: this does not handle bigendian
- switch(thread->fb_blendmode)
- {
- case DPSOFTRAST_BLENDMODE_OPAQUE:
- for (x = startx;x < endx;x++)
- {
- if (!pixelmask[x])
- continue;
- d[0] = (int)(in4f[x*4+2]*255.0f);if (d[0] > 255) d[0] = 255;
- d[1] = (int)(in4f[x*4+1]*255.0f);if (d[1] > 255) d[1] = 255;
- d[2] = (int)(in4f[x*4+0]*255.0f);if (d[2] > 255) d[2] = 255;
- d[3] = (int)(in4f[x*4+3]*255.0f);if (d[3] > 255) d[3] = 255;
- pixel[x*4+0] = d[0];
- pixel[x*4+1] = d[1];
- pixel[x*4+2] = d[2];
- pixel[x*4+3] = d[3];
- }
- break;
- case DPSOFTRAST_BLENDMODE_ALPHA:
- for (x = startx;x < endx;x++)
- {
- if (!pixelmask[x])
- continue;
- a = in4f[x*4+3] * 255.0f;
- b = 1.0f - in4f[x*4+3];
- d[0] = (int)(in4f[x*4+2]*a+pixel[x*4+0]*b);if (d[0] > 255) d[0] = 255;
- d[1] = (int)(in4f[x*4+1]*a+pixel[x*4+1]*b);if (d[1] > 255) d[1] = 255;
- d[2] = (int)(in4f[x*4+0]*a+pixel[x*4+2]*b);if (d[2] > 255) d[2] = 255;
- d[3] = (int)(in4f[x*4+3]*a+pixel[x*4+3]*b);if (d[3] > 255) d[3] = 255;
- pixel[x*4+0] = d[0];
- pixel[x*4+1] = d[1];
- pixel[x*4+2] = d[2];
- pixel[x*4+3] = d[3];
- }
- break;
- case DPSOFTRAST_BLENDMODE_ADDALPHA:
- for (x = startx;x < endx;x++)
- {
- if (!pixelmask[x])
- continue;
- a = in4f[x*4+3] * 255.0f;
- d[0] = (int)(in4f[x*4+2]*a+pixel[x*4+0]);if (d[0] > 255) d[0] = 255;
- d[1] = (int)(in4f[x*4+1]*a+pixel[x*4+1]);if (d[1] > 255) d[1] = 255;
- d[2] = (int)(in4f[x*4+0]*a+pixel[x*4+2]);if (d[2] > 255) d[2] = 255;
- d[3] = (int)(in4f[x*4+3]*a+pixel[x*4+3]);if (d[3] > 255) d[3] = 255;
- pixel[x*4+0] = d[0];
- pixel[x*4+1] = d[1];
- pixel[x*4+2] = d[2];
- pixel[x*4+3] = d[3];
- }
- break;
- case DPSOFTRAST_BLENDMODE_ADD:
- for (x = startx;x < endx;x++)
- {
- if (!pixelmask[x])
- continue;
- d[0] = (int)(in4f[x*4+2]*255.0f+pixel[x*4+0]);if (d[0] > 255) d[0] = 255;
- d[1] = (int)(in4f[x*4+1]*255.0f+pixel[x*4+1]);if (d[1] > 255) d[1] = 255;
- d[2] = (int)(in4f[x*4+0]*255.0f+pixel[x*4+2]);if (d[2] > 255) d[2] = 255;
- d[3] = (int)(in4f[x*4+3]*255.0f+pixel[x*4+3]);if (d[3] > 255) d[3] = 255;
- pixel[x*4+0] = d[0];
- pixel[x*4+1] = d[1];
- pixel[x*4+2] = d[2];
- pixel[x*4+3] = d[3];
- }
- break;
- case DPSOFTRAST_BLENDMODE_INVMOD:
- for (x = startx;x < endx;x++)
- {
- if (!pixelmask[x])
- continue;
- d[0] = (int)((1.0f-in4f[x*4+2])*pixel[x*4+0]);if (d[0] > 255) d[0] = 255;
- d[1] = (int)((1.0f-in4f[x*4+1])*pixel[x*4+1]);if (d[1] > 255) d[1] = 255;
- d[2] = (int)((1.0f-in4f[x*4+0])*pixel[x*4+2]);if (d[2] > 255) d[2] = 255;
- d[3] = (int)((1.0f-in4f[x*4+3])*pixel[x*4+3]);if (d[3] > 255) d[3] = 255;
- pixel[x*4+0] = d[0];
- pixel[x*4+1] = d[1];
- pixel[x*4+2] = d[2];
- pixel[x*4+3] = d[3];
- }
- break;
- case DPSOFTRAST_BLENDMODE_MUL:
- for (x = startx;x < endx;x++)
- {
- if (!pixelmask[x])
- continue;
- d[0] = (int)(in4f[x*4+2]*pixel[x*4+0]);if (d[0] > 255) d[0] = 255;
- d[1] = (int)(in4f[x*4+1]*pixel[x*4+1]);if (d[1] > 255) d[1] = 255;
- d[2] = (int)(in4f[x*4+0]*pixel[x*4+2]);if (d[2] > 255) d[2] = 255;
- d[3] = (int)(in4f[x*4+3]*pixel[x*4+3]);if (d[3] > 255) d[3] = 255;
- pixel[x*4+0] = d[0];
- pixel[x*4+1] = d[1];
- pixel[x*4+2] = d[2];
- pixel[x*4+3] = d[3];
- }
- break;
- case DPSOFTRAST_BLENDMODE_MUL2:
- for (x = startx;x < endx;x++)
- {
- if (!pixelmask[x])
- continue;
- d[0] = (int)(in4f[x*4+2]*pixel[x*4+0]*2.0f);if (d[0] > 255) d[0] = 255;
- d[1] = (int)(in4f[x*4+1]*pixel[x*4+1]*2.0f);if (d[1] > 255) d[1] = 255;
- d[2] = (int)(in4f[x*4+0]*pixel[x*4+2]*2.0f);if (d[2] > 255) d[2] = 255;
- d[3] = (int)(in4f[x*4+3]*pixel[x*4+3]*2.0f);if (d[3] > 255) d[3] = 255;
- pixel[x*4+0] = d[0];
- pixel[x*4+1] = d[1];
- pixel[x*4+2] = d[2];
- pixel[x*4+3] = d[3];
- }
- break;
- case DPSOFTRAST_BLENDMODE_SUBALPHA:
- for (x = startx;x < endx;x++)
- {
- if (!pixelmask[x])
- continue;
- a = in4f[x*4+3] * -255.0f;
- d[0] = (int)(in4f[x*4+2]*a+pixel[x*4+0]);if (d[0] > 255) d[0] = 255;if (d[0] < 0) d[0] = 0;
- d[1] = (int)(in4f[x*4+1]*a+pixel[x*4+1]);if (d[1] > 255) d[1] = 255;if (d[1] < 0) d[1] = 0;
- d[2] = (int)(in4f[x*4+0]*a+pixel[x*4+2]);if (d[2] > 255) d[2] = 255;if (d[2] < 0) d[2] = 0;
- d[3] = (int)(in4f[x*4+3]*a+pixel[x*4+3]);if (d[3] > 255) d[3] = 255;if (d[3] < 0) d[3] = 0;
- pixel[x*4+0] = d[0];
- pixel[x*4+1] = d[1];
- pixel[x*4+2] = d[2];
- pixel[x*4+3] = d[3];
- }
- break;
- case DPSOFTRAST_BLENDMODE_PSEUDOALPHA:
- for (x = startx;x < endx;x++)
- {
- if (!pixelmask[x])
- continue;
- a = 255.0f;
- b = 1.0f - in4f[x*4+3];
- d[0] = (int)(in4f[x*4+2]*a+pixel[x*4+0]*b);if (d[0] > 255) d[0] = 255;
- d[1] = (int)(in4f[x*4+1]*a+pixel[x*4+1]*b);if (d[1] > 255) d[1] = 255;
- d[2] = (int)(in4f[x*4+0]*a+pixel[x*4+2]*b);if (d[2] > 255) d[2] = 255;
- d[3] = (int)(in4f[x*4+3]*a+pixel[x*4+3]*b);if (d[3] > 255) d[3] = 255;
- pixel[x*4+0] = d[0];
- pixel[x*4+1] = d[1];
- pixel[x*4+2] = d[2];
- pixel[x*4+3] = d[3];
- }
- break;
- case DPSOFTRAST_BLENDMODE_INVADD:
- for (x = startx;x < endx;x++)
- {
- if (!pixelmask[x])
- continue;
- d[0] = (int)((255.0f-pixel[x*4+2])*in4f[x*4+0] + pixel[x*4+2]);if (d[0] > 255) d[0] = 255;
- d[1] = (int)((255.0f-pixel[x*4+1])*in4f[x*4+1] + pixel[x*4+1]);if (d[1] > 255) d[1] = 255;
- d[2] = (int)((255.0f-pixel[x*4+0])*in4f[x*4+2] + pixel[x*4+0]);if (d[2] > 255) d[2] = 255;
- d[3] = (int)((255.0f-pixel[x*4+3])*in4f[x*4+3] + pixel[x*4+3]);if (d[3] > 255) d[3] = 255;
- pixel[x*4+0] = d[0];
- pixel[x*4+1] = d[1];
- pixel[x*4+2] = d[2];
- pixel[x*4+3] = d[3];
- }
- break;
- }
-}
-
void DPSOFTRAST_Draw_Span_FinishBGRA8(DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Triangle * RESTRICT triangle, const DPSOFTRAST_State_Span * RESTRICT span, const unsigned char* RESTRICT in4ub)
{
#ifdef SSE_POSSIBLE
int x;
int startx = span->startx;
int endx = span->endx;
+ int maskx;
int subx;
const unsigned int * RESTRICT ini = (const unsigned int *)in4ub;
unsigned char * RESTRICT pixelmask = span->pixelmask;
case DPSOFTRAST_BLENDMODE_ALPHA:
case DPSOFTRAST_BLENDMODE_ADDALPHA:
case DPSOFTRAST_BLENDMODE_SUBALPHA:
+ maskx = startx;
for (x = startx;x < endx;x++)
- if (in4ub[x*4+3] < 1)
- pixelmask[x] = false;
+ {
+ if (in4ub[x*4+3] >= 1)
+ {
+ startx = x;
+ for (;;)
+ {
+ while (++x < endx && in4ub[x*4+3] >= 1) ;
+ maskx = x;
+ if (x >= endx) break;
+ ++x;
+ while (++x < endx && in4ub[x*4+3] < 1) pixelmask[x] = false;
+ if (x >= endx) break;
+ }
+ break;
+ }
+ }
+ endx = maskx;
break;
case DPSOFTRAST_BLENDMODE_OPAQUE:
case DPSOFTRAST_BLENDMODE_ADD:
if (x + 8 < endx)
{
// the 4-item search must be aligned or else it stalls badly
- if ((x & 3) && !pixelmask[x]) x++;
- if ((x & 3) && !pixelmask[x]) x++;
- if ((x & 3) && !pixelmask[x]) x++;
- while (*((unsigned int *)pixelmask + x) == 0x00000000)
+ if ((x & 3) && !pixelmask[x])
+ {
+ if(pixelmask[x]) goto endmasked;
+ x++;
+ if (x & 3)
+ {
+ if(pixelmask[x]) goto endmasked;
+ x++;
+ if (x & 3)
+ {
+ if(pixelmask[x]) goto endmasked;
+ x++;
+ }
+ }
+ }
+ while (*(unsigned int *)&pixelmask[x] == 0x00000000)
x += 4;
}
#endif
if (x >= endx)
break;
}
+ endmasked:
// find length of subspan
subx = x + 1;
#if 1
- if (x + 8 < endx)
+ if (subx + 8 < endx)
{
- if ((subx & 3) && pixelmask[subx]) subx++;
- if ((subx & 3) && pixelmask[subx]) subx++;
- if ((subx & 3) && pixelmask[subx]) subx++;
- while (*((unsigned int *)pixelmask + subx) == 0x01010101)
+ if (subx & 3)
+ {
+ if(!pixelmask[subx]) goto endunmasked;
+ subx++;
+ if (subx & 3)
+ {
+ if(!pixelmask[subx]) goto endunmasked;
+ subx++;
+ if (subx & 3)
+ {
+ if(!pixelmask[subx]) goto endunmasked;
+ subx++;
+ }
+ }
+ }
+ while (*(unsigned int *)&pixelmask[subx] == 0x01010101)
subx += 4;
}
#endif
// the checks can overshoot, so make sure to clip it...
if (subx > endx)
subx = endx;
+ endunmasked:
// now that we know the subspan length... process!
switch(thread->fb_blendmode)
{
{2, DPSOFTRAST_VertexShader_DeferredLightSource, DPSOFTRAST_PixelShader_DeferredLightSource, {~0}},
};
-void DPSOFTRAST_Draw_ProcessSpans(DPSOFTRAST_State_Thread *thread)
+static void DPSOFTRAST_Draw_DepthTest(DPSOFTRAST_State_Thread *thread, DPSOFTRAST_State_Span *span)
{
- int i;
int x;
int startx;
int endx;
-// unsigned int c;
-// unsigned int *colorpixel;
unsigned int *depthpixel;
- float w;
- float wslope;
int depth;
int depthslope;
unsigned int d;
+ unsigned char *pixelmask;
+ DPSOFTRAST_State_Triangle *triangle;
+ triangle = &thread->triangles[span->triangle];
+ depthpixel = dpsoftrast.fb_depthpixels + span->y * dpsoftrast.fb_width + span->x;
+ startx = span->startx;
+ endx = span->endx;
+ depth = span->depthbase;
+ depthslope = span->depthslope;
+ pixelmask = thread->pixelmaskarray;
+ if (thread->depthtest && dpsoftrast.fb_depthpixels)
+ {
+ switch(thread->fb_depthfunc)
+ {
+ default:
+ case GL_ALWAYS: for (x = startx, d = depth + depthslope*startx;x < endx;x++, d += depthslope) pixelmask[x] = true; break;
+ case GL_LESS: for (x = startx, d = depth + depthslope*startx;x < endx;x++, d += depthslope) pixelmask[x] = depthpixel[x] < d; break;
+ case GL_LEQUAL: for (x = startx, d = depth + depthslope*startx;x < endx;x++, d += depthslope) pixelmask[x] = depthpixel[x] <= d; break;
+ case GL_EQUAL: for (x = startx, d = depth + depthslope*startx;x < endx;x++, d += depthslope) pixelmask[x] = depthpixel[x] == d; break;
+ case GL_GEQUAL: for (x = startx, d = depth + depthslope*startx;x < endx;x++, d += depthslope) pixelmask[x] = depthpixel[x] >= d; break;
+ case GL_GREATER: for (x = startx, d = depth + depthslope*startx;x < endx;x++, d += depthslope) pixelmask[x] = depthpixel[x] > d; break;
+ case GL_NEVER: for (x = startx, d = depth + depthslope*startx;x < endx;x++, d += depthslope) pixelmask[x] = false; break;
+ }
+ while (startx < endx && !pixelmask[startx])
+ startx++;
+ while (endx > startx && !pixelmask[endx-1])
+ endx--;
+ }
+ else
+ {
+ // no depth testing means we're just dealing with color...
+ memset(pixelmask + startx, 1, endx - startx);
+ }
+ span->pixelmask = pixelmask;
+ span->startx = startx;
+ span->endx = endx;
+}
+
+static void DPSOFTRAST_Draw_DepthWrite(const DPSOFTRAST_State_Thread *thread, const DPSOFTRAST_State_Span *span)
+{
+ int x, d, depth, depthslope, startx, endx;
+ const unsigned char *pixelmask;
+ unsigned int *depthpixel;
+ if (thread->depthmask && thread->depthtest && dpsoftrast.fb_depthpixels)
+ {
+ depth = span->depthbase;
+ depthslope = span->depthslope;
+ pixelmask = span->pixelmask;
+ startx = span->startx;
+ endx = span->endx;
+ depthpixel = dpsoftrast.fb_depthpixels + span->y * dpsoftrast.fb_width + span->x;
+ for (x = startx, d = depth + depthslope*startx;x < endx;x++, d += depthslope)
+ if (pixelmask[x])
+ depthpixel[x] = d;
+ }
+}
+
+void DPSOFTRAST_Draw_ProcessSpans(DPSOFTRAST_State_Thread *thread)
+{
+ int i;
DPSOFTRAST_State_Triangle *triangle;
DPSOFTRAST_State_Span *span;
- unsigned char pixelmask[DPSOFTRAST_DRAW_MAXSPANLENGTH+4]; // LordHavoc: padded to allow some termination bytes
for (i = 0; i < thread->numspans; i++)
{
span = &thread->spans[i];
triangle = &thread->triangles[span->triangle];
- if (thread->depthtest && dpsoftrast.fb_depthpixels)
- {
- wslope = triangle->w[0];
- w = triangle->w[2] + span->x*wslope + span->y*triangle->w[1];
- depthslope = (int)(wslope*DPSOFTRAST_DEPTHSCALE);
- depth = (int)(w*DPSOFTRAST_DEPTHSCALE - DPSOFTRAST_DEPTHOFFSET*(thread->polygonoffset[1] + fabs(wslope)*thread->polygonoffset[0]));
- depthpixel = dpsoftrast.fb_depthpixels + span->y * dpsoftrast.fb_width + span->x;
- startx = span->startx;
- endx = span->endx;
- switch(thread->fb_depthfunc)
- {
- default:
- case GL_ALWAYS: for (x = startx, d = depth + depthslope*startx;x < endx;x++, d += depthslope) pixelmask[x] = true; break;
- case GL_LESS: for (x = startx, d = depth + depthslope*startx;x < endx;x++, d += depthslope) pixelmask[x] = depthpixel[x] < d; break;
- case GL_LEQUAL: for (x = startx, d = depth + depthslope*startx;x < endx;x++, d += depthslope) pixelmask[x] = depthpixel[x] <= d; break;
- case GL_EQUAL: for (x = startx, d = depth + depthslope*startx;x < endx;x++, d += depthslope) pixelmask[x] = depthpixel[x] == d; break;
- case GL_GEQUAL: for (x = startx, d = depth + depthslope*startx;x < endx;x++, d += depthslope) pixelmask[x] = depthpixel[x] >= d; break;
- case GL_GREATER: for (x = startx, d = depth + depthslope*startx;x < endx;x++, d += depthslope) pixelmask[x] = depthpixel[x] > d; break;
- case GL_NEVER: for (x = startx, d = depth + depthslope*startx;x < endx;x++, d += depthslope) pixelmask[x] = false; break;
- }
- //colorpixel = dpsoftrast.fb_colorpixels[0] + (span->y * dpsoftrast.fb_width + span->x) * 4;;
- //for (x = startx;x < endx;x++)
- // colorpixel[x] = (depthpixel[x] & 0xFF000000) ? (0x00FF0000) : (depthpixel[x] & 0x00FF0000);
- // if there is no color buffer, skip pixel shader
- while (startx < endx && !pixelmask[startx])
- startx++;
- while (endx > startx && !pixelmask[endx-1])
- endx--;
- if (startx >= endx)
- continue; // no pixels to fill
- span->pixelmask = pixelmask;
- span->startx = startx;
- span->endx = endx;
- // run pixel shader if appropriate
- // do this before running depthmask code, to allow the pixelshader
- // to clear pixelmask values for alpha testing
- if (dpsoftrast.fb_colorpixels[0] && thread->fb_colormask)
- DPSOFTRAST_ShaderModeTable[thread->shader_mode].Span(thread, triangle, span);
- if (thread->depthmask)
- for (x = startx, d = depth + depthslope*startx;x < endx;x++, d += depthslope)
- if (pixelmask[x])
- depthpixel[x] = d;
- }
- else
- {
- // no depth testing means we're just dealing with color...
- // if there is no color buffer, skip pixel shader
- if (dpsoftrast.fb_colorpixels[0] && thread->fb_colormask)
- {
- memset(pixelmask + span->startx, 1, span->endx - span->startx);
- span->pixelmask = pixelmask;
- DPSOFTRAST_ShaderModeTable[thread->shader_mode].Span(thread, triangle, span);
- }
- }
+ DPSOFTRAST_Draw_DepthTest(thread, span);
+ if (span->startx >= span->endx)
+ continue;
+ // run pixel shader if appropriate
+ // do this before running depthmask code, to allow the pixelshader
+ // to clear pixelmask values for alpha testing
+ if (dpsoftrast.fb_colorpixels[0] && thread->fb_colormask)
+ DPSOFTRAST_ShaderModeTable[thread->shader_mode].Span(thread, triangle, span);
+ DPSOFTRAST_Draw_DepthWrite(thread, span);
}
thread->numspans = 0;
}
clip0origin = 0;
clip0slope = 0;
clip0dir = 0;
- if(thread->clipplane[0] || thread->clipplane[1] || thread->clipplane[2])
+ if(thread->fb_clipplane[0] || thread->fb_clipplane[1] || thread->fb_clipplane[2])
{
float cliporigin, clipxslope, clipyslope;
attriborigin = _mm_shuffle_ps(screen[1], screen[1], _MM_SHUFFLE(2, 2, 2, 2));
attribxslope = _mm_sub_ss(_mm_mul_ss(attribuxslope, attribedge1), _mm_mul_ss(attribvxslope, attribedge2));
attribyslope = _mm_sub_ss(_mm_mul_ss(attribvyslope, attribedge2), _mm_mul_ss(attribuyslope, attribedge1));
attriborigin = _mm_sub_ss(attriborigin, _mm_add_ss(_mm_mul_ss(attribxslope, x1), _mm_mul_ss(attribyslope, y1)));
- cliporigin = _mm_cvtss_f32(attriborigin)*thread->clipplane[2] + thread->clipplane[3];
- clipxslope = thread->clipplane[0] + _mm_cvtss_f32(attribxslope)*thread->clipplane[2];
- clipyslope = thread->clipplane[1] + _mm_cvtss_f32(attribyslope)*thread->clipplane[2];
+ cliporigin = _mm_cvtss_f32(attriborigin)*thread->fb_clipplane[2] + thread->fb_clipplane[3];
+ clipxslope = thread->fb_clipplane[0] + _mm_cvtss_f32(attribxslope)*thread->fb_clipplane[2];
+ clipyslope = thread->fb_clipplane[1] + _mm_cvtss_f32(attribyslope)*thread->fb_clipplane[2];
if(clipxslope != 0)
{
clip0origin = -cliporigin/clipxslope;
int yccmask = _mm_movemask_epi8(ycc);
int edge0p, edge0n, edge1p, edge1n;
int nexty;
+ float w, wslope;
float clip0;
if (numpoints == 4)
{
xcoords = _mm_shuffle_ps(xcoords, xcoords, _MM_SHUFFLE(1, 0, 3, 2));
xslope = _mm_shuffle_ps(xslope, xslope, _MM_SHUFFLE(1, 0, 3, 2));
}
- clip0 = clip0origin + (y+0.5f)*clip0slope;
+ clip0 = clip0origin + (y+0.5f)*clip0slope + 0.5f;
for(; y <= nexty; y++, xcoords = _mm_add_ps(xcoords, xslope), clip0 += clip0slope)
{
- int startx, endx, clipx = minx, offset;
+ int startx, endx, offset;
startx = _mm_cvtss_si32(xcoords);
endx = _mm_cvtss_si32(_mm_movehl_ps(xcoords, xcoords));
- if (startx < minx)
- {
- if (startx < 0) startx = 0;
- startx += (minx-startx)&~(DPSOFTRAST_DRAW_MAXSPANLENGTH-1);
- }
+ if (startx < minx) startx = minx;
if (endx > maxx) endx = maxx;
if (startx >= endx) continue;
if (startx < clip0)
{
if(endx <= clip0) continue;
- clipx = max((int)clip0, minx);
- startx += (clipx-startx)&~(DPSOFTRAST_DRAW_MAXSPANLENGTH-1);
+ startx = (int)clip0;
}
}
else if (endx > clip0)
span->triangle = thread->numtriangles;
span->x = offset;
span->y = y;
- span->startx = max(clipx - offset, 0);
+ span->startx = 0;
span->endx = min(endx - offset, DPSOFTRAST_DRAW_MAXSPANLENGTH);
if (span->startx >= span->endx)
- continue;
+ continue;
+ wslope = triangle->w[0];
+ w = triangle->w[2] + span->x*wslope + span->y*triangle->w[1];
+ span->depthslope = (int)(wslope*DPSOFTRAST_DEPTHSCALE);
+ span->depthbase = (int)(w*DPSOFTRAST_DEPTHSCALE - DPSOFTRAST_DEPTHOFFSET*(thread->polygonoffset[1] + fabs(wslope)*thread->polygonoffset[0]));
if (++thread->numspans >= DPSOFTRAST_DRAW_MAXSPANS)
DPSOFTRAST_Draw_ProcessSpans(thread);
}
DPSOFTRAST_State_Thread *thread = &dpsoftrast.threads[i];
thread->index = i;
thread->cullface = GL_BACK;
+ thread->colormask[0] = 1;
thread->colormask[1] = 1;
thread->colormask[2] = 1;
thread->colormask[3] = 1;
thread->clipplane[2] = 0;
thread->clipplane[3] = 1;
- DPSOFTRAST_RecalcThread(thread);
-
thread->numspans = 0;
thread->numtriangles = 0;
thread->commandoffset = 0;