|
@@ -2,62 +2,81 @@
|
|
|
|
|
|
|
|
#include "CmPrerequisites.h"
|
|
#include "CmPrerequisites.h"
|
|
|
#include "CmModule.h"
|
|
#include "CmModule.h"
|
|
|
|
|
+#include "BsRenderStats.h"
|
|
|
|
|
|
|
|
namespace BansheeEngine
|
|
namespace BansheeEngine
|
|
|
{
|
|
{
|
|
|
|
|
+ /**
|
|
|
|
|
+ * @brief Contains various profiler statistics about a single GPU profiling sample
|
|
|
|
|
+ */
|
|
|
|
|
+ struct GPUProfileSample
|
|
|
|
|
+ {
|
|
|
|
|
+ String name; /**< Name of the sample for easier identification. */
|
|
|
|
|
+ float timeMs; /**< Time in milliseconds it took to execute the sampled block. */
|
|
|
|
|
+
|
|
|
|
|
+ UINT32 numDrawCalls; /**< Number of draw calls that happened. */
|
|
|
|
|
+ UINT32 numRenderTargetChanges; /**< How many times was render target changed. */
|
|
|
|
|
+ UINT32 numPresents; /**< How many times did a buffer swap happen on a double buffered render target. */
|
|
|
|
|
+ UINT32 numClears; /**< How many times was render target cleared. */
|
|
|
|
|
+
|
|
|
|
|
+ UINT32 numVertices; /**< Total number of vertices sent to the GPU. */
|
|
|
|
|
+ UINT32 numPrimitives; /**< Total number of primitives sent to the GPU. */
|
|
|
|
|
+ UINT32 numDrawnSamples; /**< Number of samples drawn by the GPU. */
|
|
|
|
|
+
|
|
|
|
|
+ UINT32 numBlendStateChanges; /**< How many times did the blend state change. */
|
|
|
|
|
+ UINT32 numRasterizerStateChanges; /**< How many times did the rasterizer state change. */
|
|
|
|
|
+ UINT32 numDepthStencilStateChanges; /**< How many times did the depth stencil state change. */
|
|
|
|
|
+
|
|
|
|
|
+ UINT32 numTextureBinds; /**< How many times was a texture bound. */
|
|
|
|
|
+ UINT32 numSamplerBinds; /**< How many times was a sampler bound. */
|
|
|
|
|
+ UINT32 numVertexBufferBinds; /**< How many times was a vertex buffer bound. */
|
|
|
|
|
+ UINT32 numIndexBufferBinds; /**< How many times was an index buffer bound. */
|
|
|
|
|
+ UINT32 numGpuParamBufferBinds; /**< How many times was an GPU parameter buffer bound. */
|
|
|
|
|
+ UINT32 numGpuProgramBinds; /**< How many times was a GPU program bound. */
|
|
|
|
|
+
|
|
|
|
|
+ UINT32 numResourceWrites; /**< How many times were GPU resources written to. */
|
|
|
|
|
+ UINT32 numResourceReads; /**< How many times were GPU resources read from. */
|
|
|
|
|
+
|
|
|
|
|
+ UINT32 numObjectsCreated; /**< How many GPU objects were created. */
|
|
|
|
|
+ UINT32 numObjectsDestroyed; /**< How many GPU objects were destroyed. */
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* @brief Profiler report containing information about GPU sampling data
|
|
* @brief Profiler report containing information about GPU sampling data
|
|
|
* from a single frame.
|
|
* from a single frame.
|
|
|
*/
|
|
*/
|
|
|
struct GPUProfilerReport
|
|
struct GPUProfilerReport
|
|
|
{
|
|
{
|
|
|
- /**
|
|
|
|
|
- * @brief Contains various profiler statistics about a single GPU profiling sample
|
|
|
|
|
- */
|
|
|
|
|
- struct Sample
|
|
|
|
|
- {
|
|
|
|
|
- String name; /**< Name of the sample for easier identification. */
|
|
|
|
|
- float timeMs; /**< Time in milliseconds it took to execute the sampled block. */
|
|
|
|
|
-
|
|
|
|
|
- UINT32 numDrawCalls; /**< Number of draw calls that happened. */
|
|
|
|
|
- UINT32 numRenderTargetChanges; /**< How many times was render target changed. */
|
|
|
|
|
- UINT32 numPresents; /**< How many times did a buffer swap happen on a double buffered render target. */
|
|
|
|
|
- UINT32 numClears; /**< How many times was render target cleared. */
|
|
|
|
|
-
|
|
|
|
|
- UINT32 numVertices; /**< Total number of vertices sent to the GPU. */
|
|
|
|
|
- UINT32 numTriangles; /**< Total number of triangles sent to the GPU. */
|
|
|
|
|
- UINT32 numDrawnSamples; /**< Number of samples drawn by the GPU. */
|
|
|
|
|
-
|
|
|
|
|
- UINT32 numBlendStateChanges; /**< How many times did the blend state change. */
|
|
|
|
|
- UINT32 numRasterizerStateChanges; /**< How many times did the rasterizer state change. */
|
|
|
|
|
- UINT32 numDepthStencilStateChanges; /**< How many times did the depth stencil state change. */
|
|
|
|
|
-
|
|
|
|
|
- UINT32 numTextureBinds; /**< How many times was a texture bound. */
|
|
|
|
|
- UINT32 numSamplerBinds; /**< How many times was a sampler bound. */
|
|
|
|
|
- UINT32 numVertexBufferBinds; /**< How many times was a vertex buffer bound. */
|
|
|
|
|
- UINT32 numIndexBufferBinds; /**< How many times was an index buffer bound. */
|
|
|
|
|
- UINT32 numGpuParamBufferBinds; /**< How many times was an GPU parameter buffer bound. */
|
|
|
|
|
- UINT32 numGpuProgramBinds; /**< How many times was a GPU program bound. */
|
|
|
|
|
-
|
|
|
|
|
- UINT32 numResourceWrites; /**< How many times were GPU resources written to. */
|
|
|
|
|
- UINT32 numResourceReads; /**< How many times were GPU resources read from. */
|
|
|
|
|
-
|
|
|
|
|
- UINT32 numObjectsCreated; /**< How many GPU objects were created. */
|
|
|
|
|
- UINT32 numObjectsDestroyed; /**< How many GPU objects were destroyed. */
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- Sample frameSample; /**< Sample containing data for entire frame. */
|
|
|
|
|
- Vector<Sample> samples;
|
|
|
|
|
|
|
+ GPUProfileSample frameSample; /**< Sample containing data for entire frame. */
|
|
|
|
|
+ Vector<GPUProfileSample> samples;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* @brief Profiler that measures time and amount of various GPU operations.
|
|
* @brief Profiler that measures time and amount of various GPU operations.
|
|
|
*
|
|
*
|
|
|
- * @note Sim thread only. However most operations will be queued on the core thread or
|
|
|
|
|
- * on the GPU itself so the results will not be immediately available.
|
|
|
|
|
|
|
+ * @note Core thread only.
|
|
|
*/
|
|
*/
|
|
|
class CM_EXPORT GPUProfiler : public Module<GPUProfiler>
|
|
class CM_EXPORT GPUProfiler : public Module<GPUProfiler>
|
|
|
{
|
|
{
|
|
|
|
|
+ private:
|
|
|
|
|
+ struct ActiveSample
|
|
|
|
|
+ {
|
|
|
|
|
+ ProfilerString sampleName;
|
|
|
|
|
+ RenderStats startStats;
|
|
|
|
|
+ RenderStats endStats;
|
|
|
|
|
+ TimerQueryPtr activeTimeQuery;
|
|
|
|
|
+ OcclusionQueryPtr activeOcclusionQuery;
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ struct ActiveFrame
|
|
|
|
|
+ {
|
|
|
|
|
+ ActiveSample frameSample;
|
|
|
|
|
+ Vector<ActiveSample> samples;
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ public:
|
|
|
|
|
+ GPUProfiler();
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* @brief Signals a start of a new frame. Every frame will generate a separate profiling report.
|
|
* @brief Signals a start of a new frame. Every frame will generate a separate profiling report.
|
|
|
* This call must be followed by "endFrame", and any sampling operations must happen between
|
|
* This call must be followed by "endFrame", and any sampling operations must happen between
|
|
@@ -105,6 +124,56 @@ namespace BansheeEngine
|
|
|
* @brief Gets the oldest report available and removes it from the internal list.
|
|
* @brief Gets the oldest report available and removes it from the internal list.
|
|
|
* Throws an exception if no reports are available.
|
|
* Throws an exception if no reports are available.
|
|
|
*/
|
|
*/
|
|
|
- const GPUProfilerReport& getNextReport();
|
|
|
|
|
|
|
+ GPUProfilerReport getNextReport();
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * @brief To be called once per frame from the Core thread.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @note Internal method.
|
|
|
|
|
+ */
|
|
|
|
|
+ void _update();
|
|
|
|
|
+
|
|
|
|
|
+ private:
|
|
|
|
|
+ /**
|
|
|
|
|
+ * @brief Assigns start values for the provided sample.
|
|
|
|
|
+ */
|
|
|
|
|
+ void beginSampleInternal(ActiveSample& sample);
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * @brief Assigns end values for the provided sample.
|
|
|
|
|
+ */
|
|
|
|
|
+ void endSampleInternal(ActiveSample& sample);
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * @brief Creates a new timer query or returns an existing free query.
|
|
|
|
|
+ */
|
|
|
|
|
+ TimerQueryPtr getTimerQuery() const;
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * @brief Creates a new occlusion query or returns an existing free query.
|
|
|
|
|
+ */
|
|
|
|
|
+ OcclusionQueryPtr getOcclusionQuery() const;
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * @brief Interprets the active frame results and generates a profiler report for
|
|
|
|
|
+ * the frame. Provided frame queries must have finished before calling this.
|
|
|
|
|
+ */
|
|
|
|
|
+ GPUProfilerReport resolveFrame(ActiveFrame& frame);
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * @brief Resolves an active sample and converts it to report sample.
|
|
|
|
|
+ */
|
|
|
|
|
+ void resolveSample(const ActiveSample& sample, GPUProfileSample& reportSample);
|
|
|
|
|
+
|
|
|
|
|
+ private:
|
|
|
|
|
+ ActiveFrame mActiveFrame;
|
|
|
|
|
+ bool mIsFrameActive;
|
|
|
|
|
+ UINT32 mNumActiveSamples;
|
|
|
|
|
+
|
|
|
|
|
+ Queue<ActiveFrame> mUnresolvedFrames;
|
|
|
|
|
+ Queue<GPUProfilerReport> mReadyReports;
|
|
|
|
|
+
|
|
|
|
|
+ mutable Stack<TimerQueryPtr> mFreeTimerQueries;
|
|
|
|
|
+ mutable Stack<OcclusionQueryPtr> mFreeOcclusionQueries;
|
|
|
};
|
|
};
|
|
|
}
|
|
}
|