1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: demo_AutoTester.cpp
4
5 Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Revision: 18943 $
14 *---------------------------------------------------------------------------*/
15
16 #include <nw/types.h>
17 #include <nw/os.h>
18 #include <nw/ut/ut_Inlines.h>
19 #include <nw/demo/demo_DebugUtility.h>
20
21 #include <nn/fs.h>
22
23
24 namespace nw {
25 namespace demo {
26
27 DebugUtility::AutoTester* DebugUtility::s_AutoTester = NULL;
28
29 //----------------------------------------
30 DebugUtility::AutoTester*
Create(os::IAllocator * allocator,os::IAllocator * deviceAllocator)31 DebugUtility::AutoTester::Create(
32 os::IAllocator* allocator,
33 os::IAllocator* deviceAllocator
34 )
35 {
36 void* memory = allocator->Alloc(sizeof(AutoTester));
37
38 NW_NULL_ASSERT(memory);
39
40 AutoTester* autoTester = new(memory) AutoTester(allocator, deviceAllocator);
41
42 return autoTester;
43 }
44
45 //----------------------------------------
46 int
Initialize(s32 channelNumber,bool needCustom,nw::demo::RenderSystem ** renderSystem,const u32 * correctHashDisplay0,const u32 * correctHashDisplay1)47 DebugUtility::AutoTester::Initialize(
48 s32 channelNumber,
49 bool needCustom,
50 nw::demo::RenderSystem** renderSystem,
51 const u32* correctHashDisplay0,
52 const u32* correctHashDisplay1
53 )
54 {
55 m_RenderSystem = renderSystem;
56
57 nw::demo::HioPacketChannel::Initialize(m_DeviceAllocator);
58
59 m_HioPacketChannel = nw::demo::HioPacketChannel::Builder()
60 .ChannelNumber(channelNumber)
61 .Create(m_Allocator, m_DeviceAllocator);
62
63 NW_NULL_ASSERT(m_HioPacketChannel);
64
65 if (m_HioPacketChannel->Listen(needCustom ? -1 : 0)) {
66 // 接続に成功したので、カスタムテストの初期化を開始します。
67 size_t headerWrittenSize;
68 size_t dataWrittenSize;
69
70 TestInfoHeader testInfoHeader;
71 m_HioPacketChannel->ReceivePacket(
72 &headerWrittenSize,
73 &dataWrittenSize,
74 &testInfoHeader,
75 sizeof(testInfoHeader),
76 NULL,
77 0,
78 -1
79 );
80
81 NW_ASSERT(testInfoHeader.packetType == TestInfoHeader::PACKET_TYPE_ID);
82
83 // シナリオを受信します
84 m_Scenario = nw::ut::MoveArray<TestEvent>(testInfoHeader.eventCount, m_Allocator);
85 m_Scenario.resize(testInfoHeader.eventCount);
86
87 ScenarioHeader scenarioHeader;
88 m_HioPacketChannel->ReceivePacket(
89 &headerWrittenSize,
90 &dataWrittenSize,
91 &scenarioHeader,
92 sizeof(scenarioHeader),
93 &m_Scenario[0],
94 sizeof(TestEvent) * m_Scenario.size(),
95 -1
96 );
97 NW_ASSERT(scenarioHeader.packetType == ScenarioHeader::PACKET_TYPE_ID);
98
99 DebugUtility::SetSilentMode(true);
100
101 nw::demo::PadFactory::GetPad()->EnableTestMode(true);
102 }
103 else
104 {
105 // 接続できなかったので、デフォルトテストの初期化を開始します。
106 nw::ut::SafeDestroy(m_HioPacketChannel);
107 nw::demo::HioPacketChannel::Finalize();
108
109 m_Scenario = nw::ut::MoveArray<TestEvent>(2, m_Allocator);
110
111 TestEvent event;
112
113 event.frameCount = 60;
114 event.eventType = EVENT_SCREENSHOT;
115 event.param.screenshot.display = ScreenshotParam::DISPLAY_0;
116 for (int i=0;i<5;++i)
117 {
118 if (correctHashDisplay0)
119 {
120 event.param.screenshot.hash[i] = correctHashDisplay0[i];
121 }
122 else
123 {
124 event.param.screenshot.hash[i] = 0;
125 }
126 }
127 m_Scenario.push_back(event);
128
129 event.param.screenshot.display = ScreenshotParam::DISPLAY_1;
130 for (int i=0;i<5;++i)
131 {
132 if (correctHashDisplay1)
133 {
134 event.param.screenshot.hash[i] = correctHashDisplay1[i];
135 }
136 else
137 {
138 event.param.screenshot.hash[i] = 0;
139 }
140 }
141 m_Scenario.push_back(event);
142
143 nw::demo::PadFactory::GetPad()->EnableTestMode(false);
144 }
145
146 m_ScreenshotManager = nw::dev::ScreenshotManager::Create(
147 m_Allocator,
148 1,
149 nw::dev::CalcMemorySize(GL_RGBA8_OES, 400, 320)
150 );
151 NW_POINTER_ASSERT(m_ScreenshotManager);
152
153 m_FrameCount = 0;
154 m_CurrentEvent = m_Scenario.begin();
155
156 return 0;
157 }
158
159 //----------------------------------------
160 void
Finalize()161 DebugUtility::AutoTester::Finalize()
162 {
163 if (m_HioPacketChannel)
164 {
165 m_HioPacketChannel->Disconnect();
166 nw::ut::SafeDestroy(m_HioPacketChannel);
167 nw::demo::HioPacketChannel::Finalize();
168 }
169 }
170
171 //----------------------------------------
172 void
Destroy()173 DebugUtility::AutoTester::Destroy()
174 {
175 nw::os::IAllocator* allocator = m_Allocator;
176
177 this->~AutoTester();
178 allocator->Free(this);
179 }
180
181 //----------------------------------------
182 void
AdvanceFrame()183 DebugUtility::AutoTester::AdvanceFrame()
184 {
185 while (m_CurrentEvent != m_Scenario.end() && m_CurrentEvent->frameCount == m_FrameCount)
186 {
187 switch (m_CurrentEvent->eventType)
188 {
189 case EVENT_SCREENSHOT:
190 SendScreenshot(m_CurrentEvent->param.screenshot);
191 break;
192 case EVENT_SET_PAD_STATUS:
193 SetPadStatus(m_CurrentEvent->param.setPadStatus);
194 break;
195 case EVENT_BEACON:
196 SendBeacon(m_CurrentEvent->param.beacon);
197 break;
198 case EVENT_SEND_LOAD_METER:
199 SendLoadMeter(m_CurrentEvent->param.sendLoadMeter);
200 break;
201 case EVENT_RESET_LOAD_METER:
202 if (m_RenderSystem)
203 {
204 (*m_RenderSystem)->ResetCumulativeLoadMeter();
205 }
206 break;
207 case EVENT_TEST_DONE:
208 NotifyDone();
209 break;
210 case EVENT_SWITCH_CPU_PROFILING_MODE:
211 SwitchCpuProfilingMode(m_CurrentEvent->param.switchCpuProfilingMode);
212 break;
213 default:
214 NW_FATAL_ERROR("Unsupported test event");
215 }
216
217 ++m_CurrentEvent;
218 }
219
220 ++m_FrameCount;
221 }
222
223 //----------------------------------------
224 void
SendScreenshot(const ScreenshotParam & param)225 DebugUtility::AutoTester::SendScreenshot(
226 const ScreenshotParam& param
227 )
228 {
229 int screenshotIndex;
230
231 switch (param.display)
232 {
233 case ScreenshotParam::DISPLAY_0:
234 screenshotIndex = m_ScreenshotManager->Take(NN_GX_DISPLAY0);
235 break;
236 case ScreenshotParam::DISPLAY_0_EXT:
237 screenshotIndex = m_ScreenshotManager->Take(NN_GX_DISPLAY0_EXT);
238 break;
239 case ScreenshotParam::DISPLAY_1:
240 screenshotIndex = m_ScreenshotManager->Take(NN_GX_DISPLAY1);
241 break;
242 case ScreenshotParam::DISPLAY_0_BOTH:
243 {
244 ScreenshotParam eachParam = param;
245 eachParam.display = ScreenshotParam::DISPLAY_0;
246 SendScreenshot(eachParam);
247 eachParam.display = ScreenshotParam::DISPLAY_0_EXT;
248 SendScreenshot(eachParam);
249 return;
250 }
251 case ScreenshotParam::DISPLAY_ALL:
252 {
253 ScreenshotParam eachParam = param;
254 eachParam.display = ScreenshotParam::DISPLAY_0;
255 SendScreenshot(eachParam);
256 eachParam.display = ScreenshotParam::DISPLAY_0_EXT;
257 SendScreenshot(eachParam);
258 eachParam.display = ScreenshotParam::DISPLAY_1;
259 SendScreenshot(eachParam);
260 return;
261 }
262 default:
263 NW_ASSERT(false);
264 }
265
266 if (screenshotIndex < 0)
267 {
268 if (m_HioPacketChannel)
269 {
270 ScreenshotHeader header;
271 header.frameCount = m_FrameCount;
272 header.width = 0;
273 header.height = 0;
274 header.display = param.display;
275 m_HioPacketChannel->SendPacket(
276 &header,
277 sizeof(header),
278 NULL,
279 0
280 );
281 }
282 return;
283 }
284
285 nw::dev::Screenshot* shotDisplay = m_ScreenshotManager->GetScreenshot(screenshotIndex);
286
287 if (m_HioPacketChannel)
288 {
289 ScreenshotHeader header;
290 header.frameCount = m_FrameCount;
291 header.width = shotDisplay->GetWidth();
292 header.height = shotDisplay->GetHeight();
293 header.display = param.display;
294 m_HioPacketChannel->SendPacket(
295 &header,
296 sizeof(header),
297 shotDisplay->GetBuffer(),
298 shotDisplay->GetBufferLength()
299 );
300 }
301 else
302 {
303 if (m_CurrentEvent->param.screenshot.hash[0] ||
304 m_CurrentEvent->param.screenshot.hash[0] ||
305 m_CurrentEvent->param.screenshot.hash[0] ||
306 m_CurrentEvent->param.screenshot.hash[0] ||
307 m_CurrentEvent->param.screenshot.hash[0] )
308 {
309
310 const bool result = shotDisplay->Equal(m_CurrentEvent->param.screenshot.hash);
311
312 if (result)
313 {
314 NW_DEV_LOG("NW_SCREENSHOT_TEST: OK\n");
315 shotDisplay->DumpHash();
316 }
317 else
318 {
319 NW_DEV_LOG("NW_SCREENSHOT_TEST: NG\n");
320 shotDisplay->DumpHash();
321 }
322 }
323 }
324 }
325
326 //----------------------------------------
327 void
SetPadStatus(const SetPadStatusParam & param)328 DebugUtility::AutoTester::SetPadStatus(
329 const SetPadStatusParam& param
330 )
331 {
332 nw::demo::PadFactory::GetPad()->SetTestPadStatus(param.padStatus);
333 }
334
335 //----------------------------------------
336 void
SendBeacon(const BeaconParam & param)337 DebugUtility::AutoTester::SendBeacon(
338 const BeaconParam& param
339 )
340 {
341 NW_UNUSED_VARIABLE(param);
342 if (m_HioPacketChannel)
343 {
344 BeaconHeader header;
345 header.frameCount = m_FrameCount;
346 m_HioPacketChannel->SendPacket(
347 &header,
348 sizeof(header),
349 NULL,
350 0
351 );
352 }
353 }
354
355 //----------------------------------------
356 void
SendLoadMeter(const SendLoadMeterParam & param)357 DebugUtility::AutoTester::SendLoadMeter(
358 const SendLoadMeterParam& param
359 )
360 {
361 NW_UNUSED_VARIABLE(param);
362 if (m_HioPacketChannel)
363 {
364 LoadMeterHeader header;
365 header.frameCount = m_FrameCount;
366
367 LoadMeterData data;
368 if (m_RenderSystem)
369 {
370 data.callCount = (*m_RenderSystem)->GetCumulativeLoadMeter().callCount;
371 data.cpuTime = static_cast<s32>( (*m_RenderSystem)->GetCumulativeLoadMeter().cumulativeTime * 1000 );
372 data.gpuTime = static_cast<s32>( (*m_RenderSystem)->GetCumulativeLoadMeter().cumulativeGpuTime * 1000 );
373 data.otherGpuTime = 0;
374 data.cmdSize = static_cast<s32>( (*m_RenderSystem)->GetCumulativeLoadMeter().drawCommandBufferSize );
375 }
376 else
377 {
378 data.callCount = 0;
379 data.cpuTime = 0;
380 data.gpuTime = 0;
381 data.otherGpuTime = 0;
382 data.cmdSize = 0;
383 }
384
385 m_HioPacketChannel->SendPacket(
386 &header,
387 sizeof(header),
388 &data,
389 sizeof(data)
390 );
391 }
392 }
393
394 //----------------------------------------
395 void
NotifyDone()396 DebugUtility::AutoTester::NotifyDone()
397 {
398 if (m_HioPacketChannel)
399 {
400 DoneHeader header;
401 header.frameCount = m_FrameCount;
402 m_HioPacketChannel->SendPacket(
403 &header,
404 sizeof(header),
405 NULL,
406 0
407 );
408 }
409 }
410
411 //----------------------------------------
412 void
SwitchCpuProfilingMode(const SwitchCpuProfilingModeParam & param)413 DebugUtility::AutoTester::SwitchCpuProfilingMode(const SwitchCpuProfilingModeParam& param)
414 {
415 DebugUtility::s_IsForceCpuProfilingMode = bool(param.isModeEnabled);
416 }
417
418 //----------------------------------------
419 void
NotifyMemoryLeak(s32 deviceLeakSize,s32 particleLeakSize)420 DebugUtility::AutoTester::NotifyMemoryLeak(
421 s32 deviceLeakSize,
422 s32 particleLeakSize
423 )
424 {
425 if (m_HioPacketChannel)
426 {
427 MemoryLeakHeader header;
428 header.frameCount = 0;
429
430 MemoryLeakData data;
431 data.deviceLeakSize = deviceLeakSize;
432 data.particleLeakSize = particleLeakSize;
433
434 m_HioPacketChannel->SendPacket(
435 &header,
436 sizeof(header),
437 &data,
438 sizeof(data)
439 );
440 }
441 }
442
443 //----------------------------------------------------------
444 void
NotifyMemoryStatus(nw::demo::DemoAllocator * deviceAllocator,nw::demo::DemoAllocator * particleAllocator,NOTIFY_TIMING timing)445 DebugUtility::AutoTester::NotifyMemoryStatus(
446 nw::demo::DemoAllocator* deviceAllocator,
447 nw::demo::DemoAllocator* particleAllocator,
448 NOTIFY_TIMING timing
449 )
450 {
451 if (m_HioPacketChannel)
452 {
453 MemoryStatusHeader header;
454 header.frameCount = 0;
455 header.timing = timing;
456
457 MemoryStatusData data;
458 data.deviceMemoryUsed = deviceAllocator->GetTotalSize() - deviceAllocator->GetFreeSize();
459 if (particleAllocator)
460 {
461 data.particleMemoryUsed = particleAllocator->GetTotalSize() - particleAllocator->GetFreeSize();
462 }
463 else
464 {
465 data.particleMemoryUsed = 0;
466 }
467
468 m_HioPacketChannel->SendPacket(
469 &header,
470 sizeof(header),
471 &data,
472 sizeof(data)
473 );
474 }
475 }
476
477 //----------------------------------------
AutoTester(os::IAllocator * allocator,os::IAllocator * deviceAllocator)478 DebugUtility::AutoTester::AutoTester(
479 os::IAllocator* allocator,
480 os::IAllocator* deviceAllocator
481 )
482 : m_Allocator(allocator),
483 m_DeviceAllocator(deviceAllocator),
484 m_ScreenshotManager(NULL),
485 m_HioPacketChannel(NULL),
486 m_FrameCount(0),
487 m_RenderSystem(NULL)
488 {
489 }
490
491 //----------------------------------------
~AutoTester()492 DebugUtility::AutoTester::~AutoTester()
493 {
494 m_ScreenshotManager->Destroy(m_Allocator);
495 }
496
497 } // namespace demo
498 } // namespace nw
499