Skip to content

Commit

Permalink
Fix portals not working in softpoly (#1323)
Browse files Browse the repository at this point in the history
  • Loading branch information
dpjudas committed Mar 1, 2021
1 parent c7edb9d commit d6f8e80
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 98 deletions.
14 changes: 4 additions & 10 deletions src/common/rendering/polyrenderer/drawers/poly_thread.cpp
Expand Up @@ -186,13 +186,8 @@ void PolyTriangleThreadData::SetDepthFunc(int func)

void PolyTriangleThreadData::SetDepthRange(float min, float max)
{
// The only two variants used by hwrenderer layer
if (min == 0.0f && max == 1.0f)
{
}
else if (min == 1.0f && max == 1.0f)
{
}
DepthRangeStart = min;
DepthRangeScale = max - min;
}

void PolyTriangleThreadData::SetDepthBias(float depthBiasConstantFactor, float depthBiasSlopeFactor)
Expand All @@ -210,19 +205,18 @@ void PolyTriangleThreadData::SetStencil(int stencilRef, int op)
StencilTestValue = stencilRef;
if (op == SOP_Increment)
{
WriteStencil = StencilTest;
StencilWriteValue = MIN(stencilRef + 1, (int)255);
}
else if (op == SOP_Decrement)
{
WriteStencil = StencilTest;
StencilWriteValue = MAX(stencilRef - 1, (int)0);
}
else // SOP_Keep
{
WriteStencil = false;
StencilWriteValue = stencilRef;
}

WriteStencil = StencilTest && (StencilTestValue != StencilWriteValue);
}

void PolyTriangleThreadData::SetCulling(int mode)
Expand Down
2 changes: 2 additions & 0 deletions src/common/rendering/polyrenderer/drawers/poly_thread.h
Expand Up @@ -174,6 +174,8 @@ class PolyTriangleThreadData
bool WriteDepth = true;
uint8_t StencilTestValue = 0;
uint8_t StencilWriteValue = 0;
float DepthRangeStart = 0.0f;
float DepthRangeScale = 1.0f;

void (*FragmentShader)(int x0, int x1, PolyTriangleThreadData* thread) = nullptr;
void (*WriteColorFunc)(int y, int x0, int x1, PolyTriangleThreadData* thread) = nullptr;
Expand Down
Expand Up @@ -70,11 +70,13 @@ void WriteW(int y, int x0, int x1, const TriDrawTriangleArgs* args, PolyTriangle
mposW = _mm_add_ps(mposW, mstepW);
}

posW += ssecount * stepW;
mstepW = _mm_set_ss(stepW);
for (int x = sseend; x < x1; x++)
{
w[x] = 1.0f / posW;
posW += stepW;
__m128 res = _mm_rcp_ss(mposW);
__m128 muls = _mm_mul_ss(mposW, _mm_mul_ss(res, res));
_mm_store_ss(w + x, _mm_sub_ss(_mm_add_ss(res, res), muls));
mposW = _mm_add_ss(mposW, mstepW);
}
}
#endif
Expand Down
169 changes: 89 additions & 80 deletions src/common/rendering/polyrenderer/drawers/screen_triangle.cpp
Expand Up @@ -34,31 +34,45 @@

static void WriteDepth(int y, int x0, int x1, PolyTriangleThreadData* thread)
{
size_t pitch = thread->depthstencil->Width();
float* line = thread->depthstencil->DepthValues() + pitch * y;
float* w = thread->scanline.W;
for (int x = x0; x < x1; x++)
float* line = thread->depthstencil->DepthValues() + (size_t)thread->depthstencil->Width() * y;

if (thread->DepthRangeScale != 0.0f)
{
float* w = thread->scanline.W;
for (int x = x0; x < x1; x++)
{
line[x] = w[x];
}
}
else // portal fills always uses DepthRangeStart = 1 and DepthRangeScale = 0
{
line[x] = w[x];
for (int x = x0; x < x1; x++)
{
line[x] = 65536.0f;
}
}
}

static void WriteStencil(int y, int x0, int x1, PolyTriangleThreadData* thread)
{
size_t pitch = thread->depthstencil->Width();
uint8_t* line = thread->depthstencil->StencilValues() + pitch * y;
uint8_t* line = thread->depthstencil->StencilValues() + (size_t)thread->depthstencil->Width() * y;
uint8_t value = thread->StencilWriteValue;
for (int x = x0; x < x1; x++)
{
line[x] = value;
}
}

static void DrawSpan(int y, int x0, int x1, const TriDrawTriangleArgs* args, PolyTriangleThreadData* thread)
static void RunFragmentShader(int y, int x0, int x1, const TriDrawTriangleArgs* args, PolyTriangleThreadData* thread)
{
WriteVaryings(y, x0, x1, args, thread);

thread->FragmentShader(x0, x1, thread);
}

static void DrawSpan(int y, int x0, int x1, const TriDrawTriangleArgs* args, PolyTriangleThreadData* thread)
{
if (thread->WriteColor || thread->AlphaTest)
RunFragmentShader(y, x0, x1, args, thread);

if (!thread->AlphaTest)
{
Expand Down Expand Up @@ -92,88 +106,83 @@ static void DrawSpan(int y, int x0, int x1, const TriDrawTriangleArgs* args, Pol
}
}

template<typename OptT>
static void TestSpan(int y, int x0, int x1, const TriDrawTriangleArgs* args, PolyTriangleThreadData* thread)
static void NoTestSpan(int y, int x0, int x1, const TriDrawTriangleArgs* args, PolyTriangleThreadData* thread)
{
WriteW(y, x0, x1, args, thread);
DrawSpan(y, x0, x1, args, thread);
}

static void DepthTestSpan(int y, int x0, int x1, const TriDrawTriangleArgs* args, PolyTriangleThreadData* thread)
{
WriteW(y, x0, x1, args, thread);

float* zbufferLine = thread->depthstencil->DepthValues() + (size_t)thread->depthstencil->Width() * y;
float* w = thread->scanline.W;
float depthbias = thread->depthbias;

if ((OptT::Flags & SWTRI_DepthTest) || (OptT::Flags & SWTRI_StencilTest))
int x = x0;
int xend = x1;
while (x < xend)
{
size_t pitch = thread->depthstencil->Width();
int xstart = x;

uint8_t* stencilbuffer;
uint8_t* stencilLine;
uint8_t stencilTestValue;
if (OptT::Flags & SWTRI_StencilTest)
{
stencilbuffer = thread->depthstencil->StencilValues();
stencilLine = stencilbuffer + pitch * y;
stencilTestValue = thread->StencilTestValue;
}
while (zbufferLine[x] >= w[x] + depthbias && x < xend)
x++;

float* zbuffer;
float* zbufferLine;
float* w;
float depthbias;
if (OptT::Flags & SWTRI_DepthTest)
if (x > xstart)
{
zbuffer = thread->depthstencil->DepthValues();
zbufferLine = zbuffer + pitch * y;
w = thread->scanline.W;
depthbias = thread->depthbias;
DrawSpan(y, xstart, x, args, thread);
}

int x = x0;
int xend = x1;
while (x < xend)
{
int xstart = x;
while (zbufferLine[x] < w[x] + depthbias && x < xend)
x++;
}
}

if ((OptT::Flags & SWTRI_DepthTest) && (OptT::Flags & SWTRI_StencilTest))
{
while (zbufferLine[x] >= w[x] + depthbias && stencilLine[x] == stencilTestValue && x < xend)
x++;
}
else if (OptT::Flags & SWTRI_DepthTest)
{
while (zbufferLine[x] >= w[x] + depthbias && x < xend)
x++;
}
else if (OptT::Flags & SWTRI_StencilTest)
{
while (stencilLine[x] == stencilTestValue && x < xend)
x++;
}
else
{
x = xend;
}
static void DepthStencilTestSpan(int y, int x0, int x1, const TriDrawTriangleArgs* args, PolyTriangleThreadData* thread)
{
uint8_t* stencilLine = thread->depthstencil->StencilValues() + (size_t)thread->depthstencil->Width() * y;
uint8_t stencilTestValue = thread->StencilTestValue;

if (x > xstart)
{
DrawSpan(y, xstart, x, args, thread);
}
int x = x0;
int xend = x1;
while (x < xend)
{
int xstart = x;
while (stencilLine[x] == stencilTestValue && x < xend)
x++;

if ((OptT::Flags & SWTRI_DepthTest) && (OptT::Flags & SWTRI_StencilTest))
{
while ((zbufferLine[x] < w[x] + depthbias || stencilLine[x] != stencilTestValue) && x < xend)
x++;
}
else if (OptT::Flags & SWTRI_DepthTest)
{
while (zbufferLine[x] < w[x] + depthbias && x < xend)
x++;
}
else if (OptT::Flags & SWTRI_StencilTest)
{
while (stencilLine[x] != stencilTestValue && x < xend)
x++;
}
if (x > xstart)
{
DepthTestSpan(y, xstart, x, args, thread);
}

while (stencilLine[x] != stencilTestValue && x < xend)
x++;
}
else
}

static void StencilTestSpan(int y, int x0, int x1, const TriDrawTriangleArgs* args, PolyTriangleThreadData* thread)
{
uint8_t* stencilLine = thread->depthstencil->StencilValues() + (size_t)thread->depthstencil->Width() * y;
uint8_t stencilTestValue = thread->StencilTestValue;

int x = x0;
int xend = x1;
while (x < xend)
{
DrawSpan(y, x0, x1, args, thread);
int xstart = x;
while (stencilLine[x] == stencilTestValue && x < xend)
x++;

if (x > xstart)
{
WriteW(y, x0, x1, args, thread);
DrawSpan(y, xstart, x, args, thread);
}

while (stencilLine[x] != stencilTestValue && x < xend)
x++;
}
}

Expand Down Expand Up @@ -287,8 +296,8 @@ void ScreenTriangle::Draw(const TriDrawTriangleArgs* args, PolyTriangleThreadDat

void(*ScreenTriangle::TestSpanOpts[])(int y, int x0, int x1, const TriDrawTriangleArgs* args, PolyTriangleThreadData* thread) =
{
&TestSpan<TestSpanOpt0>,
&TestSpan<TestSpanOpt1>,
&TestSpan<TestSpanOpt2>,
&TestSpan<TestSpanOpt3>
&NoTestSpan,
&DepthTestSpan,
&StencilTestSpan,
&DepthStencilTestSpan
};
5 changes: 0 additions & 5 deletions src/common/rendering/polyrenderer/drawers/screen_triangle.h
Expand Up @@ -122,8 +122,3 @@ enum SWTestSpan
SWTRI_DepthTest = 1,
SWTRI_StencilTest = 2
};

struct TestSpanOpt0 { static const int Flags = 0; };
struct TestSpanOpt1 { static const int Flags = 1; };
struct TestSpanOpt2 { static const int Flags = 2; };
struct TestSpanOpt3 { static const int Flags = 3; };

0 comments on commit d6f8e80

Please sign in to comment.