- add CPU.bSSE2 branching support to softpoly

This commit is contained in:
Magnus Norddahl 2017-04-22 20:38:06 +02:00
commit 545241aa06
5 changed files with 339 additions and 177 deletions

View file

@ -41,6 +41,13 @@
#endif
#include "poly_drawer8.h"
namespace
{
class SSE2CPU { public: static const int HasSSE2 = 1; };
class GenericCPU { public: static const int HasSSE2 = 0; };
}
template<typename CPUType>
class TriangleBlock
{
public:
@ -114,9 +121,17 @@ private:
void ClipTest();
void StencilWrite();
void SubsectorWrite();
#ifndef NO_SSE
void CoverageTestSSE2();
void StencilEqualTestSSE2();
void SubsectorTestSSE2();
void SubsectorWriteSSE2();
#endif
};
TriangleBlock::TriangleBlock(const TriDrawTriangleArgs *args)
template<typename CPUType>
TriangleBlock<CPUType>::TriangleBlock(const TriDrawTriangleArgs *args)
{
const TriVertex &v1 = *args->v1;
const TriVertex &v2 = *args->v2;
@ -145,19 +160,32 @@ TriangleBlock::TriangleBlock(const TriDrawTriangleArgs *args)
const int X2 = (int)round(16.0f * v2.x);
const int X3 = (int)round(16.0f * v3.x);
#else
int tempround[4 * 3];
__m128 m16 = _mm_set1_ps(16.0f);
__m128 mhalf = _mm_set1_ps(65536.5f);
__m128i m65536 = _mm_set1_epi32(65536);
_mm_storeu_si128((__m128i*)tempround, _mm_sub_epi32(_mm_cvtps_epi32(_mm_add_ps(_mm_mul_ps(_mm_loadu_ps((const float*)&v1), m16), mhalf)), m65536));
_mm_storeu_si128((__m128i*)(tempround + 4), _mm_sub_epi32(_mm_cvtps_epi32(_mm_add_ps(_mm_mul_ps(_mm_loadu_ps((const float*)&v2), m16), mhalf)), m65536));
_mm_storeu_si128((__m128i*)(tempround + 8), _mm_sub_epi32(_mm_cvtps_epi32(_mm_add_ps(_mm_mul_ps(_mm_loadu_ps((const float*)&v3), m16), mhalf)), m65536));
const int X1 = tempround[0];
const int X2 = tempround[4];
const int X3 = tempround[8];
const int Y1 = tempround[1];
const int Y2 = tempround[5];
const int Y3 = tempround[9];
int Y1, Y2, Y3, X1, X2, X3;
if (CPUType::HasSSE2 == 1)
{
int tempround[4 * 3];
__m128 m16 = _mm_set1_ps(16.0f);
__m128 mhalf = _mm_set1_ps(65536.5f);
__m128i m65536 = _mm_set1_epi32(65536);
_mm_storeu_si128((__m128i*)tempround, _mm_sub_epi32(_mm_cvtps_epi32(_mm_add_ps(_mm_mul_ps(_mm_loadu_ps((const float*)&v1), m16), mhalf)), m65536));
_mm_storeu_si128((__m128i*)(tempround + 4), _mm_sub_epi32(_mm_cvtps_epi32(_mm_add_ps(_mm_mul_ps(_mm_loadu_ps((const float*)&v2), m16), mhalf)), m65536));
_mm_storeu_si128((__m128i*)(tempround + 8), _mm_sub_epi32(_mm_cvtps_epi32(_mm_add_ps(_mm_mul_ps(_mm_loadu_ps((const float*)&v3), m16), mhalf)), m65536));
X1 = tempround[0];
X2 = tempround[4];
X3 = tempround[8];
Y1 = tempround[1];
Y2 = tempround[5];
Y3 = tempround[9];
}
else
{
Y1 = (int)round(16.0f * v1.y);
Y2 = (int)round(16.0f * v2.y);
Y3 = (int)round(16.0f * v3.y);
X1 = (int)round(16.0f * v1.x);
X2 = (int)round(16.0f * v2.x);
X3 = (int)round(16.0f * v3.x);
}
#endif
// Deltas
@ -203,28 +231,32 @@ TriangleBlock::TriangleBlock(const TriDrawTriangleArgs *args)
if (DY31 < 0 || (DY31 == 0 && DX31 > 0)) C3++;
#ifndef NO_SSE
mFDY12Offset = _mm_setr_epi32(0, FDY12, FDY12 * 2, FDY12 * 3);
mFDY23Offset = _mm_setr_epi32(0, FDY23, FDY23 * 2, FDY23 * 3);
mFDY31Offset = _mm_setr_epi32(0, FDY31, FDY31 * 2, FDY31 * 3);
mFDY12x4 = _mm_set1_epi32(FDY12 * 4);
mFDY23x4 = _mm_set1_epi32(FDY23 * 4);
mFDY31x4 = _mm_set1_epi32(FDY31 * 4);
mFDX12 = _mm_set1_epi32(FDX12);
mFDX23 = _mm_set1_epi32(FDX23);
mFDX31 = _mm_set1_epi32(FDX31);
mC1 = _mm_set1_epi32(C1);
mC2 = _mm_set1_epi32(C2);
mC3 = _mm_set1_epi32(C3);
mDX12 = _mm_set1_epi32(DX12);
mDY12 = _mm_set1_epi32(DY12);
mDX23 = _mm_set1_epi32(DX23);
mDY23 = _mm_set1_epi32(DY23);
mDX31 = _mm_set1_epi32(DX31);
mDY31 = _mm_set1_epi32(DY31);
if (CPUType::HasSSE2 == 1)
{
mFDY12Offset = _mm_setr_epi32(0, FDY12, FDY12 * 2, FDY12 * 3);
mFDY23Offset = _mm_setr_epi32(0, FDY23, FDY23 * 2, FDY23 * 3);
mFDY31Offset = _mm_setr_epi32(0, FDY31, FDY31 * 2, FDY31 * 3);
mFDY12x4 = _mm_set1_epi32(FDY12 * 4);
mFDY23x4 = _mm_set1_epi32(FDY23 * 4);
mFDY31x4 = _mm_set1_epi32(FDY31 * 4);
mFDX12 = _mm_set1_epi32(FDX12);
mFDX23 = _mm_set1_epi32(FDX23);
mFDX31 = _mm_set1_epi32(FDX31);
mC1 = _mm_set1_epi32(C1);
mC2 = _mm_set1_epi32(C2);
mC3 = _mm_set1_epi32(C3);
mDX12 = _mm_set1_epi32(DX12);
mDY12 = _mm_set1_epi32(DY12);
mDX23 = _mm_set1_epi32(DX23);
mDY23 = _mm_set1_epi32(DY23);
mDX31 = _mm_set1_epi32(DX31);
mDY31 = _mm_set1_epi32(DY31);
}
#endif
}
void TriangleBlock::Loop(const TriDrawTriangleArgs *args, WorkerThreadData *thread)
template<typename CPUType>
void TriangleBlock<CPUType>::Loop(const TriDrawTriangleArgs *args, WorkerThreadData *thread)
{
// First block line for this thread
int core = thread->core;
@ -236,9 +268,18 @@ void TriangleBlock::Loop(const TriDrawTriangleArgs *args, WorkerThreadData *thre
bool writeColor = args->uniforms->WriteColor();
bool writeStencil = args->uniforms->WriteStencil();
bool writeSubsector = args->uniforms->WriteSubsector();
int bmode = (int)args->uniforms->BlendMode();
// Find the drawer function for the given blend mode
#ifndef NO_SSE
void(*drawFunc)(int, int, uint32_t, uint32_t, const TriDrawTriangleArgs *);
if (CPUType::HasSSE2 == 1)
drawFunc = args->destBgra ? ScreenTriangle::TriDrawers32_SSE2[bmode] : ScreenTriangle::TriDrawers8[bmode];
else
drawFunc = args->destBgra ? ScreenTriangle::TriDrawers32[bmode] : ScreenTriangle::TriDrawers8[bmode];
#else
auto drawFunc = args->destBgra ? ScreenTriangle::TriDrawers32[bmode] : ScreenTriangle::TriDrawers8[bmode];
#endif
// Loop through blocks
for (int y = start_miny; y < maxy; y += q * num_cores)
@ -248,7 +289,11 @@ void TriangleBlock::Loop(const TriDrawTriangleArgs *args, WorkerThreadData *thre
X = x;
Y = y;
CoverageTest();
if (CPUType::HasSSE2 == 1)
CoverageTestSSE2();
else
CoverageTest();
if (Mask0 == 0 && Mask1 == 0)
continue;
@ -259,7 +304,11 @@ void TriangleBlock::Loop(const TriDrawTriangleArgs *args, WorkerThreadData *thre
// To do: make the stencil test use its own flag for comparison mode instead of abusing the subsector test..
if (!subsectorTest)
{
StencilEqualTest();
if (CPUType::HasSSE2 == 1)
StencilEqualTestSSE2();
else
StencilEqualTest();
if (Mask0 == 0 && Mask1 == 0)
continue;
}
@ -269,7 +318,11 @@ void TriangleBlock::Loop(const TriDrawTriangleArgs *args, WorkerThreadData *thre
if (Mask0 == 0 && Mask1 == 0)
continue;
SubsectorTest();
if (CPUType::HasSSE2 == 1)
SubsectorTestSSE2();
else
SubsectorTest();
if (Mask0 == 0 && Mask1 == 0)
continue;
}
@ -279,14 +332,18 @@ void TriangleBlock::Loop(const TriDrawTriangleArgs *args, WorkerThreadData *thre
if (writeStencil)
StencilWrite();
if (writeSubsector)
SubsectorWrite();
{
if (CPUType::HasSSE2 == 1)
SubsectorWriteSSE2();
else
SubsectorWrite();
}
}
}
}
#ifdef NO_SSE
void TriangleBlock::SubsectorTest()
template<typename CPUType>
void TriangleBlock<CPUType>::SubsectorTest()
{
int block = (X >> 3) + (Y >> 3) * subsectorPitch;
uint32_t *subsector = subsectorGBuffer + block * 64;
@ -312,9 +369,10 @@ void TriangleBlock::SubsectorTest()
Mask1 = Mask1 & mask1;
}
#else
#ifndef NO_SSE
void TriangleBlock::SubsectorTest()
template<typename CPUType>
void TriangleBlock<CPUType>::SubsectorTestSSE2()
{
int block = (X >> 3) + (Y >> 3) * subsectorPitch;
uint32_t *subsector = subsectorGBuffer + block * 64;
@ -342,7 +400,8 @@ void TriangleBlock::SubsectorTest()
#endif
void TriangleBlock::ClipTest()
template<typename CPUType>
void TriangleBlock<CPUType>::ClipTest()
{
static const uint32_t clipxmask[8] =
{
@ -376,9 +435,8 @@ void TriangleBlock::ClipTest()
Mask1 = Mask1 & xmask & ymask1;
}
#ifdef NO_SSE
void TriangleBlock::StencilEqualTest()
template<typename CPUType>
void TriangleBlock<CPUType>::StencilEqualTest()
{
// Stencil test the whole block, if possible
int block = (X >> 3) + (Y >> 3) * stencilPitch;
@ -421,9 +479,10 @@ void TriangleBlock::StencilEqualTest()
}
}
#else
#ifndef NO_SSE
void TriangleBlock::StencilEqualTest()
template<typename CPUType>
void TriangleBlock<CPUType>::StencilEqualTestSSE2()
{
// Stencil test the whole block, if possible
int block = (X >> 3) + (Y >> 3) * stencilPitch;
@ -489,7 +548,8 @@ void TriangleBlock::StencilEqualTest()
#endif
void TriangleBlock::StencilGreaterEqualTest()
template<typename CPUType>
void TriangleBlock<CPUType>::StencilGreaterEqualTest()
{
// Stencil test the whole block, if possible
int block = (X >> 3) + (Y >> 3) * stencilPitch;
@ -532,9 +592,8 @@ void TriangleBlock::StencilGreaterEqualTest()
}
}
#ifdef NO_SSE
void TriangleBlock::CoverageTest()
template<typename CPUType>
void TriangleBlock<CPUType>::CoverageTest()
{
// Corners of block
int x0 = X << 4;
@ -631,9 +690,10 @@ void TriangleBlock::CoverageTest()
}
}
#else
#ifndef NO_SSE
void TriangleBlock::CoverageTest()
template<typename CPUType>
void TriangleBlock<CPUType>::CoverageTestSSE2()
{
// Corners of block
int x0 = X << 4;
@ -743,7 +803,8 @@ void TriangleBlock::CoverageTest()
#endif
void TriangleBlock::StencilWrite()
template<typename CPUType>
void TriangleBlock<CPUType>::StencilWrite()
{
int block = (X >> 3) + (Y >> 3) * stencilPitch;
uint8_t *stencilBlock = &stencilValues[block * 64];
@ -793,9 +854,8 @@ void TriangleBlock::StencilWrite()
}
}
#ifdef NO_SSE
void TriangleBlock::SubsectorWrite()
template<typename CPUType>
void TriangleBlock<CPUType>::SubsectorWrite()
{
int block = (X >> 3) + (Y >> 3) * subsectorPitch;
uint32_t *subsector = subsectorGBuffer + block * 64;
@ -828,9 +888,10 @@ void TriangleBlock::SubsectorWrite()
}
}
#else
#ifndef NO_SSE
void TriangleBlock::SubsectorWrite()
template<typename CPUType>
void TriangleBlock<CPUType>::SubsectorWriteSSE2()
{
int block = (X >> 3) + (Y >> 3) * subsectorPitch;
uint32_t *subsector = subsectorGBuffer + block * 64;
@ -887,8 +948,21 @@ void TriangleBlock::SubsectorWrite()
void ScreenTriangle::Draw(const TriDrawTriangleArgs *args, WorkerThreadData *thread)
{
TriangleBlock block(args);
#ifdef NO_SSE
TriangleBlock<GenericCPU> block(args);
block.Loop(args, thread);
#else
if (CPU.bSSE2)
{
TriangleBlock<SSE2CPU> block(args);
block.Loop(args, thread);
}
else
{
TriangleBlock<GenericCPU> block(args);
block.Loop(args, thread);
}
#endif
}
void(*ScreenTriangle::TriDrawers8[])(int, int, uint32_t, uint32_t, const TriDrawTriangleArgs *) =
@ -918,40 +992,38 @@ void(*ScreenTriangle::TriDrawers8[])(int, int, uint32_t, uint32_t, const TriDraw
&TriScreenDrawer8<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::FuzzSampler>::Execute // Fuzz
};
#ifdef NO_SSE
void(*ScreenTriangle::TriDrawers32[])(int, int, uint32_t, uint32_t, const TriDrawTriangleArgs *) =
{
nullptr
};
#else
#ifndef NO_SSE
void(*ScreenTriangle::TriDrawers32[])(int, int, uint32_t, uint32_t, const TriDrawTriangleArgs *) =
void(*ScreenTriangle::TriDrawers32_SSE2[])(int, int, uint32_t, uint32_t, const TriDrawTriangleArgs *) =
{
&TriScreenDrawer32<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureOpaque
&TriScreenDrawer32<TriScreenDrawerModes::MaskedBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureMasked
&TriScreenDrawer32<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureAdd
&TriScreenDrawer32<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureSub
&TriScreenDrawer32<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureRevSub
&TriScreenDrawer32<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureAddSrcColor
&TriScreenDrawer32<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedOpaque
&TriScreenDrawer32<TriScreenDrawerModes::MaskedBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedMasked
&TriScreenDrawer32<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedAdd
&TriScreenDrawer32<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedSub
&TriScreenDrawer32<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedRevSub
&TriScreenDrawer32<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedAddSrcColor
&TriScreenDrawer32<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::ShadedSampler>::Execute, // Shaded
&TriScreenDrawer32<TriScreenDrawerModes::AddClampShadedBlend, TriScreenDrawerModes::ShadedSampler>::Execute, // AddShaded
&TriScreenDrawer32<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::StencilSampler>::Execute, // Stencil
&TriScreenDrawer32<TriScreenDrawerModes::AddClampShadedBlend, TriScreenDrawerModes::StencilSampler>::Execute, // AddStencil
&TriScreenDrawer32<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillOpaque
&TriScreenDrawer32<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillAdd
&TriScreenDrawer32<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillSub
&TriScreenDrawer32<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillRevSub
&TriScreenDrawer32<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillAddSrcColor
&TriScreenDrawer32<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::SkycapSampler>::Execute, // Skycap
&TriScreenDrawer32<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::FuzzSampler>::Execute // Fuzz
&TriScreenDrawer32_SSE2<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureOpaque
&TriScreenDrawer32_SSE2<TriScreenDrawerModes::MaskedBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureMasked
&TriScreenDrawer32_SSE2<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureAdd
&TriScreenDrawer32_SSE2<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureSub
&TriScreenDrawer32_SSE2<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureRevSub
&TriScreenDrawer32_SSE2<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureAddSrcColor
&TriScreenDrawer32_SSE2<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedOpaque
&TriScreenDrawer32_SSE2<TriScreenDrawerModes::MaskedBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedMasked
&TriScreenDrawer32_SSE2<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedAdd
&TriScreenDrawer32_SSE2<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedSub
&TriScreenDrawer32_SSE2<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedRevSub
&TriScreenDrawer32_SSE2<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedAddSrcColor
&TriScreenDrawer32_SSE2<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::ShadedSampler>::Execute, // Shaded
&TriScreenDrawer32_SSE2<TriScreenDrawerModes::AddClampShadedBlend, TriScreenDrawerModes::ShadedSampler>::Execute, // AddShaded
&TriScreenDrawer32_SSE2<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::StencilSampler>::Execute, // Stencil
&TriScreenDrawer32_SSE2<TriScreenDrawerModes::AddClampShadedBlend, TriScreenDrawerModes::StencilSampler>::Execute, // AddStencil
&TriScreenDrawer32_SSE2<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillOpaque
&TriScreenDrawer32_SSE2<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillAdd
&TriScreenDrawer32_SSE2<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillSub
&TriScreenDrawer32_SSE2<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillRevSub
&TriScreenDrawer32_SSE2<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillAddSrcColor
&TriScreenDrawer32_SSE2<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::SkycapSampler>::Execute, // Skycap
&TriScreenDrawer32_SSE2<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::FuzzSampler>::Execute // Fuzz
};
#endif
@ -983,40 +1055,38 @@ void(*ScreenTriangle::RectDrawers8[])(const void *, int, int, int, const RectDra
&RectScreenDrawer8<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::FuzzSampler>::Execute // Fuzz
};
#ifdef NO_SSE
void(*ScreenTriangle::RectDrawers32[])(const void *, int, int, int, const RectDrawArgs *, WorkerThreadData *) =
{
nullptr
};
#else
#ifndef NO_SSE
void(*ScreenTriangle::RectDrawers32[])(const void *, int, int, int, const RectDrawArgs *, WorkerThreadData *) =
void(*ScreenTriangle::RectDrawers32_SSE2[])(const void *, int, int, int, const RectDrawArgs *, WorkerThreadData *) =
{
&RectScreenDrawer32<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureOpaque
&RectScreenDrawer32<TriScreenDrawerModes::MaskedBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureMasked
&RectScreenDrawer32<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureAdd
&RectScreenDrawer32<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureSub
&RectScreenDrawer32<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureRevSub
&RectScreenDrawer32<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureAddSrcColor
&RectScreenDrawer32<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedOpaque
&RectScreenDrawer32<TriScreenDrawerModes::MaskedBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedMasked
&RectScreenDrawer32<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedAdd
&RectScreenDrawer32<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedSub
&RectScreenDrawer32<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedRevSub
&RectScreenDrawer32<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedAddSrcColor
&RectScreenDrawer32<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::ShadedSampler>::Execute, // Shaded
&RectScreenDrawer32<TriScreenDrawerModes::AddClampShadedBlend, TriScreenDrawerModes::ShadedSampler>::Execute, // AddShaded
&RectScreenDrawer32<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::StencilSampler>::Execute, // Stencil
&RectScreenDrawer32<TriScreenDrawerModes::AddClampShadedBlend, TriScreenDrawerModes::StencilSampler>::Execute, // AddStencil
&RectScreenDrawer32<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillOpaque
&RectScreenDrawer32<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillAdd
&RectScreenDrawer32<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillSub
&RectScreenDrawer32<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillRevSub
&RectScreenDrawer32<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillAddSrcColor
&RectScreenDrawer32<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::SkycapSampler>::Execute, // Skycap
&RectScreenDrawer32<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::FuzzSampler>::Execute // Fuzz
&RectScreenDrawer32_SSE2<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureOpaque
&RectScreenDrawer32_SSE2<TriScreenDrawerModes::MaskedBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureMasked
&RectScreenDrawer32_SSE2<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureAdd
&RectScreenDrawer32_SSE2<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureSub
&RectScreenDrawer32_SSE2<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureRevSub
&RectScreenDrawer32_SSE2<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureAddSrcColor
&RectScreenDrawer32_SSE2<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedOpaque
&RectScreenDrawer32_SSE2<TriScreenDrawerModes::MaskedBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedMasked
&RectScreenDrawer32_SSE2<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedAdd
&RectScreenDrawer32_SSE2<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedSub
&RectScreenDrawer32_SSE2<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedRevSub
&RectScreenDrawer32_SSE2<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedAddSrcColor
&RectScreenDrawer32_SSE2<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::ShadedSampler>::Execute, // Shaded
&RectScreenDrawer32_SSE2<TriScreenDrawerModes::AddClampShadedBlend, TriScreenDrawerModes::ShadedSampler>::Execute, // AddShaded
&RectScreenDrawer32_SSE2<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::StencilSampler>::Execute, // Stencil
&RectScreenDrawer32_SSE2<TriScreenDrawerModes::AddClampShadedBlend, TriScreenDrawerModes::StencilSampler>::Execute, // AddStencil
&RectScreenDrawer32_SSE2<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillOpaque
&RectScreenDrawer32_SSE2<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillAdd
&RectScreenDrawer32_SSE2<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillSub
&RectScreenDrawer32_SSE2<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillRevSub
&RectScreenDrawer32_SSE2<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillAddSrcColor
&RectScreenDrawer32_SSE2<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::SkycapSampler>::Execute, // Skycap
&RectScreenDrawer32_SSE2<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::FuzzSampler>::Execute // Fuzz
};
#endif