1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     demo_DebugUtility.cpp
4 
5   Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain proprietary
8   information of Nintendo and/or its licensed developers and are protected by
9   national and international copyright laws. They may not be disclosed to third
10   parties or copied or duplicated in any form, in whole or in part, without the
11   prior written consent of Nintendo.
12 
13   The content herein is highly confidential and should be handled accordingly.
14 
15   $Revision: $
16  *---------------------------------------------------------------------------*/
17 
18 #include <nw/types.h>
19 #include <nw/os.h>
20 #include <nw/ut/ut_Inlines.h>
21 #include <nw/demo/demo_DebugUtility.h>
22 
23 #include <nn/fs.h>
24 
25 
26 namespace nw {
27 namespace demo {
28 
29 size_t DebugUtility::s_DeviceMemoryFreeSize = 0;
30 size_t DebugUtility::s_ParticleMemoryFreeSize = 0;
31 nw::demo::DemoAllocator* DebugUtility::s_DeviceAllocator = NULL;
32 nw::demo::DemoAllocator* DebugUtility::s_ParticleAllocator = NULL;
33 bool DebugUtility::s_IsForceCpuProfilingMode = false;
34 bool DebugUtility::s_SilentMode = false;
35 s32 DebugUtility::s_ProfileCallCount = 0;
36 s32 DebugUtility::s_DebugFrameCount = 0;
37 
38 static bool s_LastCpuCountingMode = false;
39 
40 //----------------------------------------
41 void
CalcLoadMeter(nw::demo::RenderSystem * renderSystem)42 DebugUtility::CalcLoadMeter(
43     nw::demo::RenderSystem* renderSystem
44 )
45 {
46     NW_POINTER_ASSERT(renderSystem);
47 
48     ++s_DebugFrameCount;
49 
50     if (nw::demo::DebugUtility::IsCpuProfilingMode() != s_LastCpuCountingMode)
51     {
52         if (!s_SilentMode)
53         {
54             if (nw::demo::DebugUtility::IsCpuProfilingMode())
55             {
56                 NW_DEV_LOG("-------------------------------------------------------------------------------\n");
57                 NW_DEV_LOG("|                         Entering CPU profiling mode.                        |\n");
58                 NW_DEV_LOG("-------------------------------------------------------------------------------\n");
59                 NW_DEV_LOG("Command list won't run.\n");
60                 NW_DEV_LOG("Load meter will be output to log.\n");
61                 NW_DEV_LOG("To leave profiling mode, turn DBG switch OFF.\n");
62                 NW_DEV_LOG("\n");
63             }
64             else
65             {
66                 NW_DEV_LOG("-------------------------------------------------------------------------------\n");
67                 NW_DEV_LOG("|                         Leaving CPU profiling mode.                         |\n");
68                 NW_DEV_LOG("-------------------------------------------------------------------------------\n");
69             }
70         }
71         s_LastCpuCountingMode = nw::demo::DebugUtility::IsCpuProfilingMode();
72     }
73 
74     if (s_DebugFrameCount % NW_LOAD_METER_INTERVAL == 0)
75     {
76         if (nw::demo::DebugUtility::IsCpuProfilingMode())
77         {
78             if (s_DebugFrameCount % (NW_LOAD_METER_INTERVAL * 3) == 0)
79             {
80                 renderSystem->CalcLoadMeter();
81                 if (!s_SilentMode)
82                 {
83                     DumpLoadMeter(renderSystem);
84                     NW_DEV_LOG("\n");
85                 }
86             }
87         }
88         else
89         {
90             renderSystem->CalcLoadMeter();
91         }
92     }
93 }
94 
95 //----------------------------------------
96 void
DrawLoadMeterText(nw::demo::RenderSystem * renderSystem,nw::demo::GraphicsDrawing * graphicsDrawing)97 DebugUtility::DrawLoadMeterText(
98     nw::demo::RenderSystem* renderSystem,
99     nw::demo::GraphicsDrawing* graphicsDrawing
100 )
101 {
102     NW_POINTER_ASSERT(renderSystem);
103     NW_POINTER_ASSERT(graphicsDrawing);
104 
105     static const s32 POS_LOAD_METER_TEXT_X = POS_LOAD_METER_X + 15;
106     static const s32 POS_BAR_CHART_TEXT_X = POS_BAR_CHART_X + 14;
107 
108 
109     graphicsDrawing->DrawString(POS_COMMAND_SIZE_X, POS_COMMAND_SIZE_Y, "Cmd size : %d bytes\n",
110         renderSystem->GetLoadMeter().drawCommandBufferSize);
111 
112     float loadRate =
113         renderSystem->GetLoadMeter().loadTime * nw::demo::RenderSystem::LoadMeterDescription::MILLI_TO_RATE;
114     graphicsDrawing->DrawString(POS_LOAD_METER_TEXT_X, POS_LOAD_METER_Y, "CPU :%5.2f ms/f\n",
115         renderSystem->GetLoadMeter().loadTime);
116 
117     float loadGpuRate =
118         renderSystem->GetLoadMeter().loadGpuTime * nw::demo::RenderSystem::LoadMeterDescription::MILLI_TO_RATE;
119     graphicsDrawing->DrawString(POS_LOAD_METER_TEXT_X, POS_LOAD_METER_Y + HEIGHT_LOAD_METER,"GPU :%5.2f ms/f\n",
120         renderSystem->GetLoadMeter().loadGpuTime);
121 
122 
123     graphicsDrawing->DrawString(
124         POS_BAR_CHART_TEXT_X + WIDTH_LOAD_METER_BAR_CHART / 4 * loadRate,
125         POS_BAR_CHART_Y,
126         "%.2f %%",
127         loadRate * 100.0f
128     );
129 
130     graphicsDrawing->DrawString(
131         POS_BAR_CHART_TEXT_X + WIDTH_LOAD_METER_BAR_CHART / 4 * loadGpuRate,
132         POS_BAR_CHART_Y + HEIGHT_LOAD_METER_BAR_CHART,
133         "%.2f %%",
134         loadGpuRate * 100.0f
135     );
136 }
137 
138 //----------------------------------------
139 void
DrawLoadMeter(nw::demo::RenderSystem * renderSystem,nw::demo::GraphicsDrawing * graphicsDrawing)140 DebugUtility::DrawLoadMeter(
141     nw::demo::RenderSystem* renderSystem,
142     nw::demo::GraphicsDrawing* graphicsDrawing
143 )
144 {
145     NW_POINTER_ASSERT(renderSystem);
146     NW_POINTER_ASSERT(graphicsDrawing);
147 
148     static const s32 POS_BAR_CHART_BACKGROUND_X = POS_BAR_CHART_X + 8;
149     static const s32 WIDTH_BAR_CHART_BACKGROUND = WIDTH_LOAD_METER_BAR_CHART + 2;
150     static const s32 HEIGHT_BAR_CHART_BACKGROUND = 15;
151     static const s32 WIDTH_BAR_CHART_LEFTBOX = 8;
152     static const s32 HEIGHT_BAR_CHART_LEFTBOX = 16;
153     static const s32 POS_BAR_CHART_LINE_Y = POS_BAR_CHART_Y + HEIGHT_BAR_CHART_LEFTBOX;
154     static const s32 POS_BAR_CHART_BAR_LEFT = POS_BAR_CHART_X + WIDTH_BAR_CHART_LEFTBOX + 2;
155     static const s32 HEIGHT_BAR_CHART_BAR = 14;
156     static const s32 WIDTH_COLORBOX = 10;
157     static const s32 HEIGHT_COLORBOX = 15;
158 
159     static const u32 COLOR_CPU = 0x2DC400FF;
160     static const u32 COLOR_BAR_CHART_CPU = 0x6CFF52FF;
161     static const u32 COLOR_GPU = 0xFF0000FF;
162     static const u32 COLOR_BAR_CHART_GPU = 0xF464EFFF;
163     static const u32 COLOR_BAR_CHART_BACKGROUND = 0x4B4B4BFF;
164     static const u32 COLOR_BAR_CHART_HUNDRED_PERCENT = 0x808080FF;
165 
166     float loadRate =
167         renderSystem->GetLoadMeter().loadTime * nw::demo::RenderSystem::LoadMeterDescription::MILLI_TO_RATE;
168     float loadGpuRate =
169         renderSystem->GetLoadMeter().loadGpuTime * nw::demo::RenderSystem::LoadMeterDescription::MILLI_TO_RATE;
170 
171     // CPU メーターを描画します。
172     graphicsDrawing->FillRectangle(
173         nw::math::VEC2(POS_BAR_CHART_BACKGROUND_X, POS_BAR_CHART_Y),
174         nw::math::VEC2(WIDTH_BAR_CHART_BACKGROUND, HEIGHT_BAR_CHART_BACKGROUND),
175         COLOR_BAR_CHART_BACKGROUND
176     );
177 
178     graphicsDrawing->FillRectangle(
179         nw::math::VEC2(POS_BAR_CHART_X, POS_BAR_CHART_Y),
180         nw::math::VEC2(WIDTH_BAR_CHART_LEFTBOX, HEIGHT_BAR_CHART_LEFTBOX),
181         COLOR_CPU
182     );
183 
184     graphicsDrawing->DrawLine(
185         nw::math::VEC2(POS_BAR_CHART_X, POS_BAR_CHART_LINE_Y),
186         nw::math::VEC2(POS_BAR_CHART_BAR_LEFT + WIDTH_LOAD_METER_BAR_CHART, POS_BAR_CHART_LINE_Y),
187         COLOR_CPU
188     );
189 
190     graphicsDrawing->FillRectangle(
191         nw::math::VEC2(POS_BAR_CHART_BAR_LEFT, POS_BAR_CHART_Y),
192         nw::math::VEC2(WIDTH_LOAD_METER_BAR_CHART / 4 * loadRate, HEIGHT_BAR_CHART_BAR),
193         COLOR_BAR_CHART_CPU
194     );
195 
196     graphicsDrawing->DrawLine(
197         nw::math::VEC2(POS_BAR_CHART_BAR_LEFT + WIDTH_LOAD_METER_BAR_CHART / 4, POS_BAR_CHART_Y),
198         nw::math::VEC2(POS_BAR_CHART_BAR_LEFT + WIDTH_LOAD_METER_BAR_CHART / 4, POS_BAR_CHART_Y + HEIGHT_BAR_CHART_BACKGROUND),
199         COLOR_BAR_CHART_HUNDRED_PERCENT
200     );
201 
202     graphicsDrawing->FillRectangle(
203         nw::math::VEC2(POS_LOAD_METER_X, POS_LOAD_METER_Y),
204         nw::math::VEC2(WIDTH_COLORBOX, HEIGHT_COLORBOX),
205         COLOR_CPU
206     );
207 
208     // GPU メーターを描画します。
209     graphicsDrawing->FillRectangle(
210         nw::math::VEC2(POS_BAR_CHART_BACKGROUND_X, POS_BAR_CHART_Y + HEIGHT_LOAD_METER_BAR_CHART),
211         nw::math::VEC2(WIDTH_BAR_CHART_BACKGROUND, HEIGHT_BAR_CHART_BACKGROUND),
212         COLOR_BAR_CHART_BACKGROUND
213     );
214 
215     graphicsDrawing->FillRectangle(
216         nw::math::VEC2(POS_BAR_CHART_X, POS_BAR_CHART_Y + HEIGHT_LOAD_METER_BAR_CHART),
217         nw::math::VEC2(WIDTH_BAR_CHART_LEFTBOX, HEIGHT_BAR_CHART_LEFTBOX),
218         COLOR_GPU
219     );
220 
221     graphicsDrawing->DrawLine(
222         nw::math::VEC2(POS_BAR_CHART_X, POS_BAR_CHART_LINE_Y + HEIGHT_LOAD_METER_BAR_CHART),
223         nw::math::VEC2(POS_BAR_CHART_BAR_LEFT + WIDTH_LOAD_METER_BAR_CHART, POS_BAR_CHART_LINE_Y + HEIGHT_LOAD_METER_BAR_CHART),
224         COLOR_GPU
225     );
226 
227     graphicsDrawing->FillRectangle(
228         nw::math::VEC2(POS_BAR_CHART_BAR_LEFT, POS_BAR_CHART_Y + HEIGHT_LOAD_METER_BAR_CHART),
229         nw::math::VEC2(WIDTH_LOAD_METER_BAR_CHART / 4 * loadGpuRate, HEIGHT_BAR_CHART_BAR),
230         COLOR_BAR_CHART_GPU
231     );
232 
233     graphicsDrawing->DrawLine(
234         nw::math::VEC2(POS_BAR_CHART_BAR_LEFT + WIDTH_LOAD_METER_BAR_CHART / 4, POS_BAR_CHART_Y + HEIGHT_LOAD_METER_BAR_CHART),
235         nw::math::VEC2(POS_BAR_CHART_BAR_LEFT + WIDTH_LOAD_METER_BAR_CHART / 4, POS_BAR_CHART_Y + HEIGHT_BAR_CHART_BACKGROUND + HEIGHT_LOAD_METER_BAR_CHART),
236         COLOR_BAR_CHART_HUNDRED_PERCENT
237     );
238 
239     graphicsDrawing->FillRectangle(
240         nw::math::VEC2(POS_LOAD_METER_X, POS_LOAD_METER_Y + HEIGHT_LOAD_METER),
241         nw::math::VEC2(WIDTH_COLORBOX, HEIGHT_COLORBOX),
242         COLOR_GPU
243     );
244 }
245 
246 //----------------------------------------
247 void
DumpLoadMeter(nw::demo::RenderSystem * renderSystem)248 DebugUtility::DumpLoadMeter(
249     nw::demo::RenderSystem* renderSystem
250 )
251 {
252     float loadRate =
253         renderSystem->GetLoadMeter().loadTime * nw::demo::RenderSystem::LoadMeterDescription::MILLI_TO_RATE;
254     NW_DEV_LOG("      CPU :%5.2f ms/f (%6.2f %%)\n",
255         renderSystem->GetLoadMeter().loadTime, loadRate * 100.0f);
256 
257     float loadGpuRate =
258         renderSystem->GetLoadMeter().loadGpuTime * nw::demo::RenderSystem::LoadMeterDescription::MILLI_TO_RATE;
259     NW_DEV_LOG("      GPU :%5.2f ms/f (%6.2f %%)\n",
260         renderSystem->GetLoadMeter().loadGpuTime, loadGpuRate * 100.0f);
261 
262     NW_DEV_LOG(" Cmd size :% 8d bytes\n",
263         renderSystem->GetLoadMeter().drawCommandBufferSize);
264 }
265 
266 } // namespace demo
267 } // namespace nw
268