"Fossies" - the Fresh Open Source Software Archive

Member "mesa-20.1.8/src/gallium/drivers/swr/rasterizer/core/context.h" (16 Sep 2020, 19545 Bytes) of package /linux/misc/mesa-20.1.8.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "context.h" see the Fossies "Dox" file reference documentation.

    1 /****************************************************************************
    2  * Copyright (C) 2014-2018 Intel Corporation.   All Rights Reserved.
    3  *
    4  * Permission is hereby granted, free of charge, to any person obtaining a
    5  * copy of this software and associated documentation files (the "Software"),
    6  * to deal in the Software without restriction, including without limitation
    7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
    8  * and/or sell copies of the Software, and to permit persons to whom the
    9  * Software is furnished to do so, subject to the following conditions:
   10  *
   11  * The above copyright notice and this permission notice (including the next
   12  * paragraph) shall be included in all copies or substantial portions of the
   13  * Software.
   14  *
   15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
   18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
   21  * IN THE SOFTWARE.
   22  *
   23  * @file context.h
   24  *
   25  * @brief Definitions for SWR_CONTEXT and DRAW_CONTEXT
   26  *        The SWR_CONTEXT is our global context and contains the DC ring,
   27  *        thread state, etc.
   28  *
   29  *        The DRAW_CONTEXT contains all state associated with a draw operation.
   30  *
   31  ******************************************************************************/
   32 #pragma once
   33 
   34 #include <condition_variable>
   35 #include <algorithm>
   36 
   37 #include "core/api.h"
   38 #include "core/utils.h"
   39 #include "core/arena.h"
   40 #include "core/fifo.hpp"
   41 #include "core/knobs.h"
   42 #include "common/intrin.h"
   43 #include "common/rdtsc_buckets.h"
   44 #include "core/threads.h"
   45 #include "ringbuffer.h"
   46 #include "archrast/archrast.h"
   47 
   48 // x.8 fixed point precision values
   49 #define FIXED_POINT_SHIFT 8
   50 #define FIXED_POINT_SCALE 256
   51 
   52 // x.16 fixed point precision values
   53 #define FIXED_POINT16_SHIFT 16
   54 #define FIXED_POINT16_SCALE 65536
   55 
   56 struct SWR_CONTEXT;
   57 struct DRAW_CONTEXT;
   58 
   59 struct TRI_FLAGS
   60 {
   61     uint32_t frontFacing : 1;
   62     uint32_t yMajor : 1;
   63     uint32_t coverageMask : (SIMD_TILE_X_DIM* SIMD_TILE_Y_DIM);
   64     uint32_t reserved : 32 - 1 - 1 - (SIMD_TILE_X_DIM * SIMD_TILE_Y_DIM);
   65     float    pointSize;
   66     uint32_t renderTargetArrayIndex;
   67     uint32_t viewportIndex;
   68 };
   69 
   70 //////////////////////////////////////////////////////////////////////////
   71 /// SWR_TRIANGLE_DESC
   72 /////////////////////////////////////////////////////////////////////////
   73 struct SWR_TRIANGLE_DESC
   74 {
   75     float I[3];
   76     float J[3];
   77     float Z[3];
   78     float OneOverW[3];
   79     float recipDet;
   80 
   81     float* pRecipW;
   82     float* pAttribs;
   83     float* pPerspAttribs;
   84     float* pSamplePos;
   85     float* pUserClipBuffer;
   86 
   87     uint64_t coverageMask[SWR_MAX_NUM_MULTISAMPLES];
   88     uint64_t innerCoverageMask; // Conservative rasterization inner coverage: marked covered if
   89                                 // entire pixel is covered
   90     uint64_t anyCoveredSamples;
   91 
   92     TRI_FLAGS triFlags;
   93 };
   94 
   95 struct TRIANGLE_WORK_DESC
   96 {
   97     float* pTriBuffer;
   98     float* pAttribs;
   99     float* pUserClipBuffer;
  100     uint32_t  numAttribs;
  101     TRI_FLAGS triFlags;
  102 };
  103 
  104 struct CLEAR_DESC
  105 {
  106     SWR_RECT rect;
  107     uint32_t attachmentMask;
  108     uint32_t renderTargetArrayIndex;
  109     float    clearRTColor[4]; // RGBA_32F
  110     float    clearDepth;      // [0..1]
  111     uint8_t  clearStencil;
  112 };
  113 
  114 struct DISCARD_INVALIDATE_TILES_DESC
  115 {
  116     uint32_t       attachmentMask;
  117     SWR_RECT       rect;
  118     SWR_TILE_STATE newTileState;
  119     bool           createNewTiles;
  120     bool           fullTilesOnly;
  121 };
  122 
  123 struct SYNC_DESC
  124 {
  125     PFN_CALLBACK_FUNC pfnCallbackFunc;
  126     uint64_t          userData;
  127     uint64_t          userData2;
  128     uint64_t          userData3;
  129 };
  130 
  131 struct STORE_TILES_DESC
  132 {
  133     uint32_t       attachmentMask;
  134     SWR_TILE_STATE postStoreTileState;
  135     SWR_RECT       rect;
  136 };
  137 
  138 struct COMPUTE_DESC
  139 {
  140     uint32_t threadGroupCountX;
  141     uint32_t threadGroupCountY;
  142     uint32_t threadGroupCountZ;
  143     bool     enableThreadDispatch;
  144 };
  145 
  146 typedef void (*PFN_WORK_FUNC)(DRAW_CONTEXT* pDC,
  147                               uint32_t      workerId,
  148                               uint32_t      macroTile,
  149                               void*         pDesc);
  150 
  151 enum WORK_TYPE
  152 {
  153     SYNC,
  154     DRAW,
  155     CLEAR,
  156     DISCARDINVALIDATETILES,
  157     STORETILES,
  158     SHUTDOWN,
  159 };
  160 
  161 OSALIGNSIMD(struct) BE_WORK
  162 {
  163     WORK_TYPE     type;
  164     PFN_WORK_FUNC pfnWork;
  165     union
  166     {
  167         SYNC_DESC                     sync;
  168         TRIANGLE_WORK_DESC            tri;
  169         CLEAR_DESC                    clear;
  170         DISCARD_INVALIDATE_TILES_DESC discardInvalidateTiles;
  171         STORE_TILES_DESC              storeTiles;
  172     } desc;
  173 };
  174 
  175 struct DRAW_WORK
  176 {
  177     DRAW_CONTEXT* pDC;
  178     union
  179     {
  180         uint32_t numIndices; // DrawIndexed: Number of indices for draw.
  181         uint32_t numVerts;   // Draw: Number of verts (triangles, lines, etc)
  182     };
  183     union
  184     {
  185         gfxptr_t xpIB;        // DrawIndexed: App supplied int32 indices
  186         uint32_t startVertex; // Draw: Starting vertex in VB to render from.
  187     };
  188     int32_t  baseVertex;
  189     uint32_t numInstances;  // Number of instances
  190     uint32_t startInstance; // Instance offset
  191     uint32_t startPrimID;   // starting primitiveID for this draw batch
  192     uint32_t
  193                startVertexID; // starting VertexID for this draw batch (only needed for non-indexed draws)
  194     SWR_FORMAT type;          // index buffer type
  195 };
  196 
  197 typedef void (*PFN_FE_WORK_FUNC)(SWR_CONTEXT*  pContext,
  198                                  DRAW_CONTEXT* pDC,
  199                                  uint32_t      workerId,
  200                                  void*         pDesc);
  201 struct FE_WORK
  202 {
  203     WORK_TYPE        type;
  204     PFN_FE_WORK_FUNC pfnWork;
  205     union
  206     {
  207         SYNC_DESC                     sync;
  208         DRAW_WORK                     draw;
  209         CLEAR_DESC                    clear;
  210         DISCARD_INVALIDATE_TILES_DESC discardInvalidateTiles;
  211         STORE_TILES_DESC              storeTiles;
  212     } desc;
  213 };
  214 
  215 struct GUARDBANDS
  216 {
  217     float left[KNOB_NUM_VIEWPORTS_SCISSORS];
  218     float right[KNOB_NUM_VIEWPORTS_SCISSORS];
  219     float top[KNOB_NUM_VIEWPORTS_SCISSORS];
  220     float bottom[KNOB_NUM_VIEWPORTS_SCISSORS];
  221 };
  222 
  223 struct PA_STATE;
  224 
  225 // function signature for pipeline stages that execute after primitive assembly
  226 typedef void (*PFN_PROCESS_PRIMS)(DRAW_CONTEXT*      pDC,
  227                                   PA_STATE&          pa,
  228                                   uint32_t           workerId,
  229                                   simdvector         prims[],
  230                                   uint32_t           primMask,
  231                                   simdscalari const& primID,
  232                                   simdscalari const& viewportIdx,
  233                                   simdscalari const& rtIdx);
  234 
  235 // function signature for pipeline stages that execute after primitive assembly
  236 typedef void(SIMDCALL* PFN_PROCESS_PRIMS_SIMD16)(DRAW_CONTEXT*        pDC,
  237                                                  PA_STATE&            pa,
  238                                                  uint32_t             workerId,
  239                                                  simd16vector         prims[],
  240                                                  uint32_t             primMask,
  241                                                  simd16scalari const& primID,
  242                                                  simd16scalari const& viewportIdx,
  243                                                  simd16scalari const& rtIdx);
  244 
  245 OSALIGNLINE(struct) API_STATE
  246 {
  247     // Vertex Buffers
  248     SWR_VERTEX_BUFFER_STATE vertexBuffers[KNOB_NUM_STREAMS];
  249 
  250     // GS - Geometry Shader State
  251     SWR_GS_STATE gsState;
  252     PFN_GS_FUNC  pfnGsFunc;
  253 
  254     // FS - Fetch Shader State
  255     PFN_FETCH_FUNC pfnFetchFunc;
  256 
  257     // VS - Vertex Shader State
  258     PFN_VERTEX_FUNC pfnVertexFunc;
  259 
  260     // Index Buffer
  261     SWR_INDEX_BUFFER_STATE indexBuffer;
  262 
  263     // CS - Compute Shader
  264     PFN_CS_FUNC pfnCsFunc;
  265     uint32_t    totalThreadsInGroup;
  266     uint32_t    totalSpillFillSize;
  267     uint32_t    scratchSpaceSizePerWarp;
  268     uint32_t    scratchSpaceNumWarps;
  269 
  270     // FE - Frontend State
  271     SWR_FRONTEND_STATE frontendState;
  272 
  273     // SOS - Streamout Shader State
  274     PFN_SO_FUNC pfnSoFunc[MAX_SO_STREAMS];
  275 
  276     // Streamout state
  277     SWR_STREAMOUT_STATE          soState;
  278     mutable SWR_STREAMOUT_BUFFER soBuffer[MAX_SO_STREAMS];
  279     mutable SWR_STREAMOUT_BUFFER soPausedBuffer[MAX_SO_STREAMS];
  280 
  281     // Tessellation State
  282     PFN_HS_FUNC  pfnHsFunc;
  283     PFN_DS_FUNC  pfnDsFunc;
  284     SWR_TS_STATE tsState;
  285 
  286     // Number of attributes used by the frontend (vs, so, gs)
  287     uint32_t feNumAttributes;
  288 
  289     // RS - Rasterizer State
  290     SWR_RASTSTATE rastState;
  291     // floating point multisample offsets
  292     float samplePos[SWR_MAX_NUM_MULTISAMPLES * 2];
  293 
  294     GUARDBANDS gbState;
  295 
  296     SWR_VIEWPORT          vp[KNOB_NUM_VIEWPORTS_SCISSORS];
  297     SWR_VIEWPORT_MATRICES vpMatrices;
  298 
  299     SWR_RECT scissorRects[KNOB_NUM_VIEWPORTS_SCISSORS];
  300     SWR_RECT scissorsInFixedPoint[KNOB_NUM_VIEWPORTS_SCISSORS];
  301     bool     scissorsTileAligned;
  302 
  303     bool               forceFront;
  304     PRIMITIVE_TOPOLOGY topology;
  305 
  306 
  307     // Backend state
  308     OSALIGNLINE(SWR_BACKEND_STATE) backendState;
  309 
  310     SWR_DEPTH_BOUNDS_STATE depthBoundsState;
  311 
  312     // PS - Pixel shader state
  313     SWR_PS_STATE psState;
  314 
  315     SWR_DEPTH_STENCIL_STATE depthStencilState;
  316 
  317     // OM - Output Merger State
  318     SWR_BLEND_STATE    blendState;
  319     PFN_BLEND_JIT_FUNC pfnBlendFunc[SWR_NUM_RENDERTARGETS];
  320 
  321     struct
  322     {
  323         uint32_t enableStatsFE : 1;        // Enable frontend pipeline stats
  324         uint32_t enableStatsBE : 1;        // Enable backend pipeline stats
  325         uint32_t colorHottileEnable : 8;   // Bitmask of enabled color hottiles
  326         uint32_t depthHottileEnable : 1;   // Enable depth buffer hottile
  327         uint32_t stencilHottileEnable : 1; // Enable stencil buffer hottile
  328     };
  329 
  330     PFN_QUANTIZE_DEPTH pfnQuantizeDepth;
  331 };
  332 
  333 class MacroTileMgr;
  334 class DispatchQueue;
  335 class HOTTILE;
  336 
  337 struct RenderOutputBuffers
  338 {
  339     uint8_t* pColor[SWR_NUM_RENDERTARGETS];
  340     uint8_t* pDepth;
  341     uint8_t* pStencil;
  342 
  343     HOTTILE* pColorHotTile[SWR_NUM_RENDERTARGETS];
  344     HOTTILE* pDepthHotTile;
  345     HOTTILE* pStencilHotTile;
  346 };
  347 
  348 // Plane equation A/B/C coeffs used to evaluate I/J barycentric coords
  349 struct BarycentricCoeffs
  350 {
  351     simdscalar vIa;
  352     simdscalar vIb;
  353     simdscalar vIc;
  354 
  355     simdscalar vJa;
  356     simdscalar vJb;
  357     simdscalar vJc;
  358 
  359     simdscalar vZa;
  360     simdscalar vZb;
  361     simdscalar vZc;
  362 
  363     simdscalar vRecipDet;
  364 
  365     simdscalar vAOneOverW;
  366     simdscalar vBOneOverW;
  367     simdscalar vCOneOverW;
  368 };
  369 
  370 // pipeline function pointer types
  371 typedef void (*PFN_BACKEND_FUNC)(
  372     DRAW_CONTEXT*, uint32_t, uint32_t, uint32_t, SWR_TRIANGLE_DESC&, RenderOutputBuffers&);
  373 typedef void (*PFN_OUTPUT_MERGER)(SWR_PS_CONTEXT&,
  374                                   uint8_t* (&)[SWR_NUM_RENDERTARGETS],
  375                                   uint32_t,
  376                                   const SWR_BLEND_STATE*,
  377                                   const PFN_BLEND_JIT_FUNC (&)[SWR_NUM_RENDERTARGETS],
  378                                   simdscalar&,
  379                                   simdscalar const&);
  380 typedef void (*PFN_CALC_PIXEL_BARYCENTRICS)(const BarycentricCoeffs&, SWR_PS_CONTEXT&);
  381 typedef void (*PFN_CALC_SAMPLE_BARYCENTRICS)(const BarycentricCoeffs&, SWR_PS_CONTEXT&);
  382 typedef void (*PFN_CALC_CENTROID_BARYCENTRICS)(const BarycentricCoeffs&,
  383                                                SWR_PS_CONTEXT&,
  384                                                const uint64_t* const,
  385                                                const uint32_t,
  386                                                simdscalar const&,
  387                                                simdscalar const&);
  388 
  389 struct BACKEND_FUNCS
  390 {
  391     PFN_BACKEND_FUNC pfnBackend;
  392 };
  393 
  394 // Draw State
  395 struct DRAW_STATE
  396 {
  397     API_STATE state;
  398 
  399     void* pPrivateState; // Its required the driver sets this up for each draw.
  400 
  401     // pipeline function pointers, filled in by API thread when setting up the draw
  402     BACKEND_FUNCS     backendFuncs;
  403     PFN_PROCESS_PRIMS pfnProcessPrims;
  404 #if USE_SIMD16_FRONTEND
  405     PFN_PROCESS_PRIMS_SIMD16 pfnProcessPrims_simd16;
  406 #endif
  407 
  408     CachingArena* pArena; // This should only be used by API thread.
  409 };
  410 
  411 struct DRAW_DYNAMIC_STATE
  412 {
  413     void Reset(uint32_t numThreads)
  414     {
  415         SWR_STATS* pSavePtr = pStats;
  416         memset(this, 0, sizeof(*this));
  417         pStats = pSavePtr;
  418         memset(pStats, 0, sizeof(SWR_STATS) * numThreads);
  419     }
  420     ///@todo Currently assumes only a single FE can do stream output for a draw.
  421     uint32_t SoWriteOffset[4];
  422     bool     SoWriteOffsetDirty[4];
  423 
  424     SWR_STATS_FE statsFE; // Only one FE thread per DC.
  425     SWR_STATS*   pStats;
  426     uint64_t     soPrims; // number of primitives written to StremOut buffer
  427 };
  428 
  429 // Draw Context
  430 //    The api thread sets up a draw context that exists for the life of the draw.
  431 //    This draw context maintains all of the state needed for the draw operation.
  432 struct DRAW_CONTEXT
  433 {
  434     SWR_CONTEXT* pContext;
  435     union
  436     {
  437         MacroTileMgr*  pTileMgr;
  438         DispatchQueue* pDispatch; // Queue for thread groups. (isCompute)
  439     };
  440     DRAW_STATE*   pState; // Read-only state. Core should not update this outside of API thread.
  441     CachingArena* pArena;
  442 
  443     uint32_t drawId;
  444     bool     dependentFE;  // Frontend work is dependent on all previous FE
  445     bool     dependent;    // Backend work is dependent on all previous BE
  446     bool     isCompute;    // Is this DC a compute context?
  447     bool     cleanupState; // True if this is the last draw using an entry in the state ring.
  448 
  449     FE_WORK FeWork;
  450 
  451     SYNC_DESC retireCallback; // Call this func when this DC is retired.
  452 
  453     DRAW_DYNAMIC_STATE dynState;
  454 
  455     volatile OSALIGNLINE(bool) doneFE; // Is FE work done for this draw?
  456     volatile OSALIGNLINE(uint32_t) FeLock;
  457     volatile OSALIGNLINE(uint32_t) threadsDone;
  458 };
  459 
  460 static_assert((sizeof(DRAW_CONTEXT) & 63) == 0, "Invalid size for DRAW_CONTEXT");
  461 
  462 INLINE const API_STATE& GetApiState(const DRAW_CONTEXT* pDC)
  463 {
  464     SWR_ASSERT(pDC != nullptr);
  465     SWR_ASSERT(pDC->pState != nullptr);
  466 
  467     return pDC->pState->state;
  468 }
  469 
  470 INLINE void* GetPrivateState(const DRAW_CONTEXT* pDC)
  471 {
  472     SWR_ASSERT(pDC != nullptr);
  473     SWR_ASSERT(pDC->pState != nullptr);
  474 
  475     return pDC->pState->pPrivateState;
  476 }
  477 
  478 class HotTileMgr;
  479 
  480 struct SWR_CONTEXT
  481 {
  482     // Draw Context Ring
  483     //  Each draw needs its own state in order to support mulitple draws in flight across multiple
  484     //  threads. We maintain N draw contexts configured as a ring. The size of the ring limits the
  485     //  maximum number of draws that can be in flight at any given time.
  486     //
  487     //  Description:
  488     //  1. State - When an application first sets state we'll request a new draw context to use.
  489     //     a. If there are no available draw contexts then we'll have to wait until one becomes
  490     //     free. b. If one is available then set pCurDrawContext to point to it and mark it in use.
  491     //     c. All state calls set state on pCurDrawContext.
  492     //  2. Draw - Creates submits a work item that is associated with current draw context.
  493     //     a. Set pPrevDrawContext = pCurDrawContext
  494     //     b. Set pCurDrawContext to NULL.
  495     //  3. State - When an applications sets state after draw
  496     //     a. Same as step 1.
  497     //     b. State is copied from prev draw context to current.
  498     RingBuffer<DRAW_CONTEXT> dcRing;
  499 
  500     DRAW_CONTEXT* pCurDrawContext;  // This points to DC entry in ring for an unsubmitted draw.
  501     DRAW_CONTEXT* pPrevDrawContext; // This points to DC entry for the previous context submitted
  502                                     // that we can copy state from.
  503 
  504     MacroTileMgr*  pMacroTileManagerArray;
  505     DispatchQueue* pDispatchQueueArray;
  506 
  507     // Draw State Ring
  508     //  When draw are very large (lots of primitives) then the API thread will break these up.
  509     //  These split draws all have identical state. So instead of storing the state directly
  510     //  in the Draw Context (DC) we instead store it in a Draw State (DS). This allows multiple DCs
  511     //  to reference a single entry in the DS ring.
  512     RingBuffer<DRAW_STATE> dsRing;
  513 
  514     uint32_t curStateId; // Current index to the next available entry in the DS ring.
  515 
  516     uint32_t NumWorkerThreads;
  517     uint32_t NumFEThreads;
  518     uint32_t NumBEThreads;
  519 
  520     THREAD_POOL              threadPool; // Thread pool associated with this context
  521     SWR_THREADING_INFO       threadInfo;
  522     SWR_API_THREADING_INFO   apiThreadInfo;
  523     SWR_WORKER_PRIVATE_STATE workerPrivateState;
  524 
  525     uint32_t MAX_DRAWS_IN_FLIGHT;
  526 
  527     std::condition_variable FifosNotEmpty;
  528     std::mutex              WaitLock;
  529 
  530     uint32_t privateStateSize;
  531 
  532     HotTileMgr* pHotTileMgr;
  533 
  534     // Callback functions, passed in at create context time
  535     PFN_LOAD_TILE                  pfnLoadTile;
  536     PFN_STORE_TILE                 pfnStoreTile;
  537     PFN_TRANSLATE_GFXPTR_FOR_READ  pfnTranslateGfxptrForRead;
  538     PFN_TRANSLATE_GFXPTR_FOR_WRITE pfnTranslateGfxptrForWrite;
  539     PFN_MAKE_GFXPTR                pfnMakeGfxPtr;
  540     PFN_CREATE_MEMORY_CONTEXT      pfnCreateMemoryContext;
  541     PFN_DESTROY_MEMORY_CONTEXT     pfnDestroyMemoryContext;
  542     PFN_UPDATE_SO_WRITE_OFFSET     pfnUpdateSoWriteOffset;
  543     PFN_UPDATE_STATS               pfnUpdateStats;
  544     PFN_UPDATE_STATS_FE            pfnUpdateStatsFE;
  545     PFN_UPDATE_STREAMOUT           pfnUpdateStreamOut;
  546 
  547 
  548     // Global Stats
  549     SWR_STATS* pStats;
  550 
  551     // Scratch space for workers.
  552     uint8_t** ppScratch;
  553 
  554     volatile OSALIGNLINE(uint32_t) drawsOutstandingFE;
  555 
  556     OSALIGNLINE(CachingAllocator) cachingArenaAllocator;
  557     uint32_t frameCount;
  558 
  559     uint32_t lastFrameChecked;
  560     uint64_t lastDrawChecked;
  561     TileSet* pSingleThreadLockedTiles;
  562 
  563     // ArchRast thread contexts.
  564     HANDLE* pArContext;
  565 
  566     // handle to external memory for worker datas to create memory contexts
  567     HANDLE hExternalMemory;
  568 
  569     BucketManager *pBucketMgr;
  570 };
  571 
  572 #define UPDATE_STAT_BE(name, count)                   \
  573     if (GetApiState(pDC).enableStatsBE)               \
  574     {                                                 \
  575         pDC->dynState.pStats[workerId].name += count; \
  576     }
  577 #define UPDATE_STAT_FE(name, count)          \
  578     if (GetApiState(pDC).enableStatsFE)      \
  579     {                                        \
  580         pDC->dynState.statsFE.name += count; \
  581     }
  582 
  583 // ArchRast instrumentation framework
  584 #define AR_WORKER_CTX pDC->pContext->pArContext[workerId]
  585 #define AR_API_CTX pDC->pContext->pArContext[pContext->NumWorkerThreads]
  586 
  587 #ifdef KNOB_ENABLE_RDTSC
  588 #define RDTSC_BEGIN(pBucketMgr, type, drawid) RDTSC_START(pBucketMgr, type)
  589 #define RDTSC_END(pBucketMgr, type, count) RDTSC_STOP(pBucketMgr, type, count, 0)
  590 #else
  591 #define RDTSC_BEGIN(pBucketMgr, type, drawid)
  592 #define RDTSC_END(pBucketMgr, type, count)
  593 #endif
  594 
  595 #ifdef KNOB_ENABLE_AR
  596 #define _AR_EVENT(ctx, event) ArchRast::Dispatch(ctx, ArchRast::event)
  597 #define _AR_FLUSH(ctx, id) ArchRast::FlushDraw(ctx, id)
  598 #else
  599 #define _AR_EVENT(ctx, event)
  600 #define _AR_FLUSH(ctx, id)
  601 #endif
  602 
  603 // Use these macros for api thread.
  604 #define AR_API_EVENT(event) _AR_EVENT(AR_API_CTX, event)
  605 
  606 // Use these macros for worker threads.
  607 #define AR_EVENT(event) _AR_EVENT(AR_WORKER_CTX, event)
  608 #define AR_FLUSH(id) _AR_FLUSH(AR_WORKER_CTX, id)