Browse Source

Single pass primitive metrics for Direct3D9

Josh Engebretson 9 years ago
parent
commit
67a652f85a

+ 33 - 0
Source/Atomic/Graphics/Direct3D9/D3D9Graphics.cpp

@@ -739,6 +739,10 @@ bool Graphics::BeginFrame()
     numPrimitives_ = 0;
     numBatches_ = 0;
 
+    // ATOMIC BEGIN
+    numSinglePassPrimitives_ = 0;
+    // ATOMIC END
+
     SendEvent(E_BEGINRENDERING);
 
     return true;
@@ -848,6 +852,11 @@ void Graphics::Draw(PrimitiveType type, unsigned vertexStart, unsigned vertexCou
 
     numPrimitives_ += primitiveCount;
     ++numBatches_;
+
+    // ATOMIC BEGIN
+    if (GetNumPasses() == 1)
+        numSinglePassPrimitives_ += primitiveCount;
+    // ATOMIC END
 }
 
 void Graphics::Draw(PrimitiveType type, unsigned indexStart, unsigned indexCount, unsigned minVertex, unsigned vertexCount)
@@ -865,6 +874,12 @@ void Graphics::Draw(PrimitiveType type, unsigned indexStart, unsigned indexCount
 
     numPrimitives_ += primitiveCount;
     ++numBatches_;
+
+    // ATOMIC BEGIN
+    if (GetNumPasses() == 1)
+        numSinglePassPrimitives_ += primitiveCount;
+    // ATOMIC END
+
 }
 
 void Graphics::Draw(PrimitiveType type, unsigned indexStart, unsigned indexCount, unsigned baseVertexIndex, unsigned minVertex, unsigned vertexCount)
@@ -882,6 +897,12 @@ void Graphics::Draw(PrimitiveType type, unsigned indexStart, unsigned indexCount
 
     numPrimitives_ += primitiveCount;
     ++numBatches_;
+
+    // ATOMIC BEGIN
+    if (GetNumPasses() == 1)
+        numSinglePassPrimitives_ += primitiveCount;
+    // ATOMIC END
+
 }
 
 void Graphics::DrawInstanced(PrimitiveType type, unsigned indexStart, unsigned indexCount, unsigned minVertex, unsigned vertexCount,
@@ -912,6 +933,12 @@ void Graphics::DrawInstanced(PrimitiveType type, unsigned indexStart, unsigned i
 
     numPrimitives_ += instanceCount * primitiveCount;
     ++numBatches_;
+
+    // ATOMIC BEGIN
+    if (GetNumPasses() == 1)
+        numSinglePassPrimitives_ += instanceCount * primitiveCount;
+    // ATOMIC END
+
 }
 
 void Graphics::DrawInstanced(PrimitiveType type, unsigned indexStart, unsigned indexCount, unsigned baseVertexIndex, unsigned minVertex,
@@ -942,6 +969,12 @@ void Graphics::DrawInstanced(PrimitiveType type, unsigned indexStart, unsigned i
 
     numPrimitives_ += instanceCount * primitiveCount;
     ++numBatches_;
+
+    // ATOMIC BEGIN
+    if (GetNumPasses() == 1)
+        numSinglePassPrimitives_ += instanceCount * primitiveCount;
+    // ATOMIC END
+
 }
 
 void Graphics::SetVertexBuffer(VertexBuffer* buffer)

+ 5 - 0
Source/Atomic/Graphics/Graphics.cpp

@@ -59,6 +59,11 @@
 namespace Atomic
 {
 
+// ATOMIC BEGIN
+unsigned Graphics::numPasses_ = 0;
+unsigned Graphics::numSinglePassPrimitives_ = 0;
+// ATOMIC END
+
 void Graphics::SetExternalWindow(void* window)
 {
     if (!window_)

+ 16 - 1
Source/Atomic/Graphics/Graphics.h

@@ -545,7 +545,17 @@ public:
     bool GetMaximized();
     IntVector2 GetMonitorResolution(int monitorId) const;
     void RaiseWindow();
-
+    
+    /// Return number of passes drawn this frame
+    static unsigned GetNumPasses() { return numPasses_; }
+    /// Set number of passes drawn this frame
+    static void SetNumPasses(unsigned value) { numPasses_ = value; }
+
+    /// Return number of single render pass primitives drawn this frame (D3D9 Only)
+    static unsigned GetSinglePassPrimitives() { return numSinglePassPrimitives_; }
+    /// Set number of single render pass primitives drawn this frame (D3D9 Only)
+    static void SetSinglePassPrimitives(unsigned value) { numSinglePassPrimitives_ = value; }
+  
     // ATOMIC END
 
 private:
@@ -767,6 +777,11 @@ private:
     static const Vector2 pixelUVOffset;
     /// OpenGL3 support flag.
     static bool gl3Support;
+
+// ATOMIC BEGIN
+    static unsigned numPasses_;
+    static unsigned numSinglePassPrimitives_;
+// ATOMIC END
 };
 
 /// Register Graphics library objects.

+ 11 - 0
Source/Atomic/Graphics/View.cpp

@@ -1588,9 +1588,15 @@ void View::ExecuteRenderPathCommands()
                     ATOMIC_PROFILE(RenderLights);
 
                     SetRenderTargets(command);
+// ATOMIC BEGIN
+                    graphics_->SetNumPasses(0);
 
                     for (Vector<LightBatchQueue>::Iterator i = actualView->lightQueues_.Begin(); i != actualView->lightQueues_.End(); ++i)
                     {
+
+                        graphics_->SetNumPasses(graphics_->GetNumPasses() + 1);
+
+// ATOMIC END
                         // If reusing shadowmaps, render each of them before the lit batches
                         if (renderer_->GetReuseShadowMaps() && NeedRenderShadowMap(*i))
                         {
@@ -3043,6 +3049,11 @@ void View::RenderShadowMap(const LightBatchQueue& queue)
         {
             graphics_->SetViewport(shadowQueue.shadowViewport_);
             shadowQueue.shadowBatches_.Draw(this, shadowQueue.shadowCamera_, false, false, true);
+
+// ATOMIC BEGIN
+            graphics_->SetNumPasses(graphics_->GetNumPasses() + 1);
+// ATOMIC END
+
         }
     }
 

+ 39 - 9
Source/Atomic/UI/SystemUI/DebugHud.cpp

@@ -29,6 +29,7 @@
 #include "Font.h"
 #include "Text.h"
 #include "SystemUI.h"
+#include "UIElement.h"
 #include "DebugHud.h"
 
 #include "../../DebugNew.h"
@@ -60,7 +61,7 @@ DebugHud::DebugHud(Context* context) :
     Object(context),
     profilerMaxDepth_(M_MAX_UNSIGNED),
     profilerInterval_(1000),
-    useRendererStats_(false),
+    useRendererStats_(true),
     mode_(DEBUGHUD_SHOW_NONE),
     fpsTimeSinceUpdate_(FPS_UPDATE_INTERVAL),
     fpsFramesSinceUpdate_(0),
@@ -69,23 +70,28 @@ DebugHud::DebugHud(Context* context) :
     SystemUI* ui = GetSubsystem<SystemUI>();
     UIElement* uiRoot = ui->GetRoot();
 
+    layout_ = new UIElement(context_);
+    uiRoot->AddChild(layout_);
+
+    layout_->SetSize(uiRoot->GetSize());
+
     statsText_ = new Text(context_);
     statsText_->SetAlignment(HA_LEFT, VA_TOP);
     statsText_->SetPriority(100);
     statsText_->SetVisible(false);
-    uiRoot->AddChild(statsText_);
+    layout_->AddChild(statsText_);
 
     modeText_ = new Text(context_);
     modeText_->SetAlignment(HA_LEFT, VA_BOTTOM);
     modeText_->SetPriority(100);
     modeText_->SetVisible(false);
-    uiRoot->AddChild(modeText_);
+    layout_->AddChild(modeText_);
 
     profilerText_ = new Text(context_);
     profilerText_->SetAlignment(HA_RIGHT, VA_TOP);
     profilerText_->SetPriority(100);
     profilerText_->SetVisible(false);
-    uiRoot->AddChild(profilerText_);
+    layout_->AddChild(profilerText_);
 
     SubscribeToEvent(E_POSTUPDATE, ATOMIC_HANDLER(DebugHud, HandlePostUpdate));
 }
@@ -97,6 +103,23 @@ DebugHud::~DebugHud()
     profilerText_->Remove();
 }
 
+void DebugHud::SetExtents(bool useRootExtents, const IntVector2& position, const IntVector2& size)
+{
+    if (useRootExtents)
+    {
+        SystemUI* ui = GetSubsystem<SystemUI>();
+        UIElement* uiRoot = ui->GetRoot();
+
+        layout_->SetPosition(IntVector2::ZERO);
+        layout_->SetSize(uiRoot->GetSize());
+    }
+    else
+    {
+        layout_->SetPosition(position);
+        layout_->SetSize(size);
+    }
+}
+
 void DebugHud::Update(float timeStep)
 {
     Graphics* graphics = GetSubsystem<Graphics>();
@@ -105,13 +128,11 @@ void DebugHud::Update(float timeStep)
         return;
 
     // Ensure UI-elements are not detached
-    if (!statsText_->GetParent())
+    if (!layout_->GetParent())
     {
         SystemUI* ui = GetSubsystem<SystemUI>();
         UIElement* uiRoot = ui->GetRoot();
-        uiRoot->AddChild(statsText_);
-        uiRoot->AddChild(modeText_);
-        uiRoot->AddChild(profilerText_);
+        uiRoot->AddChild(layout_);
     }
 
     if (statsText_->IsVisible())
@@ -138,7 +159,16 @@ void DebugHud::Update(float timeStep)
         }
 
         String stats;
-        stats.AppendWithFormat("FPS %d\nTriangles %u\nBatches %u\nViews %u\nLights %u\nShadowmaps %u\nOccluders %u",
+
+        unsigned singlePassPrimitives = graphics->GetSinglePassPrimitives();
+        unsigned editorPrimitives = graphics->GetNumPrimitives() - renderer->GetNumPrimitives();
+
+        if (singlePassPrimitives)
+            stats.AppendWithFormat("FPS %d\nTriangles (All passes) %u\nTriangles (Single pass) %u\nTriangles (Editor) %u\n", fps_, primitives, singlePassPrimitives, editorPrimitives);
+        else
+            stats.AppendWithFormat("FPS %d\nTriangles %u\n", fps_, primitives);
+                    
+        stats.AppendWithFormat("Batches %u\nViews %u\nLights %u\nShadowmaps %u\nOccluders %u",
             fps_,
             primitives,
             batches,

+ 7 - 1
Source/Atomic/UI/SystemUI/DebugHud.h

@@ -36,6 +36,7 @@ namespace SystemUI
 
 class Font;
 class Text;
+class UIElement;
 
 static const unsigned DEBUGHUD_SHOW_NONE = 0x0;
 static const unsigned DEBUGHUD_SHOW_STATS = 0x1;
@@ -46,7 +47,7 @@ static const unsigned DEBUGHUD_SHOW_ALL = 0x7;
 /// Displays rendering stats and profiling information.
 class ATOMIC_API DebugHud : public Object
 {
-    ATOMIC_OBJECT(DebugHud, Object);
+    ATOMIC_OBJECT(DebugHud, Object)
 
 public:
     /// Construct.
@@ -106,10 +107,15 @@ public:
     /// Clear all application-specific stats.
     void ClearAppStats();
 
+    void SetExtents(bool useRootExtents = true, const IntVector2& position = IntVector2::ZERO, const IntVector2& size = IntVector2::ZERO);
+
 private:
     /// Handle logic post-update event. The HUD texts are updated here.
     void HandlePostUpdate(StringHash eventType, VariantMap& eventData);
 
+    /// Rendering stats text.
+    SharedPtr<UIElement> layout_;
+
     /// Rendering stats text.
     SharedPtr<Text> statsText_;
     /// Rendering mode text.

+ 11 - 0
Source/Atomic/UI/UI.cpp

@@ -905,6 +905,17 @@ void UI::ToggleDebugHud()
     hud->ToggleAll();
 }
 
+void UI::SetDebugHudExtents(bool useRootExtent, const IntVector2& position, const IntVector2& size)
+{
+    SystemUI::DebugHud* hud = GetSubsystem<SystemUI::DebugHud>();
+
+    if (!hud)
+        return;
+
+    hud->SetExtents(useRootExtent, position, size);
+
+}
+
 void UI::ShowConsole(bool value)
 {
     SystemUI::Console* console = GetSubsystem<SystemUI::Console>();

+ 2 - 0
Source/Atomic/UI/UI.h

@@ -96,6 +96,8 @@ public:
     void ShowDebugHud(bool value);
     void ToggleDebugHud();
 
+    void SetDebugHudExtents(bool useRootExtents = true, const IntVector2& position = IntVector2::ZERO, const IntVector2& size = IntVector2::ZERO);
+
     void ShowConsole(bool value);
     void ToggleConsole();
 

+ 20 - 0
Source/Atomic/UI/UIWidget.cpp

@@ -1181,7 +1181,27 @@ void UIWidget::SetTooltip(const String& tooltip)
         return;
 
     widget_->SetTooltip(tooltip.CString());
+
+}
+
+IntVector2 UIWidget::ConvertToRoot(const IntVector2 position) const
+{
+    IntVector2 result = position;
+
+    if (widget_)
+        widget_->ConvertToRoot(result.x_, result.y_);
+
+    return result;
 }
 
+IntVector2 UIWidget::ConvertFromRoot(const IntVector2 position) const
+{
+    IntVector2 result = position;
+
+    if (widget_)
+        widget_->ConvertFromRoot(result.x_, result.y_);
+
+    return result;
+}
 
 }

+ 7 - 0
Source/Atomic/UI/UIWidget.h

@@ -313,6 +313,13 @@ class UIWidget : public Object, public tb::TBWidgetDelegate
     void SetLayoutMaxHeight(int height);
     int GetLayoutMaxHeight();
 
+    //  Get x and y (relative to this widget) relative to the upper left corner of the root widget
+    IntVector2 ConvertToRoot(const IntVector2 position ) const;
+
+    // Get x and y (relative to the upper left corner of the root widget) relative to this widget
+    IntVector2 ConvertFromRoot(const IntVector2 position) const;
+
+
     // Opacity and AutoOpacity (AutoOpacity sets visibility as well based on opacity being 0.0 or non-0.0).
     void SetOpacity(float opacity);
     float GetOpacity();

+ 3 - 0
Source/AtomicEditor/Editors/SceneEditor3D/SceneEditor3D.cpp

@@ -121,6 +121,9 @@ SceneEditor3D::SceneEditor3D(Context* context, const String &fullpath, UITabCont
     IntRect rect = container_->GetContentRoot()->GetRect();
     rootContentWidget_->SetSize(rect.Width(), rect.Height());
 
+    // FIXME: This sets the debug hud to render over the scene editor, when a scene is open, which is generally more legible. This should be generalized
+    GetSubsystem<UI>()->SetDebugHudExtents(false, container_->GetContentRoot()->ConvertToRoot(IntVector2(rect.left_, rect.top_)), IntVector2(rect.Width(), rect.Height()));
+
     SubscribeToEvent(E_PROJECTUSERPREFSAVED, ATOMIC_HANDLER(SceneEditor3D, HandleUserPrefSaved));
 
     SubscribeToEvent(scene_, E_SCENEEDITNODECREATED, ATOMIC_HANDLER(SceneEditor3D, HandleSceneEditNodeCreated));