From 0a5811b0f381e8920536a19bab4d437d5bdb5b63 Mon Sep 17 00:00:00 2001 From: George Kyriazis Date: Wed, 19 Oct 2016 16:37:36 -0500 Subject: [PATCH] swr: [rasterizer core] Frontend dependency work Add frontend dependency concept in the DRAW_CONTEXT, which allows serialization of frontend work if necessary. Reviewed-by: Bruce Cherniak --- src/gallium/drivers/swr/rasterizer/core/api.cpp | 3 +++ src/gallium/drivers/swr/rasterizer/core/context.h | 3 ++- .../drivers/swr/rasterizer/core/threads.cpp | 14 +++++++++++++- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/swr/rasterizer/core/api.cpp b/src/gallium/drivers/swr/rasterizer/core/api.cpp index e67ede2610f..5f941e8402a 100644 --- a/src/gallium/drivers/swr/rasterizer/core/api.cpp +++ b/src/gallium/drivers/swr/rasterizer/core/api.cpp @@ -317,7 +317,10 @@ DRAW_CONTEXT* GetDrawContext(SWR_CONTEXT *pContext, bool isSplitDraw = false) SWR_ASSERT(pCurDrawContext->pArena->IsEmpty() == true); + // Reset dependency pCurDrawContext->dependent = false; + pCurDrawContext->dependentFE = false; + pCurDrawContext->pContext = pContext; pCurDrawContext->isCompute = false; // Dispatch has to set this to true. diff --git a/src/gallium/drivers/swr/rasterizer/core/context.h b/src/gallium/drivers/swr/rasterizer/core/context.h index 9a26e33ef42..a9de63b8cf1 100644 --- a/src/gallium/drivers/swr/rasterizer/core/context.h +++ b/src/gallium/drivers/swr/rasterizer/core/context.h @@ -404,7 +404,8 @@ struct DRAW_CONTEXT CachingArena* pArena; uint32_t drawId; - bool dependent; + bool dependentFE; // Frontend work is dependent on all previous FE + bool dependent; // Backend work is dependent on all previous BE bool isCompute; // Is this DC a compute context? bool cleanupState; // True if this is the last draw using an entry in the state ring. volatile bool doneFE; // Is FE work done for this draw? diff --git a/src/gallium/drivers/swr/rasterizer/core/threads.cpp b/src/gallium/drivers/swr/rasterizer/core/threads.cpp index ea5542ab332..701a550df20 100644 --- a/src/gallium/drivers/swr/rasterizer/core/threads.cpp +++ b/src/gallium/drivers/swr/rasterizer/core/threads.cpp @@ -313,6 +313,11 @@ bool CheckDependency(SWR_CONTEXT *pContext, DRAW_CONTEXT *pDC, uint32_t lastReti return pDC->dependent && IDComparesLess(lastRetiredDraw, pDC->drawId - 1); } +bool CheckDependencyFE(SWR_CONTEXT *pContext, DRAW_CONTEXT *pDC, uint32_t lastRetiredDraw) +{ + return pDC->dependentFE && IDComparesLess(lastRetiredDraw, pDC->drawId - 1); +} + ////////////////////////////////////////////////////////////////////////// /// @brief Update client stats. INLINE void UpdateClientStats(SWR_CONTEXT* pContext, uint32_t workerId, DRAW_CONTEXT* pDC) @@ -595,6 +600,7 @@ INLINE void CompleteDrawFE(SWR_CONTEXT* pContext, uint32_t workerId, DRAW_CONTEX // Ensure all streaming writes are globally visible before marking this FE done _mm_mfence(); pDC->doneFE = true; + InterlockedDecrement((volatile LONG*)&pContext->drawsOutstandingFE); } @@ -606,7 +612,7 @@ void WorkOnFifoFE(SWR_CONTEXT *pContext, uint32_t workerId, uint32_t &curDrawFE) { uint32_t dcSlot = curDrawFE % KNOB_MAX_DRAWS_IN_FLIGHT; DRAW_CONTEXT *pDC = &pContext->dcRing[dcSlot]; - if (pDC->isCompute || pDC->doneFE || pDC->FeLock) + if (pDC->isCompute || pDC->doneFE) { CompleteDrawContextInl(pContext, workerId, pDC); curDrawFE++; @@ -617,6 +623,7 @@ void WorkOnFifoFE(SWR_CONTEXT *pContext, uint32_t workerId, uint32_t &curDrawFE) } } + uint32_t lastRetiredFE = curDrawFE - 1; uint32_t curDraw = curDrawFE; while (IDComparesLess(curDraw, drawEnqueued)) { @@ -625,6 +632,11 @@ void WorkOnFifoFE(SWR_CONTEXT *pContext, uint32_t workerId, uint32_t &curDrawFE) if (!pDC->isCompute && !pDC->FeLock) { + if (CheckDependencyFE(pContext, pDC, lastRetiredFE)) + { + return; + } + uint32_t initial = InterlockedCompareExchange((volatile uint32_t*)&pDC->FeLock, 1, 0); if (initial == 0) { -- 2.30.2