1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#pragma once
4
5#include "BsCorePrerequisites.h"
6#include "Utility/BsModule.h"
7
8namespace bs
9{
10 /** @addtogroup Profiling-Internal
11 * @{
12 */
13
14 /** Common object types to track resource statistics for. */
15 enum RenderStatResourceType
16 {
17 RenderStatObject_IndexBuffer,
18 RenderStatObject_VertexBuffer,
19 RenderStatObject_GpuBuffer,
20 RenderStatObject_GpuParamBuffer,
21 RenderStatObject_Texture,
22 RenderStatObject_GpuProgram,
23 RenderStatObject_Query
24 };
25
26 /** Object that stores various render statistics. */
27 struct BS_CORE_EXPORT RenderStatsData
28 {
29 RenderStatsData() = default;
30
31 UINT64 numDrawCalls = 0;
32 UINT64 numComputeCalls = 0;
33 UINT64 numRenderTargetChanges = 0;
34 UINT64 numPresents = 0;
35 UINT64 numClears = 0;
36
37 UINT64 numVertices = 0;
38 UINT64 numPrimitives = 0;
39
40 UINT64 numPipelineStateChanges = 0;
41
42 UINT64 numGpuParamBinds = 0;
43 UINT64 numVertexBufferBinds = 0;
44 UINT64 numIndexBufferBinds = 0;
45
46 UINT64 numResourceWrites;
47 UINT64 numResourceReads;
48
49 UINT64 numObjectsCreated;
50 UINT64 numObjectsDestroyed;
51 };
52
53 /**
54 * Tracks various render system statistics.
55 *
56 * @note Core thread only.
57 */
58 class BS_CORE_EXPORT RenderStats : public Module<RenderStats>
59 {
60 public:
61 /** Increments draw call counter indicating how many times were render system API Draw methods called. */
62 void incNumDrawCalls() { mData.numDrawCalls++; }
63
64 /** Increments compute call counter indicating how many times were compute shaders dispatched. */
65 void incNumComputeCalls() { mData.numComputeCalls++; }
66
67 /** Increments render target change counter indicating how many times did the active render target change. */
68 void incNumRenderTargetChanges() { mData.numRenderTargetChanges++; }
69
70 /** Increments render target present counter indicating how many times did the buffer swap happen. */
71 void incNumPresents() { mData.numPresents++; }
72
73 /**
74 * Increments render target clear counter indicating how many times did the target the cleared, entirely or
75 * partially.
76 */
77 void incNumClears() { mData.numClears++; }
78
79 /** Increments vertex draw counter indicating how many vertices were sent to the pipeline. */
80 void addNumVertices(UINT32 count) { mData.numVertices += count; }
81
82 /** Increments primitive draw counter indicating how many primitives were sent to the pipeline. */
83 void addNumPrimitives(UINT32 count) { mData.numPrimitives += count; }
84
85 /** Increments pipeline state change counter indicating how many times was a pipeline state bound. */
86 void incNumPipelineStateChanges() { mData.numPipelineStateChanges++; }
87
88 /** Increments GPU parameter change counter indicating how many times were GPU parameters bound to the pipeline. */
89 void incNumGpuParamBinds() { mData.numGpuParamBinds++; }
90
91 /** Increments vertex buffer change counter indicating how many times was a vertex buffer bound to the pipeline. */
92 void incNumVertexBufferBinds() { mData.numVertexBufferBinds++; }
93
94 /** Increments index buffer change counter indicating how many times was a index buffer bound to the pipeline. */
95 void incNumIndexBufferBinds() { mData.numIndexBufferBinds++; }
96
97 /**
98 * Increments created GPU resource counter.
99 *
100 * @param[in] category Category of the resource.
101 */
102 void incResCreated(UINT32 category)
103 {
104 // TODO - I'm ignoring resourceType for now. Later I will want to
105 // count object creation/destruction/read/write per type. I will
106 // also want to allow the caller to assign names to specific "resourceType" id.
107 // (Since many types will be RenderAPI specific).
108
109 // TODO - I should also track number of active GPU objects using this method, instead
110 // of just keeping track of how many were created and destroyed during the frame.
111
112 mData.numObjectsCreated++;
113 }
114
115 /**
116 * Increments destroyed GPU resource counter.
117 *
118 * @param[in] category Category of the resource.
119 */
120 void incResDestroyed(UINT32 category) { mData.numObjectsDestroyed++; }
121
122 /**
123 * Increments GPU resource read counter.
124 *
125 * @param[in] category Category of the resource.
126 */
127 void incResRead(UINT32 category) { mData.numResourceReads++; }
128
129 /**
130 * Increments GPU resource write counter.
131 *
132 * @param[in] category Category of the resource.
133 */
134 void incResWrite(UINT32 category) { mData.numResourceWrites++; }
135
136 /**
137 * Returns an object containing various rendering statistics.
138 *
139 * @note
140 * Do not modify the returned state unless you know what you are doing, it will change the actual internal object.
141 */
142 RenderStatsData& getData() { return mData; }
143
144 private:
145 RenderStatsData mData;
146 };
147
148#if BS_PROFILING_ENABLED
149 #define BS_INC_RENDER_STAT_CAT(Stat, Category) RenderStats::instance().inc##Stat((UINT32)Category)
150 #define BS_INC_RENDER_STAT(Stat) RenderStats::instance().inc##Stat()
151 #define BS_ADD_RENDER_STAT(Stat, Count) RenderStats::instance().add##Stat(Count)
152#else
153 #define BS_INC_RENDER_STAT_CAT(Stat, Category)
154 #define BS_INC_RENDER_STAT(Stat)
155 #define BS_ADD_RENDER_STAT(Stat, Count)
156#endif
157
158 /** @} */
159}