From a16d274032cc1ee264b14de39be1bbb3f923bfb0 Mon Sep 17 00:00:00 2001 From: Tim Rowley Date: Tue, 14 Jun 2016 17:54:34 -0600 Subject: [PATCH] swr: [rasterizer core] fix dependency bug Never be dependent on "draw 0", instead have a bool that makes the draw dependent on the previous draw or not dependent at all. Reviewed-by: Bruce Cherniak --- src/gallium/drivers/swr/rasterizer/core/api.cpp | 6 +++--- src/gallium/drivers/swr/rasterizer/core/context.h | 4 ++-- src/gallium/drivers/swr/rasterizer/core/ringbuffer.h | 8 ++++---- src/gallium/drivers/swr/rasterizer/core/threads.cpp | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/gallium/drivers/swr/rasterizer/core/api.cpp b/src/gallium/drivers/swr/rasterizer/core/api.cpp index b63d5474cf3..edde91814a5 100644 --- a/src/gallium/drivers/swr/rasterizer/core/api.cpp +++ b/src/gallium/drivers/swr/rasterizer/core/api.cpp @@ -322,7 +322,7 @@ DRAW_CONTEXT* GetDrawContext(SWR_CONTEXT *pContext, bool isSplitDraw = false) SWR_ASSERT(pCurDrawContext->pArena->IsEmpty() == true); - pCurDrawContext->dependency = 0; + pCurDrawContext->dependent = false; pCurDrawContext->pContext = pContext; pCurDrawContext->isCompute = false; // Dispatch has to set this to true. @@ -406,7 +406,7 @@ void SwrSync(HANDLE hContext, PFN_CALLBACK_FUNC pfnFunc, uint64_t userData, uint pDC->FeWork.desc.sync.userData3 = userData3; // cannot execute until all previous draws have completed - pDC->dependency = pDC->drawId - 1; + pDC->dependent = true; //enqueue QueueDraw(pContext); @@ -1500,7 +1500,7 @@ void SwrGetStats( pDC->FeWork.desc.queryStats.pStats = pStats; // cannot execute until all previous draws have completed - pDC->dependency = pDC->drawId - 1; + pDC->dependent = true; //enqueue QueueDraw(pContext); diff --git a/src/gallium/drivers/swr/rasterizer/core/context.h b/src/gallium/drivers/swr/rasterizer/core/context.h index 08eadf41134..be4c2e94b42 100644 --- a/src/gallium/drivers/swr/rasterizer/core/context.h +++ b/src/gallium/drivers/swr/rasterizer/core/context.h @@ -381,8 +381,6 @@ struct DRAW_STATE struct DRAW_CONTEXT { SWR_CONTEXT* pContext; - uint32_t drawId; - uint32_t dependency; union { MacroTileMgr* pTileMgr; @@ -391,6 +389,8 @@ struct DRAW_CONTEXT DRAW_STATE* pState; CachingArena* pArena; + uint32_t drawId; + bool dependent; bool isCompute; // Is this DC a compute context? bool cleanupState; // True if this is the last draw using an entry in the state ring. volatile bool doneFE; // Is FE work done for this draw? diff --git a/src/gallium/drivers/swr/rasterizer/core/ringbuffer.h b/src/gallium/drivers/swr/rasterizer/core/ringbuffer.h index 97f75c6550e..f1bef2190fb 100644 --- a/src/gallium/drivers/swr/rasterizer/core/ringbuffer.h +++ b/src/gallium/drivers/swr/rasterizer/core/ringbuffer.h @@ -46,6 +46,7 @@ public: void Init(uint32_t numEntries) { SWR_ASSERT(numEntries > 0); + SWR_ASSERT(((1ULL << 32) % numEntries) == 0, "%d is not evenly divisible into 2 ^ 32. Wrap errors will occur!", numEntries); mNumEntries = numEntries; mpRingBuffer = (T*)AlignedMalloc(sizeof(T)*numEntries, 64); SWR_ASSERT(mpRingBuffer != nullptr); @@ -67,6 +68,8 @@ public: INLINE void Enqueue() { mRingHead++; // There's only one producer. + // Assert to find wrap-around cases, NEVER ENABLE DURING CHECKIN!! + // SWR_REL_ASSERT(mRingHead); } INLINE void Dequeue() @@ -81,10 +84,7 @@ public: INLINE bool IsFull() { - ///@note We don't handle wrap case due to using 64-bit indices. - /// It would take 11 million years to wrap at 50,000 DCs per sec. - /// If we used 32-bit indices then its about 23 hours to wrap. - uint64_t numEnqueued = GetHead() - GetTail(); + uint32_t numEnqueued = GetHead() - GetTail(); SWR_ASSERT(numEnqueued <= mNumEntries); return (numEnqueued == mNumEntries); diff --git a/src/gallium/drivers/swr/rasterizer/core/threads.cpp b/src/gallium/drivers/swr/rasterizer/core/threads.cpp index fe164a06fb4..9671f7781d7 100644 --- a/src/gallium/drivers/swr/rasterizer/core/threads.cpp +++ b/src/gallium/drivers/swr/rasterizer/core/threads.cpp @@ -317,7 +317,7 @@ bool IDComparesLess(uint32_t a, uint32_t b) INLINE bool CheckDependency(SWR_CONTEXT *pContext, DRAW_CONTEXT *pDC, uint32_t lastRetiredDraw) { - return IDComparesLess(lastRetiredDraw, pDC->dependency); + return pDC->dependent && IDComparesLess(lastRetiredDraw, pDC->drawId - 1); } // inlined-only version