├── .hgignore ├── README.md ├── bin ├── microprofile-win32-cswitch_x64.exe ├── microprofile-win32-cswitch_x64.pdb ├── microprofile-win32-cswitch_x86.exe └── microprofile-win32-cswitch_x86.pdb ├── demo ├── README ├── demo_windows.sln ├── embed.bat ├── glew │ ├── GL │ │ ├── glew.h │ │ ├── glxew.h │ │ └── wglew.h │ ├── LICENSE.txt │ └── glew.c ├── noui │ ├── Makefile │ ├── demo_noui.cpp │ ├── fakework.cpp │ ├── miniz.c │ ├── noui.vcxproj │ └── noui.vcxproj.filters ├── noui_d3d11 │ ├── Tutorial02.fx │ ├── Tutorial02_PS.hlsl │ ├── Tutorial02_VS.hlsl │ ├── demo_noui_d3d11.cpp │ ├── fakework.cpp │ ├── noui_d3d11.vcxproj │ └── noui_d3d11.vcxproj.filters ├── noui_d3d12 │ ├── d3dx12.h │ ├── noui_d3d12.cpp │ ├── noui_d3d12.vcxproj │ ├── noui_d3d12.vcxproj.filters │ └── shaders.hlsl ├── noui_d3d12_multithreading │ ├── SquidRoom.bin │ ├── SquidRoom.h │ ├── d3dx12.h │ ├── noui_d3d12_multithreading.cpp │ ├── noui_d3d12_multithreading.vcxproj │ └── shaders.hlsl └── ui │ ├── Makefile │ ├── demo.cpp │ ├── fakework.cpp │ ├── glinc.h │ ├── microprofile.cpp │ ├── ui.vcxproj │ └── ui.vcxproj.filters ├── microprofile-dev.sublime-project ├── microprofile.h ├── microprofile_html.h ├── microprofileui.h └── src ├── Makefile ├── dtrace_contextswitch ├── embed.c ├── microprofile-win32-cswitch ├── main.cpp ├── microprofile-win32-cswitch.sln ├── microprofile-win32-cswitch.vcxproj └── microprofile-win32-cswitch.vcxproj.filters ├── microprofile.html └── premake4.lua /.hgignore: -------------------------------------------------------------------------------- 1 | syntax: glob 2 | demo/build/ 3 | demo\SDL2.dll 4 | demo\microprofile.exe 5 | demo\microprofile.idb 6 | demo\microprofile.pdb 7 | demo\premake4.exe 8 | demo/sdl2/ 9 | demo\microprofile.vcxproj 10 | demo\microprofile.vcxproj.filters 11 | *.tlog 12 | *.lastbuildstate 13 | *.o 14 | *.ipdb -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # microprofile 2 | 3 | MicroProfile is a embeddable profiler in a single file, written in C++ 4 | 5 | It can display profile information in the application, or by generating captures via a minimal built in webserver. 6 | 7 | # Dependencies 8 | Microprofile supports generating compressed captures using miniz(http:/code.google.com/miniz). 9 | 10 | # License 11 | Licensed using unlicense.org 12 | 13 | # Screenshot 14 | ![Microprofile in action](https://pbs.twimg.com/media/BnvzublCEAA0Mqf.png:large) 15 | -------------------------------------------------------------------------------- /bin/microprofile-win32-cswitch_x64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dougbinks/microprofile/1478c9ddaec388914258f2fa3471ac435715c032/bin/microprofile-win32-cswitch_x64.exe -------------------------------------------------------------------------------- /bin/microprofile-win32-cswitch_x64.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dougbinks/microprofile/1478c9ddaec388914258f2fa3471ac435715c032/bin/microprofile-win32-cswitch_x64.pdb -------------------------------------------------------------------------------- /bin/microprofile-win32-cswitch_x86.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dougbinks/microprofile/1478c9ddaec388914258f2fa3471ac435715c032/bin/microprofile-win32-cswitch_x86.exe -------------------------------------------------------------------------------- /bin/microprofile-win32-cswitch_x86.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dougbinks/microprofile/1478c9ddaec388914258f2fa3471ac435715c032/bin/microprofile-win32-cswitch_x86.pdb -------------------------------------------------------------------------------- /demo/README: -------------------------------------------------------------------------------- 1 | 2 | This folder contains a few samples: 3 | 4 | ui: [windows, osx, linux] Full implementation using OpenGL. Supports 5 | Depends on SDL2. 6 | On Windows: unzip SDL2 into sdl2 subfolder below demo/ and build it, before compiling the samples 7 | OSX/Linux: sdl2 should be compiled & installed, so that sdl2-config is available. 8 | 9 | noui: [windows, osx, linux] Minimal sample, only webpage interface supported. 10 | 11 | noui_d3d11: [windows] Minimal sample plus d3d11 gpu timers. 12 | 13 | noui_d3d12: [windows10] Minimal sample plus d3d12 gpu timers. 14 | 15 | noui_d3d12_multithreading: [windows10] Minimal sample plus d3d12 gpu timers. Shows how microprofile works with multithreaded rendering, and how to support multiple command queues. 16 | -------------------------------------------------------------------------------- /demo/demo_windows.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.23107.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "noui_d3d12", "noui_d3d12\noui_d3d12.vcxproj", "{498550DB-779A-49ED-A253-33672F378337}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "noui_d3d12_multithreading", "noui_d3d12_multithreading\noui_d3d12_multithreading.vcxproj", "{DBC4664B-A190-4533-80D5-4312F7541B47}" 9 | EndProject 10 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "noui_d3d11", "noui_d3d11\noui_d3d11.vcxproj", "{5EDFD505-4ADD-44D3-9DAE-E67F4CD6CB18}" 11 | EndProject 12 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ui", "ui\ui.vcxproj", "{533791DB-8915-41AB-8201-0D605723DA32}" 13 | EndProject 14 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "noui", "noui\noui.vcxproj", "{D60DFD55-B1FB-4A27-8635-CF66B68AD288}" 15 | EndProject 16 | Global 17 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 18 | Debug|x64 = Debug|x64 19 | Debug|x86 = Debug|x86 20 | Release|x64 = Release|x64 21 | Release|x86 = Release|x86 22 | EndGlobalSection 23 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 24 | {498550DB-779A-49ED-A253-33672F378337}.Debug|x64.ActiveCfg = Debug|x64 25 | {498550DB-779A-49ED-A253-33672F378337}.Debug|x64.Build.0 = Debug|x64 26 | {498550DB-779A-49ED-A253-33672F378337}.Debug|x86.ActiveCfg = Debug|Win32 27 | {498550DB-779A-49ED-A253-33672F378337}.Debug|x86.Build.0 = Debug|Win32 28 | {498550DB-779A-49ED-A253-33672F378337}.Release|x64.ActiveCfg = Release|x64 29 | {498550DB-779A-49ED-A253-33672F378337}.Release|x64.Build.0 = Release|x64 30 | {498550DB-779A-49ED-A253-33672F378337}.Release|x86.ActiveCfg = Release|Win32 31 | {498550DB-779A-49ED-A253-33672F378337}.Release|x86.Build.0 = Release|Win32 32 | {DBC4664B-A190-4533-80D5-4312F7541B47}.Debug|x64.ActiveCfg = Debug|x64 33 | {DBC4664B-A190-4533-80D5-4312F7541B47}.Debug|x64.Build.0 = Debug|x64 34 | {DBC4664B-A190-4533-80D5-4312F7541B47}.Debug|x86.ActiveCfg = Debug|Win32 35 | {DBC4664B-A190-4533-80D5-4312F7541B47}.Debug|x86.Build.0 = Debug|Win32 36 | {DBC4664B-A190-4533-80D5-4312F7541B47}.Release|x64.ActiveCfg = Release|x64 37 | {DBC4664B-A190-4533-80D5-4312F7541B47}.Release|x64.Build.0 = Release|x64 38 | {DBC4664B-A190-4533-80D5-4312F7541B47}.Release|x86.ActiveCfg = Release|Win32 39 | {DBC4664B-A190-4533-80D5-4312F7541B47}.Release|x86.Build.0 = Release|Win32 40 | {5EDFD505-4ADD-44D3-9DAE-E67F4CD6CB18}.Debug|x64.ActiveCfg = Debug|x64 41 | {5EDFD505-4ADD-44D3-9DAE-E67F4CD6CB18}.Debug|x64.Build.0 = Debug|x64 42 | {5EDFD505-4ADD-44D3-9DAE-E67F4CD6CB18}.Debug|x86.ActiveCfg = Debug|Win32 43 | {5EDFD505-4ADD-44D3-9DAE-E67F4CD6CB18}.Debug|x86.Build.0 = Debug|Win32 44 | {5EDFD505-4ADD-44D3-9DAE-E67F4CD6CB18}.Release|x64.ActiveCfg = Release|x64 45 | {5EDFD505-4ADD-44D3-9DAE-E67F4CD6CB18}.Release|x64.Build.0 = Release|x64 46 | {5EDFD505-4ADD-44D3-9DAE-E67F4CD6CB18}.Release|x86.ActiveCfg = Release|Win32 47 | {5EDFD505-4ADD-44D3-9DAE-E67F4CD6CB18}.Release|x86.Build.0 = Release|Win32 48 | {533791DB-8915-41AB-8201-0D605723DA32}.Debug|x64.ActiveCfg = Debug|x64 49 | {533791DB-8915-41AB-8201-0D605723DA32}.Debug|x64.Build.0 = Debug|x64 50 | {533791DB-8915-41AB-8201-0D605723DA32}.Debug|x86.ActiveCfg = Debug|Win32 51 | {533791DB-8915-41AB-8201-0D605723DA32}.Debug|x86.Build.0 = Debug|Win32 52 | {533791DB-8915-41AB-8201-0D605723DA32}.Release|x64.ActiveCfg = Release|x64 53 | {533791DB-8915-41AB-8201-0D605723DA32}.Release|x64.Build.0 = Release|x64 54 | {533791DB-8915-41AB-8201-0D605723DA32}.Release|x86.ActiveCfg = Release|Win32 55 | {533791DB-8915-41AB-8201-0D605723DA32}.Release|x86.Build.0 = Release|Win32 56 | {D60DFD55-B1FB-4A27-8635-CF66B68AD288}.Debug|x64.ActiveCfg = Debug|x64 57 | {D60DFD55-B1FB-4A27-8635-CF66B68AD288}.Debug|x64.Build.0 = Debug|x64 58 | {D60DFD55-B1FB-4A27-8635-CF66B68AD288}.Debug|x86.ActiveCfg = Debug|Win32 59 | {D60DFD55-B1FB-4A27-8635-CF66B68AD288}.Debug|x86.Build.0 = Debug|Win32 60 | {D60DFD55-B1FB-4A27-8635-CF66B68AD288}.Release|x64.ActiveCfg = Release|x64 61 | {D60DFD55-B1FB-4A27-8635-CF66B68AD288}.Release|x64.Build.0 = Release|x64 62 | {D60DFD55-B1FB-4A27-8635-CF66B68AD288}.Release|x86.ActiveCfg = Release|Win32 63 | {D60DFD55-B1FB-4A27-8635-CF66B68AD288}.Release|x86.Build.0 = Release|Win32 64 | EndGlobalSection 65 | GlobalSection(SolutionProperties) = preSolution 66 | HideSolutionNode = FALSE 67 | EndGlobalSection 68 | EndGlobal 69 | -------------------------------------------------------------------------------- /demo/embed.bat: -------------------------------------------------------------------------------- 1 | @pushd ..\..\src 2 | embed.exe ../microprofile_html.h microprofile.html ____embed____ g_MicroProfileHtml MICROPROFILE_EMBED_HTML 3 | @popd 4 | @echo "done embedding" -------------------------------------------------------------------------------- /demo/glew/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The OpenGL Extension Wrangler Library 2 | Copyright (C) 2002-2007, Milan Ikits 3 | Copyright (C) 2002-2007, Marcelo E. Magallon 4 | Copyright (C) 2002, Lev Povalahev 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright notice, 11 | this list of conditions and the following disclaimer. 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | * The name of the author may be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 | THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | 31 | Mesa 3-D graphics library 32 | Version: 7.0 33 | 34 | Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 35 | 36 | Permission is hereby granted, free of charge, to any person obtaining a 37 | copy of this software and associated documentation files (the "Software"), 38 | to deal in the Software without restriction, including without limitation 39 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 40 | and/or sell copies of the Software, and to permit persons to whom the 41 | Software is furnished to do so, subject to the following conditions: 42 | 43 | The above copyright notice and this permission notice shall be included 44 | in all copies or substantial portions of the Software. 45 | 46 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 47 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 48 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 49 | BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 50 | AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 51 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 52 | 53 | 54 | Copyright (c) 2007 The Khronos Group Inc. 55 | 56 | Permission is hereby granted, free of charge, to any person obtaining a 57 | copy of this software and/or associated documentation files (the 58 | "Materials"), to deal in the Materials without restriction, including 59 | without limitation the rights to use, copy, modify, merge, publish, 60 | distribute, sublicense, and/or sell copies of the Materials, and to 61 | permit persons to whom the Materials are furnished to do so, subject to 62 | the following conditions: 63 | 64 | The above copyright notice and this permission notice shall be included 65 | in all copies or substantial portions of the Materials. 66 | 67 | THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 68 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 69 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 70 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 71 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 72 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 73 | MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. 74 | -------------------------------------------------------------------------------- /demo/noui/Makefile: -------------------------------------------------------------------------------- 1 | UNAME_S := $(shell uname -s) 2 | # ifeq ($(UNAME_S),Linux) 3 | # LDFLAGS=-lGL `sdl2-config --static-libs` -lpthread 4 | # endif 5 | # ifeq ($(UNAME_S),Darwin) 6 | # LDFLAGS=-framework OpenGL `sdl2-config --static-libs` -lpthread 7 | # endif 8 | 9 | CFLAGS=-Wno-c++11-extensions -I../.. 10 | #CFLAGS+=-fsanitize=undefined-trap -fsanitize-undefined-trap-on-error 11 | CFLAGS+=-Wall -DMICROPROFILE_UI=0 -DMICROPROFILE_WEBSERVER=1 -DMICROPROFILE_GPU_TIMERS=0 12 | CFLAGS+=-g -O0 -Wno-invalid-offsetof -Wall -Werror 13 | 14 | #CFLAGS+=-DMICROPROFILE_ENABLED=0 15 | CPPFLAGS=$(CFLAGS) 16 | CPPFLAGS+=-stdlib=libc++ -std=c++11 17 | 18 | 19 | CPP_SOURCES = fakework.cpp demo_noui.cpp 20 | C_SOURCES = 21 | 22 | TARGET=demo_noui 23 | CC=clang 24 | CPP=clang++ 25 | LD=clang++ 26 | 27 | CPP_OBJS = $(patsubst %.cpp,%.o,$(CPP_SOURCES)) 28 | C_OBJS = $(patsubst %.c,%.o,$(C_SOURCES)) 29 | 30 | all: $(TARGET) 31 | 32 | $(TARGET): $(C_OBJS) $(CPP_OBJS) 33 | $(LD) -o $(TARGET) $(C_OBJS) $(CPP_OBJS) $(LDFLAGS) $(CPPFLAGS) 34 | 35 | -include .depend 36 | 37 | .cpp.o: 38 | $(CPP) -c $< $(CPPFLAGS) -o $@ 39 | 40 | .c.o: 41 | $(CC) -c $< $(CFLAGS) -o $@ 42 | 43 | 44 | clean: depend 45 | rm *.o $(TARGET) 46 | 47 | depend: $(CPP_SOURCES) $(C_SOURCES) 48 | $(CPP) -MM $(CPPFLAGS) $(CPP_SOURCES) >> .depend 49 | 50 | embed_target: 51 | cd ../../src && make 52 | 53 | embed: embed_target all 54 | 55 | 56 | -------------------------------------------------------------------------------- /demo/noui/demo_noui.cpp: -------------------------------------------------------------------------------- 1 | // This is free and unencumbered software released into the public domain. 2 | // Anyone is free to copy, modify, publish, use, compile, sell, or 3 | // distribute this software, either in source code form or as a compiled 4 | // binary, for any purpose, commercial or non-commercial, and by any 5 | // means. 6 | // In jurisdictions that recognize copyright laws, the author or authors 7 | // of this software dedicate any and all copyright interest in the 8 | // software to the public domain. We make this dedication for the benefit 9 | // of the public at large and to the detriment of our heirs and 10 | // successors. We intend this dedication to be an overt act of 11 | // relinquishment in perpetuity of all present and future rights to this 12 | // software under copyright law. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 14 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 15 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 16 | // IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 17 | // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 18 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 19 | // OTHER DEALINGS IN THE SOFTWARE. 20 | // For more information, please refer to 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #if defined(__APPLE__) || defined(__linux__) 29 | #include 30 | #endif 31 | 32 | //generate zipped results 33 | #define MICROPROFILE_MINIZ 1 34 | #if MICROPROFILE_MINIZ 35 | #include "miniz.c" 36 | #endif 37 | 38 | 39 | 40 | #define MICROPROFILE_MAX_FRAME_HISTORY (2<<10) 41 | #define MICROPROFILE_IMPL 42 | #include "microprofile.h" 43 | 44 | MICROPROFILE_DEFINE(MAIN, "MAIN", "Main", 0xff0000); 45 | 46 | #ifdef _WIN32 47 | void usleep(__int64); 48 | #endif 49 | uint32_t g_nQuit = 0; 50 | 51 | void StartFakeWork(); 52 | void StopFakeWork(); 53 | 54 | #define DUMP_SPIKE_TEST 0 55 | 56 | MICROPROFILE_DECLARE_LOCAL_ATOMIC_COUNTER(ThreadsStarted); 57 | MICROPROFILE_DEFINE_LOCAL_ATOMIC_COUNTER(ThreadSpinSleep, "/runtime/spin_sleep"); 58 | MICROPROFILE_DECLARE_LOCAL_COUNTER(LocalCounter); 59 | int main(int argc, char* argv[]) 60 | { 61 | MicroProfileOnThreadCreate("Main"); 62 | printf("press ctrl-c to quit\n"); 63 | 64 | //turn on profiling 65 | MicroProfileSetForceEnable(true); 66 | MicroProfileSetEnableAllGroups(true); 67 | MicroProfileSetForceMetaCounters(true); 68 | 69 | MicroProfileStartContextSwitchTrace(); 70 | 71 | MICROPROFILE_COUNTER_CONFIG("/runtime/localcounter", MICROPROFILE_COUNTER_FORMAT_BYTES, 500, 0); 72 | 73 | MICROPROFILE_COUNTER_ADD("memory/main", 1000); 74 | MICROPROFILE_COUNTER_ADD("memory/gpu/vertexbuffers", 1000); 75 | MICROPROFILE_COUNTER_ADD("memory/gpu/indexbuffersxsxsxsxsxsxsxxsxsxsxs", 200); 76 | MICROPROFILE_COUNTER_ADD("memory//main", 1000); 77 | MICROPROFILE_COUNTER_ADD("memory//", 1000); 78 | MICROPROFILE_COUNTER_ADD("//memory//mainx/\\//", 1000); 79 | MICROPROFILE_COUNTER_ADD("//memoryx//mainx/", 1000); 80 | MICROPROFILE_COUNTER_ADD("//memoryy//main/", 1000); 81 | MICROPROFILE_COUNTER_ADD("//memory//main0/", 1000); 82 | MICROPROFILE_COUNTER_ADD("//memory//main1/", 1000); 83 | MICROPROFILE_COUNTER_ADD("//memory//main2/", 1000); 84 | MICROPROFILE_COUNTER_ADD("//memory//main3/", 1000); 85 | MICROPROFILE_COUNTER_ADD("//memory//main4/", 1000); 86 | MICROPROFILE_COUNTER_ADD("//memory//main5/", 1000); 87 | MICROPROFILE_COUNTER_ADD("//memory//main6/", 1000); 88 | MICROPROFILE_COUNTER_ADD("//memory//main7/", 1000); 89 | MICROPROFILE_COUNTER_ADD("//memory//main8/", 1000); 90 | MICROPROFILE_COUNTER_ADD("//memory//main9/", 1000); 91 | MICROPROFILE_COUNTER_ADD("//\\\\///lala////lelel", 1000); 92 | 93 | 94 | #if DUMP_SPIKE_TEST 95 | MicroProfileDumpFile("spike.html", "spike.csv", 200.f, -1.f); 96 | #endif 97 | 98 | StartFakeWork(); 99 | while(!g_nQuit) 100 | { 101 | MICROPROFILE_SCOPE(MAIN); 102 | { 103 | usleep(16000); 104 | } 105 | MICROPROFILE_COUNTER_LOCAL_ADD(LocalCounter, 3); 106 | MICROPROFILE_COUNTER_LOCAL_SUB(LocalCounter, 1); 107 | MicroProfileFlip(0); 108 | static bool once = false; 109 | if(!once) 110 | { 111 | 112 | once = 1; 113 | printf("open localhost:%d in chrome to capture profile data\n", MicroProfileWebServerPort()); 114 | } 115 | 116 | #if DUMP_SPIKE_TEST 117 | static int nCounter = 0; 118 | if(nCounter < 200) 119 | { 120 | printf("\r%5d/200", nCounter++); 121 | fflush(stdout); 122 | if(nCounter == 200) 123 | { 124 | printf("\nsleeping 1s\n"); 125 | MICROPROFILE_SCOPEI("SPIKE_TEST", "Test", 0xff00ff00); 126 | usleep(1000*1000); 127 | printf("sleep done, spike.html should be saved in 5 frames\n"); 128 | } 129 | } 130 | #endif 131 | 132 | 133 | MICROPROFILE_COUNTER_LOCAL_UPDATE_ADD(ThreadsStarted); 134 | MICROPROFILE_COUNTER_LOCAL_UPDATE_SET(ThreadSpinSleep); 135 | MICROPROFILE_COUNTER_LOCAL_UPDATE_ADD(LocalCounter); 136 | 137 | } 138 | 139 | StopFakeWork(); 140 | 141 | MicroProfileShutdown(); 142 | 143 | return 0; 144 | } 145 | 146 | MICROPROFILE_DEFINE_LOCAL_COUNTER(LocalCounter, "/runtime/localcounter"); 147 | -------------------------------------------------------------------------------- /demo/noui/fakework.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "microprofile.h" 4 | 5 | 6 | #if defined(__APPLE__) || defined(__linux__) 7 | #include 8 | #endif 9 | 10 | extern uint32_t g_nQuit; 11 | 12 | #ifdef _WIN32 13 | #undef near 14 | #undef far 15 | #define snprintf _snprintf 16 | #include 17 | void usleep(__int64 usec) 18 | { 19 | if(usec > 20000) 20 | { 21 | Sleep((DWORD)(usec/1000)); 22 | } 23 | else if(usec >= 1000) 24 | { 25 | timeBeginPeriod(1); 26 | Sleep((DWORD)(usec/1000)); 27 | timeEndPeriod(1); 28 | } 29 | else 30 | { 31 | __int64 time1 = 0, time2 = 0, freq = 0; 32 | QueryPerformanceCounter((LARGE_INTEGER *) &time1); 33 | QueryPerformanceFrequency((LARGE_INTEGER *)&freq); 34 | 35 | do { 36 | QueryPerformanceCounter((LARGE_INTEGER *) &time2); 37 | } while((time2-time1)*1000000ll/freq < usec); 38 | } 39 | } 40 | #endif 41 | 42 | 43 | MICROPROFILE_DEFINE_LOCAL_ATOMIC_COUNTER(ThreadsStarted, "/runtime/threadsstarted"); 44 | MICROPROFILE_DECLARE_LOCAL_ATOMIC_COUNTER(ThreadSpinSleep); 45 | 46 | MICROPROFILE_DECLARE(ThreadSafeMain); 47 | MICROPROFILE_DECLARE(ThreadSafeInner0); 48 | MICROPROFILE_DECLARE(ThreadSafeInner1); 49 | MICROPROFILE_DECLARE(ThreadSafeInner2); 50 | MICROPROFILE_DECLARE(ThreadSafeInner3); 51 | MICROPROFILE_DECLARE(ThreadSafeInner4); 52 | MICROPROFILE_DEFINE(ThreadSafeInner4,"ThreadSafe", "Inner4", 0xff00ff00); 53 | MICROPROFILE_DEFINE(ThreadSafeInner3,"ThreadSafe", "Inner3", 0xff773744); 54 | MICROPROFILE_DEFINE(ThreadSafeInner2,"ThreadSafe", "Inner2", 0xff990055); 55 | MICROPROFILE_DEFINE(ThreadSafeInner1,"ThreadSafe", "Inner1", 0xffaa00aa); 56 | MICROPROFILE_DEFINE(ThreadSafeInner0,"ThreadSafe", "Inner0", 0xff00bbee); 57 | MICROPROFILE_DEFINE(ThreadSafeMain,"ThreadSafe", "Main", 0xffdd3355); 58 | 59 | 60 | void spinsleep(int64_t nUs) 61 | { 62 | MICROPROFILE_COUNTER_LOCAL_ADD(ThreadSpinSleep, 1); 63 | MICROPROFILE_SCOPEI("spin","sleep", 0xffff); 64 | #if MICROPROFILE_ENABLED 65 | float fToMs = MicroProfileTickToMsMultiplier(MicroProfileTicksPerSecondCpu()); 66 | int64_t nTickStart = MP_TICK(); 67 | float fElapsed = 0; 68 | float fTarget = nUs / 1000000.f; 69 | do 70 | { 71 | int64_t nTickEnd = MP_TICK(); 72 | fElapsed = (nTickEnd - nTickStart) * fToMs; 73 | 74 | }while(fElapsed < fTarget); 75 | #endif 76 | } 77 | 78 | void WorkerThreadLong(int threadId) 79 | { 80 | MICROPROFILE_COUNTER_LOCAL_ADD(ThreadsStarted, 1); 81 | uint32_t c0 = 0xff3399ff; 82 | uint32_t c1 = 0xffff99ff; 83 | char name[100]; 84 | snprintf(name, 99, "Worker_long%d", threadId); 85 | MicroProfileOnThreadCreate(&name[0]); 86 | while(!g_nQuit) 87 | { 88 | MICROPROFILE_SCOPEI("long", "outer 150ms", c0); 89 | MICROPROFILE_META_CPU("Sleep",100); 90 | usleep(100*1000); 91 | for(int i = 0; i < 10; ++i) 92 | { 93 | MICROPROFILE_SCOPEI("long", "inner 5ms", c1); 94 | MICROPROFILE_META_CPU("Sleep",5); 95 | usleep(5000); 96 | } 97 | } 98 | } 99 | 100 | void WorkerThread(int threadId) 101 | { 102 | MICROPROFILE_COUNTER_LOCAL_ADD(ThreadsStarted, 1); 103 | 104 | char name[100]; 105 | snprintf(name, 99, "Worker%d", threadId); 106 | MicroProfileOnThreadCreate(&name[0]); 107 | uint32_t c0 = 0xff3399ff; 108 | uint32_t c1 = 0xffff99ff; 109 | uint32_t c2 = 0xff33ff00; 110 | uint32_t c3 = 0xff3399ff; 111 | uint32_t c4 = 0xff33ff33; 112 | while(!g_nQuit) 113 | { 114 | switch(threadId) 115 | { 116 | case 0: 117 | { 118 | usleep(100); 119 | { 120 | MICROPROFILE_SCOPEI("Thread0", "Work Thread0", c4); 121 | MICROPROFILE_META_CPU("Sleep",10); 122 | usleep(200); 123 | { 124 | MICROPROFILE_SCOPEI("Thread0", "Work Thread1", c3); 125 | MICROPROFILE_META_CPU("DrawCalls", 1); 126 | MICROPROFILE_META_CPU("DrawCalls", 1); 127 | MICROPROFILE_META_CPU("DrawCalls", 1); 128 | usleep(200); 129 | { 130 | MICROPROFILE_SCOPEI("Thread0", "Work Thread2", c2); 131 | MICROPROFILE_META_CPU("DrawCalls", 1); 132 | usleep(200); 133 | { 134 | MICROPROFILE_SCOPEI("Thread0", "Work Thread3", c1); 135 | MICROPROFILE_META_CPU("DrawCalls", 4); 136 | MICROPROFILE_META_CPU("Triangles",1000); 137 | usleep(200); 138 | } 139 | } 140 | } 141 | } 142 | } 143 | break; 144 | 145 | case 1: 146 | { 147 | usleep(100); 148 | MICROPROFILE_SCOPEI("Thread1", "Work Thread 1", c1); 149 | usleep(2000); 150 | } 151 | break; 152 | 153 | case 2: 154 | { 155 | usleep(1000); 156 | { 157 | MICROPROFILE_SCOPEI("Thread2", "Worker2", c0); 158 | spinsleep(100000); 159 | { 160 | MICROPROFILE_SCOPEI("Thread2", "InnerWork0", c1); 161 | spinsleep(100); 162 | { 163 | MICROPROFILE_SCOPEI("Thread2", "InnerWork1", c2); 164 | usleep(100); 165 | { 166 | MICROPROFILE_SCOPEI("Thread2", "InnerWork2", c3); 167 | usleep(100); 168 | { 169 | // for(uint32_t i = 0; i < 1000; ++i) 170 | // { 171 | // MICROPROFILE_SCOPEI("Thread2", "InnerWork3", c4); 172 | // spinsleep(10); 173 | // } 174 | } 175 | } 176 | } 177 | } 178 | } 179 | } 180 | break; 181 | case 3: 182 | { 183 | MICROPROFILE_SCOPEI("ThreadWork", "MAIN", c0); 184 | usleep(1000);; 185 | for(uint32_t i = 0; i < 10; ++i) 186 | { 187 | MICROPROFILE_SCOPEI("ThreadWork", "Inner0", c1); 188 | usleep(100); 189 | for(uint32_t j = 0; j < 4; ++j) 190 | { 191 | MICROPROFILE_SCOPEI("ThreadWork", "Inner1", c4); 192 | usleep(50); 193 | MICROPROFILE_SCOPEI("ThreadWork", "Inner1", c4); 194 | usleep(50); 195 | MICROPROFILE_SCOPEI("ThreadWork", "Inner2", c2); 196 | usleep(50); 197 | MICROPROFILE_SCOPEI("ThreadWork", "Inner3", c3); 198 | usleep(50); 199 | MICROPROFILE_SCOPEI("ThreadWork", "Inner4", c3); 200 | usleep(50); 201 | } 202 | } 203 | 204 | 205 | } 206 | break; 207 | default: 208 | 209 | MICROPROFILE_SCOPE(ThreadSafeMain); 210 | usleep(1000);; 211 | for(uint32_t i = 0; i < 5; ++i) 212 | { 213 | MICROPROFILE_SCOPE(ThreadSafeInner0); 214 | usleep(1000); 215 | for(uint32_t j = 0; j < 4; ++j) 216 | { 217 | MICROPROFILE_META_CPU("custom_very_long_meta", 1); 218 | MICROPROFILE_SCOPE(ThreadSafeInner1); 219 | usleep(500); 220 | MICROPROFILE_SCOPE(ThreadSafeInner2); 221 | usleep(150); 222 | MICROPROFILE_SCOPE(ThreadSafeInner3); 223 | usleep(150); 224 | MICROPROFILE_SCOPE(ThreadSafeInner4); 225 | usleep(150); 226 | } 227 | } 228 | break; 229 | } 230 | } 231 | 232 | } 233 | 234 | std::thread t0; 235 | std::thread t1; 236 | std::thread t2; 237 | std::thread t3; 238 | std::thread t42; 239 | std::thread t43; 240 | std::thread t44; 241 | std::thread t45; 242 | std::thread tlong; 243 | 244 | void StartFakeWork() 245 | { 246 | t0 = std::thread(WorkerThread, 0); 247 | t1 = std::thread(WorkerThread, 1); 248 | t2 = std::thread(WorkerThread, 2); 249 | t3 = std::thread(WorkerThread, 3); 250 | t42 = std::thread(WorkerThread, 42); 251 | t43 = std::thread(WorkerThread, 43); 252 | t44 = std::thread(WorkerThread, 44); 253 | t45 = std::thread(WorkerThread, 45); 254 | tlong = std::thread(WorkerThreadLong, 0); 255 | } 256 | void StopFakeWork() 257 | { 258 | t0.join(); 259 | t1.join(); 260 | t2.join(); 261 | t3.join(); 262 | t42.join(); 263 | t43.join(); 264 | t44.join(); 265 | t45.join(); 266 | tlong.join(); 267 | } -------------------------------------------------------------------------------- /demo/noui/noui.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {D60DFD55-B1FB-4A27-8635-CF66B68AD288} 23 | Win32Proj 24 | noui 25 | 8.1 26 | 27 | 28 | 29 | Application 30 | true 31 | v140 32 | MultiByte 33 | 34 | 35 | Application 36 | false 37 | v140 38 | true 39 | MultiByte 40 | 41 | 42 | Application 43 | true 44 | v140 45 | MultiByte 46 | 47 | 48 | Application 49 | false 50 | v140 51 | true 52 | MultiByte 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | true 74 | 75 | 76 | true 77 | 78 | 79 | false 80 | 81 | 82 | false 83 | 84 | 85 | 86 | 87 | 88 | Level3 89 | Disabled 90 | MICROPROFILE_ENABLED=1;MICROPROFILE_GPU_TIMERS=0;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) 91 | true 92 | ../.. 93 | 94 | 95 | Console 96 | true 97 | Advapi32.lib;ws2_32.lib;winmm.lib;Shell32.lib 98 | 99 | 100 | copy ..\..\bin\microprofile-win32-cswitch_$(PlatformTarget).exe $(ProjectDir) 101 | 102 | 103 | 104 | 105 | 106 | 107 | Level3 108 | Disabled 109 | MICROPROFILE_ENABLED=1;MICROPROFILE_GPU_TIMERS=0;_CRT_SECURE_NO_WARNINGS;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) 110 | true 111 | ../.. 112 | 113 | 114 | Console 115 | true 116 | Advapi32.lib;ws2_32.lib;winmm.lib;Shell32.lib 117 | 118 | 119 | copy ..\..\bin\microprofile-win32-cswitch_$(PlatformTarget).exe $(ProjectDir) 120 | 121 | 122 | 123 | 124 | Level3 125 | 126 | 127 | MaxSpeed 128 | true 129 | true 130 | MICROPROFILE_ENABLED=1;MICROPROFILE_GPU_TIMERS=0;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) 131 | true 132 | ../.. 133 | 134 | 135 | Console 136 | true 137 | true 138 | true 139 | Advapi32.lib;ws2_32.lib;winmm.lib;Shell32.lib 140 | 141 | 142 | copy ..\..\bin\microprofile-win32-cswitch_$(PlatformTarget).exe $(ProjectDir) 143 | 144 | 145 | 146 | 147 | Level3 148 | 149 | 150 | MaxSpeed 151 | true 152 | true 153 | MICROPROFILE_ENABLED=1;MICROPROFILE_GPU_TIMERS=0;_CRT_SECURE_NO_WARNINGS;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) 154 | true 155 | ../.. 156 | 157 | 158 | Console 159 | true 160 | true 161 | true 162 | Advapi32.lib;ws2_32.lib;winmm.lib;Shell32.lib 163 | 164 | 165 | copy ..\..\bin\microprofile-win32-cswitch_$(PlatformTarget).exe $(ProjectDir) 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | -------------------------------------------------------------------------------- /demo/noui/noui.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /demo/noui_d3d11/Tutorial02.fx: -------------------------------------------------------------------------------- 1 | //-------------------------------------------------------------------------------------- 2 | // File: Tutorial02.fx 3 | // 4 | // Copyright (c) Microsoft Corporation. All rights reserved. 5 | //-------------------------------------------------------------------------------------- 6 | 7 | //-------------------------------------------------------------------------------------- 8 | // Vertex Shader 9 | //-------------------------------------------------------------------------------------- 10 | float4 VS( float4 Pos : POSITION ) : SV_POSITION 11 | { 12 | return Pos; 13 | } 14 | 15 | 16 | //-------------------------------------------------------------------------------------- 17 | // Pixel Shader 18 | //-------------------------------------------------------------------------------------- 19 | float4 PS( float4 Pos : SV_POSITION ) : SV_Target 20 | { 21 | float x = Pos.x; 22 | [branch] 23 | for(int i = 0; i < 100; ++i) 24 | { 25 | x = sin(x + i * 0.2); 26 | } 27 | return float4( x, 1.0f, 0.0f, 1.0f ); // Yellow, with Alpha = 1 28 | } 29 | -------------------------------------------------------------------------------- /demo/noui_d3d11/Tutorial02_PS.hlsl: -------------------------------------------------------------------------------- 1 | #include "Tutorial02.fx" 2 | -------------------------------------------------------------------------------- /demo/noui_d3d11/Tutorial02_VS.hlsl: -------------------------------------------------------------------------------- 1 | #include "Tutorial02.fx" 2 | -------------------------------------------------------------------------------- /demo/noui_d3d11/demo_noui_d3d11.cpp: -------------------------------------------------------------------------------- 1 | //Modified version of Microsoft d3d11 tutorial 2 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define MICROPROFILE_IMPL 9 | #define MICROPROFILE_GPU_TIMERS_D3D11 1 10 | #include "microprofile.h" 11 | uint32_t g_nQuit = 0; 12 | 13 | #include 14 | 15 | using namespace DirectX; 16 | struct SimpleVertex 17 | { 18 | XMFLOAT3 Pos; 19 | }; 20 | 21 | 22 | //-------------------------------------------------------------------------------------- 23 | // Global Variables 24 | //-------------------------------------------------------------------------------------- 25 | HINSTANCE g_hInst = nullptr; 26 | HWND g_hWnd = nullptr; 27 | D3D_DRIVER_TYPE g_driverType = D3D_DRIVER_TYPE_NULL; 28 | D3D_FEATURE_LEVEL g_featureLevel = D3D_FEATURE_LEVEL_11_0; 29 | ID3D11Device* g_pd3dDevice = nullptr; 30 | ID3D11Device1* g_pd3dDevice1 = nullptr; 31 | ID3D11DeviceContext* g_pImmediateContext = nullptr; 32 | ID3D11DeviceContext1* g_pImmediateContext1 = nullptr; 33 | IDXGISwapChain* g_pSwapChain = nullptr; 34 | IDXGISwapChain1* g_pSwapChain1 = nullptr; 35 | ID3D11RenderTargetView* g_pRenderTargetView = nullptr; 36 | ID3D11VertexShader* g_pVertexShader = nullptr; 37 | ID3D11PixelShader* g_pPixelShader = nullptr; 38 | ID3D11InputLayout* g_pVertexLayout = nullptr; 39 | ID3D11Buffer* g_pVertexBuffer = nullptr; 40 | 41 | 42 | //-------------------------------------------------------------------------------------- 43 | // Forward declarations 44 | //-------------------------------------------------------------------------------------- 45 | HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow ); 46 | HRESULT InitDevice(); 47 | void CleanupDevice(); 48 | LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM ); 49 | void Render(); 50 | 51 | void StartFakeWork(); 52 | void StopFakeWork(); 53 | 54 | int g_QueueGraphics = -1; 55 | int WINAPI WinMain( _In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow ) 56 | { 57 | UNREFERENCED_PARAMETER( hPrevInstance ); 58 | UNREFERENCED_PARAMETER( lpCmdLine ); 59 | 60 | if( FAILED( InitWindow( hInstance, nCmdShow ) ) ) 61 | return 0; 62 | 63 | if( FAILED( InitDevice() ) ) 64 | { 65 | CleanupDevice(); 66 | return 0; 67 | } 68 | MicroProfileOnThreadCreate("Main"); 69 | MicroProfileSetForceEnable(true); 70 | MicroProfileSetEnableAllGroups(true); 71 | MicroProfileSetForceMetaCounters(true); 72 | 73 | 74 | MicroProfileGpuInitD3D11(g_pd3dDevice, g_pImmediateContext); 75 | MicroProfileStartContextSwitchTrace(); 76 | StartFakeWork(); 77 | char buffer[256]; 78 | snprintf(buffer, sizeof(buffer)-1, "Webserver started in localhost:%d\n", MicroProfileWebServerPort()); 79 | OutputDebugStringA(buffer); 80 | 81 | 82 | 83 | // Main message loop 84 | MSG msg = {0}; 85 | while( WM_QUIT != msg.message ) 86 | { 87 | MICROPROFILE_SCOPEI("Main", "MessagePump", 0); 88 | if( PeekMessage( &msg, nullptr, 0, 0, PM_REMOVE ) ) 89 | { 90 | TranslateMessage( &msg ); 91 | DispatchMessage( &msg ); 92 | } 93 | else 94 | { 95 | Render(); 96 | } 97 | } 98 | 99 | CleanupDevice(); 100 | StopFakeWork(); 101 | 102 | return ( int )msg.wParam; 103 | } 104 | 105 | //-------------------------------------------------------------------------------------- 106 | // Register class and create window 107 | //-------------------------------------------------------------------------------------- 108 | HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow ) 109 | { 110 | // Register class 111 | WNDCLASSEX wcex; 112 | wcex.cbSize = sizeof( WNDCLASSEX ); 113 | wcex.style = CS_HREDRAW | CS_VREDRAW; 114 | wcex.lpfnWndProc = WndProc; 115 | wcex.cbClsExtra = 0; 116 | wcex.cbWndExtra = 0; 117 | wcex.hInstance = hInstance; 118 | wcex.hIcon = 0; 119 | wcex.hCursor = LoadCursor( nullptr, IDC_ARROW ); 120 | wcex.hbrBackground = ( HBRUSH )( COLOR_WINDOW + 1 ); 121 | wcex.lpszMenuName = nullptr; 122 | wcex.lpszClassName = "TutorialWindowClass"; 123 | wcex.hIconSm = 0; 124 | if( !RegisterClassEx( &wcex ) ) 125 | return E_FAIL; 126 | 127 | // Create window 128 | g_hInst = hInstance; 129 | RECT rc = { 0, 0, 800, 600 }; 130 | AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE ); 131 | g_hWnd = CreateWindow( "TutorialWindowClass", "Direct3D 11 Tutorial 2: Rendering a Triangle", 132 | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, 133 | CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, nullptr, nullptr, hInstance, 134 | nullptr ); 135 | if( !g_hWnd ) 136 | return E_FAIL; 137 | 138 | ShowWindow( g_hWnd, nCmdShow ); 139 | 140 | return S_OK; 141 | } 142 | 143 | 144 | //-------------------------------------------------------------------------------------- 145 | // Helper for compiling shaders with D3DCompile 146 | // 147 | // With VS 11, we could load up prebuilt .cso files instead... 148 | //-------------------------------------------------------------------------------------- 149 | HRESULT CompileShaderFromFile( WCHAR* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut ) 150 | { 151 | HRESULT hr = S_OK; 152 | 153 | DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS; 154 | #ifdef _DEBUG 155 | // Set the D3DCOMPILE_DEBUG flag to embed debug information in the shaders. 156 | // Setting this flag improves the shader debugging experience, but still allows 157 | // the shaders to be optimized and to run exactly the way they will run in 158 | // the release configuration of this program. 159 | dwShaderFlags |= D3DCOMPILE_DEBUG; 160 | 161 | // Disable optimizations to further improve shader debugging 162 | dwShaderFlags |= D3DCOMPILE_SKIP_OPTIMIZATION; 163 | #endif 164 | 165 | ID3DBlob* pErrorBlob = nullptr; 166 | hr = D3DCompileFromFile( szFileName, nullptr, nullptr, szEntryPoint, szShaderModel, 167 | dwShaderFlags, 0, ppBlobOut, &pErrorBlob ); 168 | if( FAILED(hr) ) 169 | { 170 | if( pErrorBlob ) 171 | { 172 | OutputDebugStringA( reinterpret_cast( pErrorBlob->GetBufferPointer() ) ); 173 | pErrorBlob->Release(); 174 | } 175 | return hr; 176 | } 177 | if( pErrorBlob ) pErrorBlob->Release(); 178 | 179 | return S_OK; 180 | } 181 | 182 | 183 | //-------------------------------------------------------------------------------------- 184 | // Create Direct3D device and swap chain 185 | //-------------------------------------------------------------------------------------- 186 | HRESULT InitDevice() 187 | { 188 | HRESULT hr = S_OK; 189 | 190 | RECT rc; 191 | GetClientRect( g_hWnd, &rc ); 192 | UINT width = rc.right - rc.left; 193 | UINT height = rc.bottom - rc.top; 194 | 195 | UINT createDeviceFlags = 0; 196 | #ifdef _DEBUG 197 | createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; 198 | #endif 199 | 200 | D3D_DRIVER_TYPE driverTypes[] = 201 | { 202 | D3D_DRIVER_TYPE_HARDWARE, 203 | D3D_DRIVER_TYPE_WARP, 204 | D3D_DRIVER_TYPE_REFERENCE, 205 | }; 206 | UINT numDriverTypes = ARRAYSIZE( driverTypes ); 207 | 208 | D3D_FEATURE_LEVEL featureLevels[] = 209 | { 210 | D3D_FEATURE_LEVEL_11_1, 211 | D3D_FEATURE_LEVEL_11_0, 212 | D3D_FEATURE_LEVEL_10_1, 213 | D3D_FEATURE_LEVEL_10_0, 214 | }; 215 | UINT numFeatureLevels = ARRAYSIZE( featureLevels ); 216 | 217 | for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ ) 218 | { 219 | g_driverType = driverTypes[driverTypeIndex]; 220 | hr = D3D11CreateDevice( nullptr, g_driverType, nullptr, createDeviceFlags, featureLevels, numFeatureLevels, 221 | D3D11_SDK_VERSION, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext ); 222 | 223 | if ( hr == E_INVALIDARG ) 224 | { 225 | // DirectX 11.0 platforms will not recognize D3D_FEATURE_LEVEL_11_1 so we need to retry without it 226 | hr = D3D11CreateDevice( nullptr, g_driverType, nullptr, createDeviceFlags, &featureLevels[1], numFeatureLevels - 1, 227 | D3D11_SDK_VERSION, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext ); 228 | } 229 | 230 | if( SUCCEEDED( hr ) ) 231 | break; 232 | } 233 | if( FAILED( hr ) ) 234 | return hr; 235 | 236 | // Obtain DXGI factory from device (since we used nullptr for pAdapter above) 237 | IDXGIFactory1* dxgiFactory = nullptr; 238 | { 239 | IDXGIDevice* dxgiDevice = nullptr; 240 | hr = g_pd3dDevice->QueryInterface( __uuidof(IDXGIDevice), reinterpret_cast(&dxgiDevice) ); 241 | if (SUCCEEDED(hr)) 242 | { 243 | IDXGIAdapter* adapter = nullptr; 244 | hr = dxgiDevice->GetAdapter(&adapter); 245 | if (SUCCEEDED(hr)) 246 | { 247 | hr = adapter->GetParent( __uuidof(IDXGIFactory1), reinterpret_cast(&dxgiFactory) ); 248 | adapter->Release(); 249 | } 250 | dxgiDevice->Release(); 251 | } 252 | } 253 | if (FAILED(hr)) 254 | return hr; 255 | 256 | // Create swap chain 257 | IDXGIFactory2* dxgiFactory2 = nullptr; 258 | hr = dxgiFactory->QueryInterface( __uuidof(IDXGIFactory2), reinterpret_cast(&dxgiFactory2) ); 259 | if ( dxgiFactory2 ) 260 | { 261 | // DirectX 11.1 or later 262 | hr = g_pd3dDevice->QueryInterface( __uuidof(ID3D11Device1), reinterpret_cast(&g_pd3dDevice1) ); 263 | if (SUCCEEDED(hr)) 264 | { 265 | (void) g_pImmediateContext->QueryInterface( __uuidof(ID3D11DeviceContext1), reinterpret_cast(&g_pImmediateContext1) ); 266 | } 267 | 268 | DXGI_SWAP_CHAIN_DESC1 sd; 269 | ZeroMemory(&sd, sizeof(sd)); 270 | sd.Width = width; 271 | sd.Height = height; 272 | sd.Format = DXGI_FORMAT_R8G8B8A8_UNORM; 273 | sd.SampleDesc.Count = 1; 274 | sd.SampleDesc.Quality = 0; 275 | sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; 276 | sd.BufferCount = 1; 277 | 278 | hr = dxgiFactory2->CreateSwapChainForHwnd( g_pd3dDevice, g_hWnd, &sd, nullptr, nullptr, &g_pSwapChain1 ); 279 | if (SUCCEEDED(hr)) 280 | { 281 | hr = g_pSwapChain1->QueryInterface( __uuidof(IDXGISwapChain), reinterpret_cast(&g_pSwapChain) ); 282 | } 283 | 284 | dxgiFactory2->Release(); 285 | } 286 | else 287 | { 288 | // DirectX 11.0 systems 289 | DXGI_SWAP_CHAIN_DESC sd; 290 | ZeroMemory(&sd, sizeof(sd)); 291 | sd.BufferCount = 1; 292 | sd.BufferDesc.Width = width; 293 | sd.BufferDesc.Height = height; 294 | sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; 295 | sd.BufferDesc.RefreshRate.Numerator = 60; 296 | sd.BufferDesc.RefreshRate.Denominator = 1; 297 | sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; 298 | sd.OutputWindow = g_hWnd; 299 | sd.SampleDesc.Count = 1; 300 | sd.SampleDesc.Quality = 0; 301 | sd.Windowed = TRUE; 302 | 303 | hr = dxgiFactory->CreateSwapChain( g_pd3dDevice, &sd, &g_pSwapChain ); 304 | } 305 | 306 | // Note this tutorial doesn't handle full-screen swapchains so we block the ALT+ENTER shortcut 307 | dxgiFactory->MakeWindowAssociation( g_hWnd, DXGI_MWA_NO_ALT_ENTER ); 308 | 309 | dxgiFactory->Release(); 310 | 311 | if (FAILED(hr)) 312 | return hr; 313 | 314 | // Create a render target view 315 | ID3D11Texture2D* pBackBuffer = nullptr; 316 | hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), reinterpret_cast( &pBackBuffer ) ); 317 | if( FAILED( hr ) ) 318 | return hr; 319 | 320 | hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, nullptr, &g_pRenderTargetView ); 321 | pBackBuffer->Release(); 322 | if( FAILED( hr ) ) 323 | return hr; 324 | 325 | g_pImmediateContext->OMSetRenderTargets( 1, &g_pRenderTargetView, nullptr ); 326 | 327 | // Setup the viewport 328 | D3D11_VIEWPORT vp; 329 | vp.Width = (FLOAT)width; 330 | vp.Height = (FLOAT)height; 331 | vp.MinDepth = 0.0f; 332 | vp.MaxDepth = 1.0f; 333 | vp.TopLeftX = 0; 334 | vp.TopLeftY = 0; 335 | g_pImmediateContext->RSSetViewports( 1, &vp ); 336 | 337 | // Compile the vertex shader 338 | ID3DBlob* pVSBlob = nullptr; 339 | hr = CompileShaderFromFile( L"Tutorial02.fx", "VS", "vs_4_0", &pVSBlob ); 340 | if( FAILED( hr ) ) 341 | { 342 | MessageBox( nullptr, 343 | "The FX file cannot be compiled. Please run this executable from the directory that contains the FX file.", "Error", MB_OK ); 344 | return hr; 345 | } 346 | 347 | // Create the vertex shader 348 | hr = g_pd3dDevice->CreateVertexShader( pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), nullptr, &g_pVertexShader ); 349 | if( FAILED( hr ) ) 350 | { 351 | pVSBlob->Release(); 352 | return hr; 353 | } 354 | 355 | // Define the input layout 356 | D3D11_INPUT_ELEMENT_DESC layout[] = 357 | { 358 | { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, 359 | }; 360 | UINT numElements = ARRAYSIZE( layout ); 361 | 362 | // Create the input layout 363 | hr = g_pd3dDevice->CreateInputLayout( layout, numElements, pVSBlob->GetBufferPointer(), 364 | pVSBlob->GetBufferSize(), &g_pVertexLayout ); 365 | pVSBlob->Release(); 366 | if( FAILED( hr ) ) 367 | return hr; 368 | 369 | // Set the input layout 370 | g_pImmediateContext->IASetInputLayout( g_pVertexLayout ); 371 | 372 | // Compile the pixel shader 373 | ID3DBlob* pPSBlob = nullptr; 374 | hr = CompileShaderFromFile( L"Tutorial02.fx", "PS", "ps_4_0", &pPSBlob ); 375 | if( FAILED( hr ) ) 376 | { 377 | MessageBox( nullptr, 378 | "The FX file cannot be compiled. Please run this executable from the directory that contains the FX file.", "Error", MB_OK ); 379 | return hr; 380 | } 381 | 382 | // Create the pixel shader 383 | hr = g_pd3dDevice->CreatePixelShader( pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), nullptr, &g_pPixelShader ); 384 | pPSBlob->Release(); 385 | if( FAILED( hr ) ) 386 | return hr; 387 | 388 | // Create vertex buffer 389 | SimpleVertex vertices[] = 390 | { 391 | XMFLOAT3( 0.0f, 0.5f, 0.5f ), 392 | XMFLOAT3( 0.5f, -0.5f, 0.5f ), 393 | XMFLOAT3( -0.5f, -0.5f, 0.5f ), 394 | }; 395 | D3D11_BUFFER_DESC bd; 396 | ZeroMemory( &bd, sizeof(bd) ); 397 | bd.Usage = D3D11_USAGE_DEFAULT; 398 | bd.ByteWidth = sizeof( SimpleVertex ) * 3; 399 | bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; 400 | bd.CPUAccessFlags = 0; 401 | D3D11_SUBRESOURCE_DATA InitData; 402 | ZeroMemory( &InitData, sizeof(InitData) ); 403 | InitData.pSysMem = vertices; 404 | hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pVertexBuffer ); 405 | if( FAILED( hr ) ) 406 | return hr; 407 | 408 | // Set vertex buffer 409 | UINT stride = sizeof( SimpleVertex ); 410 | UINT offset = 0; 411 | g_pImmediateContext->IASetVertexBuffers( 0, 1, &g_pVertexBuffer, &stride, &offset ); 412 | 413 | // Set primitive topology 414 | g_pImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); 415 | 416 | return S_OK; 417 | } 418 | 419 | 420 | //-------------------------------------------------------------------------------------- 421 | // Clean up the objects we've created 422 | //-------------------------------------------------------------------------------------- 423 | void CleanupDevice() 424 | { 425 | if( g_pImmediateContext ) g_pImmediateContext->ClearState(); 426 | 427 | if( g_pVertexBuffer ) g_pVertexBuffer->Release(); 428 | if( g_pVertexLayout ) g_pVertexLayout->Release(); 429 | if( g_pVertexShader ) g_pVertexShader->Release(); 430 | if( g_pPixelShader ) g_pPixelShader->Release(); 431 | if( g_pRenderTargetView ) g_pRenderTargetView->Release(); 432 | if( g_pSwapChain1 ) g_pSwapChain1->Release(); 433 | if( g_pSwapChain ) g_pSwapChain->Release(); 434 | if( g_pImmediateContext1 ) g_pImmediateContext1->Release(); 435 | if( g_pImmediateContext ) g_pImmediateContext->Release(); 436 | if( g_pd3dDevice1 ) g_pd3dDevice1->Release(); 437 | if( g_pd3dDevice ) g_pd3dDevice->Release(); 438 | } 439 | 440 | 441 | //-------------------------------------------------------------------------------------- 442 | // Called every time the application receives a message 443 | //-------------------------------------------------------------------------------------- 444 | LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) 445 | { 446 | PAINTSTRUCT ps; 447 | HDC hdc; 448 | 449 | switch( message ) 450 | { 451 | case WM_PAINT: 452 | hdc = BeginPaint( hWnd, &ps ); 453 | EndPaint( hWnd, &ps ); 454 | break; 455 | 456 | case WM_DESTROY: 457 | PostQuitMessage( 0 ); 458 | break; 459 | 460 | // Note that this tutorial does not handle resizing (WM_SIZE) requests, 461 | // so we created the window without the resize border. 462 | 463 | default: 464 | return DefWindowProc( hWnd, message, wParam, lParam ); 465 | } 466 | 467 | return 0; 468 | } 469 | 470 | void Render() 471 | { 472 | MICROPROFILE_SCOPEI("Main", "Render", 0); 473 | MICROPROFILE_SCOPEGPUI("Draw Total", 0xff00ff); 474 | { 475 | // Clear the back buffer 476 | g_pImmediateContext->ClearRenderTargetView( g_pRenderTargetView, Colors::MidnightBlue ); 477 | 478 | // Render a triangle 479 | g_pImmediateContext->VSSetShader( g_pVertexShader, nullptr, 0 ); 480 | g_pImmediateContext->PSSetShader( g_pPixelShader, nullptr, 0 ); 481 | 482 | { 483 | MICROPROFILE_SCOPEGPUI("Draw0", 0xff00ff); 484 | for(int i = 0; i < 50; ++i) 485 | { 486 | g_pImmediateContext->Draw( 3, 0 ); 487 | } 488 | } 489 | { 490 | MICROPROFILE_SCOPEGPUI("Draw15567567", 0xff00ff); 491 | for(int i = 0; i < 50; ++i) 492 | { 493 | MICROPROFILE_SCOPEGPUI("Draw_INNER", 0x00); 494 | g_pImmediateContext->Draw( 3, 0 ); 495 | } 496 | } 497 | 498 | // Present the information rendered to the back buffer to the front buffer (the screen) 499 | g_pSwapChain->Present( 0, 0 ); 500 | } 501 | 502 | MicroProfileFlip(0); 503 | 504 | } 505 | -------------------------------------------------------------------------------- /demo/noui_d3d11/fakework.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "microprofile.h" 4 | 5 | 6 | #if defined(__APPLE__) || defined(__linux__) 7 | #include 8 | #endif 9 | 10 | extern uint32_t g_nQuit; 11 | 12 | #ifdef _WIN32 13 | #undef near 14 | #undef far 15 | #define snprintf _snprintf 16 | #include 17 | void usleep(__int64 usec) 18 | { 19 | if(usec > 20000) 20 | { 21 | Sleep((DWORD)(usec/1000)); 22 | } 23 | else if(usec >= 1000) 24 | { 25 | timeBeginPeriod(1); 26 | Sleep((DWORD)(usec/1000)); 27 | timeEndPeriod(1); 28 | } 29 | else 30 | { 31 | __int64 time1 = 0, time2 = 0, freq = 0; 32 | QueryPerformanceCounter((LARGE_INTEGER *) &time1); 33 | QueryPerformanceFrequency((LARGE_INTEGER *)&freq); 34 | 35 | do { 36 | QueryPerformanceCounter((LARGE_INTEGER *) &time2); 37 | } while((time2-time1)*1000000ll/freq < usec); 38 | } 39 | } 40 | #endif 41 | 42 | 43 | void spinsleep(int64_t nUs) 44 | { 45 | MICROPROFILE_SCOPEI("spin","sleep", 0xffff); 46 | #if MICROPROFILE_ENABLED 47 | float fToMs = MicroProfileTickToMsMultiplier(MicroProfileTicksPerSecondCpu()); 48 | int64_t nTickStart = MP_TICK(); 49 | float fElapsed = 0; 50 | float fTarget = nUs / 1000000.f; 51 | do 52 | { 53 | int64_t nTickEnd = MP_TICK(); 54 | fElapsed = (nTickEnd - nTickStart) * fToMs; 55 | 56 | }while(fElapsed < fTarget); 57 | #endif 58 | } 59 | 60 | MICROPROFILE_DECLARE(ThreadSafeMain); 61 | MICROPROFILE_DECLARE(ThreadSafeInner0); 62 | MICROPROFILE_DECLARE(ThreadSafeInner1); 63 | MICROPROFILE_DECLARE(ThreadSafeInner2); 64 | MICROPROFILE_DECLARE(ThreadSafeInner3); 65 | MICROPROFILE_DECLARE(ThreadSafeInner4); 66 | MICROPROFILE_DEFINE(ThreadSafeInner4,"ThreadSafe", "Inner4", 0xff00ff00); 67 | MICROPROFILE_DEFINE(ThreadSafeInner3,"ThreadSafe", "Inner3", 0xff773744); 68 | MICROPROFILE_DEFINE(ThreadSafeInner2,"ThreadSafe", "Inner2", 0xff990055); 69 | MICROPROFILE_DEFINE(ThreadSafeInner1,"ThreadSafe", "Inner1", 0xffaa00aa); 70 | MICROPROFILE_DEFINE(ThreadSafeInner0,"ThreadSafe", "Inner0", 0xff00bbee); 71 | MICROPROFILE_DEFINE(ThreadSafeMain,"ThreadSafe", "Main", 0xffdd3355); 72 | 73 | 74 | 75 | void WorkerThreadLong(int threadId) 76 | { 77 | uint32_t c0 = 0xff3399ff; 78 | uint32_t c1 = 0xffff99ff; 79 | char name[100]; 80 | snprintf(name, 99, "Worker_long%d", threadId); 81 | MicroProfileOnThreadCreate(&name[0]); 82 | while(!g_nQuit) 83 | { 84 | MICROPROFILE_SCOPEI("long", "outer 150ms", c0); 85 | MICROPROFILE_META_CPU("Sleep",100); 86 | usleep(100*1000); 87 | for(int i = 0; i < 10; ++i) 88 | { 89 | MICROPROFILE_SCOPEI("long", "inner 5ms", c1); 90 | MICROPROFILE_META_CPU("Sleep",5); 91 | usleep(5000); 92 | } 93 | } 94 | } 95 | 96 | void WorkerThread(int threadId) 97 | { 98 | char name[100]; 99 | snprintf(name, 99, "Worker%d", threadId); 100 | MicroProfileOnThreadCreate(&name[0]); 101 | uint32_t c0 = 0xff3399ff; 102 | uint32_t c1 = 0xffff99ff; 103 | uint32_t c2 = 0xff33ff00; 104 | uint32_t c3 = 0xff3399ff; 105 | uint32_t c4 = 0xff33ff33; 106 | while(!g_nQuit) 107 | { 108 | switch(threadId) 109 | { 110 | case 0: 111 | { 112 | usleep(100); 113 | { 114 | MICROPROFILE_SCOPEI("Thread0", "Work Thread0", c4); 115 | MICROPROFILE_META_CPU("Sleep",10); 116 | usleep(200); 117 | { 118 | MICROPROFILE_SCOPEI("Thread0", "Work Thread1", c3); 119 | MICROPROFILE_META_CPU("DrawCalls", 1); 120 | MICROPROFILE_META_CPU("DrawCalls", 1); 121 | MICROPROFILE_META_CPU("DrawCalls", 1); 122 | usleep(200); 123 | { 124 | MICROPROFILE_SCOPEI("Thread0", "Work Thread2", c2); 125 | MICROPROFILE_META_CPU("DrawCalls", 1); 126 | usleep(200); 127 | { 128 | MICROPROFILE_SCOPEI("Thread0", "Work Thread3", c1); 129 | MICROPROFILE_META_CPU("DrawCalls", 4); 130 | MICROPROFILE_META_CPU("Triangles",1000); 131 | usleep(200); 132 | } 133 | } 134 | } 135 | } 136 | } 137 | break; 138 | 139 | case 1: 140 | { 141 | usleep(100); 142 | MICROPROFILE_SCOPEI("Thread1", "Work Thread 1", c1); 143 | usleep(2000); 144 | } 145 | break; 146 | 147 | case 2: 148 | { 149 | usleep(1000); 150 | { 151 | MICROPROFILE_SCOPEI("Thread2", "Worker2", c0); 152 | spinsleep(100000); 153 | { 154 | MICROPROFILE_SCOPEI("Thread2", "InnerWork0", c1); 155 | spinsleep(100); 156 | { 157 | MICROPROFILE_SCOPEI("Thread2", "InnerWork1", c2); 158 | usleep(100); 159 | { 160 | MICROPROFILE_SCOPEI("Thread2", "InnerWork2", c3); 161 | usleep(100); 162 | { 163 | MICROPROFILE_SCOPEI("Thread2", "InnerWork3", c4); 164 | spinsleep(50000); 165 | } 166 | } 167 | } 168 | } 169 | } 170 | } 171 | break; 172 | case 3: 173 | { 174 | MICROPROFILE_SCOPEI("ThreadWork", "MAIN", c0); 175 | usleep(1000);; 176 | for(uint32_t i = 0; i < 10; ++i) 177 | { 178 | MICROPROFILE_SCOPEI("ThreadWork", "Inner0", c1); 179 | usleep(100); 180 | for(uint32_t j = 0; j < 4; ++j) 181 | { 182 | MICROPROFILE_SCOPEI("ThreadWork", "Inner1", c4); 183 | usleep(50); 184 | MICROPROFILE_SCOPEI("ThreadWork", "Inner2", c2); 185 | usleep(50); 186 | MICROPROFILE_SCOPEI("ThreadWork", "Inner3", c3); 187 | usleep(50); 188 | MICROPROFILE_SCOPEI("ThreadWork", "Inner4", c3); 189 | usleep(50); 190 | } 191 | } 192 | 193 | 194 | } 195 | break; 196 | default: 197 | 198 | MICROPROFILE_SCOPE(ThreadSafeMain); 199 | usleep(1000);; 200 | for(uint32_t i = 0; i < 5; ++i) 201 | { 202 | MICROPROFILE_SCOPE(ThreadSafeInner0); 203 | usleep(1000); 204 | for(uint32_t j = 0; j < 4; ++j) 205 | { 206 | MICROPROFILE_META_CPU("custom_very_long_meta", 1); 207 | MICROPROFILE_SCOPE(ThreadSafeInner1); 208 | usleep(500); 209 | MICROPROFILE_SCOPE(ThreadSafeInner2); 210 | usleep(150); 211 | MICROPROFILE_SCOPE(ThreadSafeInner3); 212 | usleep(150); 213 | MICROPROFILE_SCOPE(ThreadSafeInner4); 214 | usleep(150); 215 | } 216 | } 217 | break; 218 | } 219 | } 220 | } 221 | 222 | std::thread t0; 223 | std::thread t1; 224 | std::thread t2; 225 | std::thread t3; 226 | std::thread t42; 227 | std::thread t43; 228 | std::thread t44; 229 | std::thread t45; 230 | std::thread tlong; 231 | 232 | void StartFakeWork() 233 | { 234 | t0 = std::thread(WorkerThread, 0); 235 | t1 = std::thread(WorkerThread, 1); 236 | t2 = std::thread(WorkerThread, 2); 237 | t3 = std::thread(WorkerThread, 3); 238 | t42 = std::thread(WorkerThread, 42); 239 | t43 = std::thread(WorkerThread, 43); 240 | t44 = std::thread(WorkerThread, 44); 241 | t45 = std::thread(WorkerThread, 45); 242 | tlong = std::thread(WorkerThreadLong, 0); 243 | } 244 | void StopFakeWork() 245 | { 246 | t0.join(); 247 | t1.join(); 248 | t2.join(); 249 | t3.join(); 250 | t42.join(); 251 | t43.join(); 252 | t44.join(); 253 | t45.join(); 254 | tlong.join(); 255 | } -------------------------------------------------------------------------------- /demo/noui_d3d11/noui_d3d11.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {5EDFD505-4ADD-44D3-9DAE-E67F4CD6CB18} 23 | Win32Proj 24 | noui_d3d11 25 | 8.1 26 | 27 | 28 | 29 | Application 30 | true 31 | v140 32 | MultiByte 33 | 34 | 35 | Application 36 | false 37 | v140 38 | true 39 | MultiByte 40 | 41 | 42 | Application 43 | true 44 | v140 45 | MultiByte 46 | 47 | 48 | Application 49 | false 50 | v140 51 | true 52 | MultiByte 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | true 74 | 75 | 76 | true 77 | 78 | 79 | false 80 | 81 | 82 | false 83 | 84 | 85 | 86 | 87 | 88 | Level3 89 | Disabled 90 | MICROPROFILE_ENABLED=1;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) 91 | ..\.. 92 | 93 | 94 | Windows 95 | true 96 | winmm.lib;d3dcompiler.lib;d3d11.lib;dxguid.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 97 | 98 | 99 | copy ..\..\bin\microprofile-win32-cswitch_$(PlatformTarget).exe $(ProjectDir) 100 | 101 | 102 | 103 | 104 | 105 | 106 | Level3 107 | Disabled 108 | MICROPROFILE_ENABLED=1;_CRT_SECURE_NO_WARNINGS;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) 109 | ..\.. 110 | 111 | 112 | Windows 113 | true 114 | dxguid.lib;Ws2_32.lib;d3d11.lib;d3dcompiler.lib;dxgi.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 115 | 116 | 117 | copy ..\..\bin\microprofile-win32-cswitch_$(PlatformTarget).exe $(ProjectDir) 118 | 119 | 120 | 121 | 122 | Level3 123 | 124 | 125 | MaxSpeed 126 | true 127 | true 128 | MICROPROFILE_ENABLED=1;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) 129 | ..\.. 130 | 131 | 132 | Windows 133 | true 134 | true 135 | true 136 | winmm.lib;d3dcompiler.lib;d3d11.lib;dxguid.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 137 | 138 | 139 | copy ..\..\bin\microprofile-win32-cswitch_$(PlatformTarget).exe $(ProjectDir) 140 | 141 | 142 | 143 | 144 | Level3 145 | 146 | 147 | MaxSpeed 148 | true 149 | true 150 | MICROPROFILE_ENABLED=1;_CRT_SECURE_NO_WARNINGS;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) 151 | ..\.. 152 | 153 | 154 | Windows 155 | true 156 | true 157 | true 158 | dxguid.lib;Ws2_32.lib;d3d11.lib;d3dcompiler.lib;dxgi.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 159 | 160 | 161 | copy ..\..\bin\microprofile-win32-cswitch_$(PlatformTarget).exe $(ProjectDir) 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | -------------------------------------------------------------------------------- /demo/noui_d3d11/noui_d3d11.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /demo/noui_d3d12/noui_d3d12.cpp: -------------------------------------------------------------------------------- 1 | //based on D3D12HelloTriangle.cpp from MS dx12 graphics samples 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "d3dx12.h" 8 | 9 | #include 10 | #include 11 | 12 | #define MICROPROFILE_GPU_TIMERS_D3D12 13 | #define MICROPROFILE_IMPL 14 | #include "microprofile.h" 15 | 16 | 17 | //hack to make it work with the weird object oriented design of the sample 18 | ID3D12Device* g_pDevice = 0; 19 | ID3D12CommandQueue* g_pCommandQueue = 0; 20 | int g_QueueGraphics = -1; 21 | 22 | 23 | inline void ThrowIfFailed(HRESULT hr) 24 | { 25 | if (FAILED(hr)) 26 | { 27 | throw; 28 | } 29 | } 30 | 31 | inline void GetAssetsPath(_Out_writes_(pathSize) CHAR* path, UINT pathSize) 32 | { 33 | if (path == nullptr) 34 | { 35 | throw; 36 | } 37 | 38 | DWORD size = GetModuleFileName(nullptr, path, pathSize); 39 | 40 | if (size == 0 || size == pathSize) 41 | { 42 | // Method failed or path was truncated. 43 | throw; 44 | } 45 | 46 | CHAR* lastSlash = strrchr(path, L'\\'); 47 | if (lastSlash) 48 | { 49 | *(lastSlash + 1) = NULL; 50 | } 51 | } 52 | 53 | inline HRESULT ReadDataFromFile(LPWSTR filename, byte** data, UINT* size) 54 | { 55 | using namespace Microsoft::WRL; 56 | 57 | CREATEFILE2_EXTENDED_PARAMETERS extendedParams = { 0 }; 58 | extendedParams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS); 59 | extendedParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL; 60 | extendedParams.dwFileFlags = FILE_FLAG_SEQUENTIAL_SCAN; 61 | extendedParams.dwSecurityQosFlags = SECURITY_ANONYMOUS; 62 | extendedParams.lpSecurityAttributes = nullptr; 63 | extendedParams.hTemplateFile = nullptr; 64 | 65 | Wrappers::FileHandle file( 66 | CreateFile2( 67 | filename, 68 | GENERIC_READ, 69 | FILE_SHARE_READ, 70 | OPEN_EXISTING, 71 | &extendedParams 72 | ) 73 | ); 74 | 75 | if (file.Get() == INVALID_HANDLE_VALUE) 76 | { 77 | throw new std::exception(); 78 | } 79 | 80 | FILE_STANDARD_INFO fileInfo = { 0 }; 81 | if (!GetFileInformationByHandleEx( 82 | file.Get(), 83 | FileStandardInfo, 84 | &fileInfo, 85 | sizeof(fileInfo) 86 | )) 87 | { 88 | throw new std::exception(); 89 | } 90 | 91 | if (fileInfo.EndOfFile.HighPart != 0) 92 | { 93 | throw new std::exception(); 94 | } 95 | 96 | *data = reinterpret_cast(malloc(fileInfo.EndOfFile.LowPart)); 97 | *size = fileInfo.EndOfFile.LowPart; 98 | 99 | if (!ReadFile( 100 | file.Get(), 101 | *data, 102 | fileInfo.EndOfFile.LowPart, 103 | nullptr, 104 | nullptr 105 | )) 106 | { 107 | throw new std::exception(); 108 | } 109 | 110 | return S_OK; 111 | } 112 | 113 | class DXSample 114 | { 115 | public: 116 | DXSample(UINT width, UINT height, std::string name); 117 | virtual ~DXSample(); 118 | 119 | int Run(HINSTANCE hInstance, int nCmdShow); 120 | void SetCustomWindowText(LPCSTR text); 121 | 122 | protected: 123 | virtual void OnInit() = 0; 124 | virtual void OnUpdate() = 0; 125 | virtual void OnRender() = 0; 126 | virtual void OnDestroy() = 0; 127 | virtual bool OnEvent(MSG msg) = 0; 128 | 129 | std::string GetAssetFullPath(LPCSTR assetName); 130 | void GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter); 131 | 132 | static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); 133 | 134 | // Viewport dimensions. 135 | UINT m_width; 136 | UINT m_height; 137 | float m_aspectRatio; 138 | 139 | // Window handle. 140 | HWND m_hwnd; 141 | 142 | // Adapter info. 143 | bool m_useWarpDevice; 144 | 145 | private: 146 | void ParseCommandLineArgs(); 147 | 148 | // Root assets path. 149 | std::string m_assetsPath; 150 | 151 | // Window title. 152 | std::string m_title; 153 | }; 154 | 155 | 156 | DXSample::DXSample(UINT width, UINT height, std::string name) : 157 | m_width(width), 158 | m_height(height), 159 | m_useWarpDevice(false) 160 | { 161 | ParseCommandLineArgs(); 162 | 163 | m_title = name + (m_useWarpDevice ? " (WARP)" : ""); 164 | 165 | CHAR assetsPath[512]; 166 | GetAssetsPath(assetsPath, _countof(assetsPath)); 167 | m_assetsPath = assetsPath; 168 | 169 | m_aspectRatio = static_cast(width) / static_cast(height); 170 | } 171 | 172 | DXSample::~DXSample() 173 | { 174 | } 175 | 176 | 177 | int DXSample::Run(HINSTANCE hInstance, int nCmdShow) 178 | { 179 | 180 | 181 | // Initialize the window class. 182 | WNDCLASSEX windowClass = { 0 }; 183 | windowClass.cbSize = sizeof(WNDCLASSEX); 184 | windowClass.style = CS_HREDRAW | CS_VREDRAW; 185 | windowClass.lpfnWndProc = WindowProc; 186 | windowClass.hInstance = hInstance; 187 | windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); 188 | windowClass.lpszClassName = "WindowClass1"; 189 | RegisterClassEx(&windowClass); 190 | 191 | RECT windowRect = { 0, 0, static_cast(m_width), static_cast(m_height) }; 192 | AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE); 193 | 194 | // Create the window and store a handle to it. 195 | m_hwnd = CreateWindowEx(NULL, 196 | "WindowClass1", 197 | m_title.c_str(), 198 | WS_OVERLAPPEDWINDOW, 199 | 300, 200 | 300, 201 | windowRect.right - windowRect.left, 202 | windowRect.bottom - windowRect.top, 203 | NULL, // We have no parent window, NULL. 204 | NULL, // We aren't using menus, NULL. 205 | hInstance, 206 | NULL); // We aren't using multiple windows, NULL. 207 | 208 | ShowWindow(m_hwnd, nCmdShow); 209 | 210 | // Initialize the sample. OnInit is defined in each child-implementation of DXSample. 211 | OnInit(); 212 | 213 | MicroProfileOnThreadCreate("Main"); 214 | MicroProfileSetForceEnable(true); 215 | MicroProfileSetEnableAllGroups(true); 216 | MicroProfileSetForceMetaCounters(true); 217 | MICROPROFILE_CONDITIONAL(g_QueueGraphics = MICROPROFILE_GPU_INIT_QUEUE("GPU-Graphics-Queue")); 218 | MicroProfileGpuInitD3D12(g_pDevice, g_pCommandQueue); 219 | //MICROPROFILE_GPU_BEGIN(0, MicroProfileGetGlobaGpuThreadLog()); 220 | 221 | 222 | // Main sample loop. 223 | MSG msg = { 0 }; 224 | while (true) 225 | { 226 | // Process any messages in the queue. 227 | if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 228 | { 229 | TranslateMessage(&msg); 230 | DispatchMessage(&msg); 231 | 232 | if (msg.message == WM_QUIT) 233 | break; 234 | 235 | // Pass events into our sample. 236 | OnEvent(msg); 237 | } 238 | 239 | OnUpdate(); 240 | OnRender(); 241 | } 242 | 243 | OnDestroy(); 244 | MicroProfileGpuShutdown(); 245 | // Return this part of the WM_QUIT message to Windows. 246 | return static_cast(msg.wParam); 247 | } 248 | 249 | // Helper function for resolving the full path of assets. 250 | std::string DXSample::GetAssetFullPath(LPCSTR assetName) 251 | { 252 | return m_assetsPath + assetName; 253 | } 254 | 255 | // Helper function for acquiring the first available hardware adapter that supports Direct3D 12. 256 | // If no such adapter can be found, *ppAdapter will be set to nullptr. 257 | void DXSample::GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter) 258 | { 259 | IDXGIAdapter1* pAdapter = nullptr; 260 | *ppAdapter = nullptr; 261 | 262 | for (UINT adapterIndex = 0; DXGI_ERROR_NOT_FOUND != pFactory->EnumAdapters1(adapterIndex, &pAdapter); ++adapterIndex) 263 | { 264 | DXGI_ADAPTER_DESC1 desc; 265 | pAdapter->GetDesc1(&desc); 266 | 267 | if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) 268 | { 269 | // Don't select the Basic Render Driver adapter. 270 | // If you want a software adapter, pass in "/warp" on the command line. 271 | continue; 272 | } 273 | 274 | // Check to see if the adapter supports Direct3D 12, but don't create the 275 | // actual device yet. 276 | if (SUCCEEDED(D3D12CreateDevice(pAdapter, D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr))) 277 | { 278 | break; 279 | } 280 | } 281 | 282 | *ppAdapter = pAdapter; 283 | } 284 | 285 | // Helper function for setting the window's title text. 286 | void DXSample::SetCustomWindowText(LPCSTR text) 287 | { 288 | std::string windowText = m_title + ": " + text; 289 | SetWindowText(m_hwnd, windowText.c_str()); 290 | } 291 | 292 | // Helper function for parsing any supplied command line args. 293 | void DXSample::ParseCommandLineArgs() 294 | { 295 | int argc; 296 | LPWSTR *argv = CommandLineToArgvW(GetCommandLineW(), &argc); 297 | for (int i = 1; i < argc; ++i) 298 | { 299 | if (_wcsnicmp(argv[i], L"-warp", wcslen(argv[i])) == 0 || 300 | _wcsnicmp(argv[i], L"/warp", wcslen(argv[i])) == 0) 301 | { 302 | m_useWarpDevice = true; 303 | } 304 | } 305 | LocalFree(argv); 306 | } 307 | 308 | // Main message handler for the sample. 309 | LRESULT CALLBACK DXSample::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 310 | { 311 | // Handle destroy/shutdown messages. 312 | switch (message) 313 | { 314 | case WM_DESTROY: 315 | PostQuitMessage(0); 316 | return 0; 317 | } 318 | 319 | // Handle any messages the switch statement didn't. 320 | return DefWindowProc(hWnd, message, wParam, lParam); 321 | } 322 | 323 | 324 | using namespace DirectX; 325 | using namespace Microsoft::WRL; 326 | 327 | class D3D12HelloTriangle : public DXSample 328 | { 329 | public: 330 | D3D12HelloTriangle(UINT width, UINT height, std::string name); 331 | 332 | protected: 333 | virtual void OnInit(); 334 | virtual void OnUpdate(); 335 | virtual void OnRender(); 336 | virtual void OnDestroy(); 337 | virtual bool OnEvent(MSG msg); 338 | 339 | private: 340 | static const UINT FrameCount = 2; 341 | 342 | struct Vertex 343 | { 344 | XMFLOAT3 position; 345 | XMFLOAT4 color; 346 | }; 347 | 348 | // Pipeline objects. 349 | D3D12_VIEWPORT m_viewport; 350 | D3D12_RECT m_scissorRect; 351 | ComPtr m_swapChain; 352 | ComPtr m_device; 353 | ComPtr m_renderTargets[FrameCount]; 354 | ComPtr m_commandAllocator; 355 | ComPtr m_commandQueue; 356 | ComPtr m_rootSignature; 357 | ComPtr m_rtvHeap; 358 | ComPtr m_pipelineState; 359 | ComPtr m_commandList; 360 | UINT m_rtvDescriptorSize; 361 | 362 | // App resources. 363 | ComPtr m_vertexBuffer; 364 | D3D12_VERTEX_BUFFER_VIEW m_vertexBufferView; 365 | 366 | // Synchronization objects. 367 | UINT m_frameIndex; 368 | HANDLE m_fenceEvent; 369 | ComPtr m_fence; 370 | UINT64 m_fenceValue; 371 | 372 | void LoadPipeline(); 373 | void LoadAssets(); 374 | void PopulateCommandList(); 375 | void WaitForPreviousFrame(); 376 | }; 377 | 378 | 379 | 380 | D3D12HelloTriangle::D3D12HelloTriangle(UINT width, UINT height, std::string name) : 381 | DXSample(width, height, name), 382 | m_frameIndex(0), 383 | m_viewport(), 384 | m_scissorRect(), 385 | m_rtvDescriptorSize(0) 386 | { 387 | m_viewport.Width = static_cast(width); 388 | m_viewport.Height = static_cast(height); 389 | m_viewport.MaxDepth = 1.0f; 390 | 391 | m_scissorRect.right = static_cast(width); 392 | m_scissorRect.bottom = static_cast(height); 393 | } 394 | 395 | void D3D12HelloTriangle::OnInit() 396 | { 397 | LoadPipeline(); 398 | LoadAssets(); 399 | } 400 | 401 | // Load the rendering pipeline dependencies. 402 | void D3D12HelloTriangle::LoadPipeline() 403 | { 404 | #ifdef _DEBUG 405 | // Enable the D3D12 debug layer. 406 | { 407 | ComPtr debugController; 408 | if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController)))) 409 | { 410 | debugController->EnableDebugLayer(); 411 | } 412 | } 413 | #endif 414 | 415 | ComPtr factory; 416 | ThrowIfFailed(CreateDXGIFactory1(IID_PPV_ARGS(&factory))); 417 | 418 | if (m_useWarpDevice) 419 | { 420 | ComPtr warpAdapter; 421 | ThrowIfFailed(factory->EnumWarpAdapter(IID_PPV_ARGS(&warpAdapter))); 422 | 423 | ThrowIfFailed(D3D12CreateDevice( 424 | warpAdapter.Get(), 425 | D3D_FEATURE_LEVEL_11_0, 426 | IID_PPV_ARGS(&m_device) 427 | )); 428 | } 429 | else 430 | { 431 | ComPtr hardwareAdapter; 432 | GetHardwareAdapter(factory.Get(), &hardwareAdapter); 433 | 434 | ThrowIfFailed(D3D12CreateDevice( 435 | hardwareAdapter.Get(), 436 | D3D_FEATURE_LEVEL_11_0, 437 | IID_PPV_ARGS(&m_device) 438 | )); 439 | } 440 | g_pDevice = m_device.Get(); 441 | 442 | // Describe and create the command queue. 443 | D3D12_COMMAND_QUEUE_DESC queueDesc = {}; 444 | queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; 445 | queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; 446 | 447 | ThrowIfFailed(m_device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&m_commandQueue))); 448 | g_pCommandQueue = m_commandQueue.Get(); 449 | 450 | // Describe and create the swap chain. 451 | DXGI_SWAP_CHAIN_DESC swapChainDesc = {}; 452 | swapChainDesc.BufferCount = FrameCount; 453 | swapChainDesc.BufferDesc.Width = m_width; 454 | swapChainDesc.BufferDesc.Height = m_height; 455 | swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; 456 | swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; 457 | swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; 458 | swapChainDesc.OutputWindow = m_hwnd; 459 | swapChainDesc.SampleDesc.Count = 1; 460 | swapChainDesc.Windowed = TRUE; 461 | 462 | ComPtr swapChain; 463 | ThrowIfFailed(factory->CreateSwapChain( 464 | m_commandQueue.Get(), // Swap chain needs the queue so that it can force a flush on it. 465 | &swapChainDesc, 466 | &swapChain 467 | )); 468 | 469 | ThrowIfFailed(swapChain.As(&m_swapChain)); 470 | 471 | // This sample does not support fullscreen transitions. 472 | ThrowIfFailed(factory->MakeWindowAssociation(m_hwnd, DXGI_MWA_NO_ALT_ENTER)); 473 | 474 | m_frameIndex = m_swapChain->GetCurrentBackBufferIndex(); 475 | 476 | // Create descriptor heaps. 477 | { 478 | // Describe and create a render target view (RTV) descriptor heap. 479 | D3D12_DESCRIPTOR_HEAP_DESC rtvHeapDesc = {}; 480 | rtvHeapDesc.NumDescriptors = FrameCount; 481 | rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; 482 | rtvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; 483 | ThrowIfFailed(m_device->CreateDescriptorHeap(&rtvHeapDesc, IID_PPV_ARGS(&m_rtvHeap))); 484 | 485 | m_rtvDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); 486 | } 487 | 488 | // Create frame resources. 489 | { 490 | CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(m_rtvHeap->GetCPUDescriptorHandleForHeapStart()); 491 | 492 | // Create a RTV for each frame. 493 | for (UINT n = 0; n < FrameCount; n++) 494 | { 495 | ThrowIfFailed(m_swapChain->GetBuffer(n, IID_PPV_ARGS(&m_renderTargets[n]))); 496 | m_device->CreateRenderTargetView(m_renderTargets[n].Get(), nullptr, rtvHandle); 497 | rtvHandle.Offset(1, m_rtvDescriptorSize); 498 | } 499 | } 500 | 501 | ThrowIfFailed(m_device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&m_commandAllocator))); 502 | } 503 | 504 | // Load the sample assets. 505 | void D3D12HelloTriangle::LoadAssets() 506 | { 507 | // Create an empty root signature. 508 | { 509 | CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc; 510 | rootSignatureDesc.Init(0, nullptr, 0, nullptr, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); 511 | 512 | ComPtr signature; 513 | ComPtr error; 514 | ThrowIfFailed(D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error)); 515 | ThrowIfFailed(m_device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_rootSignature))); 516 | } 517 | 518 | // Create the pipeline state, which includes compiling and loading shaders. 519 | { 520 | ComPtr vertexShader; 521 | ComPtr pixelShader; 522 | 523 | #ifdef _DEBUG 524 | // Enable better shader debugging with the graphics debugging tools. 525 | UINT compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; 526 | #else 527 | UINT compileFlags = 0; 528 | #endif 529 | 530 | ThrowIfFailed(D3DCompileFromFile(L"shaders.hlsl", nullptr, nullptr, "VSMain", "vs_5_0", compileFlags, 0, &vertexShader, nullptr)); 531 | ThrowIfFailed(D3DCompileFromFile(L"shaders.hlsl", nullptr, nullptr, "PSMain", "ps_5_0", compileFlags, 0, &pixelShader, nullptr)); 532 | 533 | // Define the vertex input layout. 534 | D3D12_INPUT_ELEMENT_DESC inputElementDescs[] = 535 | { 536 | { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, 537 | { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 } 538 | }; 539 | 540 | // Describe and create the graphics pipeline state object (PSO). 541 | D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {}; 542 | psoDesc.InputLayout = { inputElementDescs, _countof(inputElementDescs) }; 543 | psoDesc.pRootSignature = m_rootSignature.Get(); 544 | psoDesc.VS = { reinterpret_cast(vertexShader->GetBufferPointer()), vertexShader->GetBufferSize() }; 545 | psoDesc.PS = { reinterpret_cast(pixelShader->GetBufferPointer()), pixelShader->GetBufferSize() }; 546 | psoDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT); 547 | psoDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT); 548 | psoDesc.DepthStencilState.DepthEnable = FALSE; 549 | psoDesc.DepthStencilState.StencilEnable = FALSE; 550 | psoDesc.SampleMask = UINT_MAX; 551 | psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; 552 | psoDesc.NumRenderTargets = 1; 553 | psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; 554 | psoDesc.SampleDesc.Count = 1; 555 | ThrowIfFailed(m_device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&m_pipelineState))); 556 | } 557 | 558 | // Create the command list. 559 | ThrowIfFailed(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_commandAllocator.Get(), m_pipelineState.Get(), IID_PPV_ARGS(&m_commandList))); 560 | 561 | // Command lists are created in the recording state, but there is nothing 562 | // to record yet. The main loop expects it to be closed, so close it now. 563 | ThrowIfFailed(m_commandList->Close()); 564 | 565 | // Create the vertex buffer. 566 | { 567 | // Define the geometry for a triangle. 568 | Vertex triangleVertices[] = 569 | { 570 | { { 0.0f, 0.25f * m_aspectRatio, 0.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } }, 571 | { { 0.25f, -0.25f * m_aspectRatio, 0.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } }, 572 | { { -0.25f, -0.25f * m_aspectRatio, 0.0f }, { 0.0f, 0.0f, 1.0f, 1.0f } } 573 | }; 574 | 575 | const UINT vertexBufferSize = sizeof(triangleVertices); 576 | 577 | // Note: using upload heaps to transfer static data like vert buffers is not 578 | // recommended. Every time the GPU needs it, the upload heap will be marshalled 579 | // over. Please read up on Default Heap usage. An upload heap is used here for 580 | // code simplicity and because there are very few verts to actually transfer. 581 | ThrowIfFailed(m_device->CreateCommittedResource( 582 | &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), 583 | D3D12_HEAP_FLAG_NONE, 584 | &CD3DX12_RESOURCE_DESC::Buffer(vertexBufferSize), 585 | D3D12_RESOURCE_STATE_GENERIC_READ, 586 | nullptr, 587 | IID_PPV_ARGS(&m_vertexBuffer))); 588 | 589 | // Copy the triangle data to the vertex buffer. 590 | UINT8* pVertexDataBegin; 591 | ThrowIfFailed(m_vertexBuffer->Map(0, nullptr, reinterpret_cast(&pVertexDataBegin))); 592 | memcpy(pVertexDataBegin, triangleVertices, sizeof(triangleVertices)); 593 | m_vertexBuffer->Unmap(0, nullptr); 594 | 595 | // Initialize the vertex buffer view. 596 | m_vertexBufferView.BufferLocation = m_vertexBuffer->GetGPUVirtualAddress(); 597 | m_vertexBufferView.StrideInBytes = sizeof(Vertex); 598 | m_vertexBufferView.SizeInBytes = vertexBufferSize; 599 | } 600 | 601 | // Create synchronization objects and wait until assets have been uploaded to the GPU. 602 | { 603 | ThrowIfFailed(m_device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&m_fence))); 604 | m_fenceValue = 1; 605 | 606 | // Create an event handle to use for frame synchronization. 607 | m_fenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); 608 | if (m_fenceEvent == nullptr) 609 | { 610 | ThrowIfFailed(HRESULT_FROM_WIN32(GetLastError())); 611 | } 612 | 613 | // Wait for the command list to execute; we are reusing the same command 614 | // list in our main loop but for now, we just want to wait for setup to 615 | // complete before continuing. 616 | WaitForPreviousFrame(); 617 | } 618 | } 619 | 620 | // Update frame-based values. 621 | void D3D12HelloTriangle::OnUpdate() 622 | { 623 | } 624 | 625 | // Render the scene. 626 | void D3D12HelloTriangle::OnRender() 627 | { 628 | MICROPROFILE_SCOPEI("Main", "OnRender", 0); 629 | 630 | // Record all the commands we need to render the scene into the command list. 631 | PopulateCommandList(); 632 | 633 | 634 | 635 | 636 | ThrowIfFailed(m_commandList->Close()); 637 | 638 | 639 | // Execute the command list. 640 | ID3D12CommandList* ppCommandLists[] = { m_commandList.Get() }; 641 | m_commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists); 642 | 643 | MicroProfileFlip(m_commandList.Get()); 644 | 645 | MICROPROFILE_SCOPEI("Main", "WaitPrev", 0); 646 | 647 | // Present the frame. 648 | ThrowIfFailed(m_swapChain->Present(1, 0)); 649 | 650 | WaitForPreviousFrame(); 651 | } 652 | 653 | void D3D12HelloTriangle::OnDestroy() 654 | { 655 | // Wait for the GPU to be done with all resources. 656 | WaitForPreviousFrame(); 657 | 658 | CloseHandle(m_fenceEvent); 659 | } 660 | 661 | bool D3D12HelloTriangle::OnEvent(MSG) 662 | { 663 | return false; 664 | } 665 | 666 | void D3D12HelloTriangle::PopulateCommandList() 667 | { 668 | // Command list allocators can only be reset when the associated 669 | // command lists have finished execution on the GPU; apps should use 670 | // fences to determine GPU execution progress. 671 | ThrowIfFailed(m_commandAllocator->Reset()); 672 | 673 | // However, when ExecuteCommandList() is called on a particular command 674 | // list, that command list can then be reset at any time and must be before 675 | // re-recording. 676 | ThrowIfFailed(m_commandList->Reset(m_commandAllocator.Get(), m_pipelineState.Get())); 677 | MICROPROFILE_GPU_SET_CONTEXT(m_commandList.Get(), MicroProfileGetGlobaGpuThreadLog()); 678 | MICROPROFILE_SCOPEGPUI("Full Frame", 0xff00ff00); 679 | // Set necessary state. 680 | m_commandList->SetGraphicsRootSignature(m_rootSignature.Get()); 681 | m_commandList->RSSetViewports(1, &m_viewport); 682 | m_commandList->RSSetScissorRects(1, &m_scissorRect); 683 | 684 | // Indicate that the back buffer will be used as a render target. 685 | m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_renderTargets[m_frameIndex].Get(), D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET)); 686 | 687 | CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(m_rtvHeap->GetCPUDescriptorHandleForHeapStart(), m_frameIndex, m_rtvDescriptorSize); 688 | m_commandList->OMSetRenderTargets(1, &rtvHandle, FALSE, nullptr); 689 | 690 | // Record commands. 691 | const float clearColor[] = { 0.0f, 0.2f, 0.4f, 1.0f }; 692 | m_commandList->ClearRenderTargetView(rtvHandle, clearColor, 0, nullptr); 693 | m_commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); 694 | m_commandList->IASetVertexBuffers(0, 1, &m_vertexBufferView); 695 | 696 | for (uint32_t i = 0; i < 6; ++i) 697 | { 698 | MICROPROFILE_SCOPEI("cpu", "iteration", 0xff00ff); 699 | MICROPROFILE_SCOPEGPUI("iteration", 0xff00ff); 700 | for (int j = 0; j < (1 << (2*i)); ++j) 701 | { 702 | m_commandList->DrawInstanced(3, 1, 0, 0); 703 | } 704 | } 705 | 706 | // Indicate that the back buffer will now be used to present. 707 | m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_renderTargets[m_frameIndex].Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT)); 708 | 709 | } 710 | 711 | void D3D12HelloTriangle::WaitForPreviousFrame() 712 | { 713 | // WAITING FOR THE FRAME TO COMPLETE BEFORE CONTINUING IS NOT BEST PRACTICE. 714 | // This is code implemented as such for simplicity. More advanced samples 715 | // illustrate how to use fences for efficient resource usage. 716 | 717 | // Signal and increment the fence value. 718 | const UINT64 fence = m_fenceValue; 719 | ThrowIfFailed(m_commandQueue->Signal(m_fence.Get(), fence)); 720 | m_fenceValue++; 721 | 722 | // Wait until the previous frame is finished. 723 | if (m_fence->GetCompletedValue() < fence) 724 | { 725 | ThrowIfFailed(m_fence->SetEventOnCompletion(fence, m_fenceEvent)); 726 | WaitForSingleObject(m_fenceEvent, INFINITE); 727 | } 728 | 729 | m_frameIndex = m_swapChain->GetCurrentBackBufferIndex(); 730 | } 731 | 732 | _Use_decl_annotations_ 733 | int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow) 734 | { 735 | D3D12HelloTriangle sample(1280, 720, "D3D12 Hello Triangle"); 736 | return sample.Run(hInstance, nCmdShow); 737 | } 738 | 739 | #include 740 | void uprintf(const char* fmt, ...) 741 | { 742 | char buffer[32 * 1024]; 743 | va_list args; 744 | va_start(args, fmt); 745 | vsprintf_s(buffer, fmt, args); 746 | OutputDebugStringA(&buffer[0]); 747 | va_end(args); 748 | } -------------------------------------------------------------------------------- /demo/noui_d3d12/noui_d3d12.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {498550DB-779A-49ED-A253-33672F378337} 23 | Win32Proj 24 | noui_d3d12 25 | 10.0.10240.0 26 | 27 | 28 | 29 | Application 30 | true 31 | v140 32 | MultiByte 33 | 34 | 35 | Application 36 | false 37 | v140 38 | true 39 | MultiByte 40 | 41 | 42 | Application 43 | true 44 | v140 45 | MultiByte 46 | 47 | 48 | Application 49 | false 50 | v140 51 | true 52 | MultiByte 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | true 74 | 75 | 76 | true 77 | 78 | 79 | false 80 | 81 | 82 | false 83 | 84 | 85 | 86 | 87 | 88 | Level3 89 | Disabled 90 | MICROPROFILE_ENABLED=1;MICROPROFILE_GPU_TIMERS_MULTITHREADED=1;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) 91 | ../.. 92 | 93 | 94 | Windows 95 | true 96 | dxguid.lib;Ws2_32.lib;d3d12.lib;d3dcompiler.lib;dxgi.lib;winmm.lib;%(AdditionalDependencies) 97 | 98 | 99 | copy ..\..\bin\microprofile-win32-cswitch_$(PlatformTarget).exe $(ProjectDir) 100 | 101 | 102 | 103 | 104 | 105 | 106 | Level3 107 | Disabled 108 | MICROPROFILE_ENABLED=1;MICROPROFILE_GPU_TIMERS_MULTITHREADED=1;_CRT_SECURE_NO_WARNINGS;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) 109 | ..\.. 110 | 111 | 112 | Windows 113 | true 114 | dxguid.lib;Ws2_32.lib;d3d12.lib;d3dcompiler.lib;dxgi.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 115 | 116 | 117 | copy ..\..\bin\microprofile-win32-cswitch_$(PlatformTarget).exe $(ProjectDir) 118 | 119 | 120 | 121 | 122 | Level3 123 | 124 | 125 | MaxSpeed 126 | true 127 | true 128 | MICROPROFILE_ENABLED=1;MICROPROFILE_GPU_TIMERS_MULTITHREADED=1;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) 129 | ../.. 130 | 131 | 132 | Windows 133 | true 134 | true 135 | true 136 | dxguid.lib;Ws2_32.lib;d3d12.lib;d3dcompiler.lib;dxgi.lib;winmm.lib;%(AdditionalDependencies) 137 | 138 | 139 | copy ..\..\bin\microprofile-win32-cswitch_$(PlatformTarget).exe $(ProjectDir) 140 | 141 | 142 | 143 | 144 | Level3 145 | 146 | 147 | MaxSpeed 148 | true 149 | true 150 | MICROPROFILE_ENABLED=1;MICROPROFILE_GPU_TIMERS_MULTITHREADED=1;_CRT_SECURE_NO_WARNINGS;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) 151 | ..\.. 152 | 153 | 154 | Windows 155 | true 156 | true 157 | true 158 | dxguid.lib;Ws2_32.lib;d3d12.lib;d3dcompiler.lib;dxgi.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 159 | 160 | 161 | copy ..\..\bin\microprofile-win32-cswitch_$(PlatformTarget).exe $(ProjectDir) 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | -------------------------------------------------------------------------------- /demo/noui_d3d12/noui_d3d12.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /demo/noui_d3d12/shaders.hlsl: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | struct PSInput 13 | { 14 | float4 position : SV_POSITION; 15 | float4 color : COLOR; 16 | }; 17 | 18 | PSInput VSMain(float4 position : POSITION, float4 color : COLOR) 19 | { 20 | PSInput result; 21 | 22 | result.position = position; 23 | result.color = color; 24 | 25 | return result; 26 | } 27 | 28 | float4 PSMain(PSInput input) : SV_TARGET 29 | { 30 | return input.color; 31 | } 32 | -------------------------------------------------------------------------------- /demo/noui_d3d12_multithreading/SquidRoom.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dougbinks/microprofile/1478c9ddaec388914258f2fa3471ac435715c032/demo/noui_d3d12_multithreading/SquidRoom.bin -------------------------------------------------------------------------------- /demo/noui_d3d12_multithreading/noui_d3d12_multithreading.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | {DBC4664B-A190-4533-80D5-4312F7541B47} 36 | Win32Proj 37 | noui_d3d12 38 | 10.0.10240.0 39 | 40 | 41 | 42 | Application 43 | true 44 | v140 45 | MultiByte 46 | 47 | 48 | Application 49 | false 50 | v140 51 | true 52 | MultiByte 53 | 54 | 55 | Application 56 | true 57 | v140 58 | MultiByte 59 | 60 | 61 | Application 62 | false 63 | v140 64 | true 65 | MultiByte 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | true 87 | 88 | 89 | true 90 | 91 | 92 | false 93 | 94 | 95 | false 96 | 97 | 98 | 99 | 100 | 101 | Level3 102 | Disabled 103 | MICROPROFILE_ENABLED=1;MICROPROFILE_GPU_TIMERS_MULTITHREADED=1;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) 104 | ../.. 105 | 106 | 107 | Windows 108 | true 109 | dxguid.lib;Ws2_32.lib;d3d12.lib;d3dcompiler.lib;dxgi.lib;winmm.lib;%(AdditionalDependencies) 110 | 111 | 112 | copy ..\..\bin\microprofile-win32-cswitch_$(PlatformTarget).exe $(ProjectDir) 113 | 114 | 115 | 116 | 117 | 118 | 119 | Level3 120 | Disabled 121 | MICROPROFILE_ENABLED=1;MICROPROFILE_GPU_TIMERS_MULTITHREADED=1;_CRT_SECURE_NO_WARNINGS;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) 122 | ..\.. 123 | 124 | 125 | Windows 126 | true 127 | dxguid.lib;Ws2_32.lib;d3d12.lib;d3dcompiler.lib;dxgi.lib;winmm.lib;%(AdditionalDependencies) 128 | 129 | 130 | copy ..\..\bin\microprofile-win32-cswitch_$(PlatformTarget).exe $(ProjectDir) 131 | 132 | 133 | 134 | 135 | Level3 136 | 137 | 138 | MaxSpeed 139 | true 140 | true 141 | MICROPROFILE_ENABLED=1;MICROPROFILE_GPU_TIMERS_MULTITHREADED=1;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) 142 | ../.. 143 | 144 | 145 | Windows 146 | true 147 | true 148 | true 149 | dxguid.lib;Ws2_32.lib;d3d12.lib;d3dcompiler.lib;dxgi.lib;winmm.lib;%(AdditionalDependencies) 150 | 151 | 152 | copy ..\..\bin\microprofile-win32-cswitch_$(PlatformTarget).exe $(ProjectDir) 153 | 154 | 155 | 156 | 157 | Level3 158 | 159 | 160 | MaxSpeed 161 | true 162 | true 163 | MICROPROFILE_ENABLED=1;MICROPROFILE_GPU_TIMERS_MULTITHREADED=1;_CRT_SECURE_NO_WARNINGS;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) 164 | ..\.. 165 | 166 | 167 | Windows 168 | true 169 | true 170 | true 171 | dxguid.lib;Ws2_32.lib;d3d12.lib;d3dcompiler.lib;dxgi.lib;winmm.lib;%(AdditionalDependencies) 172 | 173 | 174 | copy ..\..\bin\microprofile-win32-cswitch_$(PlatformTarget).exe $(ProjectDir) 175 | 176 | 177 | 178 | 179 | 180 | -------------------------------------------------------------------------------- /demo/noui_d3d12_multithreading/shaders.hlsl: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | Texture2D shadowMap : register(t0); 13 | Texture2D diffuseMap : register(t1); 14 | Texture2D normalMap : register(t2); 15 | 16 | SamplerState sampleWrap : register(s0); 17 | SamplerState sampleClamp : register(s1); 18 | 19 | #define NUM_LIGHTS 3 20 | 21 | #define SHADOW_DEPTH_BIAS 0.00005f 22 | 23 | struct LightState 24 | { 25 | float3 position; 26 | float3 direction; 27 | float4 color; 28 | float4 falloff; 29 | 30 | float4x4 view; 31 | float4x4 projection; 32 | 33 | }; 34 | 35 | cbuffer ConstantBuffer : register(b0) 36 | { 37 | float4x4 model; 38 | float4x4 view; 39 | float4x4 projection; 40 | float4 ambientColor; 41 | bool sampleShadowMap; 42 | LightState lights[NUM_LIGHTS]; 43 | 44 | }; 45 | 46 | struct PSInput 47 | { 48 | float4 position : SV_POSITION; 49 | float4 worldpos : POSITION; 50 | float2 uv : TEXCOORD0; 51 | float3 normal : NORMAL; 52 | float3 tangent : TANGENT; 53 | }; 54 | 55 | 56 | //-------------------------------------------------------------------------------------- 57 | // Sample normal map, convert to signed, apply tangent-to-world space transform 58 | //-------------------------------------------------------------------------------------- 59 | float3 CalcPerPixelNormal(float2 vTexcoord, float3 vVertNormal, float3 vVertTangent) 60 | { 61 | // Compute tangent frame 62 | vVertNormal = normalize(vVertNormal); 63 | vVertTangent = normalize(vVertTangent); 64 | 65 | float3 vVertBinormal = normalize(cross(vVertTangent, vVertNormal)); 66 | float3x3 mTangentSpaceToWorldSpace = float3x3(vVertTangent, vVertBinormal, vVertNormal); 67 | 68 | // Compute per-pixel normal 69 | float3 vBumpNormal = (float3)normalMap.Sample(sampleWrap, vTexcoord); 70 | vBumpNormal = 2.0f * vBumpNormal - 1.0f; 71 | 72 | return mul(vBumpNormal, mTangentSpaceToWorldSpace); 73 | } 74 | 75 | //-------------------------------------------------------------------------------------- 76 | // Diffuse lighting calculation, with angle and distance falloff 77 | //-------------------------------------------------------------------------------------- 78 | float4 CalcLightingColor(float3 vLightPos, float3 vLightDir, float4 vLightColor, float4 vFalloffs, float3 vPosWorld, float3 vPerPixelNormal) 79 | { 80 | 81 | float3 vLightToPixelUnNormalized = vPosWorld - vLightPos; 82 | 83 | // Dist falloff = 0 at vFalloffs.x, 1 at vFalloffs.x - vFalloffs.y 84 | float fDist = length(vLightToPixelUnNormalized); 85 | 86 | float fDistFalloff = saturate((vFalloffs.x - fDist) / vFalloffs.y); 87 | 88 | // Normalize from here on 89 | float3 vLightToPixelNormalized = vLightToPixelUnNormalized / fDist; 90 | 91 | // Angle falloff = 0 at vFalloffs.z, 1 at vFalloffs.z - vFalloffs.w 92 | float fCosAngle = dot(vLightToPixelNormalized, vLightDir / length(vLightDir)); 93 | float fAngleFalloff = saturate((fCosAngle - vFalloffs.z) / vFalloffs.w); 94 | 95 | // Diffuse contribution 96 | float fNDotL = saturate(-dot(vLightToPixelNormalized, vPerPixelNormal)); 97 | 98 | return vLightColor * fNDotL * fDistFalloff * fAngleFalloff; 99 | } 100 | 101 | //-------------------------------------------------------------------------------------- 102 | // Test how much pixel is in shadow, using 2x2 percentage-closer filtering 103 | //-------------------------------------------------------------------------------------- 104 | float4 CalcUnshadowedAmountPCF2x2(int lightnum, float4 vPosWorld) 105 | { 106 | Texture2D txShadow = shadowMap; 107 | 108 | // Compute pixel position in light space 109 | float4 vLightSpacePos = vPosWorld; 110 | vLightSpacePos = mul(vLightSpacePos, lights[lightnum].view); 111 | vLightSpacePos = mul(vLightSpacePos, lights[lightnum].projection); 112 | 113 | vLightSpacePos.xyz /= vLightSpacePos.w; 114 | 115 | // Translate from surface coords to texture coords 116 | // Could fold these into the matrix 117 | float2 vShadowTexCoord = 0.5f * vLightSpacePos.xy + 0.5f; 118 | vShadowTexCoord.y = 1.0f - vShadowTexCoord.y; 119 | 120 | // Depth bias to avoid pixel self-shadowing 121 | float vLightSpaceDepth = vLightSpacePos.z - SHADOW_DEPTH_BIAS; 122 | 123 | // Find sub-pixel weights 124 | float2 vShadowMapDims = float2(1280.0f / 2, 720.0f / 2); // need to keep in sync with .cpp file 125 | float4 vSubPixelCoords = float4(1.0f, 1.0f, 1.0f, 1.0f); 126 | vSubPixelCoords.xy = frac(vShadowMapDims * vShadowTexCoord); 127 | vSubPixelCoords.zw = 1.0f - vSubPixelCoords.xy; 128 | float4 vBilinearWeights = vSubPixelCoords.zxzx * vSubPixelCoords.wwyy; 129 | 130 | return (txShadow.Sample(sampleClamp, vShadowTexCoord).r >= vLightSpaceDepth) ? 1.0 : 0.0f; 131 | } 132 | 133 | PSInput VSMain(float3 position : POSITION, float3 normal : NORMAL, float2 uv : TEXCOORD0, float3 tangent : TANGENT) 134 | { 135 | PSInput result; 136 | 137 | float4 newPosition = float4(position, 1.0f); 138 | 139 | normal.z *= -1.0f; 140 | newPosition = mul(newPosition, model); 141 | 142 | result.worldpos = newPosition; 143 | 144 | newPosition = mul(newPosition, view); 145 | newPosition = mul(newPosition, projection); 146 | 147 | result.position = newPosition; 148 | 149 | result.uv = uv; 150 | result.normal = normal; 151 | result.tangent = tangent; 152 | 153 | return result; 154 | } 155 | 156 | float4 PSMain(PSInput input) : SV_TARGET 157 | { 158 | float4 diffuseColor = diffuseMap.Sample(sampleWrap, input.uv); 159 | float3 pixelNormal = CalcPerPixelNormal(input.uv, input.normal, input.tangent); 160 | float4 totalLight = ambientColor; 161 | 162 | for (int i = 0; i < NUM_LIGHTS; i++) 163 | { 164 | float4 lightPass = CalcLightingColor(lights[i].position, lights[i].direction, lights[i].color, lights[i].falloff, input.worldpos.xyz, pixelNormal); 165 | if (sampleShadowMap && i == 0) 166 | { 167 | lightPass *= CalcUnshadowedAmountPCF2x2(i, input.worldpos); 168 | } 169 | totalLight += lightPass; 170 | } 171 | 172 | return diffuseColor * saturate(totalLight); 173 | } 174 | 175 | 176 | #define threadBlockSize 128 177 | 178 | cbuffer root_arg : register(b0) 179 | { 180 | uint foo; 181 | }; 182 | 183 | struct VertexData 184 | { 185 | float3 position; 186 | float3 normal; 187 | float2 texcoord; 188 | float3 tangent; 189 | }; 190 | 191 | StructuredBuffer VertexIn : register(t0); 192 | RWStructuredBuffer VertexOut : register(u0); 193 | 194 | [numthreads(threadBlockSize, 1, 1)] 195 | void CSMain(uint3 groupId : SV_GroupID, uint groupIndex : SV_GroupIndex) 196 | { 197 | uint index = (groupId.x * threadBlockSize) + groupIndex; 198 | VertexData D = VertexIn[index]; 199 | float fSin1 = sin(length(float2(D.position.x, D.position.y))/30 + foo / 20.0) * 10; 200 | D.position.y += fSin1; 201 | VertexOut[index] = D; 202 | } 203 | -------------------------------------------------------------------------------- /demo/ui/Makefile: -------------------------------------------------------------------------------- 1 | UNAME_S := $(shell uname -s) 2 | ifeq ($(UNAME_S),Linux) 3 | LDFLAGS=-lGL `sdl2-config --static-libs` -lpthread 4 | endif 5 | ifeq ($(UNAME_S),Darwin) 6 | LDFLAGS=-framework OpenGL `sdl2-config --static-libs` -lpthread 7 | endif 8 | 9 | CFLAGS=`sdl2-config --cflags` -I../.. -I../glew -DGLEW_STATIC -Wno-c++11-extensions -Wall -Werror 10 | #CFLAGS+=-fsanitize=undefined-trap -fsanitize-undefined-trap-on-error 11 | CFLAGS+=-Wall -DMICROPROFILE_UI=1 12 | CFLAGS+=-DMICROPROFILE_WEBSERVER=1 13 | CFLAGS+=-DMICROPROFILE_GPU_TIMERS_MULTITHREADED=1 14 | #CFLAGS+=-DMICROPROFILE_ENABLED=0 15 | 16 | CFLAGS+=-g -O0 -Wno-invalid-offsetof 17 | 18 | CPPFLAGS=$(CFLAGS) 19 | CPPFLAGS+=-stdlib=libc++ -std=c++11 20 | 21 | 22 | CPP_SOURCES = microprofile.cpp fakework.cpp demo.cpp 23 | C_SOURCES = ../glew/glew.c 24 | 25 | TARGET=demo 26 | CC=clang 27 | CPP=clang++ 28 | LD=clang++ 29 | 30 | CPP_OBJS = $(patsubst %.cpp,%.o,$(CPP_SOURCES)) 31 | C_OBJS = $(patsubst %.c,%.o,$(C_SOURCES)) 32 | 33 | all: $(TARGET) 34 | 35 | $(TARGET): $(C_OBJS) $(CPP_OBJS) 36 | $(LD) -o $(TARGET) $(C_OBJS) $(CPP_OBJS) $(LDFLAGS) $(CPPFLAGS) 37 | 38 | -include .depend 39 | 40 | .cpp.o: 41 | $(CPP) -c $< $(CPPFLAGS) -o $@ 42 | 43 | .c.o: 44 | $(CC) -c $< $(CFLAGS) -o $@ 45 | 46 | 47 | clean: depend 48 | rm *.o $(TARGET) 49 | 50 | depend: $(CPP_SOURCES) $(C_SOURCES) 51 | $(CC) -MM $(CFLAGS) $(C_SOURCES) > .depend 52 | $(CPP) -MM $(CPPFLAGS) $(CPP_SOURCES) >> .depend 53 | 54 | embed_target: 55 | cd ../../src && make 56 | 57 | embed: embed_target all 58 | 59 | 60 | -------------------------------------------------------------------------------- /demo/ui/demo.cpp: -------------------------------------------------------------------------------- 1 | // This is free and unencumbered software released into the public domain. 2 | // Anyone is free to copy, modify, publish, use, compile, sell, or 3 | // distribute this software, either in source code form or as a compiled 4 | // binary, for any purpose, commercial or non-commercial, and by any 5 | // means. 6 | // In jurisdictions that recognize copyright laws, the author or authors 7 | // of this software dedicate any and all copyright interest in the 8 | // software to the public domain. We make this dedication for the benefit 9 | // of the public at large and to the detriment of our heirs and 10 | // successors. We intend this dedication to be an overt act of 11 | // relinquishment in perpetuity of all present and future rights to this 12 | // software under copyright law. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 14 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 15 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 16 | // IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 17 | // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 18 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 19 | // OTHER DEALINGS IN THE SOFTWARE. 20 | // For more information, please refer to 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #if defined(__APPLE__) || defined(__linux__) 30 | #include 31 | #endif 32 | 33 | #include "glinc.h" 34 | 35 | #define MICROPROFILE_DEBUG 1 36 | #define MICROPROFILE_WEBSERVER_MAXFRAMES 20 37 | #define MICROPROFILE_IMPL 38 | #define MICROPROFILE_GPU_TIMERS_GL 1 39 | #include "microprofile.h" 40 | #include "microprofileui.h" 41 | 42 | 43 | 44 | 45 | #ifdef main 46 | #undef main 47 | #endif 48 | 49 | #ifdef _WIN32 50 | #undef near 51 | #undef far 52 | #define snprintf _snprintf 53 | #include 54 | void usleep(__int64 usec) ; 55 | #endif 56 | 57 | 58 | #define WIDTH 1024 59 | #define HEIGHT 600 60 | 61 | uint32_t g_nQuit = 0; 62 | uint32_t g_MouseX = 0; 63 | uint32_t g_MouseY = 0; 64 | uint32_t g_MouseDown0 = 0; 65 | uint32_t g_MouseDown1 = 0; 66 | int g_MouseDelta = 0; 67 | 68 | MICROPROFILE_DEFINE(MAIN, "MAIN", "Main", 0xff0000); 69 | 70 | 71 | 72 | void HammerThread() 73 | { 74 | MicroProfileOnThreadCreate("HammerThread"); 75 | while (!g_nQuit) 76 | { 77 | MICROPROFILE_SCOPEI("Hammer", "Thread", 0xff00ff); 78 | usleep(10); 79 | 80 | } 81 | MicroProfileOnThreadExit(); 82 | } 83 | 84 | 85 | 86 | void HandleEvent(SDL_Event* pEvt) 87 | { 88 | switch(pEvt->type) 89 | { 90 | case SDL_QUIT: 91 | g_nQuit = true; 92 | break; 93 | case SDL_KEYUP: 94 | if(pEvt->key.keysym.scancode == SDL_SCANCODE_ESCAPE) 95 | { 96 | g_nQuit = 1; 97 | } 98 | if(pEvt->key.keysym.sym == 'z') 99 | { 100 | MicroProfileToggleDisplayMode(); 101 | } 102 | if(pEvt->key.keysym.sym == 'x') 103 | { 104 | bool bForceEnable = MicroProfileGetForceEnable(); 105 | MicroProfileSetForceEnable(!bForceEnable); 106 | printf("force enable is %d\n", !bForceEnable); 107 | } 108 | if(pEvt->key.keysym.sym == 'c') 109 | { 110 | bool bEnable = MicroProfileGetEnableAllGroups(); 111 | MicroProfileSetEnableAllGroups(!bEnable); 112 | printf("enable all groups is %d\n", !bEnable); 113 | } 114 | if(pEvt->key.keysym.scancode == SDL_SCANCODE_RSHIFT) 115 | { 116 | MicroProfileTogglePause(); 117 | } 118 | if(pEvt->key.keysym.scancode == SDL_SCANCODE_LCTRL) 119 | { 120 | MicroProfileModKey(0); 121 | } 122 | if(pEvt->key.keysym.sym == 'a') 123 | { 124 | MicroProfileDumpTimers(); 125 | } 126 | #if MICROPROFILE_WEBSERVER 127 | if(pEvt->key.keysym.sym == 'd') 128 | { 129 | MicroProfileDumpFile("../dump.html", "../dump.csv", -1, -1); 130 | } 131 | #endif 132 | if(pEvt->key.keysym.sym == 'l') 133 | { 134 | MicroProfileCustomGroupToggle("Custom1"); 135 | } 136 | 137 | if(pEvt->key.keysym.sym == 't') 138 | { 139 | static bool toggle = false; 140 | if(toggle) 141 | { 142 | MicroProfileEnableCategory("ThreaDS"); 143 | } 144 | else 145 | { 146 | MicroProfileDisableCategory("ThreaDS"); 147 | } 148 | toggle = !toggle; 149 | } 150 | break; 151 | 152 | 153 | break; 154 | case SDL_KEYDOWN: 155 | if(pEvt->key.keysym.scancode == SDL_SCANCODE_LCTRL) 156 | { 157 | MicroProfileModKey(1); 158 | } 159 | break; 160 | case SDL_MOUSEMOTION: 161 | g_MouseX = pEvt->motion.x; 162 | g_MouseY = pEvt->motion.y; 163 | break; 164 | case SDL_MOUSEBUTTONDOWN: 165 | if(pEvt->button.button == 1) 166 | g_MouseDown0 = 1; 167 | else if(pEvt->button.button == 3) 168 | g_MouseDown1 = 1; 169 | break; 170 | case SDL_MOUSEBUTTONUP: 171 | if(pEvt->button.button == 1) 172 | { 173 | g_MouseDown0 = 0; 174 | } 175 | else if(pEvt->button.button == 3) 176 | { 177 | g_MouseDown1 = 0; 178 | } 179 | break; 180 | case SDL_MOUSEWHEEL: 181 | g_MouseDelta -= pEvt->wheel.y; 182 | break; 183 | } 184 | 185 | 186 | 187 | } 188 | 189 | void MicroProfileDrawInit(); 190 | void MicroProfileBeginDraw(uint32_t nWidth, uint32_t nHeight, float* prj); 191 | void MicroProfileEndDraw(); 192 | 193 | void StartFakeWork(); 194 | void StopFakeWork(); 195 | MICROPROFILE_DEFINE_LOCAL_ATOMIC_COUNTER(SDLFrameEvents, "/runtime/sdl_frame_events"); 196 | 197 | 198 | #ifdef _WIN32 199 | #define __BREAK() __debugbreak() 200 | #else 201 | #define __BREAK() __builtin_trap() 202 | #endif 203 | int g_QueueGraphics = -1; 204 | int main(int argc, char* argv[]) 205 | { 206 | 207 | MICROPROFILE_REGISTER_GROUP("Thread0", "Threads", 0x88008800); 208 | MICROPROFILE_REGISTER_GROUP("Thread1", "Threads", 0x88008800); 209 | MICROPROFILE_REGISTER_GROUP("Thread2", "Threads", 0x88008800); 210 | MICROPROFILE_REGISTER_GROUP("Thread2xx", "Threads", 0x88008800); 211 | MICROPROFILE_REGISTER_GROUP("MAIN", "main", 0x88fff00f); 212 | 213 | 214 | MICROPROFILE_CONDITIONAL(g_QueueGraphics = MICROPROFILE_GPU_INIT_QUEUE("GPU-Graphics-Queue")); 215 | 216 | printf("press 'z' to toggle microprofile drawing\n"); 217 | printf("press 'right shift' to pause microprofile update\n"); 218 | printf("press 'x' to toggle profiling\n"); 219 | printf("press 'c' to toggle enable of all profiler groups\n"); 220 | MicroProfileOnThreadCreate("AA_Main"); 221 | if(SDL_Init(SDL_INIT_VIDEO) < 0) { 222 | return 1; 223 | } 224 | 225 | 226 | SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); 227 | SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); 228 | SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); 229 | SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); 230 | SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); 231 | SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); 232 | SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32); 233 | SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); 234 | SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); 235 | SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); 236 | SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); 237 | SDL_GL_SetSwapInterval(1); 238 | 239 | SDL_Window * pWindow = SDL_CreateWindow("microprofiledemo", 10, 10, WIDTH, HEIGHT, SDL_WINDOW_OPENGL); 240 | if(!pWindow) 241 | return 1; 242 | 243 | SDL_GLContext glcontext = SDL_GL_CreateContext(pWindow); 244 | 245 | glewExperimental=1; 246 | GLenum err=glewInit(); 247 | if(err!=GLEW_OK) 248 | { 249 | __BREAK(); 250 | } 251 | glGetError(); //glew generates an error 252 | 253 | std::thread HT(HammerThread); 254 | 255 | #if MICROPROFILE_ENABLED 256 | MicroProfileGpuInitGL(); 257 | MicroProfileDrawInit(); 258 | MP_ASSERT(glGetError() == 0); 259 | MicroProfileToggleDisplayMode(); 260 | 261 | MicroProfileInitUI(); 262 | 263 | MicroProfileCustomGroup("Custom1", 2, 47, 2.f, MICROPROFILE_CUSTOM_BARS); 264 | MicroProfileCustomGroupAddTimer("Custom1", "MicroProfile", "Draw"); 265 | MicroProfileCustomGroupAddTimer("Custom1", "MicroProfile", "Detailed View"); 266 | 267 | MicroProfileCustomGroup("Custom2", 2, 100, 20.f, MICROPROFILE_CUSTOM_BARS|MICROPROFILE_CUSTOM_BAR_SOURCE_MAX); 268 | MicroProfileCustomGroupAddTimer("Custom2", "MicroProfile", "Draw"); 269 | MicroProfileCustomGroupAddTimer("Custom2", "MicroProfile", "Detailed View"); 270 | 271 | 272 | MicroProfileCustomGroup("Custom3", 2, 0, 5.f, MICROPROFILE_CUSTOM_STACK|MICROPROFILE_CUSTOM_STACK_SOURCE_MAX); 273 | MicroProfileCustomGroupAddTimer("Custom3", "MicroProfile", "Draw"); 274 | MicroProfileCustomGroupAddTimer("Custom3", "MicroProfile", "Detailed View"); 275 | 276 | 277 | 278 | MicroProfileCustomGroup("ThreadSafe", 6, 10, 600.f, MICROPROFILE_CUSTOM_BARS | MICROPROFILE_CUSTOM_STACK); 279 | MicroProfileCustomGroupAddTimer("ThreadSafe", "ThreadSafe", "main"); 280 | MicroProfileCustomGroupAddTimer("ThreadSafe", "ThreadSafe", "inner0"); 281 | MicroProfileCustomGroupAddTimer("ThreadSafe", "ThreadSafe", "inner1"); 282 | MicroProfileCustomGroupAddTimer("ThreadSafe", "ThreadSafe", "inner2"); 283 | MicroProfileCustomGroupAddTimer("ThreadSafe", "ThreadSafe", "inner3"); 284 | MicroProfileCustomGroupAddTimer("ThreadSafe", "ThreadSafe", "inner4"); 285 | #endif 286 | MICROPROFILE_COUNTER_CONFIG("memory/main", MICROPROFILE_COUNTER_FORMAT_BYTES, 10ll<<30ll, 0); 287 | MICROPROFILE_COUNTER_CONFIG("memory/gpu/indexbuffers", MICROPROFILE_COUNTER_FORMAT_BYTES, 0, 0); 288 | MICROPROFILE_COUNTER_CONFIG("memory/gpu/vertexbuffers", MICROPROFILE_COUNTER_FORMAT_BYTES, 0, 0); 289 | MICROPROFILE_COUNTER_CONFIG("memory/mainx", MICROPROFILE_COUNTER_FORMAT_BYTES, 10000, 0); 290 | 291 | MICROPROFILE_COUNTER_ADD("memory/main", 1000); 292 | MICROPROFILE_COUNTER_ADD("memory/gpu/vertexbuffers", 1000); 293 | MICROPROFILE_COUNTER_ADD("memory/gpu/indexbuffers", 200); 294 | MICROPROFILE_COUNTER_ADD("memory//", 10<<10); 295 | MICROPROFILE_COUNTER_ADD("memory//main", (32ll<<30ll) + (1ll <<29ll)); 296 | MICROPROFILE_COUNTER_ADD("//memory//mainx/\\//", 1000); 297 | MICROPROFILE_COUNTER_ADD("//memoryx//mainx/", 1000); 298 | MICROPROFILE_COUNTER_ADD("//memoryy//main/", -1000000); 299 | MICROPROFILE_COUNTER_ADD("//\\\\///lala////lelel", 1000); 300 | MICROPROFILE_COUNTER_CONFIG("engine/frames", MICROPROFILE_COUNTER_FORMAT_DEFAULT, 1000, 0); 301 | MICROPROFILE_COUNTER_SET("fisk/geder/", 42); 302 | MICROPROFILE_COUNTER_SET("fisk/aborre/", -2002); 303 | MICROPROFILE_COUNTER_SET_LIMIT("fisk/aborre/", 120); 304 | static int Frames = 0; 305 | static uint64_t FramesX = 0; 306 | MICROPROFILE_COUNTER_SET_INT64_PTR("frames/int64", &FramesX); 307 | MICROPROFILE_COUNTER_SET_INT32_PTR("frames/int32", &Frames); 308 | 309 | MICROPROFILE_COUNTER_CONFIG("/test/sinus", MICROPROFILE_COUNTER_FORMAT_BYTES, 0, MICROPROFILE_COUNTER_FLAG_DETAILED); 310 | MICROPROFILE_COUNTER_CONFIG("/test/cosinus", MICROPROFILE_COUNTER_FORMAT_DEFAULT, 0, MICROPROFILE_COUNTER_FLAG_DETAILED); 311 | MICROPROFILE_COUNTER_CONFIG("/runtime/sdl_frame_events", MICROPROFILE_COUNTER_FORMAT_DEFAULT, 0, MICROPROFILE_COUNTER_FLAG_DETAILED); 312 | 313 | StartFakeWork(); 314 | while(!g_nQuit) 315 | { 316 | Frames++; 317 | FramesX += 1024*1024; 318 | MICROPROFILE_SCOPE(MAIN); 319 | MICROPROFILE_COUNTER_ADD("engine/frames", 1); 320 | 321 | SDL_Event Evt; 322 | while(SDL_PollEvent(&Evt)) 323 | { 324 | MICROPROFILE_COUNTER_LOCAL_ADD(SDLFrameEvents, 1); 325 | HandleEvent(&Evt); 326 | } 327 | 328 | MICROPROFILE_COUNTER_LOCAL_UPDATE_SET(SDLFrameEvents); 329 | glClearColor(0.3f,0.4f,0.6f,0.f); 330 | glViewport(0, 0, WIDTH, HEIGHT); 331 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 332 | 333 | 334 | #if 1||FAKE_WORK 335 | { 336 | MICROPROFILE_SCOPEI("BMain", "Dummy", 0xff3399ff); 337 | for(uint32_t i = 0; i < 14; ++i) 338 | { 339 | MICROPROFILE_SCOPEI("BMain", "1ms", 0xff3399ff); 340 | MICROPROFILE_META_CPU("Sleep",1); 341 | 342 | usleep(1000); 343 | } 344 | } 345 | #endif 346 | 347 | 348 | 349 | 350 | MicroProfileMouseButton(g_MouseDown0, g_MouseDown1); 351 | MicroProfileMousePosition(g_MouseX, g_MouseY, g_MouseDelta); 352 | g_MouseDelta = 0; 353 | 354 | 355 | MicroProfileFlip(0); 356 | static float f = 0; 357 | f += 0.1f; 358 | int sinus = (int)(10000000 * (sinf(f))); 359 | int cosinus = int(cosf(f*1.3f) * 100000 + 50000); 360 | MICROPROFILE_COUNTER_SET("/test/sinus", sinus); 361 | MICROPROFILE_COUNTER_SET("/test/cosinus", cosinus); 362 | { 363 | MICROPROFILE_SCOPEGPUI("MicroProfileDraw", 0x88dd44); 364 | float projection[16]; 365 | float left = 0.f; 366 | float right = WIDTH; 367 | float bottom = HEIGHT; 368 | float top = 0.f; 369 | float near = -1.f; 370 | float far = 1.f; 371 | memset(&projection[0], 0, sizeof(projection)); 372 | 373 | projection[0] = 2.0f / (right - left); 374 | projection[5] = 2.0f / (top - bottom); 375 | projection[10] = -2.0f / (far - near); 376 | projection[12] = - (right + left) / (right - left); 377 | projection[13] = - (top + bottom) / (top - bottom); 378 | projection[14] = - (far + near) / (far - near); 379 | projection[15] = 1.f; 380 | 381 | glEnable(GL_BLEND); 382 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 383 | glDisable(GL_DEPTH_TEST); 384 | #if MICROPROFILE_ENABLED 385 | MicroProfileBeginDraw(WIDTH, HEIGHT, &projection[0]); 386 | MicroProfileDraw(WIDTH, HEIGHT); 387 | MicroProfileEndDraw(); 388 | #endif 389 | glDisable(GL_BLEND); 390 | } 391 | 392 | MICROPROFILE_SCOPEI("MAIN", "Flip", 0xffee00); 393 | SDL_GL_SwapWindow(pWindow); 394 | } 395 | StopFakeWork(); 396 | 397 | MicroProfileShutdown(); 398 | 399 | SDL_GL_DeleteContext(glcontext); 400 | SDL_DestroyWindow(pWindow); 401 | SDL_Quit(); 402 | 403 | 404 | return 0; 405 | } 406 | -------------------------------------------------------------------------------- /demo/ui/fakework.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "microprofile.h" 4 | 5 | 6 | #if defined(__APPLE__) || defined(__linux__) 7 | #include 8 | #endif 9 | 10 | extern uint32_t g_nQuit; 11 | 12 | #ifdef _WIN32 13 | #undef near 14 | #undef far 15 | #define snprintf _snprintf 16 | #include 17 | void usleep(__int64 usec) 18 | { 19 | if(usec > 20000) 20 | { 21 | Sleep((DWORD)(usec/1000)); 22 | } 23 | else if(usec >= 1000) 24 | { 25 | timeBeginPeriod(1); 26 | Sleep((DWORD)(usec/1000)); 27 | timeEndPeriod(1); 28 | } 29 | else 30 | { 31 | __int64 time1 = 0, time2 = 0, freq = 0; 32 | QueryPerformanceCounter((LARGE_INTEGER *) &time1); 33 | QueryPerformanceFrequency((LARGE_INTEGER *)&freq); 34 | 35 | do { 36 | QueryPerformanceCounter((LARGE_INTEGER *) &time2); 37 | } while((time2-time1)*1000000ll/freq < usec); 38 | } 39 | } 40 | #endif 41 | 42 | 43 | void spinsleep(int64_t nUs) 44 | { 45 | MICROPROFILE_SCOPEI("spin","sleep", 0xffff); 46 | #if MICROPROFILE_ENABLED 47 | float fToMs = MicroProfileTickToMsMultiplier(MicroProfileTicksPerSecondCpu()); 48 | int64_t nTickStart = MP_TICK(); 49 | float fElapsed = 0; 50 | float fTarget = nUs / 1000000.f; 51 | do 52 | { 53 | int64_t nTickEnd = MP_TICK(); 54 | fElapsed = (nTickEnd - nTickStart) * fToMs; 55 | 56 | }while(fElapsed < fTarget); 57 | #endif 58 | } 59 | 60 | MICROPROFILE_DECLARE(ThreadSafeMain); 61 | MICROPROFILE_DECLARE(ThreadSafeInner0); 62 | MICROPROFILE_DECLARE(ThreadSafeInner1); 63 | MICROPROFILE_DECLARE(ThreadSafeInner2); 64 | MICROPROFILE_DECLARE(ThreadSafeInner3); 65 | MICROPROFILE_DECLARE(ThreadSafeInner4); 66 | MICROPROFILE_DEFINE(ThreadSafeInner4,"ThreadSafe", "Inner4", 0xff00ff00); 67 | MICROPROFILE_DEFINE(ThreadSafeInner3,"ThreadSafe", "Inner3", 0xff773744); 68 | MICROPROFILE_DEFINE(ThreadSafeInner2,"ThreadSafe", "Inner2", 0xff990055); 69 | MICROPROFILE_DEFINE(ThreadSafeInner1,"ThreadSafe", "Inner1", 0xffaa00aa); 70 | MICROPROFILE_DEFINE(ThreadSafeInner0,"ThreadSafe", "Inner0", 0xff00bbee); 71 | MICROPROFILE_DEFINE(ThreadSafeMain,"ThreadSafe", "Main", 0xffdd3355); 72 | 73 | 74 | 75 | void WorkerThreadLong(int threadId) 76 | { 77 | uint32_t c0 = 0xff3399ff; 78 | uint32_t c1 = 0xffff99ff; 79 | char name[100]; 80 | snprintf(name, 99, "Worker_long%d", threadId); 81 | MicroProfileOnThreadCreate(&name[0]); 82 | while(!g_nQuit) 83 | { 84 | MICROPROFILE_SCOPEI("long", "outer 150ms", c0); 85 | MICROPROFILE_META_CPU("Sleep",100); 86 | usleep(100*1000); 87 | for(int i = 0; i < 10; ++i) 88 | { 89 | MICROPROFILE_SCOPEI("long", "inner 5ms", c1); 90 | MICROPROFILE_META_CPU("Sleep",5); 91 | usleep(5000); 92 | } 93 | } 94 | } 95 | 96 | void WorkerThread(int threadId) 97 | { 98 | char name[100]; 99 | snprintf(name, 99, "Worker%d", threadId); 100 | MicroProfileOnThreadCreate(&name[0]); 101 | uint32_t c0 = 0xff3399ff; 102 | uint32_t c1 = 0xffff99ff; 103 | uint32_t c2 = 0xff33ff00; 104 | uint32_t c3 = 0xff3399ff; 105 | uint32_t c4 = 0xff33ff33; 106 | while(!g_nQuit) 107 | { 108 | switch(threadId) 109 | { 110 | case 0: 111 | { 112 | usleep(100); 113 | { 114 | MICROPROFILE_SCOPEI("Thread0", "Work Thread0", c4); 115 | MICROPROFILE_META_CPU("Sleep",10); 116 | usleep(200); 117 | { 118 | MICROPROFILE_SCOPEI("Thread0", "Work Thread1", c3); 119 | MICROPROFILE_META_CPU("DrawCalls", 1); 120 | MICROPROFILE_META_CPU("DrawCalls", 1); 121 | MICROPROFILE_META_CPU("DrawCalls", 1); 122 | usleep(200); 123 | { 124 | MICROPROFILE_SCOPEI("Thread0", "Work Thread2", c2); 125 | MICROPROFILE_META_CPU("DrawCalls", 1); 126 | usleep(200); 127 | { 128 | MICROPROFILE_SCOPEI("Thread0", "Work Thread3", c1); 129 | MICROPROFILE_META_CPU("DrawCalls", 4); 130 | MICROPROFILE_META_CPU("Triangles",1000); 131 | usleep(200); 132 | } 133 | } 134 | } 135 | } 136 | } 137 | break; 138 | 139 | case 1: 140 | { 141 | usleep(100); 142 | MICROPROFILE_SCOPEI("Thread1", "Work Thread 1", c1); 143 | usleep(2000); 144 | } 145 | break; 146 | 147 | case 2: 148 | { 149 | usleep(1000); 150 | { 151 | MICROPROFILE_SCOPEI("Thread2", "Worker2", c0); 152 | spinsleep(100000); 153 | { 154 | MICROPROFILE_SCOPEI("Thread2", "InnerWork0", c1); 155 | spinsleep(100); 156 | { 157 | MICROPROFILE_SCOPEI("Thread2", "InnerWork1", c2); 158 | usleep(100); 159 | { 160 | MICROPROFILE_SCOPEI("Thread2", "InnerWork2", c3); 161 | usleep(100); 162 | #if 0 163 | { 164 | MICROPROFILE_SCOPEI("Thread2", "InnerWork3", c4); 165 | spinsleep(50000); 166 | } 167 | #else 168 | for(uint32_t i = 0; i < 100; ++i) 169 | { 170 | MICROPROFILE_SCOPEI("Thread2xx", "Lotsofcounters", c4); 171 | spinsleep(50); 172 | } 173 | #endif 174 | } 175 | } 176 | } 177 | } 178 | } 179 | break; 180 | case 3: 181 | { 182 | MICROPROFILE_SCOPEI("ThreadWork", "MAIN", c0); 183 | usleep(1000);; 184 | for(uint32_t i = 0; i < 10; ++i) 185 | { 186 | MICROPROFILE_SCOPEI("ThreadWork", "Inner0", c1); 187 | usleep(100); 188 | for(uint32_t j = 0; j < 4; ++j) 189 | { 190 | MICROPROFILE_SCOPEI("ThreadWork", "Inner1", c4); 191 | usleep(50); 192 | MICROPROFILE_SCOPEI("ThreadWork", "Inner2", c2); 193 | usleep(50); 194 | MICROPROFILE_SCOPEI("ThreadWork", "Inner3", c3); 195 | usleep(50); 196 | MICROPROFILE_SCOPEI("ThreadWork", "Inner4", c3); 197 | usleep(50); 198 | } 199 | } 200 | 201 | 202 | } 203 | break; 204 | default: 205 | 206 | MICROPROFILE_SCOPE(ThreadSafeMain); 207 | usleep(1000);; 208 | for(uint32_t i = 0; i < 5; ++i) 209 | { 210 | MICROPROFILE_SCOPE(ThreadSafeInner0); 211 | usleep(1000); 212 | for(uint32_t j = 0; j < 4; ++j) 213 | { 214 | MICROPROFILE_META_CPU("custom_very_long_meta", 1); 215 | MICROPROFILE_SCOPE(ThreadSafeInner1); 216 | usleep(500); 217 | MICROPROFILE_SCOPE(ThreadSafeInner2); 218 | usleep(150); 219 | MICROPROFILE_SCOPE(ThreadSafeInner3); 220 | usleep(150); 221 | MICROPROFILE_SCOPE(ThreadSafeInner4); 222 | usleep(150); 223 | } 224 | } 225 | break; 226 | } 227 | } 228 | } 229 | 230 | std::thread t0; 231 | std::thread t1; 232 | std::thread t2; 233 | std::thread t3; 234 | std::thread t42; 235 | std::thread t43; 236 | std::thread t44; 237 | std::thread t45; 238 | std::thread tlong; 239 | 240 | void StartFakeWork() 241 | { 242 | t0 = std::thread(WorkerThread, 0); 243 | t1 = std::thread(WorkerThread, 1); 244 | t2 = std::thread(WorkerThread, 2); 245 | t3 = std::thread(WorkerThread, 3); 246 | t42 = std::thread(WorkerThread, 42); 247 | t43 = std::thread(WorkerThread, 43); 248 | t44 = std::thread(WorkerThread, 44); 249 | t45 = std::thread(WorkerThread, 45); 250 | tlong = std::thread(WorkerThreadLong, 0); 251 | } 252 | void StopFakeWork() 253 | { 254 | t0.join(); 255 | t1.join(); 256 | t2.join(); 257 | t3.join(); 258 | t42.join(); 259 | t43.join(); 260 | t44.join(); 261 | t45.join(); 262 | tlong.join(); 263 | } -------------------------------------------------------------------------------- /demo/ui/glinc.h: -------------------------------------------------------------------------------- 1 | // This is free and unencumbered software released into the public domain. 2 | // Anyone is free to copy, modify, publish, use, compile, sell, or 3 | // distribute this software, either in source code form or as a compiled 4 | // binary, for any purpose, commercial or non-commercial, and by any 5 | // means. 6 | // In jurisdictions that recognize copyright laws, the author or authors 7 | // of this software dedicate any and all copyright interest in the 8 | // software to the public domain. We make this dedication for the benefit 9 | // of the public at large and to the detriment of our heirs and 10 | // successors. We intend this dedication to be an overt act of 11 | // relinquishment in perpetuity of all present and future rights to this 12 | // software under copyright law. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 14 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 15 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 16 | // IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 17 | // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 18 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 19 | // OTHER DEALINGS IN THE SOFTWARE. 20 | // For more information, please refer to 21 | 22 | #ifdef _WIN32 23 | #include 24 | #endif 25 | #include 26 | #include "SDL.h" 27 | 28 | -------------------------------------------------------------------------------- /demo/ui/microprofile.cpp: -------------------------------------------------------------------------------- 1 | // This is free and unencumbered software released into the public domain. 2 | // Anyone is free to copy, modify, publish, use, compile, sell, or 3 | // distribute this software, either in source code form or as a compiled 4 | // binary, for any purpose, commercial or non-commercial, and by any 5 | // means. 6 | // In jurisdictions that recognize copyright laws, the author or authors 7 | // of this software dedicate any and all copyright interest in the 8 | // software to the public domain. We make this dedication for the benefit 9 | // of the public at large and to the detriment of our heirs and 10 | // successors. We intend this dedication to be an overt act of 11 | // relinquishment in perpetuity of all present and future rights to this 12 | // software under copyright law. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 14 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 15 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 16 | // IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 17 | // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 18 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 19 | // OTHER DEALINGS IN THE SOFTWARE. 20 | // For more information, please refer to 21 | 22 | #define MICROPROFILE_HELP_ALT "Right-Click" 23 | #define MICROPROFILE_HELP_MOD "Ctrl" 24 | 25 | #ifdef _WIN32 26 | #include 27 | #include 28 | 29 | #include 30 | void uprintf(const char* fmt, ...) 31 | { 32 | char buffer[32*1024]; 33 | va_list args; 34 | va_start (args, fmt); 35 | vsprintf_s(buffer, fmt, args); 36 | OutputDebugString(&buffer[0]); 37 | va_end (args); 38 | } 39 | //change printf function to dump in debugger 40 | #define MICROPROFILE_PRINTF uprintf 41 | #endif 42 | 43 | //#define MICROPROFILE_WEBSERVER 0 44 | #define MICROPROFILEUI_IMPL 45 | #include "microprofile.h" 46 | #include "microprofileui.h" 47 | 48 | #include "glinc.h" 49 | 50 | #if MICROPROFILE_ENABLED 51 | struct MicroProfileVertex 52 | { 53 | float nX; 54 | float nY; 55 | uint32_t nColor; 56 | float fU; 57 | float fV; 58 | }; 59 | 60 | 61 | #define MICROPROFILE_MAX_VERTICES (16<<10) 62 | #define MAX_FONT_CHARS 256 63 | #define Q0(d, member, v) d[0].member = v 64 | #define Q1(d, member, v) d[1].member = v; d[3].member = v 65 | #define Q2(d, member, v) d[4].member = v 66 | #define Q3(d, member, v) d[2].member = v; d[5].member = v 67 | 68 | void MicroProfileFlush(); 69 | namespace 70 | { 71 | uint32_t nVertexPos = 0; 72 | MicroProfileVertex nDrawBuffer[MICROPROFILE_MAX_VERTICES]; 73 | enum 74 | { 75 | MAX_COMMANDS = 1024, 76 | }; 77 | struct 78 | { 79 | uint32_t nCommand; 80 | uint32_t nNumVertices; 81 | } DrawCommands[MAX_COMMANDS]; 82 | 83 | int32_t nNumDrawCommands; 84 | uint32_t g_nW; 85 | uint32_t g_nH; 86 | uint32_t g_VAO; 87 | uint32_t g_VertexBuffer; 88 | int g_LocVertexIn; 89 | int g_LocColorIn; 90 | int g_LocTC0In; 91 | int g_LocTex; 92 | int g_LocProjectionMatrix; 93 | int g_LocfRcpFontHeight; 94 | 95 | float g_Projection[16]; 96 | 97 | 98 | GLuint g_VertexShader; 99 | GLuint g_PixelShader; 100 | GLuint g_Program; 101 | GLuint g_FontTexture; 102 | 103 | 104 | struct SFontDescription 105 | { 106 | uint16_t nCharOffsets[MAX_FONT_CHARS]; 107 | uint32_t nTextureId; 108 | }; 109 | 110 | extern unsigned char g_Font[]; 111 | SFontDescription g_FontDescription; 112 | 113 | 114 | const char* g_PixelShaderCode = "\ 115 | #version 150 \n \ 116 | uniform sampler2D tex; \ 117 | uniform float fRcpFontHeight; \ 118 | in vec2 TC0; \ 119 | in vec4 Color; \ 120 | out vec4 Out0; \ 121 | \ 122 | void main(void) \ 123 | { \ 124 | vec4 color = texture(tex, TC0.xy); \ 125 | if(TC0.x > 1.0 ) \ 126 | { \ 127 | Out0.xyz = Color.xyz; \ 128 | Out0.w = Color.w; \ 129 | } \ 130 | else \ 131 | { \ 132 | vec4 c1 = texture(tex, TC0.xy + vec2(0.0, fRcpFontHeight));\ 133 | Out0 = color * Color; \ 134 | if(color.w < 0.5){ \ 135 | Out0 = vec4(0,0,0,c1.w);\ 136 | }\ 137 | } \ 138 | } \ 139 | "; 140 | const char* g_VertexShaderCode = " \ 141 | #version 150 \n \ 142 | uniform mat4 ProjectionMatrix; \ 143 | in vec3 VertexIn; \ 144 | in vec4 ColorIn; \ 145 | in vec2 TC0In; \ 146 | out vec2 TC0; \ 147 | out vec4 Color; \ 148 | \ 149 | void main(void) \ 150 | { \ 151 | Color = ColorIn; \ 152 | TC0 = TC0In; \ 153 | gl_Position = ProjectionMatrix * vec4(VertexIn, 1.0); \ 154 | } \ 155 | "; 156 | 157 | 158 | 159 | MicroProfileVertex* PushVertices(uint32_t nCommand, int nCount) 160 | { 161 | if(nVertexPos + nCount > MICROPROFILE_MAX_VERTICES) 162 | { 163 | MicroProfileFlush(); 164 | } 165 | MP_ASSERT(nVertexPos + nCount <= MICROPROFILE_MAX_VERTICES); 166 | 167 | uint32_t nOut = nVertexPos; 168 | nVertexPos += nCount; 169 | 170 | if(nNumDrawCommands && DrawCommands[nNumDrawCommands-1].nCommand == nCommand) 171 | { 172 | DrawCommands[nNumDrawCommands-1].nNumVertices += nCount; 173 | } 174 | else 175 | { 176 | MP_ASSERT(nNumDrawCommands < MAX_COMMANDS); 177 | DrawCommands[nNumDrawCommands].nCommand = nCommand; 178 | DrawCommands[nNumDrawCommands].nNumVertices = nCount; 179 | ++nNumDrawCommands; 180 | } 181 | return &nDrawBuffer[nOut]; 182 | } 183 | void DumpGlLog(GLuint handle) 184 | { 185 | int nLogLen = 0; 186 | return;//temp hack 187 | MP_ASSERT(0 == glGetError()); 188 | glGetObjectParameterivARB(handle, GL_OBJECT_INFO_LOG_LENGTH_ARB, &nLogLen); 189 | if(nLogLen > 1) 190 | { 191 | char* pChars = (char*)malloc(nLogLen); 192 | int nLen = 0; 193 | glGetInfoLogARB(handle, nLogLen, &nLen, pChars); 194 | 195 | printf("COMPILE MESSAGE\n%s\n\n", pChars); 196 | 197 | free(pChars); 198 | MP_BREAK(); 199 | } 200 | MP_ASSERT(0 == glGetError()); 201 | } 202 | 203 | GLuint CreateProgram(int nType, const char* pShader) 204 | { 205 | MP_ASSERT(0 == glGetError()); 206 | GLuint handle = glCreateShaderObjectARB(nType); 207 | glShaderSource(handle, 1, (const char**)&pShader, 0); 208 | glCompileShader(handle); 209 | DumpGlLog(handle); 210 | MP_ASSERT(handle); 211 | MP_ASSERT(0 == glGetError()); 212 | return handle; 213 | } 214 | } 215 | 216 | #define FONT_TEX_X 1024 217 | #define FONT_TEX_Y 9 218 | #define UNPACKED_SIZE (FONT_TEX_X*FONT_TEX_Y * 4) 219 | 220 | 221 | void MicroProfileDrawInit() 222 | { 223 | glGenBuffers(1, &g_VertexBuffer); 224 | glGenVertexArrays(1, &g_VAO); 225 | g_PixelShader = CreateProgram(GL_FRAGMENT_SHADER_ARB, g_PixelShaderCode); 226 | g_VertexShader = CreateProgram(GL_VERTEX_SHADER_ARB, g_VertexShaderCode); 227 | g_Program = glCreateProgramObjectARB(); 228 | glAttachObjectARB(g_Program, g_PixelShader); 229 | glAttachObjectARB(g_Program, g_VertexShader); 230 | 231 | g_LocVertexIn = 1; 232 | g_LocColorIn = 2; 233 | g_LocTC0In = 3; 234 | 235 | glBindAttribLocation(g_Program, g_LocColorIn, "ColorIn"); 236 | glBindAttribLocation(g_Program, g_LocVertexIn, "VertexIn"); 237 | glBindAttribLocation(g_Program, g_LocTC0In, "TC0In"); 238 | glLinkProgramARB(g_Program); 239 | DumpGlLog(g_Program); 240 | 241 | g_LocTex = glGetUniformLocation(g_Program, "tex"); 242 | g_LocProjectionMatrix = glGetUniformLocation(g_Program, "ProjectionMatrix"); 243 | g_LocfRcpFontHeight = glGetUniformLocation(g_Program, "fRcpFontHeight"); 244 | 245 | for(uint32_t i = 0; i < MAX_FONT_CHARS; ++i) 246 | { 247 | g_FontDescription.nCharOffsets[i] = 206; 248 | } 249 | for(uint32_t i = 'A'; i <= 'Z'; ++i) 250 | { 251 | g_FontDescription.nCharOffsets[i] = (i-'A')*8+1; 252 | } 253 | for(uint32_t i = 'a'; i <= 'z'; ++i) 254 | { 255 | g_FontDescription.nCharOffsets[i] = (i-'a')*8+217; 256 | } 257 | for(uint32_t i = '0'; i <= '9'; ++i) 258 | { 259 | g_FontDescription.nCharOffsets[i] = (i-'0')*8+433; 260 | } 261 | for(uint32_t i = '!'; i <= '/'; ++i) 262 | { 263 | g_FontDescription.nCharOffsets[i] = (i-'!')*8+513; 264 | } 265 | for(uint32_t i = ':'; i <= '@'; ++i) 266 | { 267 | g_FontDescription.nCharOffsets[i] = (i-':')*8+625+8; 268 | } 269 | for(uint32_t i = '['; i <= '_'; ++i) 270 | { 271 | g_FontDescription.nCharOffsets[i] = (i-'[')*8+681+8; 272 | } 273 | for(uint32_t i = '{'; i <= '~'; ++i) 274 | { 275 | g_FontDescription.nCharOffsets[i] = (i-'{')*8+721+8; 276 | } 277 | 278 | uint32_t* pUnpacked = (uint32_t*)alloca(UNPACKED_SIZE); 279 | int idx = 0; 280 | int end = FONT_TEX_X * FONT_TEX_Y / 8; 281 | for(int i = 0; i < end; i++) 282 | { 283 | unsigned char pValue = g_Font[i]; 284 | for(int j = 0; j < 8; ++j) 285 | { 286 | pUnpacked[idx++] = pValue & 0x80 ? (uint32_t)-1 : 0; 287 | pValue <<= 1; 288 | } 289 | } 290 | uint32_t* p4 = &pUnpacked[0]; 291 | glGenTextures(1, &g_FontTexture); 292 | glBindTexture(GL_TEXTURE_2D, g_FontTexture); 293 | { 294 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 295 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 296 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 297 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 298 | } 299 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, FONT_TEX_X, FONT_TEX_Y, 0, GL_RGBA, GL_UNSIGNED_BYTE, &p4[0]); 300 | glBindTexture(GL_TEXTURE_2D, 0); 301 | } 302 | 303 | void MicroProfileBeginDraw(uint32_t nWidth, uint32_t nHeight, float* prj) 304 | { 305 | memcpy(g_Projection, prj, sizeof(float)*16); 306 | g_nW = nWidth; 307 | g_nH = nHeight; 308 | nVertexPos = 0; 309 | nNumDrawCommands = 0; 310 | } 311 | void MicroProfileFlush() 312 | { 313 | if(0 == nVertexPos) 314 | return; 315 | MICROPROFILE_SCOPEI("MicroProfile", "Flush", 0xffff3456); 316 | MICROPROFILE_SCOPEGPUI("FlushDraw", 0xffff4444); 317 | 318 | 319 | 320 | glUseProgramObjectARB(g_Program); 321 | 322 | 323 | glUniform1i(g_LocTex, 0); 324 | glUniformMatrix4fv(g_LocProjectionMatrix, 1, 0, g_Projection); 325 | glUniform1f(g_LocfRcpFontHeight, 1.0f / FONT_TEX_Y); 326 | 327 | glActiveTexture(GL_TEXTURE0); 328 | glBindTexture(GL_TEXTURE_2D, g_FontTexture); 329 | 330 | 331 | glBindVertexArray(g_VAO); 332 | 333 | 334 | glBindBuffer(GL_ARRAY_BUFFER, g_VertexBuffer); 335 | glBufferData(GL_ARRAY_BUFFER, sizeof(nDrawBuffer), &nDrawBuffer[0], GL_STREAM_DRAW); 336 | int nStride = sizeof(MicroProfileVertex); 337 | glVertexAttribPointer(g_LocVertexIn, 2, GL_FLOAT, 0 , nStride, 0); 338 | glVertexAttribPointer(g_LocColorIn, 4, GL_UNSIGNED_BYTE, GL_TRUE, nStride, (void*)(offsetof(MicroProfileVertex, nColor))); 339 | glVertexAttribPointer(g_LocTC0In, 2, GL_FLOAT, 0, nStride, (void*)(offsetof(MicroProfileVertex, fU))); 340 | glEnableVertexAttribArray(g_LocVertexIn); 341 | glEnableVertexAttribArray(g_LocColorIn); 342 | glEnableVertexAttribArray(g_LocTC0In); 343 | 344 | int nOffset = 0; 345 | for(int i = 0; i < nNumDrawCommands; ++i) 346 | { 347 | int nCount = DrawCommands[i].nNumVertices; 348 | glDrawArrays(DrawCommands[i].nCommand, nOffset, nCount); 349 | nOffset += nCount; 350 | } 351 | glDisableVertexAttribArray(g_LocVertexIn); 352 | glDisableVertexAttribArray(g_LocColorIn); 353 | glDisableVertexAttribArray(g_LocTC0In); 354 | 355 | glBindBuffer(GL_ARRAY_BUFFER, 0); 356 | glUseProgramObjectARB(0); 357 | glBindVertexArray(0); 358 | nVertexPos = 0; 359 | nNumDrawCommands = 0; 360 | } 361 | void MicroProfileEndDraw() 362 | { 363 | MicroProfileFlush(); 364 | 365 | } 366 | 367 | 368 | #if MICROPROFILEUI_ENABLED 369 | void MicroProfileDrawText(int nX, int nY, uint32_t nColor, const char* pText, uint32_t nLen) 370 | { 371 | MICROPROFILE_SCOPEI("MicroProfile", "TextDraw", 0xff88ee); 372 | const float fOffsetU = 5.f / 1024.f; 373 | MP_ASSERT(nLen <= strlen(pText)); 374 | float fX = (float)nX; 375 | float fY = (float)nY; 376 | float fY2 = fY + (MICROPROFILE_TEXT_HEIGHT+1); 377 | 378 | MicroProfileVertex* pVertex = PushVertices(GL_TRIANGLES, 6 * nLen); 379 | const char* pStr = pText; 380 | nColor = 0xff000000|((nColor&0xff)<<16)|(nColor&0xff00)|((nColor>>16)&0xff); 381 | 382 | for(uint32_t j = 0; j < nLen; ++j) 383 | { 384 | int16_t nOffset = g_FontDescription.nCharOffsets[(int)*pStr++]; 385 | float fOffset = nOffset / 1024.f; 386 | Q0(pVertex,nX, fX); 387 | Q0(pVertex,nY, fY); 388 | Q0(pVertex,nColor, nColor); 389 | Q0(pVertex,fU, fOffset); 390 | Q0(pVertex,fV, 0.f); 391 | 392 | Q1(pVertex, nX, fX+MICROPROFILE_TEXT_WIDTH); 393 | Q1(pVertex, nY, fY); 394 | Q1(pVertex, nColor, nColor); 395 | Q1(pVertex, fU, fOffset+fOffsetU); 396 | Q1(pVertex, fV, 0.f); 397 | 398 | Q2(pVertex, nX, fX+MICROPROFILE_TEXT_WIDTH); 399 | Q2(pVertex, nY, fY2); 400 | Q2(pVertex, nColor, nColor); 401 | Q2(pVertex, fU, fOffset+fOffsetU); 402 | Q2(pVertex, fV, 1.f); 403 | 404 | 405 | Q3(pVertex, nX, fX); 406 | Q3(pVertex, nY, fY2); 407 | Q3(pVertex, nColor, nColor); 408 | Q3(pVertex, fU, fOffset); 409 | Q3(pVertex, fV, 1.f); 410 | 411 | fX += MICROPROFILE_TEXT_WIDTH+1; 412 | pVertex += 6; 413 | } 414 | } 415 | void MicroProfileDrawBox(int nX0, int nY0, int nX1, int nY1, uint32_t nColor, MicroProfileBoxType Type) 416 | { 417 | if(Type == MicroProfileBoxTypeFlat) 418 | { 419 | nColor = ((nColor&0xff)<<16)|((nColor>>16)&0xff)|(0xff00ff00&nColor); 420 | MicroProfileVertex* pVertex = PushVertices(GL_TRIANGLES, 6); 421 | Q0(pVertex, nX, (float)nX0); 422 | Q0(pVertex, nY, (float)nY0); 423 | Q0(pVertex, nColor, nColor); 424 | Q0(pVertex, fU, 2.f); 425 | Q0(pVertex, fV, 2.f); 426 | Q1(pVertex, nX, (float)nX1); 427 | Q1(pVertex, nY, (float)nY0); 428 | Q1(pVertex, nColor, nColor); 429 | Q1(pVertex, fU, 2.f); 430 | Q1(pVertex, fV, 2.f); 431 | Q2(pVertex, nX, (float)nX1); 432 | Q2(pVertex, nY, (float)nY1); 433 | Q2(pVertex, nColor, nColor); 434 | Q2(pVertex, fU, 2.f); 435 | Q2(pVertex, fV, 2.f); 436 | Q3(pVertex, nX, (float)nX0); 437 | Q3(pVertex, nY, (float)nY1); 438 | Q3(pVertex, nColor, nColor); 439 | Q3(pVertex, fU, 2.f); 440 | Q3(pVertex, fV, 2.f); 441 | } 442 | else 443 | { 444 | uint32_t r = 0xff & (nColor>>16); 445 | uint32_t g = 0xff & (nColor>>8); 446 | uint32_t b = 0xff & nColor; 447 | uint32_t nMax = MicroProfileMax(MicroProfileMax(MicroProfileMax(r, g), b), 30u); 448 | uint32_t nMin = MicroProfileMin(MicroProfileMin(MicroProfileMin(r, g), b), 180u); 449 | 450 | uint32_t r0 = 0xff & ((r + nMax)/2); 451 | uint32_t g0 = 0xff & ((g + nMax)/2); 452 | uint32_t b0 = 0xff & ((b + nMax)/2); 453 | 454 | uint32_t r1 = 0xff & ((r+nMin)/2); 455 | uint32_t g1 = 0xff & ((g+nMin)/2); 456 | uint32_t b1 = 0xff & ((b+nMin)/2); 457 | uint32_t nColor0 = (r0<<0)|(g0<<8)|(b0<<16)|(0xff000000&nColor); 458 | uint32_t nColor1 = (r1<<0)|(g1<<8)|(b1<<16)|(0xff000000&nColor); 459 | MicroProfileVertex* pVertex = PushVertices(GL_TRIANGLES, 6); 460 | Q0(pVertex, nX, (float)nX0); 461 | Q0(pVertex, nY, (float)nY0); 462 | Q0(pVertex, nColor, nColor0); 463 | Q0(pVertex, fU, 2.f); 464 | Q0(pVertex, fV, 2.f); 465 | Q1(pVertex, nX, (float)nX1); 466 | Q1(pVertex, nY, (float)nY0); 467 | Q1(pVertex, nColor, nColor0); 468 | Q1(pVertex, fU, 3.f); 469 | Q1(pVertex, fV, 2.f); 470 | Q2(pVertex, nX, (float)nX1); 471 | Q2(pVertex, nY, (float)nY1); 472 | Q2(pVertex, nColor, nColor1); 473 | Q2(pVertex, fU, 3.f); 474 | Q2(pVertex, fV, 3.f); 475 | Q3(pVertex, nX, (float)nX0); 476 | Q3(pVertex, nY, (float)nY1); 477 | Q3(pVertex, nColor, nColor1); 478 | Q3(pVertex, fU, 2.f); 479 | Q3(pVertex, fV, 3.f); 480 | } 481 | } 482 | 483 | 484 | void MicroProfileDrawLine2D(uint32_t nVertices, float* pVertices, uint32_t nColor) 485 | { 486 | if(!nVertices) return; 487 | 488 | MicroProfileVertex* pVertex = PushVertices(GL_LINES, 2*(nVertices-1)); 489 | nColor = ((nColor&0xff)<<16)|(nColor&0xff00ff00)|((nColor>>16)&0xff); 490 | for(uint32_t i = 0; i < nVertices-1; ++i) 491 | { 492 | pVertex[0].nX = pVertices[i*2]; 493 | pVertex[0].nY = pVertices[i*2+1] ; 494 | pVertex[0].nColor = nColor; 495 | pVertex[0].fU = 2.f; 496 | pVertex[0].fV = 2.f; 497 | pVertex[1].nX = pVertices[(i+1)*2]; 498 | pVertex[1].nY = pVertices[(i+1)*2+1] ; 499 | pVertex[1].nColor = nColor; 500 | pVertex[1].fU = 2.f; 501 | pVertex[1].fV = 2.f; 502 | pVertex += 2; 503 | } 504 | } 505 | #endif 506 | 507 | namespace 508 | { 509 | unsigned char g_Font[] = 510 | { 511 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 512 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 513 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 514 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 515 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 516 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 517 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 518 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 519 | 0x10,0x78,0x38,0x78,0x7c,0x7c,0x3c,0x44,0x38,0x04,0x44,0x40,0x44,0x44,0x38,0x78, 520 | 0x38,0x78,0x38,0x7c,0x44,0x44,0x44,0x44,0x44,0x7c,0x00,0x00,0x40,0x00,0x04,0x00, 521 | 0x18,0x00,0x40,0x10,0x08,0x40,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00, 522 | 0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0x38,0x7c,0x08,0x7c,0x1c,0x7c,0x38,0x38, 523 | 0x10,0x28,0x28,0x10,0x00,0x20,0x10,0x08,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x00, 524 | 0x00,0x04,0x00,0x20,0x38,0x38,0x70,0x00,0x1c,0x10,0x00,0x1c,0x10,0x70,0x30,0x00, 525 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 526 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 527 | 0x28,0x44,0x44,0x44,0x40,0x40,0x40,0x44,0x10,0x04,0x48,0x40,0x6c,0x44,0x44,0x44, 528 | 0x44,0x44,0x44,0x10,0x44,0x44,0x44,0x44,0x44,0x04,0x00,0x00,0x40,0x00,0x04,0x00, 529 | 0x24,0x00,0x40,0x00,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00, 530 | 0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x30,0x44,0x04,0x18,0x40,0x20,0x04,0x44,0x44, 531 | 0x10,0x28,0x28,0x3c,0x44,0x50,0x10,0x10,0x08,0x54,0x10,0x00,0x00,0x00,0x04,0x00, 532 | 0x00,0x08,0x00,0x10,0x44,0x44,0x40,0x40,0x04,0x28,0x00,0x30,0x10,0x18,0x58,0x00, 533 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 534 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 535 | 0x44,0x44,0x40,0x44,0x40,0x40,0x40,0x44,0x10,0x04,0x50,0x40,0x54,0x64,0x44,0x44, 536 | 0x44,0x44,0x40,0x10,0x44,0x44,0x44,0x28,0x28,0x08,0x00,0x38,0x78,0x3c,0x3c,0x38, 537 | 0x20,0x38,0x78,0x30,0x18,0x44,0x10,0x6c,0x78,0x38,0x78,0x3c,0x5c,0x3c,0x3c,0x44, 538 | 0x44,0x44,0x44,0x44,0x7c,0x00,0x4c,0x10,0x04,0x08,0x28,0x78,0x40,0x08,0x44,0x44, 539 | 0x10,0x00,0x7c,0x50,0x08,0x50,0x00,0x20,0x04,0x38,0x10,0x00,0x00,0x00,0x08,0x10, 540 | 0x10,0x10,0x7c,0x08,0x08,0x54,0x40,0x20,0x04,0x44,0x00,0x30,0x10,0x18,0x00,0x00, 541 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 542 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 543 | 0x44,0x78,0x40,0x44,0x78,0x78,0x40,0x7c,0x10,0x04,0x60,0x40,0x54,0x54,0x44,0x78, 544 | 0x44,0x78,0x38,0x10,0x44,0x44,0x54,0x10,0x10,0x10,0x00,0x04,0x44,0x40,0x44,0x44, 545 | 0x78,0x44,0x44,0x10,0x08,0x48,0x10,0x54,0x44,0x44,0x44,0x44,0x60,0x40,0x10,0x44, 546 | 0x44,0x44,0x28,0x44,0x08,0x00,0x54,0x10,0x18,0x18,0x48,0x04,0x78,0x10,0x38,0x3c, 547 | 0x10,0x00,0x28,0x38,0x10,0x20,0x00,0x20,0x04,0x10,0x7c,0x00,0x7c,0x00,0x10,0x00, 548 | 0x00,0x20,0x00,0x04,0x10,0x5c,0x40,0x10,0x04,0x00,0x00,0x60,0x10,0x0c,0x00,0x00, 549 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 550 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 551 | 0x7c,0x44,0x40,0x44,0x40,0x40,0x4c,0x44,0x10,0x04,0x50,0x40,0x44,0x4c,0x44,0x40, 552 | 0x54,0x50,0x04,0x10,0x44,0x44,0x54,0x28,0x10,0x20,0x00,0x3c,0x44,0x40,0x44,0x7c, 553 | 0x20,0x44,0x44,0x10,0x08,0x70,0x10,0x54,0x44,0x44,0x44,0x44,0x40,0x38,0x10,0x44, 554 | 0x44,0x54,0x10,0x44,0x10,0x00,0x64,0x10,0x20,0x04,0x7c,0x04,0x44,0x20,0x44,0x04, 555 | 0x10,0x00,0x7c,0x14,0x20,0x54,0x00,0x20,0x04,0x38,0x10,0x10,0x00,0x00,0x20,0x10, 556 | 0x10,0x10,0x7c,0x08,0x10,0x58,0x40,0x08,0x04,0x00,0x00,0x30,0x10,0x18,0x00,0x00, 557 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 558 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 559 | 0x44,0x44,0x44,0x44,0x40,0x40,0x44,0x44,0x10,0x44,0x48,0x40,0x44,0x44,0x44,0x40, 560 | 0x48,0x48,0x44,0x10,0x44,0x28,0x6c,0x44,0x10,0x40,0x00,0x44,0x44,0x40,0x44,0x40, 561 | 0x20,0x3c,0x44,0x10,0x08,0x48,0x10,0x54,0x44,0x44,0x44,0x44,0x40,0x04,0x12,0x4c, 562 | 0x28,0x54,0x28,0x3c,0x20,0x00,0x44,0x10,0x40,0x44,0x08,0x44,0x44,0x20,0x44,0x08, 563 | 0x00,0x00,0x28,0x78,0x44,0x48,0x00,0x10,0x08,0x54,0x10,0x10,0x00,0x00,0x40,0x00, 564 | 0x10,0x08,0x00,0x10,0x00,0x40,0x40,0x04,0x04,0x00,0x00,0x30,0x10,0x18,0x00,0x00, 565 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 566 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 567 | 0x44,0x78,0x38,0x78,0x7c,0x40,0x3c,0x44,0x38,0x38,0x44,0x7c,0x44,0x44,0x38,0x40, 568 | 0x34,0x44,0x38,0x10,0x38,0x10,0x44,0x44,0x10,0x7c,0x00,0x3c,0x78,0x3c,0x3c,0x3c, 569 | 0x20,0x04,0x44,0x38,0x48,0x44,0x38,0x44,0x44,0x38,0x78,0x3c,0x40,0x78,0x0c,0x34, 570 | 0x10,0x6c,0x44,0x04,0x7c,0x00,0x38,0x38,0x7c,0x38,0x08,0x38,0x38,0x20,0x38,0x70, 571 | 0x10,0x00,0x28,0x10,0x00,0x34,0x00,0x08,0x10,0x10,0x00,0x20,0x00,0x10,0x00,0x00, 572 | 0x20,0x04,0x00,0x20,0x10,0x3c,0x70,0x00,0x1c,0x00,0x7c,0x1c,0x10,0x70,0x00,0x00, 573 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 574 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 575 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 576 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 577 | 0x00,0x38,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x40,0x04,0x00,0x00,0x00,0x00, 578 | 0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 579 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 580 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 581 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 582 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 583 | }; 584 | 585 | } 586 | #endif 587 | -------------------------------------------------------------------------------- /demo/ui/ui.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {533791DB-8915-41AB-8201-0D605723DA32} 23 | Win32Proj 24 | ui 25 | 8.1 26 | 27 | 28 | 29 | Application 30 | true 31 | v140 32 | MultiByte 33 | 34 | 35 | Application 36 | false 37 | v140 38 | true 39 | MultiByte 40 | 41 | 42 | Application 43 | true 44 | v140 45 | MultiByte 46 | 47 | 48 | Application 49 | false 50 | v140 51 | true 52 | MultiByte 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | true 74 | 75 | 76 | true 77 | 78 | 79 | false 80 | 81 | 82 | false 83 | 84 | 85 | 86 | 87 | 88 | Level3 89 | Disabled 90 | MICROPROFILE_ENABLED=1;MICROPROFILE_GPU_TIMERS_MULTITHREADED=1;MICROPROFILE_UI=1;GLEW_STATIC; _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) 91 | true 92 | ../..;../glew;../sdl2/include 93 | 94 | 95 | Console 96 | true 97 | Shell32.lib;Advapi32.lib;opengl32.lib;glu32.lib;winmm.lib;dxguid.lib;ws2_32.lib;../sdl2/visualc/win32/release/sdl2.lib 98 | 99 | 100 | copy ..\sdl2\visualc\win32\release\sdl2.dll $(TARGETDIR) 101 | copy ..\..\bin\microprofile-win32-cswitch_$(PlatformTarget).exe $(ProjectDir) 102 | 103 | 104 | 105 | 106 | 107 | 108 | Level3 109 | Disabled 110 | MICROPROFILE_ENABLED=1;MICROPROFILE_GPU_TIMERS_MULTITHREADED=1;MICROPROFILEUI_ENABLED=1;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) 111 | true 112 | ../..;../glew;../sdl2/include 113 | 114 | 115 | Console 116 | true 117 | Shell32.lib;Advapi32.lib;opengl32.lib;glu32.lib;winmm.lib;dxguid.lib;ws2_32.lib;../sdl2/visualc/x64/release/sdl2.lib 118 | 119 | 120 | copy ..\sdl2\visualc\x64\release\sdl2.dll $(TARGETDIR) 121 | copy ..\..\bin\microprofile-win32-cswitch_$(PlatformTarget).exe $(ProjectDir) 122 | 123 | 124 | 125 | 126 | Level3 127 | 128 | 129 | MaxSpeed 130 | true 131 | true 132 | MICROPROFILE_ENABLED=1;MICROPROFILE_GPU_TIMERS_MULTITHREADED=1;MICROPROFILE_UI=1;GLEW_STATIC; _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) 133 | true 134 | ../..;../glew;../sdl2/include 135 | 136 | 137 | Console 138 | true 139 | true 140 | true 141 | Shell32.lib;Advapi32.lib;opengl32.lib;glu32.lib;winmm.lib;dxguid.lib;ws2_32.lib;../sdl2/visualc/win32/release/sdl2.lib 142 | 143 | 144 | copy ..\sdl2\visualc\win32\release\sdl2.dll $(TARGETDIR) 145 | copy ..\..\bin\microprofile-win32-cswitch_$(PlatformTarget).exe $(ProjectDir) 146 | 147 | 148 | 149 | 150 | Level3 151 | 152 | 153 | MaxSpeed 154 | true 155 | true 156 | MICROPROFILE_ENABLED=1;MICROPROFILE_GPU_TIMERS_MULTITHREADED=1;MICROPROFILEUI_ENABLED=1;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) 157 | true 158 | ../..;../glew;../sdl2/include 159 | 160 | 161 | Console 162 | true 163 | true 164 | true 165 | Shell32.lib;Advapi32.lib;opengl32.lib;glu32.lib;winmm.lib;dxguid.lib;ws2_32.lib;../sdl2/visualc/x64/release/sdl2.lib 166 | 167 | 168 | copy ..\sdl2\visualc\x64\release\sdl2.dll $(TARGETDIR) 169 | copy ..\..\bin\microprofile-win32-cswitch_$(PlatformTarget).exe $(ProjectDir) 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | -------------------------------------------------------------------------------- /demo/ui/ui.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /microprofile-dev.sublime-project: -------------------------------------------------------------------------------- 1 | { 2 | "folders": 3 | [ 4 | { 5 | "follow_symlinks": true, 6 | "path": "." 7 | } 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | 2 | CC=clang 3 | CPP=clang++ 4 | LD=clang++ 5 | TARGET=../microprofile_html.h 6 | 7 | all: $(TARGET) 8 | 9 | embed: embed.c 10 | clang -g embed.c -o embed 11 | 12 | $(TARGET): embed microprofile.html 13 | ./embed $(TARGET) microprofile.html ____embed____ g_MicroProfileHtml MICROPROFILE_EMBED_HTML 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/dtrace_contextswitch: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | #copy to working directory and run before enabling context-switch trace 3 | mkfifo mypipe 4 | sudo dtrace -n fbt::thread_dispatch:return'{printf("X%dX%dX%d", cpu, tid, walltimestamp)}' -o mypipe 5 | rm mypipe -------------------------------------------------------------------------------- /src/embed.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | //minimal tool to embed src html into microprofile.h 5 | 6 | char* ReadFile(const char* pFile) 7 | { 8 | FILE* F = fopen(pFile, "r"); 9 | 10 | if(!F) return 0; 11 | fseek(F, 0, SEEK_END); 12 | long size = ftell(F); 13 | char* pData = (char*)malloc(size + 1); 14 | fseek(F, 0, SEEK_SET); 15 | size = fread(pData, 1, size, F); 16 | fclose(F); 17 | 18 | pData[size] = '\0'; 19 | return pData; 20 | } 21 | void DumpFile(FILE* pOut, const char* pEmbedData, const char* pPrefix, const char* pSuffix) 22 | { 23 | 24 | // fprintf(pOut, "const char %s_begin[] =\n\"", pSymbolArg); 25 | // DumpFile(pOut, pEmbedStart, pSymbolArg, "_begin"); 26 | // fprintf(pOut, "\";\n\n"); 27 | // fprintf(pOut, "const size_t %s_begin_size = sizeof(%s_begin);\n", pSymbolArg, pSymbolArg); 28 | 29 | 30 | size_t len = strlen(pEmbedData); 31 | int nNumBlocks = 0; 32 | while(len) 33 | { 34 | //split into 10k chunks.. because of visual studio.. 35 | size_t nChunk = len > (32<<10) ? (32<<10) : len; 36 | len -= nChunk; 37 | fprintf(pOut, "const char %s%s_%d[] =\n\"", pPrefix, pSuffix, nNumBlocks); 38 | for(size_t i = 0; i < nChunk; ++i) 39 | { 40 | char c = *pEmbedData++; 41 | switch(c) 42 | { 43 | case '\n': 44 | #ifdef _WIN32 45 | fprintf(pOut, "\\n\"\n\""); 46 | #else 47 | fprintf(pOut, "\\n\"\r\n\""); 48 | #endif 49 | break; 50 | case '\\': 51 | fprintf(pOut, "\\"); 52 | break; 53 | case '\"': 54 | fprintf(pOut, "\\\""); 55 | break; 56 | case '\'': 57 | fprintf(pOut, "\\\'"); 58 | break; 59 | default: 60 | fprintf(pOut, "%c", c); 61 | } 62 | } 63 | fprintf(pOut, "\";\n\n"); 64 | fprintf(pOut, "const size_t %s%s_%d_size = sizeof(%s%s_%d);\n", pPrefix, pSuffix, nNumBlocks, pPrefix, pSuffix, nNumBlocks); 65 | nNumBlocks++; 66 | } 67 | fprintf(pOut, "const char* %s%s[] = {\n", pPrefix, pSuffix); 68 | for(int i = 0; i < nNumBlocks; ++i) 69 | { 70 | fprintf(pOut, "&%s%s_%d[0],\n", pPrefix, pSuffix, i); 71 | } 72 | fprintf(pOut, "};\n"); 73 | 74 | fprintf(pOut, "size_t %s%s_sizes[] = {\n", pPrefix, pSuffix); 75 | for(int i = 0; i < nNumBlocks; ++i) 76 | { 77 | fprintf(pOut, "sizeof(%s%s_%d),\n", pPrefix, pSuffix, i); 78 | } 79 | fprintf(pOut, "};\n"); 80 | fprintf(pOut, "size_t %s%s_count = %d;\n", pPrefix, pSuffix, nNumBlocks); 81 | } 82 | 83 | 84 | int main(int argc, char* argv[]) 85 | { 86 | if(6 != argc) 87 | { 88 | printf("Syntax: %s dest embedsource pattern symbol define\n", argv[0]); 89 | return 1; 90 | } 91 | const char* pDestArg = argv[1]; 92 | const char* pEmbedSourceArg = argv[2]; 93 | const char* pPatternArg = argv[3]; 94 | const char* pSymbolArg = argv[4]; 95 | const char* pDefineArg = argv[5]; 96 | 97 | char* pEmbedSrc = ReadFile(pEmbedSourceArg); 98 | 99 | if(!pEmbedSrc) 100 | { 101 | return 1; 102 | } 103 | 104 | char* pEmbedStart = pEmbedSrc; 105 | char* pEmbedStartEnd = strstr(pEmbedStart, pPatternArg); 106 | char* pEmbedEnd = pEmbedStartEnd + strlen(pPatternArg); 107 | *pEmbedStartEnd = '\0'; 108 | 109 | FILE* pOut = fopen(pDestArg, "w"); 110 | if(!pOut) 111 | { 112 | free(pEmbedSrc); 113 | return 1; 114 | } 115 | fprintf(pOut, "///start file generated from %s\n", pEmbedSourceArg); 116 | fprintf(pOut, "#ifdef %s\n", pDefineArg); 117 | DumpFile(pOut, pEmbedStart, pSymbolArg, "_begin"); 118 | DumpFile(pOut, pEmbedEnd, pSymbolArg, "_end"); 119 | fprintf(pOut, "#endif //%s\n", pDefineArg); 120 | fprintf(pOut, "\n///end file generated from %s\n", pEmbedSourceArg); 121 | fclose(pOut); 122 | free(pEmbedSrc); 123 | 124 | return 0; 125 | } -------------------------------------------------------------------------------- /src/microprofile-win32-cswitch/main.cpp: -------------------------------------------------------------------------------- 1 | #define MICROPROFILE_GPU_TIMERS 0 2 | #define MICROPROFILE_IMPL 3 | #define MICROPROFILE_WIN32_COLLECTOR 4 | #include "../../microprofile.h" -------------------------------------------------------------------------------- /src/microprofile-win32-cswitch/microprofile-win32-cswitch.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.23107.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "microprofile-win32-cswitch", "microprofile-win32-cswitch.vcxproj", "{0ECA0FAD-36B7-4204-9544-0E3BB8315E63}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {0ECA0FAD-36B7-4204-9544-0E3BB8315E63}.Debug|x64.ActiveCfg = Debug|x64 17 | {0ECA0FAD-36B7-4204-9544-0E3BB8315E63}.Debug|x64.Build.0 = Debug|x64 18 | {0ECA0FAD-36B7-4204-9544-0E3BB8315E63}.Debug|x86.ActiveCfg = Debug|Win32 19 | {0ECA0FAD-36B7-4204-9544-0E3BB8315E63}.Debug|x86.Build.0 = Debug|Win32 20 | {0ECA0FAD-36B7-4204-9544-0E3BB8315E63}.Release|x64.ActiveCfg = Release|x64 21 | {0ECA0FAD-36B7-4204-9544-0E3BB8315E63}.Release|x64.Build.0 = Release|x64 22 | {0ECA0FAD-36B7-4204-9544-0E3BB8315E63}.Release|x86.ActiveCfg = Release|Win32 23 | {0ECA0FAD-36B7-4204-9544-0E3BB8315E63}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /src/microprofile-win32-cswitch/microprofile-win32-cswitch.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {0ECA0FAD-36B7-4204-9544-0E3BB8315E63} 23 | Win32Proj 24 | microprofilewin32cswitch 25 | 8.1 26 | 27 | 28 | 29 | Application 30 | true 31 | v140 32 | MultiByte 33 | 34 | 35 | Application 36 | false 37 | v140 38 | true 39 | MultiByte 40 | 41 | 42 | Application 43 | true 44 | v140 45 | MultiByte 46 | 47 | 48 | Application 49 | false 50 | v140 51 | true 52 | MultiByte 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | true 74 | 75 | 76 | true 77 | 78 | 79 | false 80 | 81 | 82 | false 83 | 84 | 85 | 86 | 87 | 88 | Level3 89 | Disabled 90 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 91 | 92 | 93 | Console 94 | true 95 | ws2_32.lib;%(AdditionalDependencies) 96 | RequireAdministrator 97 | 98 | 99 | copy $(OutDir)$(TargetName)$(TargetExt) ..\..\bin\$(TargetName)_$(PlatformTarget).exe 100 | copy $(OutDir)$(TargetName).pdb ..\..\bin\$(TargetName)_$(PlatformTarget).pdb 101 | 102 | 103 | 104 | 105 | 106 | 107 | Level3 108 | Disabled 109 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 110 | 111 | 112 | Console 113 | true 114 | ws2_32.lib;%(AdditionalDependencies) 115 | RequireAdministrator 116 | 117 | 118 | copy $(OutDir)$(TargetName)$(TargetExt) ..\..\bin\$(TargetName)_$(PlatformTarget).exe 119 | copy $(OutDir)$(TargetName).pdb ..\..\bin\$(TargetName)_$(PlatformTarget).pdb 120 | 121 | 122 | 123 | 124 | Level3 125 | 126 | 127 | MaxSpeed 128 | true 129 | true 130 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 131 | 132 | 133 | Console 134 | true 135 | true 136 | true 137 | ws2_32.lib;%(AdditionalDependencies) 138 | RequireAdministrator 139 | 140 | 141 | copy $(OutDir)$(TargetName)$(TargetExt) ..\..\bin\$(TargetName)_$(PlatformTarget).exe 142 | copy $(OutDir)$(TargetName).pdb ..\..\bin\$(TargetName)_$(PlatformTarget).pdb 143 | 144 | 145 | 146 | 147 | Level3 148 | 149 | 150 | MaxSpeed 151 | true 152 | true 153 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 154 | 155 | 156 | Console 157 | true 158 | true 159 | true 160 | ws2_32.lib;%(AdditionalDependencies) 161 | RequireAdministrator 162 | 163 | 164 | copy $(OutDir)$(TargetName)$(TargetExt) ..\..\bin\$(TargetName)_$(PlatformTarget).exe 165 | copy $(OutDir)$(TargetName).pdb ..\..\bin\$(TargetName)_$(PlatformTarget).pdb 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | -------------------------------------------------------------------------------- /src/microprofile-win32-cswitch/microprofile-win32-cswitch.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/premake4.lua: -------------------------------------------------------------------------------- 1 | solution "embed" 2 | configurations { "Debug"} 3 | location "build/" 4 | project "embed" 5 | kind "ConsoleApp" 6 | language "C" 7 | files { "embed.c", "microprofile.h", "microprofile.html"} 8 | 9 | defines {"GLEW_STATIC;_CRT_SECURE_NO_WARNINGS"} 10 | debugdir "." 11 | 12 | buildoptions {"/TP"} 13 | configuration "Debug" 14 | defines { "DEBUG" } 15 | flags { "Symbols", "StaticRuntime" } 16 | --------------------------------------------------------------------------------