From 238349953389bad033fb5df1e752e7b51e9fe4ba Mon Sep 17 00:00:00 2001 From: Sour Date: Mon, 31 Dec 2018 14:59:00 -0500 Subject: [PATCH] Build: Simplify PGO builds and allow it to be used when building the libretro core --- Core/Console.cpp | 7 +++ Core/Console.h | 2 + Core/Core.vcxproj | 2 + Core/Core.vcxproj.filters | 6 +++ Core/PgoUtilities.cpp | 38 +++++++++++++++++ Core/PgoUtilities.h | 14 ++++++ PGOHelper/PGOHelper.cpp | 89 ++++----------------------------------- buildPGO.sh | 22 ++++++---- makefile | 8 ++-- 9 files changed, 95 insertions(+), 93 deletions(-) create mode 100644 Core/PgoUtilities.cpp create mode 100644 Core/PgoUtilities.h diff --git a/Core/Console.cpp b/Core/Console.cpp index c70d6336..77cf7877 100644 --- a/Core/Console.cpp +++ b/Core/Console.cpp @@ -46,6 +46,7 @@ #include "NotificationManager.h" #include "HistoryViewer.h" #include "ConsolePauseHelper.h" +#include "PgoUtilities.h" Console::Console(shared_ptr master, EmulationSettings* initialSettings) { @@ -1486,3 +1487,9 @@ void Console::DisplayDebugInformation(Timer &clockTimer, Timer &lastFrameTimer, _debugHud->DrawString(134, 48, ss.str(), 0xFFFFFF, 0xFF000000, 1, startFrame); } +void Console::ExportStub() +{ + //Force the compiler to export the PgoRunTest function - otherwise it seems to be ignored since it is unused + vector testRoms; + PgoRunTest(testRoms, true); +} \ No newline at end of file diff --git a/Core/Console.h b/Core/Console.h index c103b495..3109658c 100644 --- a/Core/Console.h +++ b/Core/Console.h @@ -103,6 +103,8 @@ private: double GetFrameDelay(); void DisplayDebugInformation(Timer &clockTimer, Timer &lastFrameTimer, double &lastFrameMin, double &lastFrameMax, uint32_t lastPauseFrame); + void ExportStub(); + public: Console(shared_ptr master = nullptr, EmulationSettings* initialSettings = nullptr); ~Console(); diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj index 4e3346f4..a40b3b74 100644 --- a/Core/Core.vcxproj +++ b/Core/Core.vcxproj @@ -954,6 +954,7 @@ + @@ -984,6 +985,7 @@ + diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters index 4076cc9e..ca4950c7 100644 --- a/Core/Core.vcxproj.filters +++ b/Core/Core.vcxproj.filters @@ -1767,5 +1767,11 @@ Nes\APU\Filters + + Misc + + + Misc + \ No newline at end of file diff --git a/Core/PgoUtilities.cpp b/Core/PgoUtilities.cpp new file mode 100644 index 00000000..8b937835 --- /dev/null +++ b/Core/PgoUtilities.cpp @@ -0,0 +1,38 @@ +#include "stdafx.h" +#include +#include "PgoUtilities.h" +#include "Types.h" +#include "Debugger.h" +#include "DebuggerTypes.h" +#include "Console.h" +#include "../Utilities/FolderUtilities.h" + +extern "C" { + void __stdcall PgoRunTest(vector testRoms, bool enableDebugger) + { + const VideoFilterType filterTypes[13] = { VideoFilterType::BisqwitNtscQuarterRes, VideoFilterType::HQ2x, VideoFilterType::HQ3x, VideoFilterType::HQ4x, VideoFilterType::NTSC, VideoFilterType::Scale2x, VideoFilterType::Scale3x, VideoFilterType::Scale4x, VideoFilterType::xBRZ2x, VideoFilterType::xBRZ3x, VideoFilterType::xBRZ4x, VideoFilterType::xBRZ5x, VideoFilterType::xBRZ6x }; + FolderUtilities::SetHomeFolder("../PGOMesenHome"); + + for(size_t i = 0; i < testRoms.size(); i++) { + std::cout << "Running: " << testRoms[i] << std::endl; + + shared_ptr console(new Console()); + console->Init(); + console->Initialize(testRoms[i]); + console->GetSettings()->SetFlags(EmulationFlags::ConsoleMode | EmulationFlags::UseHdPacks); + console->GetSettings()->SetVideoFilterType(filterTypes[i % 13]); + + if(enableDebugger) { + console->GetDebugger(true)->SetFlags((uint32_t)DebuggerFlags::BreakOnFirstCycle); + } + + thread testThread([&console] { + console->Run(); + }); + std::this_thread::sleep_for(std::chrono::duration(5000)); + console->Stop(); + testThread.join(); + console->Release(true); + } + } +} \ No newline at end of file diff --git a/Core/PgoUtilities.h b/Core/PgoUtilities.h new file mode 100644 index 00000000..e59fb621 --- /dev/null +++ b/Core/PgoUtilities.h @@ -0,0 +1,14 @@ +#pragma once + +#include "stdafx.h" + +extern "C" { +#if _WIN32 || _WIN64 +#define DllExport2 __declspec(dllexport) +#else +#define DllExport2 __attribute__((visibility("default"))) +#define __stdcall +#endif + + DllExport2 void __stdcall PgoRunTest(vector testRoms, bool enableDebugger); +} diff --git a/PGOHelper/PGOHelper.cpp b/PGOHelper/PGOHelper.cpp index 1fa9f8af..9f93d8af 100644 --- a/PGOHelper/PGOHelper.cpp +++ b/PGOHelper/PGOHelper.cpp @@ -1,69 +1,18 @@ -#ifdef _WIN32 -#else - #define __stdcall -#endif - -#include -#include #include #include #include #include #include +#include "../Core/PgoUtilities.h" namespace fs = std::experimental::filesystem; using std::string; using std::vector; -using std::thread; - -enum class VideoFilterType -{ - None = 0, - NTSC = 1, - BisqwitNtscQuarterRes = 2, - BisqwitNtscHalfRes = 3, - BisqwitNtsc = 4, - xBRZ2x = 5, - xBRZ3x = 6, - xBRZ4x = 7, - xBRZ5x = 8, - xBRZ6x = 9, - HQ2x = 10, - HQ3x = 11, - HQ4x = 12, - Scale2x = 13, - Scale3x = 14, - Scale4x = 15, - _2xSai = 16, - Super2xSai = 17, - SuperEagle = 18, - Prescale2x = 19, - Prescale3x = 20, - Prescale4x = 21, - Prescale6x = 22, - Prescale8x = 23, - Prescale10x = 24, - HdPack = 999 -}; - - -extern "C" { - void __stdcall SetFlags(uint64_t flags); - void __stdcall SetVideoFilter(VideoFilterType filter); - void __stdcall InitDll(); - void __stdcall InitializeEmu(const char* homeFolder, void*, void*, bool, bool, bool); - void __stdcall LoadROM(const char* filename, const char* patchFile); - void __stdcall Run(); - void __stdcall Release(); - void __stdcall Stop(); - void __stdcall DebugInitialize(); - void __stdcall DebugSetFlags(uint32_t flags); -} vector GetFilesInFolder(string rootFolder, std::unordered_set extensions) { vector files; vector folders = { { rootFolder } }; - + std::error_code errorCode; if(!fs::is_directory(fs::u8path(rootFolder), errorCode)) { return files; @@ -84,35 +33,13 @@ vector GetFilesInFolder(string rootFolder, std::unordered_set ex int main(int argc, char* argv[]) { - vector testRoms = GetFilesInFolder("../PGOGames", { ".nes" }); + string romFolder = "../PGOGames"; + if(argc >= 2) { + romFolder = argv[1]; + } - string homeFolder = "../PGOMesenHome"; - - InitDll(); - SetFlags(0x8000000000000000 | 0x20); //EmulationFlags::ConsoleMode | UseHdPacks - InitializeEmu(homeFolder.c_str(), nullptr, nullptr, false, false, false); - LoadROM(testRoms[0].c_str(), ""); - std::cout << "Running: " << testRoms[0] << std::endl; - - thread testThread([testRoms] { - VideoFilterType filterTypes[13] = { - VideoFilterType::BisqwitNtscQuarterRes, VideoFilterType::HQ2x, VideoFilterType::HQ3x, VideoFilterType::HQ4x, VideoFilterType::NTSC, VideoFilterType::Scale2x, VideoFilterType::Scale3x, VideoFilterType::Scale4x, VideoFilterType::xBRZ2x, VideoFilterType::xBRZ3x, VideoFilterType::xBRZ4x, VideoFilterType::xBRZ5x, VideoFilterType::xBRZ6x - }; - - for(size_t i = 1; i < testRoms.size(); i++) { - std::this_thread::sleep_for(std::chrono::duration(5000)); - std::cout << "Running: " << testRoms[i] << std::endl; - SetVideoFilter(filterTypes[i % 13]); - LoadROM(testRoms[i].c_str(), ""); - DebugInitialize(); - DebugSetFlags(0x10000 /*DebuggerFlags::BreakOnFirstCycle*/); - } - std::this_thread::sleep_for(std::chrono::duration(5000)); - Stop(); - Release(); - }); - Run(); - testThread.join(); + vector testRoms = GetFilesInFolder(romFolder, { {".nes"} }); + PgoRunTest(testRoms, true); return 0; } diff --git a/buildPGO.sh b/buildPGO.sh index 726c3938..3bebdb57 100644 --- a/buildPGO.sh +++ b/buildPGO.sh @@ -14,27 +14,27 @@ # Note: While GCC runs through this script just fine, the runtime performance is pretty terrible (something must be wrong with the way this is built) # # This will produce the following binary: bin/x64/Release/Mesen.exe - -if [ "$BUILDTARGET" = core ]; then - TARG="core" -else - TARG="" -fi - if [ "$MESENPLATFORM" = x86 ]; then PLAT="x86" else PLAT="x64" fi +if [ "$BUILDTARGET" = libretro ]; then + TARG="libretro" +else + TARG="core" +fi + OBJ="PGOHelper/obj.${PLAT}/" FLAGS="LTO=true MESENPLATFORM=${PLAT}" eval ${FLAGS} make clean #create instrumented binary -eval ${FLAGS} PGO=profile make pgohelper -j 16 -eval cp InteropDLL/obj.${PLAT}/libMesenCore.${PLAT}.dll ${OBJ} +eval ${FLAGS} PGO=profile make ${TARG} -j 16 +eval ${FLAGS} PGO=profile make pgohelper -B +eval cp bin/pgohelperlib.so ${OBJ} #run the instrumented binary cd ${OBJ} @@ -50,6 +50,10 @@ else cd .. fi +if [ "$BUILDTARGET" = "" ]; then + TARG="" +fi + #rebuild using the profiling data to optimize eval ${FLAGS} PGO=optimize make ${TARG} -j 16 -B diff --git a/makefile b/makefile index 642d1423..ffc4f0fb 100644 --- a/makefile +++ b/makefile @@ -112,8 +112,8 @@ testhelper: InteropDLL/$(OBJFOLDER)/$(SHAREDLIB) $(CPPC) $(GCCOPTIONS) -Wl,-z,defs -o testhelper TestHelper/*.cpp InteropDLL/ConsoleWrapper.cpp $(SEVENZIPOBJ) $(LUAOBJ) $(LINUXOBJ) $(LIBEVDEVOBJ) $(UTILOBJ) $(COREOBJ) -pthread $(FSLIB) $(SDL2LIB) $(LIBEVDEVLIB) mv testhelper TestHelper/$(OBJFOLDER) -pgohelper: InteropDLL/$(OBJFOLDER)/$(SHAREDLIB) - mkdir -p PGOHelper/$(OBJFOLDER) && cd PGOHelper/$(OBJFOLDER) && $(CPPC) $(GCCOPTIONS) -Wl,-z,defs -o pgohelper ../PGOHelper.cpp ../../InteropDLL/$(OBJFOLDER)/$(SHAREDLIB) -pthread $(FSLIB) $(SDL2LIB) $(LIBEVDEVLIB) +pgohelper: + mkdir -p PGOHelper/$(OBJFOLDER) && cd PGOHelper/$(OBJFOLDER) && $(CPPC) $(GCCOPTIONS) -Wl,-z,defs -o pgohelper ../PGOHelper.cpp ../../bin/pgohelperlib.so -pthread $(FSLIB) $(SDL2LIB) $(LIBEVDEVLIB) SevenZip/$(OBJFOLDER)/%.o: SevenZip/%.c mkdir -p SevenZip/$(OBJFOLDER) && cd SevenZip/$(OBJFOLDER) && $(CC) $(CCOPTIONS) -c $(patsubst SevenZip/%, ../%, $<) @@ -139,11 +139,13 @@ Linux/$(OBJFOLDER)/%.o: Linux/libevdev/%.c InteropDLL/$(OBJFOLDER)/$(SHAREDLIB): $(SEVENZIPOBJ) $(LUAOBJ) $(UTILOBJ) $(COREOBJ) $(LIBEVDEVOBJ) $(LINUXOBJ) InteropDLL/ConsoleWrapper.cpp InteropDLL/DebugWrapper.cpp mkdir -p InteropDLL/$(OBJFOLDER) $(CPPC) $(GCCOPTIONS) -Wl,-z,defs -shared -o $(SHAREDLIB) InteropDLL/*.cpp $(SEVENZIPOBJ) $(LUAOBJ) $(LINUXOBJ) $(LIBEVDEVOBJ) $(UTILOBJ) $(COREOBJ) $(SDL2INC) -pthread $(FSLIB) $(SDL2LIB) $(LIBEVDEVLIB) + cp $(SHAREDLIB) bin/pgohelperlib.so mv $(SHAREDLIB) InteropDLL/$(OBJFOLDER) - + Libretro/$(OBJFOLDER)/$(LIBRETROLIB): $(SEVENZIPOBJ) $(UTILOBJ) $(COREOBJ) $(LUAOBJ) Libretro/libretro.cpp mkdir -p Libretro/$(OBJFOLDER) $(CPPC) $(GCCOPTIONS) -Wl,-z,defs -shared -o $(LIBRETROLIB) Libretro/*.cpp $(SEVENZIPOBJ) $(UTILOBJ) $(COREOBJ) $(LUAOBJ) -pthread $(FSLIB) + cp $(LIBRETROLIB) bin/pgohelperlib.so mv $(LIBRETROLIB) Libretro/$(OBJFOLDER) pgo: