mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 14:51:51 +00:00
Select blend function once per triangle
This commit is contained in:
parent
73c62c5404
commit
f7ae955e6a
2 changed files with 62 additions and 36 deletions
|
@ -272,6 +272,8 @@ public:
|
||||||
uint8_t StencilTestValue = 0;
|
uint8_t StencilTestValue = 0;
|
||||||
uint8_t StencilWriteValue = 0;
|
uint8_t StencilWriteValue = 0;
|
||||||
|
|
||||||
|
void (*WriteColorFunc)(int y, int x0, int x1, PolyTriangleThreadData* thread) = nullptr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ShadedTriVertex ShadeVertex(int index);
|
ShadedTriVertex ShadeVertex(int index);
|
||||||
void DrawShadedPoint(const ShadedTriVertex *const* vertex);
|
void DrawShadedPoint(const ShadedTriVertex *const* vertex);
|
||||||
|
|
|
@ -596,57 +596,78 @@ static void BlendColor(int y, int x0, int x1, PolyTriangleThreadData* thread)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void WriteColor(int y, int x0, int x1, PolyTriangleThreadData* thread)
|
#ifdef NO_SSE
|
||||||
|
static void BlendColorOpaque(int y, int x0, int x1, PolyTriangleThreadData* thread)
|
||||||
{
|
{
|
||||||
using namespace TriScreenDrawerModes;
|
uint32_t* dest = (uint32_t*)thread->dest;
|
||||||
|
uint32_t* line = dest + y * (ptrdiff_t)thread->dest_pitch;
|
||||||
|
uint32_t* fragcolor = thread->scanline.FragColor;
|
||||||
|
|
||||||
|
memcpy(line + x0, fragcolor + x0, (x1 - x0) * sizeof(uint32_t));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static void BlendColorOpaque(int y, int x0, int x1, PolyTriangleThreadData* thread)
|
||||||
|
{
|
||||||
|
uint32_t* dest = (uint32_t*)thread->dest;
|
||||||
|
uint32_t* line = dest + y * (ptrdiff_t)thread->dest_pitch;
|
||||||
|
uint32_t* fragcolor = thread->scanline.FragColor;
|
||||||
|
|
||||||
|
int ssecount = ((x1 - x0) & ~3);
|
||||||
|
int sseend = x0 + ssecount;
|
||||||
|
|
||||||
|
for (int x = x0; x < sseend; x += 4)
|
||||||
|
{
|
||||||
|
__m128i v = _mm_loadu_si128((__m128i*) & fragcolor[x]);
|
||||||
|
_mm_storeu_si128((__m128i*) & line[x], v);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int x = sseend; x < x1; x++)
|
||||||
|
{
|
||||||
|
line[x] = fragcolor[x];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void BlendColorOpaqueAlphaTest(int y, int x0, int x1, PolyTriangleThreadData* thread)
|
||||||
|
{
|
||||||
|
uint32_t* dest = (uint32_t*)thread->dest;
|
||||||
|
uint32_t* line = dest + y * (ptrdiff_t)thread->dest_pitch;
|
||||||
|
uint32_t* fragcolor = thread->scanline.FragColor;
|
||||||
|
uint8_t* discard = thread->scanline.discard;
|
||||||
|
for (int x = x0; x < x1; x++)
|
||||||
|
{
|
||||||
|
if (!discard[x])
|
||||||
|
line[x] = fragcolor[x];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SelectWriteColorFunc(PolyTriangleThreadData* thread)
|
||||||
|
{
|
||||||
|
void(*writecolorfunc)(int y, int x0, int x1, PolyTriangleThreadData * thread);
|
||||||
|
|
||||||
FRenderStyle style = thread->RenderStyle;
|
FRenderStyle style = thread->RenderStyle;
|
||||||
if (style.BlendOp == STYLEOP_Add && style.SrcAlpha == STYLEALPHA_One && style.DestAlpha == STYLEALPHA_Zero)
|
if (style.BlendOp == STYLEOP_Add && style.SrcAlpha == STYLEALPHA_One && style.DestAlpha == STYLEALPHA_Zero)
|
||||||
{
|
{
|
||||||
uint32_t* dest = (uint32_t*)thread->dest;
|
|
||||||
uint32_t* line = dest + y * (ptrdiff_t)thread->dest_pitch;
|
|
||||||
uint32_t* fragcolor = thread->scanline.FragColor;
|
|
||||||
|
|
||||||
if (!thread->AlphaTest)
|
if (!thread->AlphaTest)
|
||||||
{
|
{
|
||||||
#if !defined(NO_SSE)
|
writecolorfunc = &BlendColorOpaque;
|
||||||
int ssecount = ((x1 - x0) & ~3);
|
|
||||||
int sseend = x0 + ssecount;
|
|
||||||
|
|
||||||
for (int x = x0; x < sseend; x += 4)
|
|
||||||
{
|
|
||||||
__m128i v = _mm_loadu_si128((__m128i*)&fragcolor[x]);
|
|
||||||
_mm_storeu_si128((__m128i*)&line[x], v);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int x = sseend; x < x1; x++)
|
|
||||||
{
|
|
||||||
line[x] = fragcolor[x];
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
memcpy(line + x0, fragcolor + x0, (x1 - x0) * sizeof(uint32_t));
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint8_t* discard = thread->scanline.discard;
|
writecolorfunc = &BlendColorOpaqueAlphaTest;
|
||||||
for (int x = x0; x < x1; x++)
|
|
||||||
{
|
|
||||||
if (!discard[x])
|
|
||||||
line[x] = fragcolor[x];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
using namespace TriScreenDrawerModes;
|
||||||
if (!thread->AlphaTest)
|
if (!thread->AlphaTest)
|
||||||
{
|
{
|
||||||
switch (style.BlendOp)
|
switch (style.BlendOp)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
case STYLEOP_Add: BlendColor<BlendColorOpt_Add>(y, x0, x1, thread); break;
|
case STYLEOP_Add: writecolorfunc = &BlendColor<BlendColorOpt_Add>; break;
|
||||||
case STYLEOP_Sub: BlendColor<BlendColorOpt_Sub>(y, x0, x1, thread); break;
|
case STYLEOP_Sub: writecolorfunc = &BlendColor<BlendColorOpt_Sub>; break;
|
||||||
case STYLEOP_RevSub: BlendColor<BlendColorOpt_RevSub>(y, x0, x1, thread); break;
|
case STYLEOP_RevSub: writecolorfunc = &BlendColor<BlendColorOpt_RevSub>; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -654,12 +675,13 @@ static void WriteColor(int y, int x0, int x1, PolyTriangleThreadData* thread)
|
||||||
switch (style.BlendOp)
|
switch (style.BlendOp)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
case STYLEOP_Add: BlendColor<BlendColorOpt_AlphaTest_Add>(y, x0, x1, thread); break;
|
case STYLEOP_Add: writecolorfunc = BlendColor<BlendColorOpt_AlphaTest_Add>; break;
|
||||||
case STYLEOP_Sub: BlendColor<BlendColorOpt_AlphaTest_Sub>(y, x0, x1, thread); break;
|
case STYLEOP_Sub: writecolorfunc = BlendColor<BlendColorOpt_AlphaTest_Sub>; break;
|
||||||
case STYLEOP_RevSub: BlendColor<BlendColorOpt_AlphaTest_RevSub>(y, x0, x1, thread); break;
|
case STYLEOP_RevSub: writecolorfunc = BlendColor<BlendColorOpt_AlphaTest_RevSub>; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
thread->WriteColorFunc = writecolorfunc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WriteDepth(int y, int x0, int x1, PolyTriangleThreadData* thread)
|
static void WriteDepth(int y, int x0, int x1, PolyTriangleThreadData* thread)
|
||||||
|
@ -1210,7 +1232,7 @@ static void DrawSpan(int y, int x0, int x1, const TriDrawTriangleArgs* args, Pol
|
||||||
RunShader(x0, x1, thread);
|
RunShader(x0, x1, thread);
|
||||||
|
|
||||||
if (thread->WriteColor)
|
if (thread->WriteColor)
|
||||||
WriteColor(y, x0, x1, thread);
|
thread->WriteColorFunc(y, x0, x1, thread);
|
||||||
if (thread->WriteDepth)
|
if (thread->WriteDepth)
|
||||||
WriteDepth(y, x0, x1, thread);
|
WriteDepth(y, x0, x1, thread);
|
||||||
if (thread->WriteStencil)
|
if (thread->WriteStencil)
|
||||||
|
@ -1340,6 +1362,8 @@ void ScreenTriangle::Draw(const TriDrawTriangleArgs* args, PolyTriangleThreadDat
|
||||||
if (topY >= bottomY)
|
if (topY >= bottomY)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
SelectWriteColorFunc(thread);
|
||||||
|
|
||||||
void(*testfunc)(int y, int x0, int x1, const TriDrawTriangleArgs * args, PolyTriangleThreadData * thread);
|
void(*testfunc)(int y, int x0, int x1, const TriDrawTriangleArgs * args, PolyTriangleThreadData * thread);
|
||||||
|
|
||||||
int opt = 0;
|
int opt = 0;
|
||||||
|
|
Loading…
Reference in a new issue