in d3d/archive/images/d3d11/tessellator.cpp [2429:2534]
void CHLSLTessellator::TriHLSLProcessTessFactors( float tessFactor_Ueq0, float tessFactor_Veq0, float tessFactor_Weq0,
float insideTessFactorScale )
{
if( !(tessFactor_Ueq0 > 0) || // NaN will pass
!(tessFactor_Veq0 > 0) ||
!(tessFactor_Weq0 > 0) )
{
m_LastUnRoundedComputedTessFactors[0] = tessFactor_Ueq0;
m_LastUnRoundedComputedTessFactors[1] = tessFactor_Veq0;
m_LastUnRoundedComputedTessFactors[2] = tessFactor_Weq0;
m_LastUnRoundedComputedTessFactors[3] =
m_LastComputedTessFactors[0] =
m_LastComputedTessFactors[1] =
m_LastComputedTessFactors[2] =
m_LastComputedTessFactors[3] = 0;
return;
}
CleanupFloatTessFactor(tessFactor_Ueq0); // clamp to [1.0f..INF], NaN->1.0f
CleanupFloatTessFactor(tessFactor_Veq0);
CleanupFloatTessFactor(tessFactor_Weq0);
// Save off TessFactors so they can be returned to app
m_LastUnRoundedComputedTessFactors[0] = tessFactor_Ueq0;
m_LastUnRoundedComputedTessFactors[1] = tessFactor_Veq0;
m_LastUnRoundedComputedTessFactors[2] = tessFactor_Weq0;
// Process outside TessFactors
float outsideTessFactor[TRI_EDGES] = {tessFactor_Ueq0, tessFactor_Veq0, tessFactor_Weq0};
int edge;
if( Pow2Partitioning() || IntegerPartitioning() )
{
for( edge = 0; edge < TRI_EDGES; edge++ )
{
RoundUpTessFactor(outsideTessFactor[edge]); // for pow2 this rounds to pow2
ClampTessFactor(outsideTessFactor[edge]); // clamp unbounded user input based on tessellation mode
}
}
else
{
for( edge = 0; edge < TRI_EDGES; edge++ )
{
ClampTessFactor(outsideTessFactor[edge]); // clamp unbounded user input based on tessellation mode
}
}
// Compute inside TessFactor
float insideTessFactor;
switch( m_insideTessFactorReduction )
{
case D3D11_TESSELLATOR_REDUCTION_MIN:
insideTessFactor = fmin(fmin(tessFactor_Ueq0,tessFactor_Veq0),tessFactor_Weq0);
break;
case D3D11_TESSELLATOR_REDUCTION_MAX:
insideTessFactor = fmax(fmax(tessFactor_Ueq0,tessFactor_Veq0),tessFactor_Weq0);
break;
case D3D11_TESSELLATOR_REDUCTION_AVERAGE:
insideTessFactor = (tessFactor_Ueq0 + tessFactor_Veq0 + tessFactor_Weq0) / 3;
break;
}
// Scale inside TessFactor based on user scale factor.
ClampFloatTessFactorScale(insideTessFactorScale); // clamp scale value to [0..1], NaN->0
insideTessFactor = insideTessFactor*fmin(FLOAT_ONE,insideTessFactorScale);
ClampTessFactor(insideTessFactor); // clamp reduction + scale result that is based on unbounded user input
m_LastUnRoundedComputedTessFactors[3] = insideTessFactor;// Save off TessFactors so they can be returned to app
TESSELLATOR_PARITY parity;
if( Pow2Partitioning() || IntegerPartitioning() )
{
RoundUpTessFactor(insideTessFactor);
parity = (isEven(insideTessFactor) || (FLOAT_ONE == insideTessFactor))
? TESSELLATOR_PARITY_EVEN : TESSELLATOR_PARITY_ODD;
}
else
{
parity = m_originalParity;
}
if( (TESSELLATOR_PARITY_ODD == parity) &&
(insideTessFactor < FLOAT_THREE))
{
// To prevent snapping on edges, the "picture frame" comes
// in using avg or max (and ignore inside TessFactor scaling) until it is at least 3.
if(D3D11_TESSELLATOR_REDUCTION_MAX == m_insideTessFactorReduction)
{
insideTessFactor = fmin(FLOAT_THREE,fmax(tessFactor_Ueq0,fmax(tessFactor_Veq0,tessFactor_Weq0)));
}
else
{
insideTessFactor = fmin(FLOAT_THREE,(tessFactor_Ueq0 + tessFactor_Veq0 + tessFactor_Weq0) / 3);
}
ClampTessFactor(insideTessFactor); // clamp reduction result that is based on unbounded user input
m_LastUnRoundedComputedTessFactors[3] = insideTessFactor;// Save off TessFactors so they can be returned to app
if( IntegerPartitioning())
{
RoundUpTessFactor(insideTessFactor);
}
}
// Save off TessFactors so they can be returned to app
m_LastComputedTessFactors[0] = outsideTessFactor[Ueq0];
m_LastComputedTessFactors[1] = outsideTessFactor[Veq0];
m_LastComputedTessFactors[2] = outsideTessFactor[Weq0];
m_LastComputedTessFactors[3] = insideTessFactor;
}