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@intel.com>
This commit is contained in:
Tim Rowley 2016-08-03 16:40:27 -06:00
parent 8dfaf249cc
commit e0c10306f5
4 changed files with 51 additions and 14 deletions

View 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,

View 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

View 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;
};

View 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++;