swr: [rasterizer core] SIMD16 Frontend WIP - Clipper

Implement widened clipper for SIMD16.

Reviewed-by: Bruce Cherniak <bruce.cherniak@intel.com>
This commit is contained in:
Tim Rowley
2017-04-06 15:22:55 -05:00
parent 0033e86b2c
commit 08a7136848
5 changed files with 941 additions and 124 deletions
@@ -436,7 +436,7 @@ INLINE simd16scalar _simd16_cvtepi32_ps(simd16scalari a)
}
template <int comp>
INLINE simd16scalar _simd16_cmp_ps(simd16scalar a, simd16scalar b)
INLINE simd16scalar _simd16_cmp_ps_temp(simd16scalar a, simd16scalar b)
{
simd16scalar result;
@@ -446,12 +446,14 @@ INLINE simd16scalar _simd16_cmp_ps(simd16scalar a, simd16scalar b)
return result;
}
#define _simd16_cmplt_ps(a, b) _simd16_cmp_ps<_CMP_LT_OQ>(a, b)
#define _simd16_cmpgt_ps(a, b) _simd16_cmp_ps<_CMP_GT_OQ>(a, b)
#define _simd16_cmpneq_ps(a, b) _simd16_cmp_ps<_CMP_NEQ_OQ>(a, b)
#define _simd16_cmpeq_ps(a, b) _simd16_cmp_ps<_CMP_EQ_OQ>(a, b)
#define _simd16_cmpge_ps(a, b) _simd16_cmp_ps<_CMP_GE_OQ>(a, b)
#define _simd16_cmple_ps(a, b) _simd16_cmp_ps<_CMP_LE_OQ>(a, b)
#define _simd16_cmp_ps(a, b, comp) _simd16_cmp_ps_temp<comp>(a, b)
#define _simd16_cmplt_ps(a, b) _simd16_cmp_ps(a, b, _CMP_LT_OQ)
#define _simd16_cmpgt_ps(a, b) _simd16_cmp_ps(a, b, _CMP_GT_OQ)
#define _simd16_cmpneq_ps(a, b) _simd16_cmp_ps(a, b, _CMP_NEQ_OQ)
#define _simd16_cmpeq_ps(a, b) _simd16_cmp_ps(a, b, _CMP_EQ_OQ)
#define _simd16_cmpge_ps(a, b) _simd16_cmp_ps(a, b, _CMP_GE_OQ)
#define _simd16_cmple_ps(a, b) _simd16_cmp_ps(a, b, _CMP_LE_OQ)
SIMD16_EMU_AVX512_2(simd16scalar, _simd16_and_ps, _simd_and_ps)
SIMD16_EMU_AVX512_2(simd16scalar, _simd16_andnot_ps, _simd_andnot_ps)
@@ -525,8 +527,8 @@ SIMD16_EMU_AVX512_2(simd16scalari, _simd16_cmplt_epi32, _simd_cmplt_epi32)
INLINE int _simd16_testz_ps(simd16scalar a, simd16scalar b)
{
int lo = _mm256_testz_ps(a.lo, b.lo);
int hi = _mm256_testz_ps(a.hi, b.hi);
int lo = _simd_testz_ps(a.lo, b.lo);
int hi = _simd_testz_ps(a.hi, b.hi);
return lo & hi;
}
@@ -912,19 +914,19 @@ INLINE int _simd16_movemask_epi8(simd16scalari a)
template <int comp>
INLINE simd16scalar _simd16_cmp_ps_temp(simd16scalar a, simd16scalar b)
{
simd16mask k = _mm512_cmpeq_ps_mask(a, b);
simd16mask k = _mm512_cmp_ps_mask(a, b, comp);
return _mm512_castsi512_ps(_mm512_mask_blend_epi32(k, _mm512_setzero_epi32(), _mm512_set1_epi32(0xFFFFFFFF)));
}
#define _simd16_cmp_ps(a, b, comp) _simd16_cmp_ps_temp<comp>(a, b)
#define _simd16_cmplt_ps(a, b) _simd16_cmp_ps<_CMP_LT_OQ>(a, b)
#define _simd16_cmpgt_ps(a, b) _simd16_cmp_ps<_CMP_GT_OQ>(a, b)
#define _simd16_cmpneq_ps(a, b) _simd16_cmp_ps<_CMP_NEQ_OQ>(a, b)
#define _simd16_cmpeq_ps(a, b) _simd16_cmp_ps<_CMP_EQ_OQ>(a, b)
#define _simd16_cmpge_ps(a, b) _simd16_cmp_ps<_CMP_GE_OQ>(a, b)
#define _simd16_cmple_ps(a, b) _simd16_cmp_ps<_CMP_LE_OQ>(a, b)
#define _simd16_cmplt_ps(a, b) _simd16_cmp_ps(a, b, _CMP_LT_OQ)
#define _simd16_cmpgt_ps(a, b) _simd16_cmp_ps(a, b, _CMP_GT_OQ)
#define _simd16_cmpneq_ps(a, b) _simd16_cmp_ps(a, b, _CMP_NEQ_OQ)
#define _simd16_cmpeq_ps(a, b) _simd16_cmp_ps(a, b, _CMP_EQ_OQ)
#define _simd16_cmpge_ps(a, b) _simd16_cmp_ps(a, b, _CMP_GE_OQ)
#define _simd16_cmple_ps(a, b) _simd16_cmp_ps(a, b, _CMP_LE_OQ)
#define _simd16_castsi_ps _mm512_castsi512_ps
#define _simd16_castps_si _mm512_castps_si512
@@ -982,17 +984,14 @@ INLINE simd16scalari _simd16_cmplt_epi32(simd16scalari a, simd16scalari b)
return _mm512_mask_blend_epi32(k, _mm512_setzero_epi32(), _mm512_set1_epi32(0xFFFFFFFF));
}
#if 0
INLINE int _simd16_testz_ps(simd16scalar a, simd16scalar b)
{
int lo = _mm256_testz_ps(a.lo, b.lo);
int hi = _mm256_testz_ps(a.hi, b.hi);
int lo = _simd_testz_ps(_simd16_extract_ps(a, 0), _simd16_extract_ps(b, 0));
int hi = _simd_testz_ps(_simd16_extract_ps(a, 1), _simd16_extract_ps(b, 1));
return lo & hi;
}
#endif
#define _simd16_unpacklo_ps _mm512_unpacklo_ps
#define _simd16_unpackhi_ps _mm512_unpackhi_ps
#define _simd16_unpacklo_pd _mm512_unpacklo_pd
@@ -1007,16 +1007,6 @@ endBinTriangles:
}
#if USE_SIMD16_FRONTEND
inline uint32_t GetPrimMaskLo(uint32_t primMask)
{
return primMask & 255;
}
inline uint32_t GetPrimMaskHi(uint32_t primMask)
{
return (primMask >> 8) & 255;
}
template <typename CT>
void BinTriangles_simd16(
DRAW_CONTEXT *pDC,
@@ -1105,8 +1095,8 @@ void BinTriangles_simd16(
calcDeterminantIntVertical(vAi, vBi, vDet);
// cull zero area
simd16mask maskLo = _simd16_movemask_pd(_simd16_castsi_pd(_simd16_cmpeq_epi64(vDet[0], _simd16_setzero_si())));
simd16mask maskHi = _simd16_movemask_pd(_simd16_castsi_pd(_simd16_cmpeq_epi64(vDet[1], _simd16_setzero_si())));
uint32_t maskLo = _simd16_movemask_pd(_simd16_castsi_pd(_simd16_cmpeq_epi64(vDet[0], _simd16_setzero_si())));
uint32_t maskHi = _simd16_movemask_pd(_simd16_castsi_pd(_simd16_cmpeq_epi64(vDet[1], _simd16_setzero_si())));
uint32_t cullZeroAreaMask = maskLo | (maskHi << (KNOB_SIMD16_WIDTH / 2));
@@ -1133,7 +1123,6 @@ void BinTriangles_simd16(
maskLo = _simd16_movemask_pd(_simd16_castsi_pd(_simd16_cmpgt_epi64(_simd16_setzero_si(), vDet[0])));
maskHi = _simd16_movemask_pd(_simd16_castsi_pd(_simd16_cmpgt_epi64(_simd16_setzero_si(), vDet[1])));
}
frontWindingTris = maskLo | (maskHi << (KNOB_SIMD16_WIDTH / 2));
// cull
@@ -2756,7 +2745,7 @@ void BinLines_simd16(
{
viewportTransform<2>(prim, state.vpMatrices);
}
}
}
// adjust for pixel center location
simd16scalar offset = g_pixelOffsets_simd16[rastState.pixelLocation];
@@ -33,6 +33,9 @@
// Temp storage used by the clipper
THREAD simdvertex tlsTempVertices[7];
#if USE_SIMD16_FRONTEND
THREAD simd16vertex tlsTempVertices_simd16[7];
#endif
float ComputeInterpFactor(float boundaryCoord0, float boundaryCoord1)
{
@@ -185,16 +188,6 @@ void ClipPoints(DRAW_CONTEXT *pDC, PA_STATE& pa, uint32_t workerId, simdvector p
}
#if USE_SIMD16_FRONTEND
inline uint32_t GetPrimMaskLo(uint32_t primMask)
{
return primMask & 255;
}
inline uint32_t GetPrimMaskHi(uint32_t primMask)
{
return (primMask >> 8) & 255;
}
void ClipTriangles_simd16(DRAW_CONTEXT *pDC, PA_STATE& pa, uint32_t workerId, simd16vector prims[], uint32_t primMask, simd16scalari primId, simd16scalari viewportIdx)
{
SWR_CONTEXT *pContext = pDC->pContext;
@@ -204,32 +197,8 @@ void ClipTriangles_simd16(DRAW_CONTEXT *pDC, PA_STATE& pa, uint32_t workerId, si
Clipper<VERTS_PER_PRIM> clipper(workerId, pDC);
simdvector verts[VERTS_PER_PRIM];
for (uint32_t i = 0; i < VERTS_PER_PRIM; i += 1)
{
for (uint32_t j = 0; j < 4; j += 1)
{
verts[i][j] = _simd16_extract_ps(prims[i][j], 0);
}
}
pa.useAlternateOffset = false;
clipper.ExecuteStage(pa, verts, GetPrimMaskLo(primMask), _simd16_extract_si(primId, 0), _simd16_extract_si(viewportIdx, 0));
if (GetPrimMaskHi(primMask))
{
for (uint32_t i = 0; i < VERTS_PER_PRIM; i += 1)
{
for (uint32_t j = 0; j < 4; j += 1)
{
verts[i][j] = _simd16_extract_ps(prims[i][j], 1);
}
}
pa.useAlternateOffset = true;
clipper.ExecuteStage(pa, verts, GetPrimMaskHi(primMask), _simd16_extract_si(primId, 1), _simd16_extract_si(viewportIdx, 1));
}
clipper.ExecuteStage(pa, prims, primMask, primId, viewportIdx);
AR_END(FEClipTriangles, 1);
}
@@ -243,32 +212,8 @@ void ClipLines_simd16(DRAW_CONTEXT *pDC, PA_STATE& pa, uint32_t workerId, simd16
Clipper<VERTS_PER_PRIM> clipper(workerId, pDC);
simdvector verts[VERTS_PER_PRIM];
for (uint32_t i = 0; i < VERTS_PER_PRIM; i += 1)
{
for (uint32_t j = 0; j < 4; j += 1)
{
verts[i][j] = _simd16_extract_ps(prims[i][j], 0);
}
}
pa.useAlternateOffset = false;
clipper.ExecuteStage(pa, verts, GetPrimMaskLo(primMask), _simd16_extract_si(primId, 0), _simd16_extract_si(viewportIdx, 0));
if (GetPrimMaskHi(primMask))
{
for (uint32_t i = 0; i < VERTS_PER_PRIM; i += 1)
{
for (uint32_t j = 0; j < 4; j += 1)
{
verts[i][j] = _simd16_extract_ps(prims[i][j], 1);
}
}
pa.useAlternateOffset = true;
clipper.ExecuteStage(pa, verts, GetPrimMaskHi(primMask), _simd16_extract_si(primId, 1), _simd16_extract_si(viewportIdx, 1));
}
clipper.ExecuteStage(pa, prims, primMask, primId, viewportIdx);
AR_END(FEClipLines, 1);
}
@@ -282,32 +227,8 @@ void ClipPoints_simd16(DRAW_CONTEXT *pDC, PA_STATE& pa, uint32_t workerId, simd1
Clipper<VERTS_PER_PRIM> clipper(workerId, pDC);
simdvector verts[VERTS_PER_PRIM];
for (uint32_t i = 0; i < VERTS_PER_PRIM; i += 1)
{
for (uint32_t j = 0; j < 4; j += 1)
{
verts[i][j] = _simd16_extract_ps(prims[i][j], 0);
}
}
pa.useAlternateOffset = false;
clipper.ExecuteStage(pa, verts, GetPrimMaskLo(primMask), _simd16_extract_si(primId, 0), _simd16_extract_si(viewportIdx, 0));
if (GetPrimMaskHi(primMask))
{
for (uint32_t i = 0; i < VERTS_PER_PRIM; i += 1)
{
for (uint32_t j = 0; j < 4; j += 1)
{
verts[i][j] = _simd16_extract_ps(prims[i][j], 1);
}
}
pa.useAlternateOffset = true;
clipper.ExecuteStage(pa, verts, GetPrimMaskHi(primMask), _simd16_extract_si(primId, 1), _simd16_extract_si(viewportIdx, 1));
}
clipper.ExecuteStage(pa, prims, primMask, primId, viewportIdx);
AR_END(FEClipPoints, 1);
}
File diff suppressed because it is too large Load Diff
@@ -208,14 +208,34 @@ void calcDeterminantIntVertical(const simd16scalari vA[3], const simd16scalari v
{
// refer to calcDeterminantInt comment for calculation explanation
// A1*B2
simd16scalari vA1Lo = _simd16_unpacklo_epi32(vA[1], vA[1]); // 0 0 1 1 4 4 5 5
simd16scalari vA1Hi = _simd16_unpackhi_epi32(vA[1], vA[1]); // 2 2 3 3 6 6 7 7
#if 1
// TODO: get the native SIMD16 version working..
simdscalari vA_lo[3];
simdscalari vA_hi[3];
simdscalari vB_lo[3];
simdscalari vB_hi[3];
for (uint32_t i = 0; i < 3; i += 1)
{
vA_lo[i] = _simd16_extract_si(vA[i], 0);
vA_hi[i] = _simd16_extract_si(vA[i], 1);
vB_lo[i] = _simd16_extract_si(vB[i], 0);
vB_hi[i] = _simd16_extract_si(vB[i], 1);
}
calcDeterminantIntVertical(vA_lo, vB_lo, reinterpret_cast<simdscalari *>(&pvDet[0]));
calcDeterminantIntVertical(vA_hi, vB_hi, reinterpret_cast<simdscalari *>(&pvDet[1]));
#else
simd16scalari vA1Lo = _simd16_unpacklo_epi32(vA[1], vA[1]); // 0 0 1 1 4 4 5 5 8 8 9 9 C C D D
simd16scalari vA1Hi = _simd16_unpackhi_epi32(vA[1], vA[1]); // 2 2 3 3 6 6 7 7 A A B B E E F F
simd16scalari vB2Lo = _simd16_unpacklo_epi32(vB[2], vB[2]);
simd16scalari vB2Hi = _simd16_unpackhi_epi32(vB[2], vB[2]);
simd16scalari vA1B2Lo = _simd16_mul_epi32(vA1Lo, vB2Lo); // 0 1 4 5
simd16scalari vA1B2Hi = _simd16_mul_epi32(vA1Hi, vB2Hi); // 2 3 6 7
simd16scalari vA1B2Lo = _simd16_mul_epi32(vA1Lo, vB2Lo); // 0 1 4 5 8 9 C D
simd16scalari vA1B2Hi = _simd16_mul_epi32(vA1Hi, vB2Hi); // 2 3 6 7 A B E F
// B1*A2
simd16scalari vA2Lo = _simd16_unpacklo_epi32(vA[2], vA[2]);
@@ -237,6 +257,7 @@ void calcDeterminantIntVertical(const simd16scalari vA[3], const simd16scalari v
pvDet[0] = vResultLo;
pvDet[1] = vResultHi;
#endif
}
#endif