From bcb0c069c33788018258c6ecd5f4be4b1d596ba9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= <5415177+ZehMatt@users.noreply.github.com> Date: Mon, 26 Jun 2023 21:59:27 +0300 Subject: [PATCH 1/4] Remove dead code of TestPaint and remove BenchSpriteSort --- src/openrct2/command_line/BenchSpriteSort.cpp | 235 ------------------ src/openrct2/command_line/CommandLine.hpp | 1 - src/openrct2/command_line/RootCommands.cpp | 1 - src/openrct2/interface/Viewport.cpp | 91 +------ src/openrct2/interface/Viewport.h | 9 +- src/openrct2/libopenrct2.vcxproj | 1 - src/openrct2/paint/Paint.h | 6 - 7 files changed, 9 insertions(+), 335 deletions(-) delete mode 100644 src/openrct2/command_line/BenchSpriteSort.cpp diff --git a/src/openrct2/command_line/BenchSpriteSort.cpp b/src/openrct2/command_line/BenchSpriteSort.cpp deleted file mode 100644 index e24c76c812..0000000000 --- a/src/openrct2/command_line/BenchSpriteSort.cpp +++ /dev/null @@ -1,235 +0,0 @@ -/***************************************************************************** - * Copyright (c) 2014-2023 OpenRCT2 developers - * - * For a complete list of all authors, please refer to contributors.md - * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 - * - * OpenRCT2 is licensed under the GNU General Public License version 3. - *****************************************************************************/ - -#include "CommandLine.hpp" - -#ifdef USE_BENCHMARK - -# include "../Context.h" -# include "../Game.h" -# include "../Intro.h" -# include "../OpenRCT2.h" -# include "../audio/audio.h" -# include "../core/Console.hpp" -# include "../core/File.h" -# include "../core/Imaging.h" -# include "../drawing/Drawing.h" -# include "../interface/Viewport.h" -# include "../localisation/Localisation.h" -# include "../paint/Paint.h" -# include "../platform/Platform.h" -# include "../util/Util.h" -# include "../world/Climate.h" -# include "../world/Map.h" -# include "../world/Park.h" -# include "../world/Surface.h" - -# include -# include -# include -# include - -static void fixup_pointers(std::vector& s) -{ - for (size_t i = 0; i < s.size(); i++) - { - auto& entries = s[i].Entries; - auto& quadrants = s[i].Session.Quadrants; - for (size_t j = 0; j < entries.size(); j++) - { - if (entries[j].AsBasic()->NextQuadrantEntry == reinterpret_cast(-1)) - { - entries[j].AsBasic()->NextQuadrantEntry = nullptr; - } - else - { - auto nextQuadrantPs = reinterpret_cast(entries[j].AsBasic()->NextQuadrantEntry) / sizeof(PaintEntry); - entries[j].AsBasic()->NextQuadrantEntry = s[i].Entries[nextQuadrantPs].AsBasic(); - } - } - for (size_t j = 0; j < std::size(quadrants); j++) - { - if (quadrants[j] == reinterpret_cast(-1)) - { - quadrants[j] = nullptr; - } - else - { - auto ps = reinterpret_cast(quadrants[j]) / sizeof(PaintEntry); - quadrants[j] = entries[ps].AsBasic(); - } - } - } -} - -static std::vector extract_paint_session(std::string_view parkFileName) -{ - gOpenRCT2Headless = true; - auto context = OpenRCT2::CreateContext(); - std::vector sessions; - LOG_INFO("Starting..."); - if (context->Initialise()) - { - DrawingEngineInit(); - if (!context->LoadParkFromFile(std::string(parkFileName))) - { - LOG_ERROR("Failed to load park!"); - return {}; - } - - gIntroState = IntroState::None; - gScreenFlags = SCREEN_FLAGS_PLAYING; - - int32_t resolutionWidth = (gMapSize.x * COORDS_XY_STEP * 2); - int32_t resolutionHeight = (gMapSize.y * COORDS_XY_STEP * 1); - - resolutionWidth += 8; - resolutionHeight += 128; - - Viewport viewport; - viewport.pos = { 0, 0 }; - viewport.width = resolutionWidth; - viewport.height = resolutionHeight; - viewport.view_width = viewport.width; - viewport.view_height = viewport.height; - viewport.var_11 = 0; - viewport.flags = 0; - - auto customXY = TileCoordsXY(gMapSize.x / 2, gMapSize.y / 2).ToCoordsXY().ToTileCentre(); - auto customXYZ = CoordsXYZ(customXY, TileElementHeight(customXY)); - auto screenXY = Translate3DTo2DWithZ(0, customXYZ); - - viewport.viewPos = { screenXY.x - (viewport.view_width / 2), screenXY.y - (viewport.view_height / 2) }; - viewport.zoom = ZoomLevel{ 0 }; - gCurrentRotation = 0; - - // Ensure sprites appear regardless of rotation - ResetAllSpriteQuadrantPlacements(); - - DrawPixelInfo dpi; - dpi.x = 0; - dpi.y = 0; - dpi.width = resolutionWidth; - dpi.height = resolutionHeight; - dpi.pitch = 0; - dpi.bits = static_cast(malloc(dpi.width * dpi.height)); - - LOG_INFO("Obtaining sprite data..."); - ViewportRender(dpi, &viewport, { { 0, 0 }, { viewport.width, viewport.height } }, &sessions); - - free(dpi.bits); - DrawingEngineDispose(); - } - LOG_INFO("Got %u paint sessions.", std::size(sessions)); - return sessions; -} - -// This function is based on BenchgfxRenderScreenshots -static void BM_paint_session_arrange(benchmark::State& state, const std::vector inputSessions) -{ - auto sessions = inputSessions; - // Fixing up the pointers continuously is wasteful. Fix it up once for `sessions` and store a copy. - // Keep in mind we need bit-exact copy, as the lists use pointers. - // Once sorted, just restore the copy with the original fixed-up version. - RecordedPaintSession* local_s = new RecordedPaintSession[std::size(sessions)]; - fixup_pointers(sessions); - std::copy_n(sessions.cbegin(), std::size(sessions), local_s); - for (auto _ : state) - { - state.PauseTiming(); - std::copy_n(local_s, std::size(sessions), sessions.begin()); - state.ResumeTiming(); - PaintSessionArrange(sessions[0].Session); - benchmark::DoNotOptimize(sessions); - } - state.SetItemsProcessed(state.iterations() * std::size(sessions)); - delete[] local_s; -} - -static int command_line_for_bench_sprite_sort(int argc, const char** argv) -{ - { - // Register some basic "baseline" benchmark - std::vector sessions(1); - for (auto& ps : sessions[0].Entries) - { - ps.AsBasic()->NextQuadrantEntry = reinterpret_cast(-1); - } - for (auto& quad : sessions[0].Session.Quadrants) - { - quad = reinterpret_cast(-1); - } - benchmark::RegisterBenchmark("baseline", BM_paint_session_arrange, sessions); - } - - // Google benchmark does stuff to argv. It doesn't modify the pointees, - // but it wants to reorder the pointers, so present a copy of them. - std::vector argv_for_benchmark; - - // argv[0] is expected to contain the binary name. It's only for logging purposes, don't bother. - argv_for_benchmark.push_back(nullptr); - - // Extract file names from argument list. If there is no such file, consider it benchmark option. - for (int i = 0; i < argc; i++) - { - if (File::Exists(argv[i])) - { - // Register benchmark for sv6 if valid - std::vector sessions = extract_paint_session(argv[i]); - if (!sessions.empty()) - benchmark::RegisterBenchmark(argv[i], BM_paint_session_arrange, sessions); - } - else - { - argv_for_benchmark.push_back(const_cast(argv[i])); - } - } - // Update argc with all the changes made - argc = static_cast(argv_for_benchmark.size()); - ::benchmark::Initialize(&argc, &argv_for_benchmark[0]); - if (::benchmark::ReportUnrecognizedArguments(argc, &argv_for_benchmark[0])) - return -1; - ::benchmark::RunSpecifiedBenchmarks(); - return 0; -} - -static exitcode_t HandleBenchSpriteSort(CommandLineArgEnumerator* argEnumerator) -{ - const char** argv = const_cast(argEnumerator->GetArguments()) + argEnumerator->GetIndex(); - int32_t argc = argEnumerator->GetCount() - argEnumerator->GetIndex(); - int32_t result = command_line_for_bench_sprite_sort(argc, argv); - if (result < 0) - { - return EXITCODE_FAIL; - } - return EXITCODE_OK; -} - -#else -static exitcode_t HandleBenchSpriteSort(CommandLineArgEnumerator* argEnumerator) -{ - LOG_ERROR("Sorry, Google benchmark not enabled in this build"); - return EXITCODE_FAIL; -} -#endif // USE_BENCHMARK - -const CommandLineCommand CommandLine::BenchSpriteSortCommands[]{ -#ifdef USE_BENCHMARK - DefineCommand( - "", - "[]... [--benchmark_list_tests={true|false}] [--benchmark_filter=] [--benchmark_min_time=] " - "[--benchmark_repetitions=] [--benchmark_report_aggregates_only={true|false}] " - "[--benchmark_format=] [--benchmark_out=] [--benchmark_out_format=] " - "[--benchmark_color={auto|true|false}] [--benchmark_counters_tabular={true|false}] [--v=]", - nullptr, HandleBenchSpriteSort), - CommandTableEnd -#else - DefineCommand("", "*** SORRY NOT ENABLED IN THIS BUILD ***", nullptr, HandleBenchSpriteSort), CommandTableEnd -#endif // USE_BENCHMARK -}; diff --git a/src/openrct2/command_line/CommandLine.hpp b/src/openrct2/command_line/CommandLine.hpp index 3f2f6aa161..fadcb45229 100644 --- a/src/openrct2/command_line/CommandLine.hpp +++ b/src/openrct2/command_line/CommandLine.hpp @@ -117,7 +117,6 @@ namespace CommandLine extern const CommandLineCommand ScreenshotCommands[]; extern const CommandLineCommand SpriteCommands[]; extern const CommandLineCommand BenchGfxCommands[]; - extern const CommandLineCommand BenchSpriteSortCommands[]; extern const CommandLineCommand BenchUpdateCommands[]; extern const CommandLineCommand SimulateCommands[]; extern const CommandLineCommand ParkInfoCommands[]; diff --git a/src/openrct2/command_line/RootCommands.cpp b/src/openrct2/command_line/RootCommands.cpp index 2d7d2c99b9..2fde2b306e 100644 --- a/src/openrct2/command_line/RootCommands.cpp +++ b/src/openrct2/command_line/RootCommands.cpp @@ -141,7 +141,6 @@ const CommandLineCommand CommandLine::RootCommands[] DefineSubCommand("screenshot", CommandLine::ScreenshotCommands ), DefineSubCommand("sprite", CommandLine::SpriteCommands ), DefineSubCommand("benchgfx", CommandLine::BenchGfxCommands ), - DefineSubCommand("benchspritesort", CommandLine::BenchSpriteSortCommands ), DefineSubCommand("benchsimulate", CommandLine::BenchUpdateCommands ), DefineSubCommand("simulate", CommandLine::SimulateCommands ), DefineSubCommand("parkinfo", CommandLine::ParkInfoCommands ), diff --git a/src/openrct2/interface/Viewport.cpp b/src/openrct2/interface/Viewport.cpp index 391eca93c1..b04bbfd43a 100644 --- a/src/openrct2/interface/Viewport.cpp +++ b/src/openrct2/interface/Viewport.cpp @@ -806,8 +806,7 @@ void ViewportUpdateSmartFollowVehicle(WindowBase* window) * edi: dpi * ebp: bottom */ -void ViewportRender( - DrawPixelInfo& dpi, const Viewport* viewport, const ScreenRect& screenRect, std::vector* sessions) +void ViewportRender(DrawPixelInfo& dpi, const Viewport* viewport, const ScreenRect& screenRect) { auto [topLeft, bottomRight] = screenRect; @@ -837,7 +836,7 @@ void ViewportRender( viewport->zoom.ApplyTo(std::min(bottomRight.y, viewport->height)), } + viewport->viewPos; - ViewportPaint(viewport, dpi, { topLeft, bottomRight }, sessions); + ViewportPaint(viewport, dpi, { topLeft, bottomRight }); #ifdef DEBUG_SHOW_DIRTY_BOX // FIXME g_viewport_list doesn't exist anymore @@ -846,75 +845,11 @@ void ViewportRender( #endif } -static void RecordSession( - const PaintSession& session, std::vector* recorded_sessions, size_t record_index) -{ - // Perform a deep copy of the paint session, use relative offsets. - // This is done to extract the session for benchmark. - // Place the copied session at provided record_index, so the caller can decide which columns/paint sessions to copy; - // there is no column information embedded in the session itself. - auto& recordedSession = recorded_sessions->at(record_index); - recordedSession.Session = session; - recordedSession.Entries.resize(session.PaintEntryChain.GetCount()); - - // Mind the offset needs to be calculated against the original `session`, not `session_copy` - std::unordered_map entryRemap; - - // Copy all entries - auto paintIndex = 0; - auto chain = session.PaintEntryChain.Head; - while (chain != nullptr) - { - for (size_t i = 0; i < chain->Count; i++) - { - auto& src = chain->PaintStructs[i]; - auto& dst = recordedSession.Entries[paintIndex++]; - dst = src; - entryRemap[src.AsBasic()] = reinterpret_cast(i * sizeof(PaintEntry)); - } - chain = chain->Next; - } - entryRemap[nullptr] = reinterpret_cast(-1); - - // Remap all entries - for (auto& ps : recordedSession.Entries) - { - auto& ptr = ps.AsBasic()->NextQuadrantEntry; - auto it = entryRemap.find(ptr); - if (it == entryRemap.end()) - { - assert(false); - ptr = nullptr; - } - else - { - ptr = it->second; - } - } - for (auto& ptr : recordedSession.Session.Quadrants) - { - auto it = entryRemap.find(ptr); - if (it == entryRemap.end()) - { - assert(false); - ptr = nullptr; - } - else - { - ptr = it->second; - } - } -} - -static void ViewportFillColumn(PaintSession& session, std::vector* recorded_sessions, size_t record_index) +static void ViewportFillColumn(PaintSession& session) { PROFILED_FUNCTION(); PaintSessionGenerate(session); - if (recorded_sessions != nullptr) - { - RecordSession(session, recorded_sessions, record_index); - } PaintSessionArrange(session); } @@ -959,9 +894,7 @@ static void ViewportPaintColumn(PaintSession& session) * edi: dpi * ebp: bottom */ -void ViewportPaint( - const Viewport* viewport, DrawPixelInfo& dpi, const ScreenRect& screenRect, - std::vector* recorded_sessions) +void ViewportPaint(const Viewport* viewport, DrawPixelInfo& dpi, const ScreenRect& screenRect) { PROFILED_FUNCTION(); @@ -1019,17 +952,8 @@ void ViewportPaint( useParallelDrawing = true; } - // Create space to record sessions and keep track which index is being drawn - size_t index = 0; - if (recorded_sessions != nullptr) - { - auto columnSize = rightBorder - alignedX; - auto columnCount = (columnSize + 31) / 32; - recorded_sessions->resize(columnCount); - } - // Generate and sort columns. - for (x = alignedX; x < rightBorder; x += 32, index++) + for (x = alignedX; x < rightBorder; x += 32) { PaintSession* session = PaintSessionAlloc(dpi1, viewFlags); _paintColumns.push_back(session); @@ -1055,12 +979,11 @@ void ViewportPaint( if (useMultithreading) { - _paintJobs->AddTask( - [session, recorded_sessions, index]() -> void { ViewportFillColumn(*session, recorded_sessions, index); }); + _paintJobs->AddTask([session]() -> void { ViewportFillColumn(*session); }); } else { - ViewportFillColumn(*session, recorded_sessions, index); + ViewportFillColumn(*session); } } diff --git a/src/openrct2/interface/Viewport.h b/src/openrct2/interface/Viewport.h index c9d96df639..47be0146af 100644 --- a/src/openrct2/interface/Viewport.h +++ b/src/openrct2/interface/Viewport.h @@ -17,7 +17,6 @@ #include struct PaintSession; -struct RecordedPaintSession; struct PaintStruct; struct DrawPixelInfo; struct TileElement; @@ -140,12 +139,8 @@ void ViewportUpdateSmartFollowEntity(WindowBase* window); void ViewportUpdateSmartFollowGuest(WindowBase* window, const Guest* peep); void ViewportUpdateSmartFollowStaff(WindowBase* window, const Staff* peep); void ViewportUpdateSmartFollowVehicle(WindowBase* window); -void ViewportRender( - DrawPixelInfo& dpi, const Viewport* viewport, const ScreenRect& screenRect, - std::vector* sessions = nullptr); -void ViewportPaint( - const Viewport* viewport, DrawPixelInfo& dpi, const ScreenRect& screenRect, - std::vector* sessions = nullptr); +void ViewportRender(DrawPixelInfo& dpi, const Viewport* viewport, const ScreenRect& screenRect); +void ViewportPaint(const Viewport* viewport, DrawPixelInfo& dpi, const ScreenRect& screenRect); CoordsXYZ ViewportAdjustForMapHeight(const ScreenCoordsXY& startCoords); diff --git a/src/openrct2/libopenrct2.vcxproj b/src/openrct2/libopenrct2.vcxproj index 950019c42e..b8c7a1e785 100644 --- a/src/openrct2/libopenrct2.vcxproj +++ b/src/openrct2/libopenrct2.vcxproj @@ -691,7 +691,6 @@ - diff --git a/src/openrct2/paint/Paint.h b/src/openrct2/paint/Paint.h index a50dcdb7e5..017df904c0 100644 --- a/src/openrct2/paint/Paint.h +++ b/src/openrct2/paint/Paint.h @@ -270,12 +270,6 @@ struct FootpathPaintInfo colour_t SupportColour = 255; }; -struct RecordedPaintSession -{ - PaintSessionCore Session; - std::vector Entries; -}; - extern PaintSession gPaintSession; // Globals for paint clipping From edabd97c8accdf9389de7988169a98511eda5636 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= <5415177+ZehMatt@users.noreply.github.com> Date: Mon, 26 Jun 2023 22:10:46 +0300 Subject: [PATCH 2/4] Remove benchmark code from game logic --- src/openrct2/GameState.cpp | 38 +---- src/openrct2/GameState.h | 42 +----- src/openrct2/command_line/BenchUpdate.cpp | 160 --------------------- src/openrct2/command_line/CommandLine.hpp | 1 - src/openrct2/command_line/RootCommands.cpp | 1 - src/openrct2/libopenrct2.vcxproj | 1 - 6 files changed, 2 insertions(+), 241 deletions(-) delete mode 100644 src/openrct2/command_line/BenchUpdate.cpp diff --git a/src/openrct2/GameState.cpp b/src/openrct2/GameState.cpp index 3f3fb39184..9a96c5cca0 100644 --- a/src/openrct2/GameState.cpp +++ b/src/openrct2/GameState.cpp @@ -250,19 +250,10 @@ void GameState::Tick() gDoSingleUpdate = false; } -void GameState::UpdateLogic(LogicTimings* timings) +void GameState::UpdateLogic() { PROFILED_FUNCTION(); - auto start_time = std::chrono::high_resolution_clock::now(); - - auto report_time = [timings, start_time](LogicTimePart part) { - if (timings != nullptr) - { - timings->TimingInfo[part][timings->CurrentIdx] = std::chrono::high_resolution_clock::now() - start_time; - } - }; - gInUpdateCode = true; gScreenAge++; @@ -272,7 +263,6 @@ void GameState::UpdateLogic(LogicTimings* timings) GetContext()->GetReplayManager()->Update(); NetworkUpdate(); - report_time(LogicTimePart::NetworkUpdate); if (NetworkGetMode() == NETWORK_MODE_SERVER) { @@ -316,51 +306,33 @@ void GameState::UpdateLogic(LogicTimings* timings) #endif _date.Update(); - report_time(LogicTimePart::Date); ScenarioUpdate(); - report_time(LogicTimePart::Scenario); ClimateUpdate(); - report_time(LogicTimePart::Climate); MapUpdateTiles(); - report_time(LogicTimePart::MapTiles); // Temporarily remove provisional paths to prevent peep from interacting with them MapRemoveProvisionalElements(); - report_time(LogicTimePart::MapStashProvisionalElements); MapUpdatePathWideFlags(); - report_time(LogicTimePart::MapPathWideFlags); PeepUpdateAll(); - report_time(LogicTimePart::Peep); MapRestoreProvisionalElements(); - report_time(LogicTimePart::MapRestoreProvisionalElements); VehicleUpdateAll(); - report_time(LogicTimePart::Vehicle); UpdateAllMiscEntities(); - report_time(LogicTimePart::Misc); Ride::UpdateAll(); - report_time(LogicTimePart::Ride); if (!(gScreenFlags & SCREEN_FLAGS_EDITOR)) { _park->Update(_date); } - report_time(LogicTimePart::Park); ResearchUpdate(); - report_time(LogicTimePart::Research); RideRatingsUpdateAll(); - report_time(LogicTimePart::RideRatings); RideMeasurementsUpdate(); - report_time(LogicTimePart::RideMeasurments); News::UpdateCurrentItem(); - report_time(LogicTimePart::News); MapAnimationInvalidateAll(); - report_time(LogicTimePart::MapAnimation); VehicleSoundsUpdate(); PeepUpdateCrowdNoise(); ClimateUpdateSound(); - report_time(LogicTimePart::Sounds); EditorOpenWindowsForCurrentStep(); // Update windows @@ -373,11 +345,9 @@ void GameState::UpdateLogic(LogicTimings* timings) } GameActions::ProcessQueue(); - report_time(LogicTimePart::GameActions); NetworkProcessPending(); NetworkFlush(); - report_time(LogicTimePart::NetworkFlush); gCurrentTicks++; gSavedAge++; @@ -390,14 +360,8 @@ void GameState::UpdateLogic(LogicTimings* timings) { hookEngine.Call(HOOK_TYPE::INTERVAL_DAY, true); } - report_time(LogicTimePart::Scripts); #endif - if (timings != nullptr) - { - timings->CurrentIdx = (timings->CurrentIdx + 1) % LOGIC_UPDATE_MEASUREMENTS_COUNT; - } - gInUpdateCode = false; } diff --git a/src/openrct2/GameState.h b/src/openrct2/GameState.h index 3cc2d29b40..7ac9da61a2 100644 --- a/src/openrct2/GameState.h +++ b/src/openrct2/GameState.h @@ -21,46 +21,6 @@ namespace OpenRCT2 { class Park; - // Information regarding various pieces of logic update - enum class LogicTimePart - { - NetworkUpdate, - Date, - Scenario, - Climate, - MapTiles, - MapStashProvisionalElements, - MapPathWideFlags, - Peep, - MapRestoreProvisionalElements, - Vehicle, - Misc, - Ride, - Park, - Research, - RideRatings, - RideMeasurments, - News, - MapAnimation, - Sounds, - GameActions, - NetworkFlush, - Scripts, - }; - - // ~6.5s at 40Hz - constexpr size_t LOGIC_UPDATE_MEASUREMENTS_COUNT = 256; - - // In order not to cause allocations, collect multiple samples into single pre-allocated struct - using LogicTimingInfo = std::unordered_map< - LogicTimePart, std::array, LOGIC_UPDATE_MEASUREMENTS_COUNT>>; - - struct LogicTimings - { - LogicTimingInfo TimingInfo; - size_t CurrentIdx{}; - }; - /** * Class to update the state of the map and park. */ @@ -85,7 +45,7 @@ namespace OpenRCT2 void InitAll(const TileCoordsXY& mapSize); void Tick(); - void UpdateLogic(LogicTimings* timings = nullptr); + void UpdateLogic(); void SetDate(Date newDate); void ResetDate(); diff --git a/src/openrct2/command_line/BenchUpdate.cpp b/src/openrct2/command_line/BenchUpdate.cpp deleted file mode 100644 index d87777a8da..0000000000 --- a/src/openrct2/command_line/BenchUpdate.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/***************************************************************************** - * Copyright (c) 2014-2023 OpenRCT2 developers - * - * For a complete list of all authors, please refer to contributors.md - * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 - * - * OpenRCT2 is licensed under the GNU General Public License version 3. - *****************************************************************************/ - -#include "CommandLine.hpp" - -#ifdef USE_BENCHMARK - -# include "../Context.h" -# include "../GameState.h" -# include "../OpenRCT2.h" -# include "../core/File.h" -# include "../platform/Platform.h" - -# include -# include -# include -# include -# include - -using namespace OpenRCT2; - -static void BM_update(benchmark::State& state, const std::string& filename) -{ - std::unique_ptr context(CreateContext()); - if (context->Initialise()) - { - if (!filename.empty() && !context->LoadParkFromFile(filename)) - { - state.SkipWithError("Failed to load file!"); - } - - std::vector timings(1); - timings.reserve(100); - int currentTimingIdx = 0; - for (auto _ : state) - { - if (timings[currentTimingIdx].CurrentIdx == (LOGIC_UPDATE_MEASUREMENTS_COUNT - 1)) - { - timings.resize(timings.size() + 1); - currentTimingIdx++; - } - LogicTimings* timingToUse = &timings[currentTimingIdx]; - context->GetGameState()->UpdateLogic(timingToUse); - } - state.SetItemsProcessed(state.iterations()); - auto accumulator = [timings](LogicTimePart part) -> double { - std::chrono::duration timesum; - for (const auto& timing : timings) - { - timesum = std::accumulate( - timing.TimingInfo.at(part).begin(), timing.TimingInfo.at(part).end(), std::chrono::duration()); - } - return std::chrono::duration_cast(timesum).count(); - }; - state.counters["NetworkUpdateAcc_ms"] = accumulator(LogicTimePart::NetworkUpdate); - state.counters["DateAcc_ms"] = accumulator(LogicTimePart::Date); - state.counters["ScenarioAcc_ms"] = accumulator(LogicTimePart::Scenario); - state.counters["ClimateAcc_ms"] = accumulator(LogicTimePart::Climate); - state.counters["MapTilesAcc_ms"] = accumulator(LogicTimePart::MapTiles); - state.counters["MapStashProvisionalElementsAcc_ms"] = accumulator(LogicTimePart::MapStashProvisionalElements); - state.counters["MapPathWideFlagsAcc_ms"] = accumulator(LogicTimePart::MapPathWideFlags); - state.counters["PeepAcc_ms"] = accumulator(LogicTimePart::Peep); - state.counters["MapRestoreProvisionalElementsAcc_ms"] = accumulator(LogicTimePart::MapRestoreProvisionalElements); - state.counters["VehicleAcc_ms"] = accumulator(LogicTimePart::Vehicle); - state.counters["MiscAcc_ms"] = accumulator(LogicTimePart::Misc); - state.counters["RideAcc_ms"] = accumulator(LogicTimePart::Ride); - state.counters["ParkAcc_ms"] = accumulator(LogicTimePart::Park); - state.counters["ResearchAcc_ms"] = accumulator(LogicTimePart::Research); - state.counters["RideRatingsAcc_ms"] = accumulator(LogicTimePart::RideRatings); - state.counters["RideMeasurmentsAcc_ms"] = accumulator(LogicTimePart::RideMeasurments); - state.counters["NewsAcc_ms"] = accumulator(LogicTimePart::News); - state.counters["MapAnimationAcc_ms"] = accumulator(LogicTimePart::MapAnimation); - state.counters["SoundsAcc_ms"] = accumulator(LogicTimePart::Sounds); - state.counters["GameActionsAcc_ms"] = accumulator(LogicTimePart::GameActions); - state.counters["NetworkFlushAcc_ms"] = accumulator(LogicTimePart::NetworkFlush); - state.counters["ScriptsAcc_ms"] = accumulator(LogicTimePart::Scripts); - } - else - { - state.SkipWithError("Context initialization failed."); - } -} - -static int CommandLineForBenchSpriteSort(int argc, const char* const* argv) -{ - // Add a baseline test on an empty park - benchmark::RegisterBenchmark("baseline", BM_update, std::string{}); - - // Google benchmark does stuff to argv. It doesn't modify the pointees, - // but it wants to reorder the pointers, so present a copy of them. - std::vector argv_for_benchmark; - - // argv[0] is expected to contain the binary name. It's only for logging purposes, don't bother. - argv_for_benchmark.push_back(nullptr); - - // Extract file names from argument list. If there is no such file, consider it benchmark option. - for (int i = 0; i < argc; i++) - { - if (File::Exists(argv[i])) - { - // Register benchmark for sv6 if valid - benchmark::RegisterBenchmark(argv[i], BM_update, argv[i]); - } - else - { - argv_for_benchmark.push_back(const_cast(argv[i])); - } - } - // Update argc with all the changes made - argc = static_cast(argv_for_benchmark.size()); - ::benchmark::Initialize(&argc, &argv_for_benchmark[0]); - if (::benchmark::ReportUnrecognizedArguments(argc, &argv_for_benchmark[0])) - return -1; - - gOpenRCT2Headless = true; - - ::benchmark::RunSpecifiedBenchmarks(); - return 0; -} - -static exitcode_t HandleBenchUpdate(CommandLineArgEnumerator* argEnumerator) -{ - const char* const* argv = static_cast(argEnumerator->GetArguments()) + argEnumerator->GetIndex(); - int32_t argc = argEnumerator->GetCount() - argEnumerator->GetIndex(); - int32_t result = CommandLineForBenchSpriteSort(argc, argv); - if (result < 0) - { - return EXITCODE_FAIL; - } - return EXITCODE_OK; -} - -#else -static exitcode_t HandleBenchUpdate(CommandLineArgEnumerator* argEnumerator) -{ - LOG_ERROR("Sorry, Google benchmark not enabled in this build"); - return EXITCODE_FAIL; -} -#endif // USE_BENCHMARK - -const CommandLineCommand CommandLine::BenchUpdateCommands[]{ -#ifdef USE_BENCHMARK - DefineCommand( - "", - "... [--benchmark_list_tests={true|false}] [--benchmark_filter=] [--benchmark_min_time=] " - "[--benchmark_repetitions=] [--benchmark_report_aggregates_only={true|false}] " - "[--benchmark_format=] [--benchmark_out=] [--benchmark_out_format=] " - "[--benchmark_color={auto|true|false}] [--benchmark_counters_tabular={true|false}] [--v=]", - nullptr, HandleBenchUpdate), - CommandTableEnd -#else - DefineCommand("", "*** SORRY NOT ENABLED IN THIS BUILD ***", nullptr, HandleBenchUpdate), CommandTableEnd -#endif // USE_BENCHMARK -}; diff --git a/src/openrct2/command_line/CommandLine.hpp b/src/openrct2/command_line/CommandLine.hpp index fadcb45229..0897cc12b1 100644 --- a/src/openrct2/command_line/CommandLine.hpp +++ b/src/openrct2/command_line/CommandLine.hpp @@ -117,7 +117,6 @@ namespace CommandLine extern const CommandLineCommand ScreenshotCommands[]; extern const CommandLineCommand SpriteCommands[]; extern const CommandLineCommand BenchGfxCommands[]; - extern const CommandLineCommand BenchUpdateCommands[]; extern const CommandLineCommand SimulateCommands[]; extern const CommandLineCommand ParkInfoCommands[]; diff --git a/src/openrct2/command_line/RootCommands.cpp b/src/openrct2/command_line/RootCommands.cpp index 2fde2b306e..1d404b22d3 100644 --- a/src/openrct2/command_line/RootCommands.cpp +++ b/src/openrct2/command_line/RootCommands.cpp @@ -141,7 +141,6 @@ const CommandLineCommand CommandLine::RootCommands[] DefineSubCommand("screenshot", CommandLine::ScreenshotCommands ), DefineSubCommand("sprite", CommandLine::SpriteCommands ), DefineSubCommand("benchgfx", CommandLine::BenchGfxCommands ), - DefineSubCommand("benchsimulate", CommandLine::BenchUpdateCommands ), DefineSubCommand("simulate", CommandLine::SimulateCommands ), DefineSubCommand("parkinfo", CommandLine::ParkInfoCommands ), CommandTableEnd diff --git a/src/openrct2/libopenrct2.vcxproj b/src/openrct2/libopenrct2.vcxproj index b8c7a1e785..c6e016e532 100644 --- a/src/openrct2/libopenrct2.vcxproj +++ b/src/openrct2/libopenrct2.vcxproj @@ -691,7 +691,6 @@ - From d61ce4e38c95e2bf58bc0e4e08175a0befcd8ec1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= <5415177+ZehMatt@users.noreply.github.com> Date: Mon, 26 Jun 2023 22:14:11 +0300 Subject: [PATCH 3/4] Remove BenchGfx --- .../command_line/BenchGfxCommmands.cpp | 30 ----- src/openrct2/command_line/CommandLine.hpp | 1 - src/openrct2/command_line/RootCommands.cpp | 1 - src/openrct2/interface/Screenshot.cpp | 123 ------------------ src/openrct2/interface/Screenshot.h | 1 - src/openrct2/libopenrct2.vcxproj | 1 - 6 files changed, 157 deletions(-) delete mode 100644 src/openrct2/command_line/BenchGfxCommmands.cpp diff --git a/src/openrct2/command_line/BenchGfxCommmands.cpp b/src/openrct2/command_line/BenchGfxCommmands.cpp deleted file mode 100644 index 439e6fbd58..0000000000 --- a/src/openrct2/command_line/BenchGfxCommmands.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/***************************************************************************** - * Copyright (c) 2014-2023 OpenRCT2 developers - * - * For a complete list of all authors, please refer to contributors.md - * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 - * - * OpenRCT2 is licensed under the GNU General Public License version 3. - *****************************************************************************/ - -#include "../interface/Screenshot.h" -#include "CommandLine.hpp" - -static exitcode_t HandleBenchGfx(CommandLineArgEnumerator* argEnumerator); - -const CommandLineCommand CommandLine::BenchGfxCommands[]{ - // Main commands - DefineCommand("", " [iterations count]", nullptr, HandleBenchGfx), CommandTableEnd -}; - -static exitcode_t HandleBenchGfx(CommandLineArgEnumerator* argEnumerator) -{ - const char** argv = const_cast(argEnumerator->GetArguments()) + argEnumerator->GetIndex(); - int32_t argc = argEnumerator->GetCount() - argEnumerator->GetIndex(); - int32_t result = CommandLineForGfxbench(argv, argc); - if (result < 0) - { - return EXITCODE_FAIL; - } - return EXITCODE_OK; -} diff --git a/src/openrct2/command_line/CommandLine.hpp b/src/openrct2/command_line/CommandLine.hpp index 0897cc12b1..f8d0d7f489 100644 --- a/src/openrct2/command_line/CommandLine.hpp +++ b/src/openrct2/command_line/CommandLine.hpp @@ -116,7 +116,6 @@ namespace CommandLine extern const CommandLineCommand RootCommands[]; extern const CommandLineCommand ScreenshotCommands[]; extern const CommandLineCommand SpriteCommands[]; - extern const CommandLineCommand BenchGfxCommands[]; extern const CommandLineCommand SimulateCommands[]; extern const CommandLineCommand ParkInfoCommands[]; diff --git a/src/openrct2/command_line/RootCommands.cpp b/src/openrct2/command_line/RootCommands.cpp index 1d404b22d3..d2d6335505 100644 --- a/src/openrct2/command_line/RootCommands.cpp +++ b/src/openrct2/command_line/RootCommands.cpp @@ -140,7 +140,6 @@ const CommandLineCommand CommandLine::RootCommands[] // Sub-commands DefineSubCommand("screenshot", CommandLine::ScreenshotCommands ), DefineSubCommand("sprite", CommandLine::SpriteCommands ), - DefineSubCommand("benchgfx", CommandLine::BenchGfxCommands ), DefineSubCommand("simulate", CommandLine::SimulateCommands ), DefineSubCommand("parkinfo", CommandLine::ParkInfoCommands ), CommandTableEnd diff --git a/src/openrct2/interface/Screenshot.cpp b/src/openrct2/interface/Screenshot.cpp index 24ec108206..c033df8473 100644 --- a/src/openrct2/interface/Screenshot.cpp +++ b/src/openrct2/interface/Screenshot.cpp @@ -390,129 +390,6 @@ void ScreenshotGiant() ReleaseDPI(dpi); } -// TODO: Move this at some point into a more appropriate place. -template static inline double MeasureFunctionTime(const FN& fn) -{ - const auto startTime = std::chrono::high_resolution_clock::now(); - fn(); - const auto endTime = std::chrono::high_resolution_clock::now(); - return std::chrono::duration(endTime - startTime).count(); -} - -static void BenchgfxRenderScreenshots(const char* inputPath, std::unique_ptr& context, uint32_t iterationCount) -{ - if (!context->LoadParkFromFile(inputPath)) - { - return; - } - - gIntroState = IntroState::None; - gScreenFlags = SCREEN_FLAGS_PLAYING; - - // Create Viewport and DPI for every rotation and zoom. - // We iterate from the default zoom level to the max zoomed out zoom level, then run GetGiantViewport once for each - // rotation. - constexpr int32_t NUM_ROTATIONS = 4; - constexpr auto NUM_ZOOM_LEVELS = static_cast(ZoomLevel::max()); - std::array dpis; - std::array viewports; - - for (ZoomLevel zoom{ 0 }; zoom < ZoomLevel::max(); zoom++) - { - int32_t zoomIndex{ static_cast(zoom) }; - for (int32_t rotation = 0; rotation < NUM_ROTATIONS; rotation++) - { - auto& viewport = viewports[zoomIndex * NUM_ZOOM_LEVELS + rotation]; - auto& dpi = dpis[zoomIndex * NUM_ZOOM_LEVELS + rotation]; - viewport = GetGiantViewport(rotation, zoom); - dpi = CreateDPI(viewport); - } - } - - const uint32_t totalRenderCount = iterationCount * NUM_ROTATIONS * NUM_ZOOM_LEVELS; - - try - { - double totalTime = 0.0; - - std::array zoomAverages; - - // Render at every zoom. - for (int32_t zoom = 0; zoom < NUM_ZOOM_LEVELS; zoom++) - { - double zoomLevelTime = 0.0; - - // Render at every rotation. - for (int32_t rotation = 0; rotation < NUM_ROTATIONS; rotation++) - { - // N iterations. - for (uint32_t i = 0; i < iterationCount; i++) - { - auto& dpi = dpis[zoom * NUM_ZOOM_LEVELS + rotation]; - auto& viewport = viewports[zoom * NUM_ZOOM_LEVELS + rotation]; - double elapsed = MeasureFunctionTime([&viewport, &dpi]() { RenderViewport(nullptr, viewport, dpi); }); - totalTime += elapsed; - zoomLevelTime += elapsed; - } - } - - zoomAverages[zoom] = zoomLevelTime / static_cast(NUM_ROTATIONS * iterationCount); - } - - const double average = totalTime / static_cast(totalRenderCount); - const auto engineStringId = DrawingEngineStringIds[EnumValue(DrawingEngine::Software)]; - const auto engineName = FormatStringID(engineStringId, nullptr); - std::printf("Engine: %s\n", engineName.c_str()); - std::printf("Render Count: %u\n", totalRenderCount); - for (ZoomLevel zoom{ 0 }; zoom < ZoomLevel::max(); zoom++) - { - int32_t zoomIndex{ static_cast(zoom) }; - const auto zoomAverage = zoomAverages[zoomIndex]; - std::printf("Zoom[%d] average: %.06fs, %.f FPS\n", zoomIndex, zoomAverage, 1.0 / zoomAverage); - } - std::printf("Total average: %.06fs, %.f FPS\n", average, 1.0 / average); - std::printf("Time: %.05fs\n", totalTime); - } - catch (const std::exception& e) - { - Console::Error::WriteLine("%s", e.what()); - } - - for (auto& dpi : dpis) - ReleaseDPI(dpi); -} - -int32_t CommandLineForGfxbench(const char** argv, int32_t argc) -{ - if (argc != 1 && argc != 2) - { - printf("Usage: openrct2 benchgfx []\n"); - return -1; - } - - int32_t iterationCount = 5; - if (argc == 2) - { - iterationCount = atoi(argv[1]); - } - - const char* inputPath = argv[0]; - - gOpenRCT2Headless = true; - - std::unique_ptr context(CreateContext()); - if (context->Initialise()) - { - DrawingEngineInit(); - - BenchgfxRenderScreenshots(inputPath, context, iterationCount); - - DrawingEngineDispose(); - } - - return 1; -} - static void ApplyOptions(const ScreenshotOptions* options, Viewport& viewport) { if (options->weather != WeatherType::Sunny && options->weather != WeatherType::Count) diff --git a/src/openrct2/interface/Screenshot.h b/src/openrct2/interface/Screenshot.h index 30eacdcded..ba6ab28de9 100644 --- a/src/openrct2/interface/Screenshot.h +++ b/src/openrct2/interface/Screenshot.h @@ -59,6 +59,5 @@ std::string ScreenshotDumpPNG32bpp(int32_t width, int32_t height, const void* pi void ScreenshotGiant(); int32_t CommandLineForScreenshot(const char** argv, int32_t argc, ScreenshotOptions* options); -int32_t CommandLineForGfxbench(const char** argv, int32_t argc); void CaptureImage(const CaptureOptions& options); diff --git a/src/openrct2/libopenrct2.vcxproj b/src/openrct2/libopenrct2.vcxproj index c6e016e532..ea555463ee 100644 --- a/src/openrct2/libopenrct2.vcxproj +++ b/src/openrct2/libopenrct2.vcxproj @@ -690,7 +690,6 @@ - From d37478e29411d331bace43986d1cc0ec3104baeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= <5415177+ZehMatt@users.noreply.github.com> Date: Mon, 26 Jun 2023 22:25:07 +0300 Subject: [PATCH 4/4] Remove google benchmark dependency --- CMakeLists.txt | 3 ++- openrct2.common.props | 6 +++--- src/openrct2/libopenrct2.vcxproj | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a8d4b88580..03de46bd94 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -100,7 +100,8 @@ option(STATIC "Create a static build.") option(USE_MMAP "Use mmap to try loading rct2's data segment into memory.") option(DISABLE_DISCORD_RPC "Disable Discord-RPC support." OFF) -option(DISABLE_GOOGLE_BENCHMARK "Disable Google Benchmarks support." OFF) +# Currently unused, disable by default. +option(DISABLE_GOOGLE_BENCHMARK "Disable Google Benchmarks support." ON) option(DISABLE_HTTP "Disable HTTP support.") option(DISABLE_NETWORK "Disable multiplayer functionality. Mainly for testing.") option(DISABLE_TTF "Disable support for TTF provided by freetype2.") diff --git a/openrct2.common.props b/openrct2.common.props index 6c3401d04c..ecb0b4a280 100644 --- a/openrct2.common.props +++ b/openrct2.common.props @@ -58,7 +58,7 @@ C4549: 'operator': operator before comma has no effect; did you intend 'operator'? C4555: expression has no effect; expected expression with side-effect --> - BENCHMARK_STATIC_DEFINE;OPENGL_NO_LINK;_CRT_SECURE_NO_WARNINGS;SDL_MAIN_HANDLED;_WINSOCK_DEPRECATED_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions) + OPENGL_NO_LINK;_CRT_SECURE_NO_WARNINGS;SDL_MAIN_HANDLED;_WINSOCK_DEPRECATED_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions) __AVX2__;__SSE4_1__;%(PreprocessorDefinitions) ENABLE_SCRIPTING;%(PreprocessorDefinitions) MultiThreaded @@ -86,7 +86,7 @@ DebugFull - benchmark.lib;brotlicommon-static.lib;brotlidec-static.lib;brotlienc-static.lib;%(AdditionalDependencies) + brotlicommon-static.lib;brotlidec-static.lib;brotlienc-static.lib;%(AdditionalDependencies) libbreakpadd.lib;libbreakpad_clientd.lib;%(AdditionalDependencies) bz2d.lib;discord-rpc.lib;flac.lib;freetyped.lib;libpng16d.lib;ogg.lib;speexdsp.lib;SDL2-staticd.lib;vorbis.lib;vorbisfile.lib;zip.lib;zlibd.lib;%(AdditionalDependencies) @@ -107,7 +107,7 @@ DebugFull true true - benchmark.lib;brotlicommon-static.lib;brotlidec-static.lib;brotlienc-static.lib;%(AdditionalDependencies) + brotlicommon-static.lib;brotlidec-static.lib;brotlienc-static.lib;%(AdditionalDependencies) libbreakpad.lib;libbreakpad_client.lib;%(AdditionalDependencies) bz2.lib;discord-rpc.lib;flac.lib;freetype.lib;libpng16.lib;ogg.lib;speexdsp.lib;SDL2-static.lib;vorbis.lib;vorbisfile.lib;zip.lib;zlib.lib;%(AdditionalDependencies) diff --git a/src/openrct2/libopenrct2.vcxproj b/src/openrct2/libopenrct2.vcxproj index ea555463ee..49134f082c 100644 --- a/src/openrct2/libopenrct2.vcxproj +++ b/src/openrct2/libopenrct2.vcxproj @@ -51,7 +51,7 @@ - __ENABLE_DISCORD__;USE_BENCHMARK;%(PreprocessorDefinitions) + __ENABLE_DISCORD__;%(PreprocessorDefinitions) USE_BREAKPAD;%(PreprocessorDefinitions) USE_FRIBIDI;%(PreprocessorDefinitions) Use