1 /****************************************************************************
2  * Copyright (C) 2014-2015 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 
24 #pragma once
25 #include "knobs.h"
26 
27 #include "common/os.h"
28 #include "common/rdtsc_buckets.h"
29 
30 #include <vector>
31 
32 ///////////////////////////////////////////////////////////////////////////////
33 // NOTE:  This enum MUST be kept in sync with gCoreBuckets in rdtsc_core.cpp
34 ///////////////////////////////////////////////////////////////////////////////
35 enum CORE_BUCKETS
36 {
37     APIClearRenderTarget,
38     APIDraw,
39     APIDrawWakeAllThreads,
40     APIDrawIndexed,
41     APIDispatch,
42     APIStoreTiles,
43     APIGetDrawContext,
44     APISync,
45     APIWaitForIdle,
46     FEProcessDraw,
47     FEProcessDrawIndexed,
48     FEFetchShader,
49     FEVertexShader,
50     FEHullShader,
51     FETessellation,
52     FEDomainShader,
53     FEGeometryShader,
54     FEStreamout,
55     FEPAAssemble,
56     FEBinPoints,
57     FEBinLines,
58     FEBinTriangles,
59     FETriangleSetup,
60     FEViewportCull,
61     FEGuardbandClip,
62     FEClipPoints,
63     FEClipLines,
64     FEClipTriangles,
65     FEClipRectangles,
66     FECullZeroAreaAndBackface,
67     FECullBetweenCenters,
68     FEEarlyRastEnter,
69     FEEarlyRastExit,
70     FEProcessStoreTiles,
71     FEProcessInvalidateTiles,
72     WorkerWorkOnFifoBE,
73     WorkerFoundWork,
74     BELoadTiles,
75     BEDispatch,
76     BEClear,
77     BERasterizeLine,
78     BERasterizeTriangle,
79     BETriangleSetup,
80     BEStepSetup,
81     BECullZeroArea,
82     BEEmptyTriangle,
83     BETrivialAccept,
84     BETrivialReject,
85     BERasterizePartial,
86     BEPixelBackend,
87     BESetup,
88     BEBarycentric,
89     BEEarlyDepthTest,
90     BEPixelShader,
91     BESingleSampleBackend,
92     BEPixelRateBackend,
93     BESampleRateBackend,
94     BENullBackend,
95     BELateDepthTest,
96     BEOutputMerger,
97     BEStoreTiles,
98     BEEndTile,
99 
100     NumBuckets
101 };
102 
103 void rdtscReset(BucketManager* pBucketMgr);
104 void rdtscInit(BucketManager* pBucketMgr, int threadId);
105 void rdtscStart(BucketManager* pBucketMgr, uint32_t bucketId);
106 void rdtscStop(BucketManager* pBucketMgr, uint32_t bucketId, uint32_t count, uint64_t drawId);
107 void rdtscEvent(BucketManager* pBucketMgr, uint32_t bucketId, uint32_t count1, uint32_t count2);
108 void rdtscEndFrame(BucketManager* pBucketMgr);
109 
110 #ifdef KNOB_ENABLE_RDTSC
111 #define RDTSC_RESET(pBucketMgr) rdtscReset(pBucketMgr)
112 #define RDTSC_INIT(pBucketMgr, threadId) rdtscInit(pBucketMgr,threadId)
113 #define RDTSC_START(pBucketMgr, bucket) rdtscStart(pBucketMgr, bucket)
114 #define RDTSC_STOP(pBucketMgr, bucket, count, draw) rdtscStop(pBucketMgr, bucket, count, draw)
115 #define RDTSC_EVENT(pBucketMgr, bucket, count1, count2) rdtscEvent(pBucketMgr, bucket, count1, count2)
116 #define RDTSC_ENDFRAME(pBucketMgr) rdtscEndFrame(pBucketMgr)
117 #else
118 #define RDTSC_RESET(pBucketMgr)
119 #define RDTSC_INIT(pBucketMgr, threadId)
120 #define RDTSC_START(pBucketMgr, bucket)
121 #define RDTSC_STOP(pBucketMgr, bucket, count, draw)
122 #define RDTSC_EVENT(pBucketMgr, bucket, count1, count2)
123 #define RDTSC_ENDFRAME(pBucketMgr)
124 #endif
125 
126 extern BUCKET_DESC           gCoreBuckets[];
127 
rdtscReset(BucketManager * pBucketMgr)128 INLINE void rdtscReset(BucketManager *pBucketMgr)
129 {
130     pBucketMgr->mCurrentFrame = 0;
131     pBucketMgr->ClearThreads();
132 }
133 
rdtscInit(BucketManager * pBucketMgr,int threadId)134 INLINE void rdtscInit(BucketManager* pBucketMgr, int threadId)
135 {
136     // register all the buckets once
137     if (!pBucketMgr->mBucketsInitialized && (threadId == 0))
138     {
139         pBucketMgr->mBucketMap.resize(NumBuckets);
140         for (uint32_t i = 0; i < NumBuckets; ++i)
141         {
142             pBucketMgr->mBucketMap[i] = pBucketMgr->RegisterBucket(gCoreBuckets[i]);
143         }
144         pBucketMgr->mBucketsInitialized = true;
145     }
146 
147     std::string name = threadId == 0 ? "API" : "WORKER";
148     pBucketMgr->RegisterThread(name);
149 }
150 
rdtscStart(BucketManager * pBucketMgr,uint32_t bucketId)151 INLINE void rdtscStart(BucketManager* pBucketMgr, uint32_t bucketId)
152 {
153     uint32_t id = pBucketMgr->mBucketMap[bucketId];
154     pBucketMgr->StartBucket(id);
155 }
156 
rdtscStop(BucketManager * pBucketMgr,uint32_t bucketId,uint32_t count,uint64_t drawId)157 INLINE void rdtscStop(BucketManager* pBucketMgr, uint32_t bucketId, uint32_t count, uint64_t drawId)
158 {
159     uint32_t id = pBucketMgr->mBucketMap[bucketId];
160     pBucketMgr->StopBucket(id);
161 }
162 
rdtscEvent(BucketManager * pBucketMgr,uint32_t bucketId,uint32_t count1,uint32_t count2)163 INLINE void rdtscEvent(BucketManager* pBucketMgr, uint32_t bucketId, uint32_t count1, uint32_t count2)
164 {
165     uint32_t id = pBucketMgr->mBucketMap[bucketId];
166     pBucketMgr->AddEvent(id, count1);
167 }
168 
rdtscEndFrame(BucketManager * pBucketMgr)169 INLINE void rdtscEndFrame(BucketManager* pBucketMgr)
170 {
171     pBucketMgr->mCurrentFrame++;
172 
173     if (pBucketMgr->mCurrentFrame == KNOB_BUCKETS_START_FRAME &&
174         KNOB_BUCKETS_START_FRAME < KNOB_BUCKETS_END_FRAME)
175     {
176         pBucketMgr->StartCapture();
177     }
178 
179     if (pBucketMgr->mCurrentFrame == KNOB_BUCKETS_END_FRAME &&
180         KNOB_BUCKETS_START_FRAME < KNOB_BUCKETS_END_FRAME)
181     {
182         pBucketMgr->StopCapture();
183         pBucketMgr->PrintReport("rdtsc.txt");
184     }
185 }
186