mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2025-02-21 11:01:36 +00:00
Fix portals not working in softpoly (#1323)
This commit is contained in:
parent
c7edb9d22f
commit
d6f8e80177
5 changed files with 105 additions and 103 deletions
|
@ -186,13 +186,8 @@ void PolyTriangleThreadData::SetDepthFunc(int func)
|
||||||
|
|
||||||
void PolyTriangleThreadData::SetDepthRange(float min, float max)
|
void PolyTriangleThreadData::SetDepthRange(float min, float max)
|
||||||
{
|
{
|
||||||
// The only two variants used by hwrenderer layer
|
DepthRangeStart = min;
|
||||||
if (min == 0.0f && max == 1.0f)
|
DepthRangeScale = max - min;
|
||||||
{
|
|
||||||
}
|
|
||||||
else if (min == 1.0f && max == 1.0f)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PolyTriangleThreadData::SetDepthBias(float depthBiasConstantFactor, float depthBiasSlopeFactor)
|
void PolyTriangleThreadData::SetDepthBias(float depthBiasConstantFactor, float depthBiasSlopeFactor)
|
||||||
|
@ -210,19 +205,18 @@ void PolyTriangleThreadData::SetStencil(int stencilRef, int op)
|
||||||
StencilTestValue = stencilRef;
|
StencilTestValue = stencilRef;
|
||||||
if (op == SOP_Increment)
|
if (op == SOP_Increment)
|
||||||
{
|
{
|
||||||
WriteStencil = StencilTest;
|
|
||||||
StencilWriteValue = MIN(stencilRef + 1, (int)255);
|
StencilWriteValue = MIN(stencilRef + 1, (int)255);
|
||||||
}
|
}
|
||||||
else if (op == SOP_Decrement)
|
else if (op == SOP_Decrement)
|
||||||
{
|
{
|
||||||
WriteStencil = StencilTest;
|
|
||||||
StencilWriteValue = MAX(stencilRef - 1, (int)0);
|
StencilWriteValue = MAX(stencilRef - 1, (int)0);
|
||||||
}
|
}
|
||||||
else // SOP_Keep
|
else // SOP_Keep
|
||||||
{
|
{
|
||||||
WriteStencil = false;
|
|
||||||
StencilWriteValue = stencilRef;
|
StencilWriteValue = stencilRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WriteStencil = StencilTest && (StencilTestValue != StencilWriteValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PolyTriangleThreadData::SetCulling(int mode)
|
void PolyTriangleThreadData::SetCulling(int mode)
|
||||||
|
|
|
@ -174,6 +174,8 @@ public:
|
||||||
bool WriteDepth = true;
|
bool WriteDepth = true;
|
||||||
uint8_t StencilTestValue = 0;
|
uint8_t StencilTestValue = 0;
|
||||||
uint8_t StencilWriteValue = 0;
|
uint8_t StencilWriteValue = 0;
|
||||||
|
float DepthRangeStart = 0.0f;
|
||||||
|
float DepthRangeScale = 1.0f;
|
||||||
|
|
||||||
void (*FragmentShader)(int x0, int x1, PolyTriangleThreadData* thread) = nullptr;
|
void (*FragmentShader)(int x0, int x1, PolyTriangleThreadData* thread) = nullptr;
|
||||||
void (*WriteColorFunc)(int y, int x0, int x1, PolyTriangleThreadData* thread) = nullptr;
|
void (*WriteColorFunc)(int y, int x0, int x1, PolyTriangleThreadData* thread) = nullptr;
|
||||||
|
|
|
@ -70,11 +70,13 @@ void WriteW(int y, int x0, int x1, const TriDrawTriangleArgs* args, PolyTriangle
|
||||||
mposW = _mm_add_ps(mposW, mstepW);
|
mposW = _mm_add_ps(mposW, mstepW);
|
||||||
}
|
}
|
||||||
|
|
||||||
posW += ssecount * stepW;
|
mstepW = _mm_set_ss(stepW);
|
||||||
for (int x = sseend; x < x1; x++)
|
for (int x = sseend; x < x1; x++)
|
||||||
{
|
{
|
||||||
w[x] = 1.0f / posW;
|
__m128 res = _mm_rcp_ss(mposW);
|
||||||
posW += stepW;
|
__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
|
#endif
|
||||||
|
|
|
@ -34,19 +34,28 @@
|
||||||
|
|
||||||
static void WriteDepth(int y, int x0, int x1, PolyTriangleThreadData* thread)
|
static void WriteDepth(int y, int x0, int x1, PolyTriangleThreadData* thread)
|
||||||
{
|
{
|
||||||
size_t pitch = thread->depthstencil->Width();
|
float* line = thread->depthstencil->DepthValues() + (size_t)thread->depthstencil->Width() * y;
|
||||||
float* line = thread->depthstencil->DepthValues() + pitch * y;
|
|
||||||
|
if (thread->DepthRangeScale != 0.0f)
|
||||||
|
{
|
||||||
float* w = thread->scanline.W;
|
float* w = thread->scanline.W;
|
||||||
for (int x = x0; x < x1; x++)
|
for (int x = x0; x < x1; x++)
|
||||||
{
|
{
|
||||||
line[x] = w[x];
|
line[x] = w[x];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else // portal fills always uses DepthRangeStart = 1 and DepthRangeScale = 0
|
||||||
|
{
|
||||||
|
for (int x = x0; x < x1; x++)
|
||||||
|
{
|
||||||
|
line[x] = 65536.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void WriteStencil(int y, int x0, int x1, PolyTriangleThreadData* thread)
|
static void WriteStencil(int y, int x0, int x1, PolyTriangleThreadData* thread)
|
||||||
{
|
{
|
||||||
size_t pitch = thread->depthstencil->Width();
|
uint8_t* line = thread->depthstencil->StencilValues() + (size_t)thread->depthstencil->Width() * y;
|
||||||
uint8_t* line = thread->depthstencil->StencilValues() + pitch * y;
|
|
||||||
uint8_t value = thread->StencilWriteValue;
|
uint8_t value = thread->StencilWriteValue;
|
||||||
for (int x = x0; x < x1; x++)
|
for (int x = x0; x < x1; x++)
|
||||||
{
|
{
|
||||||
|
@ -54,11 +63,16 @@ static void WriteStencil(int y, int x0, int x1, PolyTriangleThreadData* thread)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
WriteVaryings(y, x0, x1, args, thread);
|
||||||
|
|
||||||
thread->FragmentShader(x0, x1, 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)
|
if (!thread->AlphaTest)
|
||||||
{
|
{
|
||||||
|
@ -92,36 +106,19 @@ static void DrawSpan(int y, int x0, int x1, const TriDrawTriangleArgs* args, Pol
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename OptT>
|
static void NoTestSpan(int y, int x0, int x1, const TriDrawTriangleArgs* args, PolyTriangleThreadData* thread)
|
||||||
static void TestSpan(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);
|
WriteW(y, x0, x1, args, thread);
|
||||||
|
|
||||||
if ((OptT::Flags & SWTRI_DepthTest) || (OptT::Flags & SWTRI_StencilTest))
|
float* zbufferLine = thread->depthstencil->DepthValues() + (size_t)thread->depthstencil->Width() * y;
|
||||||
{
|
float* w = thread->scanline.W;
|
||||||
size_t pitch = thread->depthstencil->Width();
|
float depthbias = thread->depthbias;
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
float* zbuffer;
|
|
||||||
float* zbufferLine;
|
|
||||||
float* w;
|
|
||||||
float depthbias;
|
|
||||||
if (OptT::Flags & SWTRI_DepthTest)
|
|
||||||
{
|
|
||||||
zbuffer = thread->depthstencil->DepthValues();
|
|
||||||
zbufferLine = zbuffer + pitch * y;
|
|
||||||
w = thread->scanline.W;
|
|
||||||
depthbias = thread->depthbias;
|
|
||||||
}
|
|
||||||
|
|
||||||
int x = x0;
|
int x = x0;
|
||||||
int xend = x1;
|
int xend = x1;
|
||||||
|
@ -129,51 +126,63 @@ static void TestSpan(int y, int x0, int x1, const TriDrawTriangleArgs* args, Pol
|
||||||
{
|
{
|
||||||
int xstart = x;
|
int xstart = 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)
|
while (zbufferLine[x] >= w[x] + depthbias && x < xend)
|
||||||
x++;
|
x++;
|
||||||
}
|
|
||||||
else if (OptT::Flags & SWTRI_StencilTest)
|
|
||||||
{
|
|
||||||
while (stencilLine[x] == stencilTestValue && x < xend)
|
|
||||||
x++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
x = xend;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (x > xstart)
|
if (x > xstart)
|
||||||
{
|
{
|
||||||
DrawSpan(y, xstart, x, args, thread);
|
DrawSpan(y, xstart, x, args, thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
while (zbufferLine[x] < w[x] + depthbias && x < xend)
|
||||||
x++;
|
x++;
|
||||||
}
|
}
|
||||||
else if (OptT::Flags & SWTRI_StencilTest)
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
int x = x0;
|
||||||
|
int xend = x1;
|
||||||
|
while (x < xend)
|
||||||
|
{
|
||||||
|
int xstart = x;
|
||||||
|
while (stencilLine[x] == stencilTestValue && x < xend)
|
||||||
|
x++;
|
||||||
|
|
||||||
|
if (x > xstart)
|
||||||
|
{
|
||||||
|
DepthTestSpan(y, xstart, x, args, thread);
|
||||||
|
}
|
||||||
|
|
||||||
while (stencilLine[x] != stencilTestValue && x < xend)
|
while (stencilLine[x] != stencilTestValue && x < xend)
|
||||||
x++;
|
x++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
static void StencilTestSpan(int y, int x0, int x1, const TriDrawTriangleArgs* args, PolyTriangleThreadData* thread)
|
||||||
{
|
{
|
||||||
DrawSpan(y, x0, x1, args, 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)
|
||||||
|
{
|
||||||
|
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++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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) =
|
void(*ScreenTriangle::TestSpanOpts[])(int y, int x0, int x1, const TriDrawTriangleArgs* args, PolyTriangleThreadData* thread) =
|
||||||
{
|
{
|
||||||
&TestSpan<TestSpanOpt0>,
|
&NoTestSpan,
|
||||||
&TestSpan<TestSpanOpt1>,
|
&DepthTestSpan,
|
||||||
&TestSpan<TestSpanOpt2>,
|
&StencilTestSpan,
|
||||||
&TestSpan<TestSpanOpt3>
|
&DepthStencilTestSpan
|
||||||
};
|
};
|
||||||
|
|
|
@ -122,8 +122,3 @@ enum SWTestSpan
|
||||||
SWTRI_DepthTest = 1,
|
SWTRI_DepthTest = 1,
|
||||||
SWTRI_StencilTest = 2
|
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; };
|
|
||||||
|
|
Loading…
Reference in a new issue