DRAW_CONTEXT* pDC = GetDrawContext(pContext);
AR_API_BEGIN(APIDraw, pDC->drawId);
+ AR_API_EVENT(DrawInstancedEvent(pDC->drawId, topology, numVertices, startVertex, numInstances, startInstance));
uint32_t maxVertsPerDraw = MaxVertsPerDraw(pDC, numVertices, topology);
uint32_t primsPerDraw = GetNumPrims(topology, maxVertsPerDraw);
API_STATE* pState = &pDC->pState->state;
AR_API_BEGIN(APIDrawIndexed, pDC->drawId);
- AR_API_EVENT(DrawIndexedInstance(topology, numIndices, indexOffset, baseVertex, numInstances, startInstance));
+ AR_API_EVENT(DrawIndexedInstancedEvent(pDC->drawId, topology, numIndices, indexOffset, baseVertex, numInstances, startInstance));
uint32_t maxIndicesPerDraw = MaxVertsPerDraw(pDC, numIndices, topology);
uint32_t primsPerDraw = GetNumPrims(topology, maxIndicesPerDraw);
DRAW_CONTEXT* pDC = GetDrawContext(pContext);
AR_API_BEGIN(APIDispatch, pDC->drawId);
-
+ AR_API_EVENT(DispatchEvent(pDC->drawId, threadGroupCountX, threadGroupCountY, threadGroupCountZ));
pDC->isCompute = true; // This is a compute context.
COMPUTE_DESC* pTaskData = (COMPUTE_DESC*)pDC->pArena->AllocAligned(sizeof(COMPUTE_DESC), 64);
void SWR_API SwrEndFrame(
HANDLE hContext)
{
- RDTSC_ENDFRAME();
SWR_CONTEXT *pContext = GetContext(hContext);
+ DRAW_CONTEXT* pDC = GetDrawContext(pContext);
+
+ RDTSC_ENDFRAME();
+ AR_API_EVENT(FrameEndEvent(pContext->frameCount, pDC->drawId));
+
pContext->frameCount++;
}
//////////////////////////////////////////////////////////////////////////
/// @brief Update client stats.
-INLINE void UpdateClientStats(SWR_CONTEXT* pContext, DRAW_CONTEXT* pDC)
+INLINE void UpdateClientStats(SWR_CONTEXT* pContext, uint32_t workerId, DRAW_CONTEXT* pDC)
{
if ((pContext->pfnUpdateStats == nullptr) || (GetApiState(pDC).enableStats == false))
{
stats.CsInvocations += dynState.pStats[i].CsInvocations;
}
+
pContext->pfnUpdateStats(GetPrivateState(pDC), &stats);
}
-INLINE void ExecuteCallbacks(SWR_CONTEXT* pContext, DRAW_CONTEXT* pDC)
+INLINE void ExecuteCallbacks(SWR_CONTEXT* pContext, uint32_t workerId, DRAW_CONTEXT* pDC)
{
- UpdateClientStats(pContext, pDC);
+ UpdateClientStats(pContext, workerId, pDC);
if (pDC->retireCallback.pfnCallbackFunc)
{
}
// inlined-only version
-INLINE int32_t CompleteDrawContextInl(SWR_CONTEXT* pContext, DRAW_CONTEXT* pDC)
+INLINE int32_t CompleteDrawContextInl(SWR_CONTEXT* pContext, uint32_t workerId, DRAW_CONTEXT* pDC)
{
int32_t result = InterlockedDecrement((volatile LONG*)&pDC->threadsDone);
SWR_ASSERT(result >= 0);
if (result == 0)
{
- ExecuteCallbacks(pContext, pDC);
+ ExecuteCallbacks(pContext, workerId, pDC);
// Cleanup memory allocations
pDC->pArena->Reset(true);
// available to other translation modules
int32_t CompleteDrawContext(SWR_CONTEXT* pContext, DRAW_CONTEXT* pDC)
{
- return CompleteDrawContextInl(pContext, pDC);
+ return CompleteDrawContextInl(pContext, 0, pDC);
}
-INLINE bool FindFirstIncompleteDraw(SWR_CONTEXT* pContext, uint32_t& curDrawBE, uint32_t& drawEnqueued)
+INLINE bool FindFirstIncompleteDraw(SWR_CONTEXT* pContext, uint32_t workerId, uint32_t& curDrawBE, uint32_t& drawEnqueued)
{
// increment our current draw id to the first incomplete draw
drawEnqueued = GetEnqueuedDraw(pContext);
if (isWorkComplete)
{
curDrawBE++;
- CompleteDrawContextInl(pContext, pDC);
+ CompleteDrawContextInl(pContext, workerId, pDC);
}
else
{
// Find the first incomplete draw that has pending work. If no such draw is found then
// return. FindFirstIncompleteDraw is responsible for incrementing the curDrawBE.
uint32_t drawEnqueued = 0;
- if (FindFirstIncompleteDraw(pContext, curDrawBE, drawEnqueued) == false)
+ if (FindFirstIncompleteDraw(pContext, workerId, curDrawBE, drawEnqueued) == false)
{
return false;
}
{
// We can increment the current BE and safely move to next draw since we know this draw is complete.
curDrawBE++;
- CompleteDrawContextInl(pContext, pDC);
+ CompleteDrawContextInl(pContext, workerId, pDC);
lastRetiredDraw++;
//////////////////////////////////////////////////////////////////////////
/// @brief Called when FE work is complete for this DC.
-INLINE void CompleteDrawFE(SWR_CONTEXT* pContext, DRAW_CONTEXT* pDC)
+INLINE void CompleteDrawFE(SWR_CONTEXT* pContext, uint32_t workerId, DRAW_CONTEXT* pDC)
{
if (pContext->pfnUpdateStatsFE && GetApiState(pDC).enableStats)
{
- pContext->pfnUpdateStatsFE(GetPrivateState(pDC), &pDC->dynState.statsFE);
+ SWR_STATS_FE& stats = pDC->dynState.statsFE;
+
+ AR_EVENT(FrontendStatsEvent(
+ stats.IaVertices, stats.IaPrimitives, stats.VsInvocations, stats.HsInvocations,
+ stats.DsInvocations, stats.GsInvocations, stats.GsPrimitives, stats.CInvocations, stats.CPrimitives,
+ stats.SoPrimStorageNeeded[0], stats.SoPrimStorageNeeded[1], stats.SoPrimStorageNeeded[2], stats.SoPrimStorageNeeded[3],
+ stats.SoNumPrimsWritten[0], stats.SoNumPrimsWritten[1], stats.SoNumPrimsWritten[2], stats.SoNumPrimsWritten[3]
+ ));
+
+ pContext->pfnUpdateStatsFE(GetPrivateState(pDC), &stats);
}
if (pContext->pfnUpdateSoWriteOffset)
DRAW_CONTEXT *pDC = &pContext->dcRing[dcSlot];
if (pDC->isCompute || pDC->doneFE || pDC->FeLock)
{
- CompleteDrawContextInl(pContext, pDC);
+ CompleteDrawContextInl(pContext, workerId, pDC);
curDrawFE++;
}
else
// successfully grabbed the DC, now run the FE
pDC->FeWork.pfnWork(pContext, pDC, workerId, &pDC->FeWork.desc);
- CompleteDrawFE(pContext, pDC);
+ CompleteDrawFE(pContext, workerId, pDC);
}
}
curDraw++;
uint32_t& curDrawBE)
{
uint32_t drawEnqueued = 0;
- if (FindFirstIncompleteDraw(pContext, curDrawBE, drawEnqueued) == false)
+ if (FindFirstIncompleteDraw(pContext, workerId, curDrawBE, drawEnqueued) == false)
{
return;
}