Browse Source

Modified some platform and compiler defines (add clang/intel and removed some unused ones), also added thread localstorage
Started work on profiler

Marko Pintera 12 years ago
parent
commit
33e91538e9

+ 0 - 1
BansheeEngine.sln

@@ -42,7 +42,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
 		Dependencies.txt = Dependencies.txt
 		DrawHelper.txt = DrawHelper.txt
 		EditorWindowDock.txt = EditorWindowDock.txt
-		Localization.txt = Localization.txt
 		Notes.txt = Notes.txt
 		RenderOperation.txt = RenderOperation.txt
 		TODO.txt = TODO.txt

+ 2 - 0
CamelotUtility/CamelotUtility.vcxproj

@@ -251,6 +251,7 @@
     <ClCompile Include="Source\CmInt2.cpp" />
     <ClCompile Include="Source\CmManagedDataBlock.cpp" />
     <ClCompile Include="Source\CmMemStack.cpp" />
+    <ClCompile Include="Source\CmProfiler.cpp" />
     <ClCompile Include="Source\CmRect.cpp" />
     <ClCompile Include="Source\CmStringTable.cpp" />
     <ClCompile Include="Source\CmTexAtlasGenerator.cpp" />
@@ -279,6 +280,7 @@
     <ClInclude Include="Include\CmMemoryAllocator.h" />
     <ClInclude Include="Include\CmModule.h" />
     <ClInclude Include="Include\CmPath.h" />
+    <ClInclude Include="Include\CmProfiler.h" />
     <ClInclude Include="Include\CmRect.h" />
     <ClInclude Include="Include\CmRTTIField.h" />
     <ClInclude Include="Include\CmRTTIManagedDataBlockField.h" />

+ 6 - 0
CamelotUtility/CamelotUtility.vcxproj.filters

@@ -228,6 +228,9 @@
     <ClInclude Include="Include\CmStringTable.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="Include\CmProfiler.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\CmMath.cpp">
@@ -344,5 +347,8 @@
     <ClCompile Include="Source\CmStringTable.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="Source\CmProfiler.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 29 - 113
CamelotUtility/Include/CmPlatformDefines.h

@@ -1,44 +1,14 @@
-/*
------------------------------------------------------------------------------
-This source file is part of OGRE
-    (Object-oriented Graphics Rendering Engine)
-For the latest info, see http://www.ogre3d.org/
-
-Copyright (c) 2000-2011 Torus Knot Software Ltd
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
------------------------------------------------------------------------------
-*/
 #pragma once
 
-namespace CamelotFramework {
-/* Initial platform/compiler-related stuff to set.
-*/
+// Initial platform/compiler-related stuff to set.
 #define CM_PLATFORM_WIN32 1
 #define CM_PLATFORM_LINUX 2
 #define CM_PLATFORM_APPLE 3
 
 #define CM_COMPILER_MSVC 1
 #define CM_COMPILER_GNUC 2
-#define CM_COMPILER_BORL 3
-#define CM_COMPILER_WINSCW 4
-#define CM_COMPILER_GCCE 5
+#define CM_COMPILER_INTEL 3
+#define CM_COMPILER_CLANG 4
 
 #define CM_ARCHITECTURE_32 1
 #define CM_ARCHITECTURE_64 2
@@ -48,34 +18,31 @@ namespace CamelotFramework {
 
 #define CM_ENDIAN CM_ENDIAN_LITTLE
 
-/* Finds the compiler type and version.
-*/
-#if defined( __GCCE__ )
-#   define CM_COMPILER CM_COMPILER_GCCE
-#   define CM_COMP_VER _MSC_VER
-//#	include <staticlibinit_gcce.h> // This is a GCCE toolchain workaround needed when compiling with GCCE 
-#elif defined( __WINSCW__ )
-#   define CM_COMPILER CM_COMPILER_WINSCW
-#   define CM_COMP_VER _MSC_VER
-#elif defined( _MSC_VER )
+// Finds the compiler type and version.
+#if defined( _MSC_VER )
 #   define CM_COMPILER CM_COMPILER_MSVC
 #   define CM_COMP_VER _MSC_VER
+#	define CM_THREADLOCAL __declspec(thread)
 #elif defined( __GNUC__ )
 #   define CM_COMPILER CM_COMPILER_GNUC
 #   define CM_COMP_VER (((__GNUC__)*100) + \
         (__GNUC_MINOR__*10) + \
         __GNUC_PATCHLEVEL__)
-
-#elif defined( __BORLANDC__ )
-#   define CM_COMPILER CM_COMPILER_BORL
-#   define CM_COMP_VER __BCPLUSPLUS__
-#   define __FUNCTION__ __FUNC__ 
+#   define CM_THREADLOCAL __thread
+#elif defined ( __INTEL_COMPILER )
+#   define CM_COMPILER CM_COMPILER_INTEL
+#	define CM_COMP_VER __INTEL_COMPILER
+	// CM_THREADLOCAL define is down below because Intel compiler defines it differently based on platform
+#elif defined ( __clang__ )
+#   define CM_COMPILER CM_COMPILER_CLANG
+#	define CM_COMP_VER __clang_major__
+#   define CM_THREADLOCAL __thread
 #else
-#   pragma error "No known compiler. Abort! Abort!"
+#   pragma error "No known compiler. "
 
 #endif
 
-/* See if we can use __forceinline or if we need to use __inline instead */
+// See if we can use __forceinline or if we need to use __inline instead
 #if CM_COMPILER == CM_COMPILER_MSVC
 #   if CM_COMP_VER >= 1200
 #       define FORCEINLINE __forceinline
@@ -88,8 +55,7 @@ namespace CamelotFramework {
 #   define FORCEINLINE __inline
 #endif
 
-/* Finds the current platform */
-
+// Finds the current platform
 #if defined( __WIN32__ ) || defined( _WIN32 )
 #   define CM_PLATFORM CM_PLATFORM_WIN32
 #elif defined( __APPLE_CC__)
@@ -98,14 +64,13 @@ namespace CamelotFramework {
 #   define CM_PLATFORM CM_PLATFORM_LINUX
 #endif
 
-    /* Find the arch type */
+// Find the architecture type
 #if defined(__x86_64__) || defined(_M_X64) || defined(__powerpc64__) || defined(__alpha__) || defined(__ia64__) || defined(__s390__) || defined(__s390x__)
 #   define CM_ARCH_TYPE CM_ARCHITECTURE_64
 #else
 #   define CM_ARCH_TYPE CM_ARCHITECTURE_32
 #endif
 
-//----------------------------------------------------------------------------
 // Windows Settings
 #if CM_PLATFORM == CM_PLATFORM_WIN32
 
@@ -133,10 +98,13 @@ namespace CamelotFramework {
 #       define CM_DEBUG_MODE 0
 #   endif
 
+#	if CM_COMPILER == CM_COMPILER_INTEL
+#        define CM_THREADLOCAL __declspec(thread)
+#	endif
+
 #endif // CM_PLATFORM == CM_PLATFORM_WIN32
 
-//----------------------------------------------------------------------------
-// Linux/Apple/Symbian Settings
+// Linux/Apple Settings
 #if CM_PLATFORM == CM_PLATFORM_LINUX || CM_PLATFORM == CM_PLATFORM_APPLE
 
 // Enable GCC symbol visibility
@@ -146,72 +114,20 @@ namespace CamelotFramework {
 #       define CM_UTILITY_EXPORT
 #   endif
 
-// A quick define to overcome different names for the same function
-#   define stricmp strcasecmp
-
-// Unlike the Win32 compilers, Linux compilers seem to use DEBUG for when
-// specifying a debug build.
-// (??? this is wrong, on Linux debug builds aren't marked in any way unless
-// you mark it yourself any way you like it -- zap ???)
 #   ifdef DEBUG
 #       define CM_DEBUG_MODE 1
 #   else
 #       define CM_DEBUG_MODE 0
 #   endif
 
+#	if CM_COMPILER == CM_COMPILER_INTEL
+#        define CM_THREADLOCAL __thread
+#	endif
+
 #if CM_PLATFORM == CM_PLATFORM_APPLE
     #define CM_PLATFORM_LIB "CmPlatform.bundle"
 #else //CM_PLATFORM_LINUX
     #define CM_PLATFORM_LIB "libCmPlatform.so"
 #endif
 
-#endif
-
-//----------------------------------------------------------------------------
-
-/* Initial CPU stuff to set.
-*/
-#define CM_CPU_UNKNOWN    0
-#define CM_CPU_X86        1
-#define CM_CPU_PPC        2
-
-/* Find CPU type
-*/
-#if (defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))) || \
-    (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)))
-#   define CM_CPU CM_CPU_X86
-
-#elif CM_PLATFORM == CM_PLATFORM_APPLE && defined(__BIG_ENDIAN__)
-#   define CM_CPU CM_CPU_PPC
-#elif CM_PLATFORM == CM_PLATFORM_APPLE
-#	define CM_CPU CM_CPU_X86
-#else
-#   define CM_CPU CM_CPU_UNKNOWN
-#endif
-
-/* Find how to declare aligned variable.
-*/
-#if CM_COMPILER == CM_COMPILER_MSVC
-#   define CM_ALIGNED_DECL(type, var, alignment)  __declspec(align(alignment)) type var
-
-#elif CM_COMPILER == CM_COMPILER_GNUC
-#   define CM_ALIGNED_DECL(type, var, alignment)  type var __attribute__((__aligned__(alignment)))
-
-#else
-#   define CM_ALIGNED_DECL(type, var, alignment)  type var
-#endif
-
-/** Find perfect alignment (should supports SIMD alignment if SIMD available)
-*/
-#if CM_CPU == CM_CPU_X86
-#   define CM_SIMD_ALIGNMENT  16
-
-#else
-#   define CM_SIMD_ALIGNMENT  16
-#endif
-
-/* Declare variable aligned to SIMD alignment.
-*/
-#define CM_SIMD_ALIGNED_DECL(type, var)   CM_ALIGNED_DECL(type, var, CM_SIMD_ALIGNMENT)
-
-}
+#endif

+ 78 - 0
CamelotUtility/Include/CmProfiler.h

@@ -0,0 +1,78 @@
+#pragma once
+
+#include "CmPrerequisitesUtil.h"
+#include "CmModule.h"
+
+namespace CamelotFramework
+{
+	/**
+	 * @brief	Provides various performance measuring methods
+	 */
+	class CM_UTILITY_EXPORT Profiler : public Module<Profiler>
+	{
+	public:
+		class CM_UTILITY_EXPORT Data
+		{
+			String name;
+			float timeAvgMs;
+			float timeMaxMs;
+			float timeTotalMs;
+			UINT32 hitCount;
+		};
+
+		class CM_UTILITY_EXPORT PreciseData
+		{
+			String name;
+			UINT64 cyclesAvg;
+			UINT64 cyclesMax;
+			UINT64 cyclesTotal;
+			UINT32 hitCount;
+
+			// TODO - Add cache misses, branch mispredictions, retired instructions vs. optimal number of cycles
+		};
+
+		/**
+		 * @brief	Begins sample measurement. Must be followed by endSample. 
+		 *
+		 * @param	name	Unique name for the sample you can later use to find the sampling data.
+		 */
+		void beginSample(const String& name);
+
+		/**
+		 * @brief	Ends sample measurement and returns measured data.
+		 *
+		 * @param	name	Unique name for the sample. 
+		 * 					
+		 * @note	Unique name is primarily needed to more easily identify mismatched
+		 * 			begin/end sample pairs. Otherwise the name in beginSample would be enough.
+		 */
+		Data endSample(const String& name);
+
+		/**
+		 * @brief	Begins sample measurement. Must be followed by endSample. 
+		 *
+		 * @param	name	Unique name for the sample you can later use to find the sampling data.
+		 * 					
+		 * @note	This method uses very precise CPU counters to determine variety of data not
+		 * 			provided by standard beginSample. However due to the way these counters work you should
+		 * 			not use this method for larger parts of code. It does not consider context switches so if the OS
+		 * 			decides to switch context between measurements you will get invalid data.
+		 */
+		void beginSamplePrecise(const String& name);
+
+		/**
+		 * @brief	Ends precise sample measurement and returns measured data.
+		 *
+		 * @param	name	Unique name for the sample. 
+		 * 					
+		 * @note	Unique name is primarily needed to more easily identify mismatched
+		 * 			begin/end sample pairs. Otherwise the name in beginSamplePrecise would be enough.
+		 */
+		PreciseData endSamplePrecise(const String& name);
+
+		/**
+		 * @brief	Called every frame. Internal method.
+		 */
+		void update();
+	};
+}

+ 29 - 0
CamelotUtility/Source/CmProfiler.cpp

@@ -0,0 +1,29 @@
+#include "CmProfiler.h"
+
+namespace CamelotFramework
+{
+	void Profiler::beginSample(const String& name)
+	{
+
+	}
+
+	Profiler::Data Profiler::endSample(const String& name)
+	{
+		return Profiler::Data();
+	}
+
+	void Profiler::beginSamplePrecise(const String& name)
+	{
+
+	}
+
+	Profiler::PreciseData Profiler::endSamplePrecise(const String& name)
+	{
+		return Profiler::PreciseData();
+	}
+
+	void Profiler::update()
+	{
+
+	}
+}

+ 1 - 0
TODO.txt

@@ -6,6 +6,7 @@ LONGTERM TODO:
 3. Window drag'n'drop detect
 4. Basic profiler
   - When building a profiler have main Profiler class which just does measurements, then ProfilerOverlay for data display on-screen, ProfilerEditor for Unity-like Profiler, etc.
+  - For now just create a profiler with basic measuring stats (FPS, core & sim thread time, plus times for most important systems), and ProfilerOverlay to display them
 
 I still re-create GUIWidget mesh every frame instead of just updating it.