swr: [rasterizer core] Fix center sample pattern
Fix long hidden bug in rasterizer handling of center sample pattern. Reviewed-by: Bruce Cherniak <bruce.cherniak@intel.com>
This commit is contained in:
@@ -599,9 +599,6 @@ void BinTriangles(
|
||||
uint32_t *pPrimID = (uint32_t *)&primID;
|
||||
const uint32_t *pViewportIndex = (uint32_t *)&viewportIdx;
|
||||
DWORD triIndex = 0;
|
||||
// for center sample pattern, all samples are at pixel center; calculate coverage
|
||||
// once at center and broadcast the results in the backend
|
||||
const SWR_MULTISAMPLE_COUNT sampleCount = (rastState.samplePattern == SWR_MSAA_STANDARD_PATTERN) ? rastState.sampleCount : SWR_MULTISAMPLE_1X;
|
||||
uint32_t edgeEnable;
|
||||
PFN_WORK_FUNC pfnWork;
|
||||
if (CT::IsConservativeT::value)
|
||||
@@ -643,8 +640,8 @@ void BinTriangles(
|
||||
else
|
||||
{
|
||||
// degenerate triangles won't be sent to rasterizer; just enable all edges
|
||||
pfnWork = GetRasterizerFunc(sampleCount, (rastState.conservativeRast > 0),
|
||||
(SWR_INPUT_COVERAGE)pDC->pState->state.psState.inputCoverage, ALL_EDGES_VALID,
|
||||
pfnWork = GetRasterizerFunc(rastState.sampleCount, (rastState.samplePattern == SWR_MSAA_CENTER_PATTERN),
|
||||
(rastState.conservativeRast > 0), (SWR_INPUT_COVERAGE)pDC->pState->state.psState.inputCoverage, ALL_EDGES_VALID,
|
||||
(state.scissorsTileAligned == false));
|
||||
}
|
||||
|
||||
@@ -661,7 +658,8 @@ void BinTriangles(
|
||||
// only discard for non-MSAA case and when conservative rast is disabled
|
||||
// (xmin + 127) & ~255
|
||||
// (xmax + 128) & ~255
|
||||
if (rastState.sampleCount == SWR_MULTISAMPLE_1X && (!CT::IsConservativeT::value))
|
||||
if((rastState.sampleCount == SWR_MULTISAMPLE_1X || rastState.samplePattern == SWR_MSAA_CENTER_PATTERN) &&
|
||||
(!CT::IsConservativeT::value))
|
||||
{
|
||||
origTriMask = triMask;
|
||||
|
||||
@@ -789,8 +787,8 @@ endBinTriangles:
|
||||
{
|
||||
// only rasterize valid edges if we have a degenerate primitive
|
||||
int32_t triEdgeEnable = (edgeEnable >> (triIndex * 3)) & ALL_EDGES_VALID;
|
||||
work.pfnWork = GetRasterizerFunc(sampleCount, (rastState.conservativeRast > 0),
|
||||
(SWR_INPUT_COVERAGE)pDC->pState->state.psState.inputCoverage, triEdgeEnable,
|
||||
work.pfnWork = GetRasterizerFunc(rastState.sampleCount, (rastState.samplePattern == SWR_MSAA_CENTER_PATTERN),
|
||||
(rastState.conservativeRast > 0), (SWR_INPUT_COVERAGE)pDC->pState->state.psState.inputCoverage, triEdgeEnable,
|
||||
(state.scissorsTileAligned == false));
|
||||
|
||||
// Degenerate triangles are required to be constant interpolated
|
||||
|
||||
@@ -814,7 +814,7 @@ struct UpdateEdgeMasksInnerConservative<RT, AllEdgesValidT, InnerConservativeCov
|
||||
adjustEdgeConservative<RT, typename RT::InnerConservativeEdgeOffsetT>(vAi, vBi, vTempEdge[1]);
|
||||
adjustEdgeConservative<RT, typename RT::InnerConservativeEdgeOffsetT>(vAi, vBi, vTempEdge[2]);
|
||||
|
||||
UpdateEdgeMasks<typename RT::NumRasterSamplesT>(vEdgeTileBbox, vTempEdge, mask0, mask1, mask2);
|
||||
UpdateEdgeMasks<typename RT::NumCoverageSamplesT>(vEdgeTileBbox, vTempEdge, mask0, mask1, mask2);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1037,11 +1037,11 @@ void RasterizeTriangle(DRAW_CONTEXT* pDC, uint32_t workerId, uint32_t macroTile,
|
||||
int32_t y = AlignDown(intersect.ymin, (FIXED_POINT_SCALE * KNOB_TILE_Y_DIM));
|
||||
|
||||
// convenience typedef
|
||||
typedef typename RT::NumRasterSamplesT NumRasterSamplesT;
|
||||
typedef typename RT::NumCoverageSamplesT NumCoverageSamplesT;
|
||||
|
||||
// single sample rasterization evaluates edges at pixel center,
|
||||
// multisample evaluates edges UL pixel corner and steps to each sample position
|
||||
if(std::is_same<NumRasterSamplesT, SingleSampleT>::value)
|
||||
if(std::is_same<NumCoverageSamplesT, SingleSampleT>::value)
|
||||
{
|
||||
// Add 0.5, in fixed point, to offset to pixel center
|
||||
x += (FIXED_POINT_SCALE / 2);
|
||||
@@ -1116,7 +1116,7 @@ void RasterizeTriangle(DRAW_CONTEXT* pDC, uint32_t workerId, uint32_t macroTile,
|
||||
// | |
|
||||
// min(xSamples),max(ySamples) ------ max(xSamples),max(ySamples)
|
||||
__m256d vEdgeTileBbox[3];
|
||||
if (NumRasterSamplesT::value > 1)
|
||||
if (NumCoverageSamplesT::value > 1)
|
||||
{
|
||||
__m128i vTileSampleBBoxXh = RT::MT::TileSampleOffsetsX();
|
||||
__m128i vTileSampleBBoxYh = RT::MT::TileSampleOffsetsY();
|
||||
@@ -1163,9 +1163,9 @@ void RasterizeTriangle(DRAW_CONTEXT* pDC, uint32_t workerId, uint32_t macroTile,
|
||||
|
||||
// is the corner of the edge outside of the raster tile? (vEdge < 0)
|
||||
int mask0, mask1, mask2;
|
||||
UpdateEdgeMasks<NumRasterSamplesT>(vEdgeTileBbox, vEdgeFix16, mask0, mask1, mask2);
|
||||
UpdateEdgeMasks<NumCoverageSamplesT>(vEdgeTileBbox, vEdgeFix16, mask0, mask1, mask2);
|
||||
|
||||
for (uint32_t sampleNum = 0; sampleNum < NumRasterSamplesT::value; sampleNum++)
|
||||
for (uint32_t sampleNum = 0; sampleNum < NumCoverageSamplesT::value; sampleNum++)
|
||||
{
|
||||
// trivial reject, at least one edge has all 4 corners of raster tile outside
|
||||
bool trivialReject = TrivialRejectTest<typename RT::ValidEdgeMaskT>(mask0, mask1, mask2);
|
||||
@@ -1196,7 +1196,7 @@ void RasterizeTriangle(DRAW_CONTEXT* pDC, uint32_t workerId, uint32_t macroTile,
|
||||
else
|
||||
{
|
||||
__m256d vEdgeAtSample[RT::NumEdgesT::value];
|
||||
if(std::is_same<NumRasterSamplesT, SingleSampleT>::value)
|
||||
if(std::is_same<NumCoverageSamplesT, SingleSampleT>::value)
|
||||
{
|
||||
// should get optimized out for single sample case (global value numbering or copy propagation)
|
||||
for (uint32_t e = 0; e < RT::NumEdgesT::value; ++e)
|
||||
@@ -1242,7 +1242,7 @@ void RasterizeTriangle(DRAW_CONTEXT* pDC, uint32_t workerId, uint32_t macroTile,
|
||||
else
|
||||
{
|
||||
// if we're calculating coverage per sample, need to store it off. otherwise no covered samples, don't need to do anything
|
||||
if(NumRasterSamplesT::value > 1)
|
||||
if(NumCoverageSamplesT::value > 1)
|
||||
{
|
||||
triDesc.coverageMask[sampleNum] = 0;
|
||||
}
|
||||
@@ -1339,11 +1339,9 @@ void RasterizeTriPoint(DRAW_CONTEXT *pDC, uint32_t workerId, uint32_t macroTile,
|
||||
|
||||
// setup triangle rasterizer function
|
||||
PFN_WORK_FUNC pfnTriRast;
|
||||
// for center sample pattern, all samples are at pixel center; calculate coverage
|
||||
// once at center and broadcast the results in the backend
|
||||
uint32_t sampleCount = (rastState.samplePattern == SWR_MSAA_STANDARD_PATTERN) ? rastState.sampleCount : SWR_MULTISAMPLE_1X;
|
||||
// conservative rast not supported for points/lines
|
||||
pfnTriRast = GetRasterizerFunc(sampleCount, false, SWR_INPUT_COVERAGE_NONE, ALL_EDGES_VALID, (pDC->pState->state.scissorsTileAligned == false));
|
||||
pfnTriRast = GetRasterizerFunc(rastState.sampleCount, (rastState.samplePattern == SWR_MSAA_CENTER_PATTERN), false,
|
||||
SWR_INPUT_COVERAGE_NONE, ALL_EDGES_VALID, (pDC->pState->state.scissorsTileAligned == false));
|
||||
|
||||
// overwrite texcoords for point sprites
|
||||
if (isPointSpriteTexCoordEnabled)
|
||||
@@ -1674,9 +1672,9 @@ void RasterizeLine(DRAW_CONTEXT *pDC, uint32_t workerId, uint32_t macroTile, voi
|
||||
|
||||
// setup triangle rasterizer function
|
||||
PFN_WORK_FUNC pfnTriRast;
|
||||
uint32_t sampleCount = (rastState.samplePattern == SWR_MSAA_STANDARD_PATTERN) ? rastState.sampleCount : SWR_MULTISAMPLE_1X;
|
||||
// conservative rast not supported for points/lines
|
||||
pfnTriRast = GetRasterizerFunc(sampleCount, false, SWR_INPUT_COVERAGE_NONE, ALL_EDGES_VALID, (pDC->pState->state.scissorsTileAligned == false));
|
||||
pfnTriRast = GetRasterizerFunc(rastState.sampleCount, (rastState.samplePattern == SWR_MSAA_CENTER_PATTERN), false,
|
||||
SWR_INPUT_COVERAGE_NONE, ALL_EDGES_VALID, (pDC->pState->state.scissorsTileAligned == false));
|
||||
|
||||
// make sure this macrotile intersects the triangle
|
||||
__m128i vXai = fpToFixedPoint(vXa);
|
||||
@@ -1786,6 +1784,7 @@ struct RasterizerChooser
|
||||
// Selector for correct templated RasterizeTriangle function
|
||||
PFN_WORK_FUNC GetRasterizerFunc(
|
||||
uint32_t numSamples,
|
||||
bool IsCenter,
|
||||
bool IsConservative,
|
||||
uint32_t InputCoverage,
|
||||
uint32_t EdgeEnable,
|
||||
@@ -1794,6 +1793,7 @@ PFN_WORK_FUNC GetRasterizerFunc(
|
||||
{
|
||||
return TemplateArgUnroller<RasterizerChooser>::GetFunc(
|
||||
IntArg<SWR_MULTISAMPLE_1X,SWR_MULTISAMPLE_TYPE_COUNT-1>{numSamples},
|
||||
IsCenter,
|
||||
IsConservative,
|
||||
IntArg<SWR_INPUT_COVERAGE_NONE, SWR_INPUT_COVERAGE_COUNT-1>{InputCoverage},
|
||||
IntArg<0, VALID_TRI_EDGE_COUNT-1>{EdgeEnable},
|
||||
|
||||
@@ -46,6 +46,7 @@ __m128i fpToFixedPoint(const __m128 vIn)
|
||||
// Selector for correct templated RasterizeTriangle function
|
||||
PFN_WORK_FUNC GetRasterizerFunc(
|
||||
uint32_t numSamples,
|
||||
bool IsCenter,
|
||||
bool IsConservative,
|
||||
uint32_t InputCoverage,
|
||||
uint32_t EdgeEnable,
|
||||
@@ -110,19 +111,20 @@ struct RasterEdgeTraits<std::false_type, std::false_type, EdgeMaskT>
|
||||
/// @tparam InputCoverageT: what type of input coverage is the PS expecting?
|
||||
/// (only used with conservative rasterization)
|
||||
/// @tparam RasterScissorEdgesT: do we need to rasterize with a scissor?
|
||||
template <typename NumSamplesT, typename ConservativeT, typename InputCoverageT, typename EdgeEnableT, typename RasterScissorEdgesT>
|
||||
template <typename NumSamplesT, typename CenterPatternT, typename ConservativeT, typename InputCoverageT, typename EdgeEnableT, typename RasterScissorEdgesT>
|
||||
struct RasterizerTraits final : public ConservativeRastBETraits<ConservativeT, InputCoverageT>,
|
||||
public RasterEdgeTraits<RasterScissorEdgesT, ConservativeT, std::integral_constant<uint32_t, EdgeEnableT::value>>
|
||||
{
|
||||
typedef MultisampleTraits<static_cast<SWR_MULTISAMPLE_COUNT>(NumSamplesT::value)> MT;
|
||||
typedef MultisampleTraits<static_cast<SWR_MULTISAMPLE_COUNT>(NumSamplesT::value),
|
||||
(CenterPatternT::value ? SWR_MSAA_CENTER_PATTERN : SWR_MSAA_STANDARD_PATTERN)> MT;
|
||||
|
||||
/// Fixed point precision the rasterizer is using
|
||||
typedef FixedPointTraits<Fixed_16_8> PrecisionT;
|
||||
/// Fixed point precision of the edge tests used during rasterization
|
||||
typedef FixedPointTraits<Fixed_X_16> EdgePrecisionT;
|
||||
|
||||
// If conservative rast is enabled, only need a single sample coverage test, with the result copied to all samples
|
||||
typedef std::integral_constant<int, (ConservativeT::value) ? 1 : MT::numSamples> NumRasterSamplesT;
|
||||
// If conservative rast or MSAA center pattern is enabled, only need a single sample coverage test, with the result copied to all samples
|
||||
typedef std::integral_constant<int, ConservativeT::value ? 1 : MT::numCoverageSamples> NumCoverageSamplesT;
|
||||
|
||||
static_assert(EdgePrecisionT::BitsT::value >= ConservativeRastBETraits<ConservativeT, InputCoverageT>::ConservativePrecisionT::BitsT::value,
|
||||
"Rasterizer edge fixed point precision < required conservative rast precision");
|
||||
|
||||
Reference in New Issue
Block a user