swr: [rasterizer core] add SwrWaitForIdleFE
authorTim Rowley <timothy.o.rowley@intel.com>
Wed, 3 Aug 2016 22:40:27 +0000 (16:40 -0600)
committerTim Rowley <timothy.o.rowley@intel.com>
Wed, 10 Aug 2016 16:07:59 +0000 (11:07 -0500)
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@intel.com>
src/gallium/drivers/swr/rasterizer/core/api.cpp
src/gallium/drivers/swr/rasterizer/core/api.h
src/gallium/drivers/swr/rasterizer/core/context.h
src/gallium/drivers/swr/rasterizer/core/threads.cpp

index bc36cfb7727cb003404cd78d2270d906a25e32dd..a4856ee2aede770dbd4359f56e434463e9517244 100644 (file)
@@ -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,
index 681792fcd26607a2372cf2feda41bfea31d6435f..b45d4498ea0634f4599adb98a9428f0e97e351df 100644 (file)
@@ -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
index 48cd7991084d111c74add8cdad7bc92d4c1f20aa..7e6a167321177445d880b0d7993aec4a700c3653 100644 (file)
@@ -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;
 };
index ea7cbab364744ae23aff0ade3260d6bbd075de5c..b207ebd17311622f76222ee2d17c16bbfadcdca6 100644 (file)
@@ -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++;