From: Tim Rowley Date: Wed, 29 Jun 2016 15:47:31 +0000 (-0600) Subject: swr: [rasterizer core] correct MSAA behavior for conservative rasterization X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=be126c8a2a4e67fff47e02078fceacb33ddac67f;p=mesa.git swr: [rasterizer core] correct MSAA behavior for conservative rasterization Signed-off-by: Tim Rowley --- diff --git a/src/gallium/drivers/swr/rasterizer/core/multisample.h b/src/gallium/drivers/swr/rasterizer/core/multisample.h index a52e8ac1065..bba0d9ab79a 100644 --- a/src/gallium/drivers/swr/rasterizer/core/multisample.h +++ b/src/gallium/drivers/swr/rasterizer/core/multisample.h @@ -29,6 +29,10 @@ #include "context.h" #include "format_traits.h" +////////////////////////////////////////////////////////////////////////// +/// @brief convenience typedef for testing for single sample case +typedef std::integral_constant SingleSampleT; + INLINE uint32_t GetNumSamples(SWR_MULTISAMPLE_COUNT sampleCount) { diff --git a/src/gallium/drivers/swr/rasterizer/core/rasterizer.cpp b/src/gallium/drivers/swr/rasterizer/core/rasterizer.cpp index c9b0285a5c8..1e7da2bf81e 100644 --- a/src/gallium/drivers/swr/rasterizer/core/rasterizer.cpp +++ b/src/gallium/drivers/swr/rasterizer/core/rasterizer.cpp @@ -516,7 +516,7 @@ void ComputeEdgeData(const POS& p0, const POS& p1, EDGE& edge) /// the UpdateEdgeMasks function. Offset evaluated edges from UL pixel /// corner to sample position, and test for coverage /// @tparam sampleCount: multisample count -template +template INLINE void UpdateEdgeMasks(const __m256d (&vEdgeTileBbox)[3], const __m256d (&vEdgeFix16)[7], 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 partial specialization, -/// instantiated when MSAA is disabled. +/// @brief UpdateEdgeMasks specialization, instantiated +/// when only rasterizing a single coverage test point template <> -INLINE void UpdateEdgeMasks(const __m256d(&)[3], const __m256d (&vEdgeFix16)[7], - int32_t &mask0, int32_t &mask1, int32_t &mask2) +INLINE void UpdateEdgeMasks(const __m256d(&)[3], const __m256d (&vEdgeFix16)[7], + int32_t &mask0, int32_t &mask1, int32_t &mask2) { mask0 = _mm256_movemask_pd(vEdgeFix16[0]); 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 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::value) { // Add 0.5, in fixed point, to offset to pixel center 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) __m256d vEdgeTileBbox[3]; - if (RT::MT::sampleCount > SWR_MULTISAMPLE_1X) + if (NumRasterSamplesT::value > 1) { __m128i vTileSampleBBoxXh = RT::MT::TileSampleOffsetsX(); __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) int mask0, mask1, mask2; - UpdateEdgeMasks(vEdgeTileBbox, vEdgeFix16, mask0, mask1, mask2); + UpdateEdgeMasks(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 bool trivialReject = (!(mask0 && mask1 && mask2)) ? true : false; @@ -952,7 +957,7 @@ void RasterizeTriangle(DRAW_CONTEXT* pDC, uint32_t workerId, uint32_t macroTile, else { __m256d vEdgeAtSample[RT::NumEdgesT::value]; - if(RT::MT::sampleCount == SWR_MULTISAMPLE_1X) + if(std::is_same::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) @@ -995,7 +1000,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(RT::MT::sampleCount > SWR_MULTISAMPLE_1X) + if(NumRasterSamplesT::value > 1) { triDesc.coverageMask[sampleNum] = 0; } @@ -1012,6 +1017,14 @@ void RasterizeTriangle(DRAW_CONTEXT* pDC, uint32_t workerId, uint32_t macroTile, #endif 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); backendFuncs.pfnBackend(pDC, workerId, tileX << KNOB_TILE_X_DIM_SHIFT, tileY << KNOB_TILE_Y_DIM_SHIFT, triDesc, renderBuffers); RDTSC_STOP(BEPixelBackend, 0, 0); diff --git a/src/gallium/drivers/swr/rasterizer/core/rasterizer.h b/src/gallium/drivers/swr/rasterizer/core/rasterizer.h index a400780f85d..1b5cac26be5 100644 --- a/src/gallium/drivers/swr/rasterizer/core/rasterizer.h +++ b/src/gallium/drivers/swr/rasterizer/core/rasterizer.h @@ -97,6 +97,9 @@ struct RasterizerTraits final : public ConservativeRastBETraits EdgePrecisionT; + // If conservative rast is enabled, only need a single sample coverage test, with the result copied to all samples + typedef std::integral_constant NumRasterSamplesT; + static_assert(EdgePrecisionT::BitsT::value >= ConservativeRastBETraits::ConservativePrecisionT::BitsT::value, "Rasterizer edge fixed point precision < required conservative rast precision");