From e0c10306f58fa3e1a1cb6a23b8942701d8529cce Mon Sep 17 00:00:00 2001 From: Tim Rowley Date: Wed, 3 Aug 2016 16:40:27 -0600 Subject: [PATCH] swr: [rasterizer core] add SwrWaitForIdleFE This is a blocking call that waits until all FE work is complete. This is useful for waiting for FE work to complete such as for streamout. Signed-off-by: Tim Rowley --- .../drivers/swr/rasterizer/core/api.cpp | 19 ++++++++++ src/gallium/drivers/swr/rasterizer/core/api.h | 6 +++ .../drivers/swr/rasterizer/core/context.h | 2 + .../drivers/swr/rasterizer/core/threads.cpp | 38 ++++++++++++------- 4 files changed, 51 insertions(+), 14 deletions(-) diff --git a/src/gallium/drivers/swr/rasterizer/core/api.cpp b/src/gallium/drivers/swr/rasterizer/core/api.cpp index bc36cfb7727..a4856ee2aed 100644 --- a/src/gallium/drivers/swr/rasterizer/core/api.cpp +++ b/src/gallium/drivers/swr/rasterizer/core/api.cpp @@ -207,6 +207,11 @@ void QueueWork(SWR_CONTEXT *pContext) // then moved on if all work is done.) pContext->pCurDrawContext->threadsDone = pContext->NumFEThreads + pContext->NumBEThreads; + if (IsDraw) + { + InterlockedIncrement((volatile LONG*)&pContext->drawsOutstandingFE); + } + _ReadWriteBarrier(); { std::unique_lock lock(pContext->WaitLock); @@ -431,6 +436,20 @@ void SwrWaitForIdle(HANDLE hContext) RDTSC_STOP(APIWaitForIdle, 1, 0); } +void SwrWaitForIdleFE(HANDLE hContext) +{ + SWR_CONTEXT *pContext = GetContext(hContext); + + RDTSC_START(APIWaitForIdle); + + while (pContext->drawsOutstandingFE > 0) + { + _mm_pause(); + } + + RDTSC_STOP(APIWaitForIdle, 1, 0); +} + void SwrSetVertexBuffers( HANDLE hContext, uint32_t numBuffers, diff --git a/src/gallium/drivers/swr/rasterizer/core/api.h b/src/gallium/drivers/swr/rasterizer/core/api.h index 681792fcd26..b45d4498ea0 100644 --- a/src/gallium/drivers/swr/rasterizer/core/api.h +++ b/src/gallium/drivers/swr/rasterizer/core/api.h @@ -177,6 +177,12 @@ void SWR_API SwrSync( void SWR_API SwrWaitForIdle( HANDLE hContext); +////////////////////////////////////////////////////////////////////////// +/// @brief Blocks until all FE rendering has been completed. +/// @param hContext - Handle passed back from SwrCreateContext +void SWR_API SwrWaitForIdleFE( + HANDLE hContext); + ////////////////////////////////////////////////////////////////////////// /// @brief Set vertex buffer state. /// @param hContext - Handle passed back from SwrCreateContext diff --git a/src/gallium/drivers/swr/rasterizer/core/context.h b/src/gallium/drivers/swr/rasterizer/core/context.h index 48cd7991084..7e6a1673211 100644 --- a/src/gallium/drivers/swr/rasterizer/core/context.h +++ b/src/gallium/drivers/swr/rasterizer/core/context.h @@ -486,6 +486,8 @@ struct SWR_CONTEXT // Scratch space for workers. uint8_t* pScratch[KNOB_MAX_NUM_THREADS]; + volatile int32_t drawsOutstandingFE; + CachingAllocator cachingArenaAllocator; uint32_t frameCount; }; diff --git a/src/gallium/drivers/swr/rasterizer/core/threads.cpp b/src/gallium/drivers/swr/rasterizer/core/threads.cpp index ea7cbab3647..b207ebd1731 100644 --- a/src/gallium/drivers/swr/rasterizer/core/threads.cpp +++ b/src/gallium/drivers/swr/rasterizer/core/threads.cpp @@ -322,18 +322,6 @@ bool CheckDependency(SWR_CONTEXT *pContext, DRAW_CONTEXT *pDC, uint32_t lastReti INLINE void ExecuteCallbacks(SWR_CONTEXT* pContext, DRAW_CONTEXT* pDC) { - if (pContext->pfnUpdateSoWriteOffset) - { - for (uint32_t i = 0; i < MAX_SO_BUFFERS; ++i) - { - if ((pDC->dynState.SoWriteOffsetDirty[i]) && - (pDC->pState->state.soBuffer[i].soWriteEnable)) - { - pContext->pfnUpdateSoWriteOffset(GetPrivateState(pDC), i, pDC->dynState.SoWriteOffset[i]); - } - } - } - if (pDC->retireCallback.pfnCallbackFunc) { pDC->retireCallback.pfnCallbackFunc(pDC->retireCallback.userData, @@ -540,6 +528,29 @@ void WorkOnFifoBE( } } +////////////////////////////////////////////////////////////////////////// +/// @brief Called when FE work is complete for this DC. +INLINE void CompleteDrawFE(SWR_CONTEXT* pContext, DRAW_CONTEXT* pDC) +{ + _ReadWriteBarrier(); + + if (pContext->pfnUpdateSoWriteOffset) + { + for (uint32_t i = 0; i < MAX_SO_BUFFERS; ++i) + { + if ((pDC->dynState.SoWriteOffsetDirty[i]) && + (pDC->pState->state.soBuffer[i].soWriteEnable)) + { + pContext->pfnUpdateSoWriteOffset(GetPrivateState(pDC), i, pDC->dynState.SoWriteOffset[i]); + } + } + } + + pDC->doneFE = true; + + InterlockedDecrement((volatile LONG*)&pContext->drawsOutstandingFE); +} + void WorkOnFifoFE(SWR_CONTEXT *pContext, uint32_t workerId, uint32_t &curDrawFE) { // Try to grab the next DC from the ring @@ -573,8 +584,7 @@ void WorkOnFifoFE(SWR_CONTEXT *pContext, uint32_t workerId, uint32_t &curDrawFE) // successfully grabbed the DC, now run the FE pDC->FeWork.pfnWork(pContext, pDC, workerId, &pDC->FeWork.desc); - _ReadWriteBarrier(); - pDC->doneFE = true; + CompleteDrawFE(pContext, pDC); } } curDraw++; -- 2.30.2