Просмотр исходного кода

Fixed an issue with GUI layout calculation
Added sample tiles to GPU profiler overlay

Marko Pintera 11 лет назад
Родитель
Сommit
5d7e93aeee

+ 1 - 1
BansheeCore/Include/BsProfilerGPU.h

@@ -172,7 +172,7 @@ namespace BansheeEngine
 	private:
 	private:
 		ActiveFrame mActiveFrame;
 		ActiveFrame mActiveFrame;
 		bool mIsFrameActive;
 		bool mIsFrameActive;
-		UINT32 mNumActiveSamples;
+		Stack<UINT32> mActiveSampleIndexes;
 
 
 		Queue<ActiveFrame> mUnresolvedFrames;
 		Queue<ActiveFrame> mUnresolvedFrames;
 		Queue<GPUProfilerReport> mReadyReports;
 		Queue<GPUProfilerReport> mReadyReports;

+ 3 - 0
BansheeCore/Include/BsRenderStats.h

@@ -137,6 +137,9 @@ namespace BansheeEngine
 			// also want to allow the caller to assign names to specific "resourceType" id.
 			// also want to allow the caller to assign names to specific "resourceType" id.
 			// (Since many types will be RenderSystem specific).
 			// (Since many types will be RenderSystem specific).
 
 
+			// TODO - I should also track number of active GPU objects using this method, instead
+			// of just keeping track of how many were created and destroyed during the frame.
+
 			mData.numObjectsCreated++;
 			mData.numObjectsCreated++;
 		}
 		}
 
 

+ 4 - 0
BansheeCore/Source/BsCoreApplication.cpp

@@ -209,10 +209,14 @@ namespace BansheeEngine
 	{
 	{
 		gProfilerCPU().beginThread("Core");
 		gProfilerCPU().beginThread("Core");
 		ProfilerGPU::instance().beginFrame();
 		ProfilerGPU::instance().beginFrame();
+		ProfilerGPU::instance().beginSample("DBG1");
+		ProfilerGPU::instance().beginSample("DBG2");
 	}
 	}
 
 
 	void CoreApplication::endCoreProfiling()
 	void CoreApplication::endCoreProfiling()
 	{
 	{
+		ProfilerGPU::instance().endSample("DBG2");
+		ProfilerGPU::instance().endSample("DBG1");
 		ProfilerGPU::instance().endFrame();
 		ProfilerGPU::instance().endFrame();
 		ProfilerGPU::instance()._update();
 		ProfilerGPU::instance()._update();
 
 

+ 8 - 6
BansheeCore/Source/BsProfilerGPU.cpp

@@ -7,7 +7,7 @@
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
 	ProfilerGPU::ProfilerGPU()
 	ProfilerGPU::ProfilerGPU()
-		:mNumActiveSamples(0), mIsFrameActive(false)
+		:mIsFrameActive(false)
 	{ }
 	{ }
 
 
 	void ProfilerGPU::beginFrame()
 	void ProfilerGPU::beginFrame()
@@ -25,7 +25,7 @@ namespace BansheeEngine
 
 
 	void ProfilerGPU::endFrame()
 	void ProfilerGPU::endFrame()
 	{
 	{
-		if (mNumActiveSamples > 0)
+		if (mActiveSampleIndexes.size() > 0)
 			BS_EXCEPT(InvalidStateException, "Attempting to end a frame while a sample is active.");
 			BS_EXCEPT(InvalidStateException, "Attempting to end a frame while a sample is active.");
 
 
 		if (!mIsFrameActive)
 		if (!mIsFrameActive)
@@ -47,15 +47,17 @@ namespace BansheeEngine
 
 
 		sample.sampleName = name;
 		sample.sampleName = name;
 		beginSampleInternal(sample);
 		beginSampleInternal(sample);
-		mNumActiveSamples++;
+
+		mActiveSampleIndexes.push((UINT32)mActiveFrame.samples.size() - 1);
 	}
 	}
 
 
 	void ProfilerGPU::endSample(const ProfilerString& name)
 	void ProfilerGPU::endSample(const ProfilerString& name)
 	{
 	{
-		if (mNumActiveSamples == 0)
+		if (mActiveSampleIndexes.size() == 0)
 			return;
 			return;
 
 
-		ActiveSample& sample = mActiveFrame.samples.back();
+		UINT32 lastSampleIdx = mActiveSampleIndexes.top();
+		ActiveSample& sample = mActiveFrame.samples[lastSampleIdx];
 		if (sample.sampleName != name)
 		if (sample.sampleName != name)
 		{
 		{
 			String errorStr = "Attempting to end a sample that doesn't match. Got: " + 
 			String errorStr = "Attempting to end a sample that doesn't match. Got: " + 
@@ -65,7 +67,7 @@ namespace BansheeEngine
 		}
 		}
 
 
 		endSampleInternal(sample);
 		endSampleInternal(sample);
-		mNumActiveSamples--;
+		mActiveSampleIndexes.pop();
 	}
 	}
 
 
 	UINT32 ProfilerGPU::getNumAvailableReports()
 	UINT32 ProfilerGPU::getNumAvailableReports()

+ 2 - 2
BansheeEngine/Source/BsGUILayoutX.cpp

@@ -383,7 +383,7 @@ namespace BansheeEngine
 				newClipRect.clip(clipRect);
 				newClipRect.clip(clipRect);
 				element->_updateLayoutInternal(offset.x, offset.y, elemWidth, elemHeight, newClipRect, widgetDepth, areaDepth);
 				element->_updateLayoutInternal(offset.x, offset.y, elemWidth, elemHeight, newClipRect, widgetDepth, areaDepth);
 
 
-				mActualHeight = std::max(mActualHeight, elemHeight);
+				mActualHeight = std::max(height, elemHeight);
 			}
 			}
 			else if(child->_getType() == GUIElementBase::Type::Layout)
 			else if(child->_getType() == GUIElementBase::Type::Layout)
 			{
 			{
@@ -394,7 +394,7 @@ namespace BansheeEngine
 				layout->_updateLayoutInternal(x + xOffset, y, elemWidth, height, newClipRect, widgetDepth, areaDepth);
 				layout->_updateLayoutInternal(x + xOffset, y, elemWidth, height, newClipRect, widgetDepth, areaDepth);
 
 
 				UINT32 childHeight = layout->_getActualHeight();
 				UINT32 childHeight = layout->_getActualHeight();
-				mActualHeight = std::max(mActualHeight, childHeight);
+				mActualHeight = std::max(height, childHeight);
 
 
 				// It's possible all elements didn't fit in the child layout size we provided, in which case adjust our measurements
 				// It's possible all elements didn't fit in the child layout size we provided, in which case adjust our measurements
 				elemWidth = layout->_getActualWidth();
 				elemWidth = layout->_getActualWidth();

+ 2 - 2
BansheeEngine/Source/BsGUILayoutY.cpp

@@ -376,7 +376,7 @@ namespace BansheeEngine
 				newClipRect.clip(clipRect);
 				newClipRect.clip(clipRect);
 				element->_updateLayoutInternal(offset.x, offset.y, elemWidth, elemHeight, newClipRect, widgetDepth, areaDepth);
 				element->_updateLayoutInternal(offset.x, offset.y, elemWidth, elemHeight, newClipRect, widgetDepth, areaDepth);
 
 
-				mActualWidth = std::max(mActualWidth, elemWidth);
+				mActualWidth = std::max(width, elemWidth);
 			}
 			}
 			else if(child->_getType() == GUIElementBase::Type::Layout)
 			else if(child->_getType() == GUIElementBase::Type::Layout)
 			{
 			{
@@ -386,7 +386,7 @@ namespace BansheeEngine
 				newClipRect.clip(clipRect);
 				newClipRect.clip(clipRect);
 				layout->_updateLayoutInternal(x, y + yOffset, width, elemHeight, newClipRect, widgetDepth, areaDepth);
 				layout->_updateLayoutInternal(x, y + yOffset, width, elemHeight, newClipRect, widgetDepth, areaDepth);
 
 
-				mActualWidth = std::max(mActualWidth, layout->_getActualWidth());
+				mActualWidth = std::max(width, layout->_getActualWidth());
 
 
 				// It's possible all elements didn't fit in the child layout size we provided, in which case adjust our measurements
 				// It's possible all elements didn't fit in the child layout size we provided, in which case adjust our measurements
 				elemHeight = layout->_getActualHeight();
 				elemHeight = layout->_getActualHeight();

+ 21 - 4
BansheeEngine/Source/BsProfilerOverlay.cpp

@@ -239,7 +239,7 @@ namespace BansheeEngine
 			UINT32 excessEntries = (UINT32)rows.size() - curIdx;
 			UINT32 excessEntries = (UINT32)rows.size() - curIdx;
 			for (UINT32 i = 0; i < excessEntries; i++)
 			for (UINT32 i = 0; i < excessEntries; i++)
 			{
 			{
-				layout.removeChildAt(layout.getNumChildren() - i - 1); // -1 because last element is flexible space and we want to skip it
+				layout.removeChildAt(layout.getNumChildren() - i); 
 
 
 				ProfilerOverlay::GPUSampleRow& row = rows[curIdx + i];
 				ProfilerOverlay::GPUSampleRow& row = rows[curIdx + i];
 
 
@@ -258,10 +258,10 @@ namespace BansheeEngine
 
 
 				ProfilerOverlay::GPUSampleRow& newRow = rows.back();
 				ProfilerOverlay::GPUSampleRow& newRow = rows.back();
 
 
-				newRow.name = HString(L"Name");
+				newRow.name = HString(L"{1}");
 				newRow.time = HString(L"{0}");
 				newRow.time = HString(L"{0}");
 
 
-				newRow.layout = &layout.insertLayoutX(layout.getNumChildren() - 1); // Insert before flexible space
+				newRow.layout = &layout.insertLayoutX(layout.getNumChildren());
 
 
 				GUILabel* nameLabel = GUILabel::create(newRow.name, GUIOptions(GUIOption::fixedWidth(100)));
 				GUILabel* nameLabel = GUILabel::create(newRow.name, GUIOptions(GUIOption::fixedWidth(100)));
 				GUILabel* timeLabel = GUILabel::create(newRow.time, GUIOptions(GUIOption::fixedWidth(100)));
 				GUILabel* timeLabel = GUILabel::create(newRow.time, GUIOptions(GUIOption::fixedWidth(100)));
@@ -274,6 +274,7 @@ namespace BansheeEngine
 			}
 			}
 
 
 			ProfilerOverlay::GPUSampleRow& row = rows[curIdx];
 			ProfilerOverlay::GPUSampleRow& row = rows[curIdx];
+			row.name.setParameter(0, toWString(name));
 			row.time.setParameter(0, toWString(timeMs));
 			row.time.setParameter(0, toWString(timeMs));
 
 
 			curIdx++;
 			curIdx++;
@@ -384,7 +385,23 @@ namespace BansheeEngine
 		mGPUAreaFrameSamples = GUIArea::create(*mWidget, 0, 0);
 		mGPUAreaFrameSamples = GUIArea::create(*mWidget, 0, 0);
 		mGPULayoutFrameContentsLeft = &mGPUAreaFrameContents->getLayout().addLayoutY();
 		mGPULayoutFrameContentsLeft = &mGPUAreaFrameContents->getLayout().addLayoutY();
 		mGPULayoutFrameContentsRight = &mGPUAreaFrameContents->getLayout().addLayoutY();
 		mGPULayoutFrameContentsRight = &mGPUAreaFrameContents->getLayout().addLayoutY();
-		mGPULayoutSamples = &mGPUAreaFrameSamples->getLayout().addLayoutY();
+
+		GUILayout& gpuSamplesMain = mGPUAreaFrameSamples->getLayout().addLayoutY();
+
+		GUILayout& gpuSampleTitle = gpuSamplesMain.addLayoutY();
+		mGPULayoutSamples = &gpuSamplesMain.addLayoutY();
+		gpuSamplesMain.addFlexibleSpace();
+
+		HString gpuSamplesStr(L"__ProfOvGPUSamples", L"Samples");
+		gpuSampleTitle.addElement(GUILabel::create(gpuSamplesStr));
+		gpuSampleTitle.addSpace(20);
+
+		GUILayout& gpuSampleTitleRow = gpuSampleTitle.addLayoutX();
+
+		HString gpuSamplesNameStr(L"__ProfOvGPUSampName", L"Name");
+		HString gpuSamplesTimeStr(L"__ProfOvGPUSampTime", L"Time");
+		gpuSampleTitleRow.addElement(GUILabel::create(gpuSamplesNameStr, GUIOptions(GUIOption::fixedWidth(100))));
+		gpuSampleTitleRow.addElement(GUILabel::create(gpuSamplesTimeStr, GUIOptions(GUIOption::fixedWidth(100))));
 
 
 		mGPUFrameNumStr = HString(L"__ProfOvFrame", L"Frame #{0}");
 		mGPUFrameNumStr = HString(L"__ProfOvFrame", L"Frame #{0}");
 		mGPUTimeStr = HString(L"__ProfOvTime", L"Time: {0}ms");
 		mGPUTimeStr = HString(L"__ProfOvTime", L"Time: {0}ms");

+ 0 - 6
Polish.txt

@@ -1,7 +1,6 @@
 Polish TODO:
 Polish TODO:
  - Finish basic example, get a model rendering on screen
  - Finish basic example, get a model rendering on screen
  - Fix FBX importer so proper number of vertices show
  - Fix FBX importer so proper number of vertices show
- - Finish and test GPU profiler
  - Test and fix full-screen transitions
  - Test and fix full-screen transitions
  - Add virtual input axes
  - Add virtual input axes
  - Compress and generate mips for texture on input (testing NVTT stuff)
  - Compress and generate mips for texture on input (testing NVTT stuff)
@@ -17,11 +16,6 @@ Polish TODO:
 
 
 There's still a crash regarding an uninitialized mCachedPtr on a C# class when shutting down. Attempt to find consistent repro steps.
 There's still a crash regarding an uninitialized mCachedPtr on a C# class when shutting down. Attempt to find consistent repro steps.
 
 
-Finish GPUProfiler:
- - Resource writes/reads/creation/destruction is not currently increased in RenderStats
-   - Make RenderStats global so resources can more easily access those methods.
- - Test overlay and add title labels for samples
-
  ---------------------------
  ---------------------------
 
 
  Make hierarchical documentation. Organize stuff based on type. Once I actually generate the documentation add Doxygen grouping tags (or whatever they're called)
  Make hierarchical documentation. Organize stuff based on type. Once I actually generate the documentation add Doxygen grouping tags (or whatever they're called)