pContext->dcRing.Init(KNOB_MAX_DRAWS_IN_FLIGHT);
pContext->dsRing.Init(KNOB_MAX_DRAWS_IN_FLIGHT);
- pContext->numSubContexts = pCreateInfo->maxSubContexts;
- if (pContext->numSubContexts > 1)
- {
- pContext->subCtxSave = (DRAW_STATE*)_aligned_malloc(sizeof(DRAW_STATE) * pContext->numSubContexts, 64);
- memset(pContext->subCtxSave, 0, sizeof(DRAW_STATE) * pContext->numSubContexts);
- }
-
for (uint32_t dc = 0; dc < KNOB_MAX_DRAWS_IN_FLIGHT; ++dc)
{
pContext->dcRing[dc].pArena = new Arena();
pCreateInfo->pBucketMgr = &gBucketMgr;
#endif
+ pCreateInfo->contextSaveSize = sizeof(API_STATE);
+
return (HANDLE)pContext;
}
_aligned_free(pContext->pScratch[i]);
}
- _aligned_free(pContext->subCtxSave);
-
delete(pContext->pHotTileMgr);
pContext->~SWR_CONTEXT();
return pContext->pCurDrawContext;
}
-void SWR_API SwrSetActiveSubContext(
- HANDLE hContext,
- uint32_t subContextIndex)
+API_STATE* GetDrawState(SWR_CONTEXT *pContext)
{
- SWR_CONTEXT *pContext = (SWR_CONTEXT*)hContext;
- if (subContextIndex >= pContext->numSubContexts)
- {
- return;
- }
+ DRAW_CONTEXT* pDC = GetDrawContext(pContext);
+ SWR_ASSERT(pDC->pState != nullptr);
- if (subContextIndex != pContext->curSubCtxId)
- {
- // Save and restore draw state
- DRAW_CONTEXT* pDC = GetDrawContext(pContext);
- CopyState(
- pContext->subCtxSave[pContext->curSubCtxId],
- *(pDC->pState));
+ return &pDC->pState->state;
+}
- CopyState(
- *(pDC->pState),
- pContext->subCtxSave[subContextIndex]);
+void SWR_API SwrSaveState(
+ HANDLE hContext,
+ void* pOutputStateBlock,
+ size_t memSize)
+{
+ SWR_CONTEXT *pContext = (SWR_CONTEXT*)hContext;
+ auto pSrc = GetDrawState(pContext);
+ SWR_ASSERT(pOutputStateBlock && memSize >= sizeof(*pSrc));
- pContext->curSubCtxId = subContextIndex;
- }
+ memcpy(pOutputStateBlock, pSrc, sizeof(*pSrc));
}
-API_STATE* GetDrawState(SWR_CONTEXT *pContext)
+void SWR_API SwrRestoreState(
+ HANDLE hContext,
+ const void* pStateBlock,
+ size_t memSize)
{
- DRAW_CONTEXT* pDC = GetDrawContext(pContext);
- SWR_ASSERT(pDC->pState != nullptr);
+ SWR_CONTEXT *pContext = (SWR_CONTEXT*)hContext;
+ auto pDst = GetDrawState(pContext);
+ SWR_ASSERT(pStateBlock && memSize >= sizeof(*pDst));
- return &pDC->pState->state;
+ memcpy(pDst, pStateBlock, sizeof(*pDst));
}
void SetupDefaultState(SWR_CONTEXT *pContext)
// Use SwrGetPrivateContextState() to access private state.
uint32_t privateStateSize;
- // Each SWR context can have multiple sets of active state
- uint32_t maxSubContexts;
-
// Tile manipulation functions
PFN_LOAD_TILE pfnLoadTile;
PFN_STORE_TILE pfnStoreTile;
// Pointer to rdtsc buckets mgr returned to the caller.
// Only populated when KNOB_ENABLE_RDTSC is set
BucketManager* pBucketMgr;
+
+ // Output: size required memory passed to for SwrSaveState / SwrRestoreState
+ size_t contextSaveSize;
};
//////////////////////////////////////////////////////////////////////////
HANDLE hContext);
//////////////////////////////////////////////////////////////////////////
-/// @brief Set currently active state context
-/// @param subContextIndex - value from 0 to
-/// SWR_CREATECONTEXT_INFO.maxSubContexts. Defaults to 0.
-void SWR_API SwrSetActiveSubContext(
+/// @brief Saves API state associated with hContext
+/// @param hContext - Handle passed back from SwrCreateContext
+/// @param pOutputStateBlock - Memory block to receive API state data
+/// @param memSize - Size of memory pointed to by pOutputStateBlock
+void SWR_API SwrSaveState(
+ HANDLE hContext,
+ void* pOutputStateBlock,
+ size_t memSize);
+
+//////////////////////////////////////////////////////////////////////////
+/// @brief Restores API state to hContext previously saved with SwrSaveState
+/// @param hContext - Handle passed back from SwrCreateContext
+/// @param pStateBlock - Memory block to read API state data from
+/// @param memSize - Size of memory pointed to by pStateBlock
+void SWR_API SwrRestoreState(
HANDLE hContext,
- uint32_t subContextIndex);
+ const void* pStateBlock,
+ size_t memSize);
//////////////////////////////////////////////////////////////////////////
/// @brief Sync cmd. Executes the callback func when all rendering up to this sync
uint32_t curStateId; // Current index to the next available entry in the DS ring.
- DRAW_STATE* subCtxSave; // Save area for inactive contexts.
- uint32_t curSubCtxId; // Current index for active state subcontext.
- uint32_t numSubContexts; // Number of available subcontexts
-
uint32_t NumWorkerThreads;
THREAD_POOL threadPool; // Thread pool associated with this context
INLINE volatile uint64_t GetTail() { return mRingTail; }
INLINE volatile uint64_t GetHead() { return mRingHead; }
-private:
+protected:
T* mpRingBuffer;
uint32_t mNumEntries;
numThreads, KNOB_MAX_NUM_THREADS);
}
+ uint32_t numAPIReservedThreads = 1;
+
+
if (numThreads == 1)
{
- // If only 1 worker thread, try to move it to an available
+ // If only 1 worker threads, try to move it to an available
// HW thread. If that fails, use the API thread.
if (numCoresPerNode < numHWCoresPerNode)
{
}
else
{
- // Save a HW thread for the API thread.
- numThreads--;
+ // Save HW threads for the API if we can
+ if (numThreads > numAPIReservedThreads)
+ {
+ numThreads -= numAPIReservedThreads;
+ }
+ else
+ {
+ numAPIReservedThreads = 0;
+ }
}
pPool->numThreads = numThreads;
auto& core = node.cores[c];
for (uint32_t t = 0; t < numHyperThreads; ++t)
{
- if (c == 0 && n == 0 && t == 0)
+ if (numAPIReservedThreads)
{
- // Skip core 0, thread0 on node 0 to reserve for API thread
+ --numAPIReservedThreads;
continue;
}
# Python source
KNOBS = [
+
['ENABLE_ASSERT_DIALOGS', {
'type' : 'bool',
'default' : 'true',
SWR_CREATECONTEXT_INFO createInfo;
createInfo.driver = GL;
createInfo.privateStateSize = sizeof(swr_draw_context);
- createInfo.maxSubContexts = 0;
createInfo.pfnLoadTile = swr_LoadHotTile;
createInfo.pfnStoreTile = swr_StoreHotTile;
createInfo.pfnClearTile = swr_StoreHotTileClear;