# Stage 1.7.1
- Add Min and Max to timetrace - Add TestBench
This commit is contained in:
		@@ -76,10 +76,15 @@ target_compile_definitions(${TARGET_NAME} PUBLIC
 | 
				
			|||||||
    -DBUILD_CTR=1
 | 
					    -DBUILD_CTR=1
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
add_executable(test test/main.cpp)
 | 
					add_executable(test test/app/main.cpp)
 | 
				
			||||||
target_include_directories(test PUBLIC include test)
 | 
					target_include_directories(test PUBLIC include test/app)
 | 
				
			||||||
target_link_directories(test PUBLIC ${CMAKE_BINARY_DIR})
 | 
					target_link_directories(test PUBLIC ${CMAKE_BINARY_DIR})
 | 
				
			||||||
target_link_libraries(test PUBLIC palladium citro3d ctru m)
 | 
					target_link_libraries(test PUBLIC palladium citro3d ctru m)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					add_executable(testbench test/bench/main.cpp)
 | 
				
			||||||
 | 
					target_include_directories(testbench PUBLIC include test/bench)
 | 
				
			||||||
 | 
					target_link_directories(testbench PUBLIC ${CMAKE_BINARY_DIR})
 | 
				
			||||||
 | 
					target_link_libraries(testbench PUBLIC palladium citro3d ctru m)
 | 
				
			||||||
# Generate 3DSX
 | 
					# Generate 3DSX
 | 
				
			||||||
ctr_generate_smdh(
 | 
					ctr_generate_smdh(
 | 
				
			||||||
    ${CMAKE_BINARY_DIR}/test.smdh
 | 
					    ${CMAKE_BINARY_DIR}/test.smdh
 | 
				
			||||||
@@ -94,5 +99,11 @@ ctr_create_3dsx(
 | 
				
			|||||||
    SMDH "${CMAKE_BINARY_DIR}/test.smdh"
 | 
					    SMDH "${CMAKE_BINARY_DIR}/test.smdh"
 | 
				
			||||||
    ROMFS "${CMAKE_SOURCE_DIR}/test/romfs"
 | 
					    ROMFS "${CMAKE_SOURCE_DIR}/test/romfs"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					ctr_create_3dsx(
 | 
				
			||||||
 | 
					    testbench
 | 
				
			||||||
 | 
					    OUTPUT "${CMAKE_BINARY_DIR}/testbench.3dsx"
 | 
				
			||||||
 | 
					    SMDH "${CMAKE_BINARY_DIR}/test.smdh"
 | 
				
			||||||
 | 
					    ROMFS "${CMAKE_SOURCE_DIR}/test/romfs"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
install(TARGETS ${TARGET_NAME})
 | 
					install(TARGETS ${TARGET_NAME})
 | 
				
			||||||
install(DIRECTORY include DESTINATION ".")
 | 
					install(DIRECTORY include DESTINATION ".")
 | 
				
			||||||
@@ -31,23 +31,47 @@ class TimeStats : public SmartCtor<TimeStats> {
 | 
				
			|||||||
  TimeStats(int l) : len(l), val(l, 0) {}
 | 
					  TimeStats(int l) : len(l), val(l, 0) {}
 | 
				
			||||||
  ~TimeStats() = default;
 | 
					  ~TimeStats() = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void Add(unsigned long long v) {
 | 
					  void Add(u64 v) {
 | 
				
			||||||
    val[idx] = v;
 | 
					    val[idx] = v;
 | 
				
			||||||
    idx = next(idx);
 | 
					    idx = next(idx);
 | 
				
			||||||
    num_val = std::min(num_val + 1, len);
 | 
					    num_val = std::min(num_val + 1, len);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  unsigned long long GetAverage() {
 | 
					  u64 GetAverage() {
 | 
				
			||||||
    if (!num_val) return 0.f;
 | 
					    if (!num_val) return 0.f;
 | 
				
			||||||
    unsigned long long res = 0;
 | 
					    u64 res = 0;
 | 
				
			||||||
    for (int i = 0; i < num_val; i++) {
 | 
					    for (int i = 0; i < num_val; i++) {
 | 
				
			||||||
      res += val[smart_idx(i)];
 | 
					      res += val[smart_idx(i)];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return res / num_val;
 | 
					    return res / num_val;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const std::vector<unsigned long long> &GetData() { return val; }
 | 
					  u64 GetMin() {
 | 
				
			||||||
  const unsigned long long &operator[](int i) { return val[smart_idx(i)]; }
 | 
					    if (!num_val) return 0.f;
 | 
				
			||||||
 | 
					    u64 res = std::numeric_limits<u64>::max();
 | 
				
			||||||
 | 
					    for (int i = 0; i < num_val; i++) {
 | 
				
			||||||
 | 
					      res = std::min(val[smart_idx(i)], res);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  u64 GetMax() {
 | 
				
			||||||
 | 
					    if (!num_val) return 0.f;
 | 
				
			||||||
 | 
					    u64 res = 0;
 | 
				
			||||||
 | 
					    for (int i = 0; i < num_val; i++) {
 | 
				
			||||||
 | 
					      res = std::max(val[smart_idx(i)], res);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void Clear() {
 | 
				
			||||||
 | 
					    val.assign(len, 0);
 | 
				
			||||||
 | 
					    idx = 0;
 | 
				
			||||||
 | 
					    num_val = 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const std::vector<u64> &GetData() { return val; }
 | 
				
			||||||
 | 
					  const u64 &operator[](int i) { return val[smart_idx(i)]; }
 | 
				
			||||||
  const size_t GetLen() { return len; }
 | 
					  const size_t GetLen() { return len; }
 | 
				
			||||||
  const size_t GetNumValues() { return num_val; }
 | 
					  const size_t GetNumValues() { return num_val; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -56,7 +80,7 @@ class TimeStats : public SmartCtor<TimeStats> {
 | 
				
			|||||||
  size_t smart_idx(size_t v) const { return (idx + len - num_val + v) % len; }
 | 
					  size_t smart_idx(size_t v) const { return (idx + len - num_val + v) % len; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  int len = 0;
 | 
					  int len = 0;
 | 
				
			||||||
  std::vector<unsigned long long> val;
 | 
					  std::vector<u64> val;
 | 
				
			||||||
  int idx = 0;
 | 
					  int idx = 0;
 | 
				
			||||||
  int num_val = 0;
 | 
					  int num_val = 0;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -68,21 +92,21 @@ class Res : public SmartCtor<Res> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  void SetID(const std::string &v) { id = v; }
 | 
					  void SetID(const std::string &v) { id = v; }
 | 
				
			||||||
  const std::string GetID() { return id; }
 | 
					  const std::string GetID() { return id; }
 | 
				
			||||||
  void SetStart(unsigned long long v) { start = v; }
 | 
					  void SetStart(u64 v) { start = v; }
 | 
				
			||||||
  unsigned long long GetStart() { return start; }
 | 
					  u64 GetStart() { return start; }
 | 
				
			||||||
  void SetEnd(unsigned long long v) {
 | 
					  void SetEnd(u64 v) {
 | 
				
			||||||
    end = v;
 | 
					    end = v;
 | 
				
			||||||
    protocol->Add(GetLastDiff());
 | 
					    protocol->Add(GetLastDiff());
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  unsigned long long GetEnd() { return end; }
 | 
					  u64 GetEnd() { return end; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  unsigned long long GetLastDiff() { return end - start; }
 | 
					  u64 GetLastDiff() { return end - start; }
 | 
				
			||||||
  TimeStats::Ref GetProtocol() { return protocol; }
 | 
					  TimeStats::Ref GetProtocol() { return protocol; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 private:
 | 
					 private:
 | 
				
			||||||
  std::string id;
 | 
					  std::string id;
 | 
				
			||||||
  unsigned long long start;
 | 
					  u64 start;
 | 
				
			||||||
  unsigned long long end;
 | 
					  u64 end;
 | 
				
			||||||
  TimeStats::Ref protocol;
 | 
					  TimeStats::Ref protocol;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
void Beg(const std::string &id);
 | 
					void Beg(const std::string &id);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										178
									
								
								test/bench/main.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										178
									
								
								test/bench/main.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,178 @@
 | 
				
			|||||||
 | 
					#include <pd.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct StatsRes {
 | 
				
			||||||
 | 
					  std::string name;
 | 
				
			||||||
 | 
					  std::string average;
 | 
				
			||||||
 | 
					  std::string min;
 | 
				
			||||||
 | 
					  std::string max;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TestBench : public PD::App {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  TestBench() = default;
 | 
				
			||||||
 | 
					  ~TestBench() = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void Init() override {
 | 
				
			||||||
 | 
					    /// Test in OLD3DS Mode
 | 
				
			||||||
 | 
					    osSetSpeedupEnable(false);
 | 
				
			||||||
 | 
					    PD::TT::Beg("BaseInit");
 | 
				
			||||||
 | 
					    inp = Input();
 | 
				
			||||||
 | 
					    ren = Renderer();
 | 
				
			||||||
 | 
					    font = PD::LI::Font::New();
 | 
				
			||||||
 | 
					    font->LoadTTF("romfs:/fonts/JetBrainsMono-Medium.ttf", 32);
 | 
				
			||||||
 | 
					    ren->Font(font);
 | 
				
			||||||
 | 
					    ui7 = PD::UI7::Context::New(ren, inp);
 | 
				
			||||||
 | 
					    /// Maximum frames for 5 seconds
 | 
				
			||||||
 | 
					    li_stats = PD::TimeStats::New(300);
 | 
				
			||||||
 | 
					    PD::TT::End("BaseInit");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool MainLoop(float delta, float time) {
 | 
				
			||||||
 | 
					    if (stime == 0.f) {
 | 
				
			||||||
 | 
					      stime = time;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    switch (test) {
 | 
				
			||||||
 | 
					      case 0:
 | 
				
			||||||
 | 
					        Test1(time);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 1:
 | 
				
			||||||
 | 
					        Test2(delta, time);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      default:
 | 
				
			||||||
 | 
					        Result(delta);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (time - stime > 5.f && test < 2) {
 | 
				
			||||||
 | 
					      if (test == 0) {
 | 
				
			||||||
 | 
					        results.push_back(std::make_pair<std::string, std::vector<StatsRes>>(
 | 
				
			||||||
 | 
					            std::to_string(test + 1),
 | 
				
			||||||
 | 
					            {MakeRes("LI", li_stats),
 | 
				
			||||||
 | 
					             MakeRes("Scene1", PD::Sys::GetTraceRef("Test1")->GetProtocol())}));
 | 
				
			||||||
 | 
					      } else if (test == 1) {
 | 
				
			||||||
 | 
					        results.push_back(std::make_pair<std::string, std::vector<StatsRes>>(
 | 
				
			||||||
 | 
					            std::to_string(test + 1),
 | 
				
			||||||
 | 
					            {MakeRes("LI", li_stats),
 | 
				
			||||||
 | 
					             MakeRes("Scene2", PD::Sys::GetTraceRef("Test2")->GetProtocol())}));
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        results.push_back(std::make_pair<std::string, std::vector<StatsRes>>(
 | 
				
			||||||
 | 
					            std::to_string(test + 1), {MakeRes("LI", li_stats)}));
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      test++;
 | 
				
			||||||
 | 
					      stime = time;
 | 
				
			||||||
 | 
					      frame = 0;
 | 
				
			||||||
 | 
					      li_stats->Clear();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    frame++;
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  StatsRes MakeRes(const std::string& name, PD::TimeStats::Ref s) {
 | 
				
			||||||
 | 
					    StatsRes res;
 | 
				
			||||||
 | 
					    res.name = name;
 | 
				
			||||||
 | 
					    res.average = PD::Strings::FormatNanos(s->GetAverage());
 | 
				
			||||||
 | 
					    res.min = PD::Strings::FormatNanos(s->GetMin());
 | 
				
			||||||
 | 
					    res.max = PD::Strings::FormatNanos(s->GetMax());
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void Result(float delta) {
 | 
				
			||||||
 | 
					    UpdateLiTimes();
 | 
				
			||||||
 | 
					    ren->OnScreen(PD::Screen::Top);
 | 
				
			||||||
 | 
					    if (ui7->BeginMenu("TestBench")) {
 | 
				
			||||||
 | 
					      auto m = ui7->GetCurrentMenu();
 | 
				
			||||||
 | 
					      m->Label("Base Init: " + TTime("BaseInit"));
 | 
				
			||||||
 | 
					      m->Label("Render All: " +
 | 
				
			||||||
 | 
					               PD::Strings::FormatNanos(li_stats->GetAverage()));
 | 
				
			||||||
 | 
					      ui7->EndMenu();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    ren->OnScreen(PD::Screen::Bottom);
 | 
				
			||||||
 | 
					    if (ui7->BeginMenu("Test Results", UI7MenuFlags_Scrolling)) {
 | 
				
			||||||
 | 
					      auto m = ui7->GetCurrentMenu();
 | 
				
			||||||
 | 
					      for (auto& it : results) {
 | 
				
			||||||
 | 
					        m->SeparatorText("Test " + it.first);
 | 
				
			||||||
 | 
					        for (int i = 0; i < (int)it.second.size(); i++) {
 | 
				
			||||||
 | 
					          m->Label(it.second[i].name + ":");
 | 
				
			||||||
 | 
					          m->Label("AVG: " + it.second[i].average);
 | 
				
			||||||
 | 
					          m->Label("MIN: " + it.second[i].min);
 | 
				
			||||||
 | 
					          m->Label("MAX: " + it.second[i].max);
 | 
				
			||||||
 | 
					          if (i != (int)it.second.size() - 1) {
 | 
				
			||||||
 | 
					            m->Separator();
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      ui7->EndMenu();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    ui7->Update(delta);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void Test1(float time) {
 | 
				
			||||||
 | 
					    PD::TT::Scope st("Test1");
 | 
				
			||||||
 | 
					    UpdateLiTimes();
 | 
				
			||||||
 | 
					    DrawFancyBG(time);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void Test2(float delta, float time) {
 | 
				
			||||||
 | 
					    PD::TT::Scope st("Test2");
 | 
				
			||||||
 | 
					    UpdateLiTimes();
 | 
				
			||||||
 | 
					    DrawFancyBG(time);
 | 
				
			||||||
 | 
					    if (ui7->BeginMenu("Test2")) {
 | 
				
			||||||
 | 
					      auto m = ui7->GetCurrentMenu();
 | 
				
			||||||
 | 
					      m->Button("Test");
 | 
				
			||||||
 | 
					      m->Separator();
 | 
				
			||||||
 | 
					      m->Label("Line1");
 | 
				
			||||||
 | 
					      m->Label("Line2");
 | 
				
			||||||
 | 
					      ui7->EndMenu();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    ui7->Update(delta);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void DrawFancyBG(float time) {
 | 
				
			||||||
 | 
					    ren->DrawRect(vec2(0, 0), vec2(400, 240), 0xff64c9fd);
 | 
				
			||||||
 | 
					    for (int i = 0; i < 44; i++) Append(i, vec2(0, 0), vec2(400, 240), time);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  float Offset(float x) {
 | 
				
			||||||
 | 
					    float y = cos(x) * 42;
 | 
				
			||||||
 | 
					    return y - floor(y);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  void Append(int index, vec2 position, vec2 size, float time) {
 | 
				
			||||||
 | 
					    float offset = Offset(index) * 62;
 | 
				
			||||||
 | 
					    float x_position = position.x() + size.x() / 8 * ((index % 11) - 1) +
 | 
				
			||||||
 | 
					                       cos(offset + time) * 10;
 | 
				
			||||||
 | 
					    float y_position = position.y() + size.y() / 8 * (index / 11) + 40 +
 | 
				
			||||||
 | 
					                       sin(offset + time) * 10 + 30;
 | 
				
			||||||
 | 
					    float color_effect = 1 - exp(-(index / 11) / 3.0f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ren->DrawTriangle(
 | 
				
			||||||
 | 
					        vec2(x_position, y_position), vec2(x_position + 300, y_position + (90)),
 | 
				
			||||||
 | 
					        vec2(x_position - 300, y_position + (90)),
 | 
				
			||||||
 | 
					        PD::Color(.94f - .17f * color_effect, .61f - .25f * color_effect,
 | 
				
			||||||
 | 
					                  .36f + .38f * color_effect));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::string TTime(const std::string& id) {
 | 
				
			||||||
 | 
					    return PD::Strings::FormatNanos(PD::Sys::GetTraceRef(id)->GetLastDiff());
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void UpdateLiTimes() {
 | 
				
			||||||
 | 
					    if (frame) {
 | 
				
			||||||
 | 
					      li_stats->Add(PD::Sys::GetTraceRef("LI_RenderAll")->GetLastDiff());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 private:
 | 
				
			||||||
 | 
					  PD::Hid::Ref inp;
 | 
				
			||||||
 | 
					  PD::LI::Renderer::Ref ren;
 | 
				
			||||||
 | 
					  PD::UI7::Context::Ref ui7;
 | 
				
			||||||
 | 
					  PD::LI::Font::Ref font;
 | 
				
			||||||
 | 
					  PD::TimeStats::Ref li_stats;
 | 
				
			||||||
 | 
					  int test = 0;
 | 
				
			||||||
 | 
					  float stime = 0.f;
 | 
				
			||||||
 | 
					  std::vector<std::pair<std::string, std::vector<StatsRes>>> results;
 | 
				
			||||||
 | 
					  int frame = 0;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main() {
 | 
				
			||||||
 | 
					  TestBench app;
 | 
				
			||||||
 | 
					  app.Run();
 | 
				
			||||||
 | 
					  return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user