From 12e6f4c87970e57d2b92b1cc81490037c40e8186 Mon Sep 17 00:00:00 2001 From: Tim Rowley Date: Thu, 6 Oct 2016 21:06:59 -0500 Subject: swr: [rasterizer core] implement depth bounds test Signed-off-by: Tim Rowley --- src/gallium/drivers/swr/rasterizer/core/api.cpp | 13 +++++ src/gallium/drivers/swr/rasterizer/core/api.h | 8 +++ .../drivers/swr/rasterizer/core/backend.cpp | 58 ++++++++++++++++++---- src/gallium/drivers/swr/rasterizer/core/backend.h | 20 ++++++++ src/gallium/drivers/swr/rasterizer/core/context.h | 2 + src/gallium/drivers/swr/rasterizer/core/state.h | 9 ++++ 6 files changed, 101 insertions(+), 9 deletions(-) (limited to 'src/gallium/drivers/swr/rasterizer') diff --git a/src/gallium/drivers/swr/rasterizer/core/api.cpp b/src/gallium/drivers/swr/rasterizer/core/api.cpp index a90d9933735..cb0098d3db3 100644 --- a/src/gallium/drivers/swr/rasterizer/core/api.cpp +++ b/src/gallium/drivers/swr/rasterizer/core/api.cpp @@ -422,6 +422,10 @@ void SetupDefaultState(SWR_CONTEXT *pContext) pState->rastState.cullMode = SWR_CULLMODE_NONE; pState->rastState.frontWinding = SWR_FRONTWINDING_CCW; + + pState->depthBoundsState.depthBoundsTestEnable = false; + pState->depthBoundsState.depthBoundsTestMinValue = 0.0f; + pState->depthBoundsState.depthBoundsTestMaxValue = 1.0f; } void SwrSync(HANDLE hContext, PFN_CALLBACK_FUNC pfnFunc, uint64_t userData, uint64_t userData2, uint64_t userData3) @@ -628,6 +632,15 @@ void SwrSetBackendState( pState->backendState = *pBEState; } +void SwrSetDepthBoundsState( + HANDLE hContext, + SWR_DEPTH_BOUNDS_STATE *pDBState) +{ + API_STATE* pState = GetDrawState(GetContext(hContext)); + + pState->depthBoundsState = *pDBState; +} + void SwrSetPixelShaderState( HANDLE hContext, SWR_PS_STATE *pPSState) diff --git a/src/gallium/drivers/swr/rasterizer/core/api.h b/src/gallium/drivers/swr/rasterizer/core/api.h index 93337e662ba..8ad40ea57b1 100644 --- a/src/gallium/drivers/swr/rasterizer/core/api.h +++ b/src/gallium/drivers/swr/rasterizer/core/api.h @@ -412,6 +412,14 @@ void SWR_API SwrSetBackendState( HANDLE hContext, SWR_BACKEND_STATE *pState); +////////////////////////////////////////////////////////////////////////// +/// @brief Set depth bounds state +/// @param hContext - Handle passed back from SwrCreateContext +/// @param pState - Pointer to state. +void SWR_API SwrSetDepthBoundsState( + HANDLE hContext, + SWR_DEPTH_BOUNDS_STATE *pState); + ////////////////////////////////////////////////////////////////////////// /// @brief Set pixel shader state /// @param hContext - Handle passed back from SwrCreateContext diff --git a/src/gallium/drivers/swr/rasterizer/core/backend.cpp b/src/gallium/drivers/swr/rasterizer/core/backend.cpp index 888af794e95..ad9f0d3d300 100644 --- a/src/gallium/drivers/swr/rasterizer/core/backend.cpp +++ b/src/gallium/drivers/swr/rasterizer/core/backend.cpp @@ -501,10 +501,22 @@ void BackendSingleSample(DRAW_CONTEXT *pDC, uint32_t workerId, uint32_t x, uint3 simdmask clipCoverageMask = coverageMask & MASK; // interpolate user clip distance if available - if(rastState.clipDistanceMask) + if (rastState.clipDistanceMask) { clipCoverageMask &= ~ComputeUserClipMask(rastState.clipDistanceMask, work.pUserClipBuffer, - psContext.vI.center, psContext.vJ.center); + psContext.vI.center, psContext.vJ.center); + } + + if (state.depthHottileEnable && state.depthBoundsState.depthBoundsTestEnable) + { + static_assert(KNOB_DEPTH_HOT_TILE_FORMAT == R32_FLOAT, "Unsupported depth hot tile format"); + + const simdscalar z = _simd_load_ps(reinterpret_cast(pDepthBase)); + + const float minz = state.depthBoundsState.depthBoundsTestMinValue; + const float maxz = state.depthBoundsState.depthBoundsTestMaxValue; + + clipCoverageMask &= CalcDepthBoundsAcceptMask(z, minz, maxz); } simdscalar vCoverageMask = vMask(clipCoverageMask); @@ -724,14 +736,26 @@ void BackendSampleRate(DRAW_CONTEXT *pDC, uint32_t workerId, uint32_t x, uint32_ psContext.vI.sample, psContext.vJ.sample); } - simdscalar vCoverageMask = vMask(coverageMask); - simdscalar depthPassMask = vCoverageMask; - simdscalar stencilPassMask = vCoverageMask; - // offset depth/stencil buffers current sample uint8_t *pDepthSample = pDepthBase + RasterTileDepthOffset(sample); uint8_t *pStencilSample = pStencilBase + RasterTileStencilOffset(sample); + if (state.depthHottileEnable && state.depthBoundsState.depthBoundsTestEnable) + { + static_assert(KNOB_DEPTH_HOT_TILE_FORMAT == R32_FLOAT, "Unsupported depth hot tile format"); + + const simdscalar z = _simd_load_ps(reinterpret_cast(pDepthSample)); + + const float minz = state.depthBoundsState.depthBoundsTestMinValue; + const float maxz = state.depthBoundsState.depthBoundsTestMaxValue; + + coverageMask &= CalcDepthBoundsAcceptMask(z, minz, maxz); + } + + simdscalar vCoverageMask = vMask(coverageMask); + simdscalar depthPassMask = vCoverageMask; + simdscalar stencilPassMask = vCoverageMask; + // Early-Z? if (T::bCanEarlyZ) { @@ -802,6 +826,8 @@ void BackendSampleRate(DRAW_CONTEXT *pDC, uint32_t workerId, uint32_t x, uint32_ } work.coverageMask[sample] >>= (SIMD_TILE_Y_DIM * SIMD_TILE_X_DIM); } + +Endtile: AR_BEGIN(BEEndTile, pDC->drawId); if(T::InputCoverage == SWR_INPUT_COVERAGE_INNER_CONSERVATIVE) { @@ -1113,13 +1139,25 @@ void BackendNullPS(DRAW_CONTEXT *pDC, uint32_t workerId, uint32_t x, uint32_t y, psContext.vI.sample, psContext.vJ.sample); } - simdscalar vCoverageMask = vMask(coverageMask); - simdscalar stencilPassMask = vCoverageMask; - // offset depth/stencil buffers current sample uint8_t *pDepthSample = pDepthBase + RasterTileDepthOffset(sample); uint8_t *pStencilSample = pStencilBase + RasterTileStencilOffset(sample); + if (state.depthHottileEnable && state.depthBoundsState.depthBoundsTestEnable) + { + static_assert(KNOB_DEPTH_HOT_TILE_FORMAT == R32_FLOAT, "Unsupported depth hot tile format"); + + const simdscalar z = _simd_load_ps(reinterpret_cast(pDepthSample)); + + const float minz = state.depthBoundsState.depthBoundsTestMinValue; + const float maxz = state.depthBoundsState.depthBoundsTestMaxValue; + + coverageMask &= CalcDepthBoundsAcceptMask(z, minz, maxz); + } + + simdscalar vCoverageMask = vMask(coverageMask); + simdscalar stencilPassMask = vCoverageMask; + AR_BEGIN(BEEarlyDepthTest, pDC->drawId); simdscalar depthPassMask = DepthStencilTest(&state, work.triFlags.frontFacing, work.triFlags.viewportIndex, psContext.vZ, pDepthSample, vCoverageMask, pStencilSample, &stencilPassMask); @@ -1131,6 +1169,8 @@ void BackendNullPS(DRAW_CONTEXT *pDC, uint32_t workerId, uint32_t x, uint32_t y, uint32_t statCount = _mm_popcnt_u32(statMask); UPDATE_STAT(DepthPassCount, statCount); } + +Endtile: work.coverageMask[sample] >>= (SIMD_TILE_Y_DIM * SIMD_TILE_X_DIM); } pDepthBase += (KNOB_SIMD_WIDTH * FormatTraits::bpp) / 8; diff --git a/src/gallium/drivers/swr/rasterizer/core/backend.h b/src/gallium/drivers/swr/rasterizer/core/backend.h index da4f46e7fd2..fcc78f71afd 100644 --- a/src/gallium/drivers/swr/rasterizer/core/backend.h +++ b/src/gallium/drivers/swr/rasterizer/core/backend.h @@ -410,6 +410,14 @@ INLINE void CalcCentroidBarycentrics(const BarycentricCoeffs& coeffs, SWR_PS_CON psContext.vOneOverW.centroid = vplaneps(coeffs.vAOneOverW, coeffs.vBOneOverW, coeffs.vCOneOverW, psContext.vI.centroid, psContext.vJ.centroid); } +INLINE simdmask CalcDepthBoundsAcceptMask(simdscalar z, float minz, float maxz) +{ + const simdscalar minzMask = _simd_cmpge_ps(z, _simd_set1_ps(minz)); + const simdscalar maxzMask = _simd_cmple_ps(z, _simd_set1_ps(maxz)); + + return _simd_movemask_ps(_simd_and_ps(minzMask, maxzMask)); +} + template INLINE uint32_t GetNumOMSamples(SWR_MULTISAMPLE_COUNT blendSampleCount) { @@ -490,6 +498,18 @@ struct PixelRateZTestLoop uint8_t *pDepthSample = pDepthBase + RasterTileDepthOffset(sample); uint8_t * pStencilSample = pStencilBase + RasterTileStencilOffset(sample); + if (state.depthHottileEnable && state.depthBoundsState.depthBoundsTestEnable) + { + static_assert(KNOB_DEPTH_HOT_TILE_FORMAT == R32_FLOAT, "Unsupported depth hot tile format"); + + const simdscalar z = _simd_load_ps(reinterpret_cast(pDepthSample)); + + const float minz = state.depthBoundsState.depthBoundsTestMinValue; + const float maxz = state.depthBoundsState.depthBoundsTestMaxValue; + + vCoverageMask[sample] = _simd_and_ps(vCoverageMask[sample], vMask(CalcDepthBoundsAcceptMask(z, minz, maxz))); + } + // ZTest for this sample ///@todo Need to uncomment out this bucket. //AR_BEGIN(BEDepthBucket, pDC->drawId); diff --git a/src/gallium/drivers/swr/rasterizer/core/context.h b/src/gallium/drivers/swr/rasterizer/core/context.h index 1f56dfc76d4..9a26e33ef42 100644 --- a/src/gallium/drivers/swr/rasterizer/core/context.h +++ b/src/gallium/drivers/swr/rasterizer/core/context.h @@ -286,6 +286,8 @@ OSALIGNLINE(struct) API_STATE // Backend state SWR_BACKEND_STATE backendState; + SWR_DEPTH_BOUNDS_STATE depthBoundsState; + // PS - Pixel shader state SWR_PS_STATE psState; diff --git a/src/gallium/drivers/swr/rasterizer/core/state.h b/src/gallium/drivers/swr/rasterizer/core/state.h index 7efae5646f1..93e4565735a 100644 --- a/src/gallium/drivers/swr/rasterizer/core/state.h +++ b/src/gallium/drivers/swr/rasterizer/core/state.h @@ -1079,3 +1079,12 @@ struct SWR_PS_STATE uint32_t forceEarlyZ : 1; // force execution of early depth/stencil test }; + +// depth bounds state +struct SWR_DEPTH_BOUNDS_STATE +{ + bool depthBoundsTestEnable; + float depthBoundsTestMinValue; + float depthBoundsTestMaxValue; +}; + -- cgit v1.2.3