mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 07:08:04 +02:00
swr: [rasterizer core] correct MSAA behavior for conservative rasterization
Signed-off-by: Tim Rowley <timothy.o.rowley@intel.com>
This commit is contained in:
parent
c6ca126591
commit
be126c8a2a
3 changed files with 31 additions and 11 deletions
|
|
@ -29,6 +29,10 @@
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
#include "format_traits.h"
|
#include "format_traits.h"
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief convenience typedef for testing for single sample case
|
||||||
|
typedef std::integral_constant<int, 1> SingleSampleT;
|
||||||
|
|
||||||
INLINE
|
INLINE
|
||||||
uint32_t GetNumSamples(SWR_MULTISAMPLE_COUNT sampleCount)
|
uint32_t GetNumSamples(SWR_MULTISAMPLE_COUNT sampleCount)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -516,7 +516,7 @@ void ComputeEdgeData(const POS& p0, const POS& p1, EDGE& edge)
|
||||||
/// the UpdateEdgeMasks function. Offset evaluated edges from UL pixel
|
/// the UpdateEdgeMasks function. Offset evaluated edges from UL pixel
|
||||||
/// corner to sample position, and test for coverage
|
/// corner to sample position, and test for coverage
|
||||||
/// @tparam sampleCount: multisample count
|
/// @tparam sampleCount: multisample count
|
||||||
template <uint32_t numEdges>
|
template <typename NumSamplesT>
|
||||||
INLINE void UpdateEdgeMasks(const __m256d (&vEdgeTileBbox)[3], const __m256d (&vEdgeFix16)[7],
|
INLINE void UpdateEdgeMasks(const __m256d (&vEdgeTileBbox)[3], const __m256d (&vEdgeFix16)[7],
|
||||||
int32_t &mask0, int32_t &mask1, int32_t &mask2)
|
int32_t &mask0, int32_t &mask1, int32_t &mask2)
|
||||||
{
|
{
|
||||||
|
|
@ -531,11 +531,11 @@ INLINE void UpdateEdgeMasks(const __m256d (&vEdgeTileBbox)[3], const __m256d (&v
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief UpdateEdgeMasks<SWR_MULTISAMPLE_1X, numEdges> partial specialization,
|
/// @brief UpdateEdgeMasks<SingleSampleT> specialization, instantiated
|
||||||
/// instantiated when MSAA is disabled.
|
/// when only rasterizing a single coverage test point
|
||||||
template <>
|
template <>
|
||||||
INLINE void UpdateEdgeMasks<SWR_MULTISAMPLE_1X>(const __m256d(&)[3], const __m256d (&vEdgeFix16)[7],
|
INLINE void UpdateEdgeMasks<SingleSampleT>(const __m256d(&)[3], const __m256d (&vEdgeFix16)[7],
|
||||||
int32_t &mask0, int32_t &mask1, int32_t &mask2)
|
int32_t &mask0, int32_t &mask1, int32_t &mask2)
|
||||||
{
|
{
|
||||||
mask0 = _mm256_movemask_pd(vEdgeFix16[0]);
|
mask0 = _mm256_movemask_pd(vEdgeFix16[0]);
|
||||||
mask1 = _mm256_movemask_pd(vEdgeFix16[1]);
|
mask1 = _mm256_movemask_pd(vEdgeFix16[1]);
|
||||||
|
|
@ -812,7 +812,12 @@ void RasterizeTriangle(DRAW_CONTEXT* pDC, uint32_t workerId, uint32_t macroTile,
|
||||||
int32_t x = AlignDown(intersect.left, (FIXED_POINT_SCALE * KNOB_TILE_X_DIM));
|
int32_t x = AlignDown(intersect.left, (FIXED_POINT_SCALE * KNOB_TILE_X_DIM));
|
||||||
int32_t y = AlignDown(intersect.top, (FIXED_POINT_SCALE * KNOB_TILE_Y_DIM));
|
int32_t y = AlignDown(intersect.top, (FIXED_POINT_SCALE * KNOB_TILE_Y_DIM));
|
||||||
|
|
||||||
if(RT::MT::sampleCount == SWR_MULTISAMPLE_1X)
|
// convenience typedef
|
||||||
|
typedef typename RT::NumRasterSamplesT NumRasterSamplesT;
|
||||||
|
|
||||||
|
// 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)
|
||||||
{
|
{
|
||||||
// Add 0.5, in fixed point, to offset to pixel center
|
// Add 0.5, in fixed point, to offset to pixel center
|
||||||
x += (FIXED_POINT_SCALE / 2);
|
x += (FIXED_POINT_SCALE / 2);
|
||||||
|
|
@ -887,7 +892,7 @@ void RasterizeTriangle(DRAW_CONTEXT* pDC, uint32_t workerId, uint32_t macroTile,
|
||||||
// | |
|
// | |
|
||||||
// min(xSamples),max(ySamples) ------ max(xSamples),max(ySamples)
|
// min(xSamples),max(ySamples) ------ max(xSamples),max(ySamples)
|
||||||
__m256d vEdgeTileBbox[3];
|
__m256d vEdgeTileBbox[3];
|
||||||
if (RT::MT::sampleCount > SWR_MULTISAMPLE_1X)
|
if (NumRasterSamplesT::value > 1)
|
||||||
{
|
{
|
||||||
__m128i vTileSampleBBoxXh = RT::MT::TileSampleOffsetsX();
|
__m128i vTileSampleBBoxXh = RT::MT::TileSampleOffsetsX();
|
||||||
__m128i vTileSampleBBoxYh = RT::MT::TileSampleOffsetsY();
|
__m128i vTileSampleBBoxYh = RT::MT::TileSampleOffsetsY();
|
||||||
|
|
@ -931,9 +936,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)
|
// is the corner of the edge outside of the raster tile? (vEdge < 0)
|
||||||
int mask0, mask1, mask2;
|
int mask0, mask1, mask2;
|
||||||
UpdateEdgeMasks<RT::MT::sampleCount>(vEdgeTileBbox, vEdgeFix16, mask0, mask1, mask2);
|
UpdateEdgeMasks<NumRasterSamplesT>(vEdgeTileBbox, vEdgeFix16, mask0, mask1, mask2);
|
||||||
|
|
||||||
for (uint32_t sampleNum = 0; sampleNum < RT::MT::numSamples; sampleNum++)
|
for (uint32_t sampleNum = 0; sampleNum < NumRasterSamplesT::value; sampleNum++)
|
||||||
{
|
{
|
||||||
// trivial reject, at least one edge has all 4 corners of raster tile outside
|
// trivial reject, at least one edge has all 4 corners of raster tile outside
|
||||||
bool trivialReject = (!(mask0 && mask1 && mask2)) ? true : false;
|
bool trivialReject = (!(mask0 && mask1 && mask2)) ? true : false;
|
||||||
|
|
@ -952,7 +957,7 @@ void RasterizeTriangle(DRAW_CONTEXT* pDC, uint32_t workerId, uint32_t macroTile,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
__m256d vEdgeAtSample[RT::NumEdgesT::value];
|
__m256d vEdgeAtSample[RT::NumEdgesT::value];
|
||||||
if(RT::MT::sampleCount == SWR_MULTISAMPLE_1X)
|
if(std::is_same<NumRasterSamplesT, SingleSampleT>::value)
|
||||||
{
|
{
|
||||||
// should get optimized out for single sample case (global value numbering or copy propagation)
|
// should get optimized out for single sample case (global value numbering or copy propagation)
|
||||||
for (uint32_t e = 0; e < RT::NumEdgesT::value; ++e)
|
for (uint32_t e = 0; e < RT::NumEdgesT::value; ++e)
|
||||||
|
|
@ -995,7 +1000,7 @@ void RasterizeTriangle(DRAW_CONTEXT* pDC, uint32_t workerId, uint32_t macroTile,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// if we're calculating coverage per sample, need to store it off. otherwise no covered samples, don't need to do anything
|
// if we're calculating coverage per sample, need to store it off. otherwise no covered samples, don't need to do anything
|
||||||
if(RT::MT::sampleCount > SWR_MULTISAMPLE_1X)
|
if(NumRasterSamplesT::value > 1)
|
||||||
{
|
{
|
||||||
triDesc.coverageMask[sampleNum] = 0;
|
triDesc.coverageMask[sampleNum] = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -1012,6 +1017,14 @@ void RasterizeTriangle(DRAW_CONTEXT* pDC, uint32_t workerId, uint32_t macroTile,
|
||||||
#endif
|
#endif
|
||||||
if(triDesc.anyCoveredSamples)
|
if(triDesc.anyCoveredSamples)
|
||||||
{
|
{
|
||||||
|
// if conservative rast and MSAA are enabled, conservative coverage for a pixel means all samples in that pixel are covered
|
||||||
|
// copy conservative coverage result to all samples
|
||||||
|
if(RT::IsConservativeT::value)
|
||||||
|
{
|
||||||
|
auto copyCoverage = [&](int sample){triDesc.coverageMask[sample] = triDesc.coverageMask[0]; };
|
||||||
|
UnrollerL<1, RT::MT::numSamples, 1>::step(copyCoverage);
|
||||||
|
}
|
||||||
|
|
||||||
RDTSC_START(BEPixelBackend);
|
RDTSC_START(BEPixelBackend);
|
||||||
backendFuncs.pfnBackend(pDC, workerId, tileX << KNOB_TILE_X_DIM_SHIFT, tileY << KNOB_TILE_Y_DIM_SHIFT, triDesc, renderBuffers);
|
backendFuncs.pfnBackend(pDC, workerId, tileX << KNOB_TILE_X_DIM_SHIFT, tileY << KNOB_TILE_Y_DIM_SHIFT, triDesc, renderBuffers);
|
||||||
RDTSC_STOP(BEPixelBackend, 0, 0);
|
RDTSC_STOP(BEPixelBackend, 0, 0);
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,9 @@ struct RasterizerTraits final : public ConservativeRastBETraits<ConservativeT, I
|
||||||
/// Fixed point precision of the edge tests used during rasterization
|
/// Fixed point precision of the edge tests used during rasterization
|
||||||
typedef FixedPointTraits<Fixed_X_16> EdgePrecisionT;
|
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;
|
||||||
|
|
||||||
static_assert(EdgePrecisionT::BitsT::value >= ConservativeRastBETraits<ConservativeT, InputCoverageT>::ConservativePrecisionT::BitsT::value,
|
static_assert(EdgePrecisionT::BitsT::value >= ConservativeRastBETraits<ConservativeT, InputCoverageT>::ConservativePrecisionT::BitsT::value,
|
||||||
"Rasterizer edge fixed point precision < required conservative rast precision");
|
"Rasterizer edge fixed point precision < required conservative rast precision");
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue