Mesa (master): swr: [rasterizer core] add SwrWaitForIdleFE

Tim Rowley torowley at kemper.freedesktop.org
Wed Aug 10 18:17:13 UTC 2016


Module: Mesa
Branch: master
Commit: e0c10306f58fa3e1a1cb6a23b8942701d8529cce
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=e0c10306f58fa3e1a1cb6a23b8942701d8529cce

Author: Tim Rowley <timothy.o.rowley at intel.com>
Date:   Wed Aug  3 16:40:27 2016 -0600

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 <timothy.o.rowley at intel.com>

---

 src/gallium/drivers/swr/rasterizer/core/api.cpp    | 19 +++++++++++
 src/gallium/drivers/swr/rasterizer/core/api.h      |  6 ++++
 src/gallium/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 bc36cfb..a4856ee 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<std::mutex> 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 681792f..b45d449 100644
--- a/src/gallium/drivers/swr/rasterizer/core/api.h
+++ b/src/gallium/drivers/swr/rasterizer/core/api.h
@@ -178,6 +178,12 @@ 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
 /// @param numBuffers - Number of vertex buffer state descriptors.
diff --git a/src/gallium/drivers/swr/rasterizer/core/context.h b/src/gallium/drivers/swr/rasterizer/core/context.h
index 48cd799..7e6a167 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 ea7cbab..b207ebd 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++;




More information about the mesa-commit mailing list