aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Rowley <[email protected]>2016-08-03 16:40:27 -0600
committerTim Rowley <[email protected]>2016-08-10 11:07:59 -0500
commite0c10306f58fa3e1a1cb6a23b8942701d8529cce (patch)
tree0c04a0ce5ea63333b565e69f803116a629ce1487
parent8dfaf249cc00178e126cc2469671fedb789698fa (diff)
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 <[email protected]>
-rw-r--r--src/gallium/drivers/swr/rasterizer/core/api.cpp19
-rw-r--r--src/gallium/drivers/swr/rasterizer/core/api.h6
-rw-r--r--src/gallium/drivers/swr/rasterizer/core/context.h2
-rw-r--r--src/gallium/drivers/swr/rasterizer/core/threads.cpp38
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<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 681792fcd26..b45d4498ea0 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 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++;