mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-09-09 14:13:34 +02:00
Merge pull request #19252 from hrydgard/jitir-profiling-prep
Preparations for adding a performance profiler for the IR Interpreter
This commit is contained in:
@@ -1554,6 +1554,8 @@ list(APPEND NativeAppSource
|
||||
UI/CwCheatScreen.cpp
|
||||
UI/InstallZipScreen.h
|
||||
UI/InstallZipScreen.cpp
|
||||
UI/JitCompareScreen.h
|
||||
UI/JitCompareScreen.cpp
|
||||
UI/MemStickScreen.h
|
||||
UI/MemStickScreen.cpp
|
||||
UI/ProfilerDraw.h
|
||||
|
||||
@@ -234,7 +234,7 @@ void LogManager::Log(LogLevel level, LogType type, const char *file, int line, c
|
||||
file = fileshort + 1;
|
||||
}
|
||||
|
||||
GetTimeFormatted(message.timestamp);
|
||||
GetCurrentTimeFormatted(message.timestamp);
|
||||
|
||||
if (hleCurrentThreadName) {
|
||||
snprintf(message.header, sizeof(message.header), "%-12.12s %c[%s]: %s:%d",
|
||||
|
||||
@@ -33,7 +33,9 @@ public:
|
||||
Destroy();
|
||||
}
|
||||
|
||||
if (factory == nullptr) return;
|
||||
if (!factory) {
|
||||
return;
|
||||
}
|
||||
|
||||
HRESULT hr = factory->CreateTextFormat(
|
||||
fname.c_str(),
|
||||
@@ -45,15 +47,20 @@ public:
|
||||
L"",
|
||||
&textFmt
|
||||
);
|
||||
if (FAILED(hr)) {
|
||||
ERROR_LOG(G3D, "Failed creating font %s", fname.c_str());
|
||||
}
|
||||
}
|
||||
void Destroy() {
|
||||
textFmt->Release();
|
||||
if (textFmt) {
|
||||
textFmt->Release();
|
||||
}
|
||||
textFmt = nullptr;
|
||||
}
|
||||
|
||||
IDWriteFactory4* factory = nullptr;
|
||||
IDWriteFontCollection1* fontCollection = nullptr;
|
||||
IDWriteTextFormat* textFmt = nullptr;
|
||||
IDWriteFactory4 *factory = nullptr;
|
||||
IDWriteFontCollection1 *fontCollection = nullptr;
|
||||
IDWriteTextFormat *textFmt = nullptr;
|
||||
std::wstring fname;
|
||||
int height;
|
||||
DWRITE_FONT_WEIGHT weight;
|
||||
@@ -61,8 +68,8 @@ public:
|
||||
};
|
||||
|
||||
struct TextDrawerContext {
|
||||
ID2D1Bitmap1* bitmap;
|
||||
ID2D1Bitmap1* mirror_bmp;
|
||||
ID2D1Bitmap1 *bitmap;
|
||||
ID2D1Bitmap1 *mirror_bmp;
|
||||
};
|
||||
|
||||
TextDrawerUWP::TextDrawerUWP(Draw::DrawContext *draw) : TextDrawer(draw), ctx_(nullptr) {
|
||||
|
||||
+74
-6
@@ -4,6 +4,7 @@
|
||||
#include <cstdint>
|
||||
|
||||
#include "Common/TimeUtil.h"
|
||||
#include "Common/Log.h"
|
||||
|
||||
#ifdef HAVE_LIBNX
|
||||
#include <switch.h>
|
||||
@@ -31,8 +32,8 @@
|
||||
|
||||
// TODO: https://github.com/floooh/sokol/blob/9a6237fcdf213e6da48e4f9201f144bcb2dcb46f/sokol_time.h#L229-L248
|
||||
|
||||
static const double micros = 1000000.0;
|
||||
static const double nanos = 1000000000.0;
|
||||
constexpr double micros = 1000000.0;
|
||||
constexpr double nanos = 1000000000.0;
|
||||
|
||||
#if PPSSPP_PLATFORM(WINDOWS)
|
||||
|
||||
@@ -40,12 +41,16 @@ static LARGE_INTEGER frequency;
|
||||
static double frequencyMult;
|
||||
static LARGE_INTEGER startTime;
|
||||
|
||||
double time_now_d() {
|
||||
static inline void InitTime() {
|
||||
if (frequency.QuadPart == 0) {
|
||||
QueryPerformanceFrequency(&frequency);
|
||||
QueryPerformanceCounter(&startTime);
|
||||
frequencyMult = 1.0 / static_cast<double>(frequency.QuadPart);
|
||||
}
|
||||
}
|
||||
|
||||
double time_now_d() {
|
||||
InitTime();
|
||||
LARGE_INTEGER time;
|
||||
QueryPerformanceCounter(&time);
|
||||
double elapsed = static_cast<double>(time.QuadPart - startTime.QuadPart);
|
||||
@@ -86,6 +91,22 @@ void yield() {
|
||||
YieldProcessor();
|
||||
}
|
||||
|
||||
TimeSpan::TimeSpan() {
|
||||
_dbg_assert_(frequencyMult != 0.0);
|
||||
QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER *>(&nativeStart_));
|
||||
}
|
||||
|
||||
double TimeSpan::ElapsedSeconds() const {
|
||||
LARGE_INTEGER time;
|
||||
QueryPerformanceCounter(&time);
|
||||
double elapsed = static_cast<double>(time.QuadPart - nativeStart_);
|
||||
return elapsed * frequencyMult;
|
||||
}
|
||||
|
||||
int64_t TimeSpan::ElapsedNanos() const {
|
||||
return (int64_t)(ElapsedSeconds() * 1000000000.0);
|
||||
}
|
||||
|
||||
#elif PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(LINUX) || PPSSPP_PLATFORM(MAC) || PPSSPP_PLATFORM(IOS)
|
||||
|
||||
// The only intended use is to match the timings in VK_GOOGLE_display_timing
|
||||
@@ -128,10 +149,34 @@ void yield() {
|
||||
#endif
|
||||
}
|
||||
|
||||
TimeSpan::TimeSpan() {
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
nativeStart_ = ts.tv_sec;
|
||||
nsecs_ = ts.tv_nsec;
|
||||
}
|
||||
|
||||
int64_t TimeSpan::ElapsedNanos() const {
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
int64_t secs = ts.tv_sec - nativeStart_;
|
||||
int64_t nsecs = ts.tv_nsec - nsecs_;
|
||||
if (nsecs < 0) {
|
||||
secs--;
|
||||
nsecs += 1000000000;
|
||||
}
|
||||
return secs * 1000000000ULL + nsecs;
|
||||
}
|
||||
|
||||
double TimeSpan::ElapsedSeconds() const {
|
||||
return (double)ElapsedNanos() * (1.0 / nanos);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static time_t start;
|
||||
|
||||
double time_now_d() {
|
||||
static time_t start;
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, nullptr);
|
||||
if (start == 0) {
|
||||
@@ -141,7 +186,6 @@ double time_now_d() {
|
||||
}
|
||||
|
||||
uint64_t time_now_raw() {
|
||||
static time_t start;
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, nullptr);
|
||||
if (start == 0) {
|
||||
@@ -164,6 +208,30 @@ double time_now_unix_utc() {
|
||||
return time_now_raw();
|
||||
}
|
||||
|
||||
TimeSpan::TimeSpan() {
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, nullptr);
|
||||
nativeStart_ = tv.tv_sec;
|
||||
nsecs_ = tv.tv_usec;
|
||||
}
|
||||
|
||||
int64_t TimeSpan::ElapsedNanos() const {
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
|
||||
int64_t secs = ts.tv_sec - nativeStart_;
|
||||
int64_t usecs = ts.tv_nsec - nsecs_;
|
||||
if (usecs < 0) {
|
||||
secs--;
|
||||
usecs += 1000000;
|
||||
}
|
||||
return secs * 1000000000 + usecs * 1000;
|
||||
}
|
||||
|
||||
double TimeSpan::ElapsedSeconds() const {
|
||||
return (double)ElapsedNanos() * (1.0 / 1000000000);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void sleep_ms(int ms) {
|
||||
@@ -180,7 +248,7 @@ void sleep_ms(int ms) {
|
||||
|
||||
// Return the current time formatted as Minutes:Seconds:Milliseconds
|
||||
// in the form 00:00:000.
|
||||
void GetTimeFormatted(char formattedTime[13]) {
|
||||
void GetCurrentTimeFormatted(char formattedTime[13]) {
|
||||
time_t sysTime;
|
||||
time(&sysTime);
|
||||
|
||||
|
||||
+15
-3
@@ -1,5 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
// Seconds.
|
||||
@@ -22,7 +21,7 @@ void sleep_ms(int ms);
|
||||
// Yield. Signals that this thread is busy-waiting but wants to allow other hyperthreads to run.
|
||||
void yield();
|
||||
|
||||
void GetTimeFormatted(char formattedTime[13]);
|
||||
void GetCurrentTimeFormatted(char formattedTime[13]);
|
||||
|
||||
// Rust-style Instant for clear and easy timing.
|
||||
class Instant {
|
||||
@@ -30,10 +29,23 @@ public:
|
||||
static Instant Now() {
|
||||
return Instant(time_now_d());
|
||||
}
|
||||
double Elapsed() const {
|
||||
double ElapsedSeconds() const {
|
||||
return time_now_d() - instantTime_;
|
||||
}
|
||||
private:
|
||||
explicit Instant(double initTime) : instantTime_(initTime) {}
|
||||
double instantTime_;
|
||||
};
|
||||
|
||||
// Most accurate timer possible - no extra double conversions. Only for spans.
|
||||
class TimeSpan {
|
||||
public:
|
||||
TimeSpan();
|
||||
double ElapsedSeconds() const;
|
||||
int64_t ElapsedNanos() const;
|
||||
private:
|
||||
uint64_t nativeStart_;
|
||||
#ifndef _WIN32
|
||||
int64_t nsecs_;
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -23,14 +23,14 @@ public:
|
||||
if (at3pCtx_) {
|
||||
codecOpen_ = true;
|
||||
} else {
|
||||
ERROR_LOG(ME, "Failed to open atrac3+ context! (channels=%d blockAlign=%d ed=%d)", channels, blockAlign, extraDataSize);
|
||||
ERROR_LOG(ME, "Failed to open atrac3+ context! (channels=%d blockAlign=%d ed=%d)", channels, (int)blockAlign, (int)extraDataSize);
|
||||
}
|
||||
} else if (audioType_ == PSP_CODEC_AT3) {
|
||||
at3Ctx_ = atrac3_alloc(channels, &blockAlign_, extraData, (int)extraDataSize);
|
||||
if (at3Ctx_) {
|
||||
codecOpen_ = true;
|
||||
} else {
|
||||
ERROR_LOG(ME, "Failed to open atrac3 context! !channels=%d blockAlign=%d ed=%d)", channels, blockAlign, extraDataSize);
|
||||
ERROR_LOG(ME, "Failed to open atrac3 context! !channels=%d blockAlign=%d ed=%d)", channels, (int)blockAlign, (int)extraDataSize);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 2; i++) {
|
||||
|
||||
+1
-361
@@ -69,6 +69,7 @@
|
||||
#include "UI/MainScreen.h"
|
||||
#include "UI/ControlMappingScreen.h"
|
||||
#include "UI/GameSettingsScreen.h"
|
||||
#include "UI/JitCompareScreen.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
// Want to avoid including the full header here as it includes d3dx.h
|
||||
@@ -920,367 +921,6 @@ void SystemInfoScreen::CreateInternalsTab(UI::ViewGroup *internals) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void AddressPromptScreen::CreatePopupContents(UI::ViewGroup *parent) {
|
||||
using namespace UI;
|
||||
|
||||
auto dev = GetI18NCategory(I18NCat::DEVELOPER);
|
||||
|
||||
addrView_ = new TextView(dev->T("Enter address"), ALIGN_HCENTER, false);
|
||||
parent->Add(addrView_);
|
||||
|
||||
ViewGroup *grid = new GridLayout(GridLayoutSettings(60, 40));
|
||||
parent->Add(grid);
|
||||
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
char temp[16];
|
||||
snprintf(temp, 16, " %X ", i);
|
||||
buttons_[i] = new Button(temp);
|
||||
grid->Add(buttons_[i])->OnClick.Handle(this, &AddressPromptScreen::OnDigitButton);
|
||||
}
|
||||
|
||||
parent->Add(new Button(dev->T("Backspace")))->OnClick.Handle(this, &AddressPromptScreen::OnBackspace);
|
||||
}
|
||||
|
||||
void AddressPromptScreen::OnCompleted(DialogResult result) {
|
||||
if (result == DR_OK) {
|
||||
UI::EventParams e{};
|
||||
e.v = root_;
|
||||
e.a = addr_;
|
||||
OnChoice.Trigger(e);
|
||||
}
|
||||
}
|
||||
|
||||
UI::EventReturn AddressPromptScreen::OnDigitButton(UI::EventParams &e) {
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
if (buttons_[i] == e.v) {
|
||||
AddDigit(i);
|
||||
}
|
||||
}
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
UI::EventReturn AddressPromptScreen::OnBackspace(UI::EventParams &e) {
|
||||
BackspaceDigit();
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
void AddressPromptScreen::AddDigit(int n) {
|
||||
if ((addr_ & 0xF0000000) == 0) {
|
||||
addr_ = addr_ * 16 + n;
|
||||
}
|
||||
UpdatePreviewDigits();
|
||||
}
|
||||
|
||||
void AddressPromptScreen::BackspaceDigit() {
|
||||
addr_ /= 16;
|
||||
UpdatePreviewDigits();
|
||||
}
|
||||
|
||||
void AddressPromptScreen::UpdatePreviewDigits() {
|
||||
if (addr_ != 0) {
|
||||
char temp[32];
|
||||
snprintf(temp, 32, "%8X", addr_);
|
||||
addrView_->SetText(temp);
|
||||
} else {
|
||||
auto dev = GetI18NCategory(I18NCat::DEVELOPER);
|
||||
addrView_->SetText(dev->T("Enter address"));
|
||||
}
|
||||
}
|
||||
|
||||
bool AddressPromptScreen::key(const KeyInput &key) {
|
||||
if (key.flags & KEY_DOWN) {
|
||||
if (key.keyCode >= NKCODE_0 && key.keyCode <= NKCODE_9) {
|
||||
AddDigit(key.keyCode - NKCODE_0);
|
||||
} else if (key.keyCode >= NKCODE_A && key.keyCode <= NKCODE_F) {
|
||||
AddDigit(10 + key.keyCode - NKCODE_A);
|
||||
// NKCODE_DEL is backspace.
|
||||
} else if (key.keyCode == NKCODE_DEL) {
|
||||
BackspaceDigit();
|
||||
} else if (key.keyCode == NKCODE_ENTER) {
|
||||
TriggerFinish(DR_OK);
|
||||
} else {
|
||||
return UIDialogScreen::key(key);
|
||||
}
|
||||
} else {
|
||||
return UIDialogScreen::key(key);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Three panes: Block chooser, MIPS view, ARM/x86 view
|
||||
void JitCompareScreen::CreateViews() {
|
||||
auto di = GetI18NCategory(I18NCat::DIALOG);
|
||||
auto dev = GetI18NCategory(I18NCat::DEVELOPER);
|
||||
|
||||
using namespace UI;
|
||||
|
||||
root_ = new LinearLayout(ORIENT_HORIZONTAL);
|
||||
|
||||
ScrollView *leftColumnScroll = root_->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0f)));
|
||||
LinearLayout *leftColumn = leftColumnScroll->Add(new LinearLayout(ORIENT_VERTICAL));
|
||||
|
||||
ScrollView *midColumnScroll = root_->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(2.0f)));
|
||||
LinearLayout *midColumn = midColumnScroll->Add(new LinearLayout(ORIENT_VERTICAL));
|
||||
midColumn->SetTag("JitCompareLeftDisasm");
|
||||
leftDisasm_ = midColumn->Add(new LinearLayout(ORIENT_VERTICAL));
|
||||
leftDisasm_->SetSpacing(0.0f);
|
||||
|
||||
ScrollView *rightColumnScroll = root_->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(2.0f)));
|
||||
rightColumnScroll->SetTag("JitCompareRightDisasm");
|
||||
LinearLayout *rightColumn = rightColumnScroll->Add(new LinearLayout(ORIENT_VERTICAL));
|
||||
rightDisasm_ = rightColumn->Add(new LinearLayout(ORIENT_VERTICAL));
|
||||
rightDisasm_->SetSpacing(0.0f);
|
||||
|
||||
leftColumn->Add(new Choice(dev->T("Current")))->OnClick.Handle(this, &JitCompareScreen::OnCurrentBlock);
|
||||
leftColumn->Add(new Choice(dev->T("By Address")))->OnClick.Handle(this, &JitCompareScreen::OnSelectBlock);
|
||||
leftColumn->Add(new Choice(dev->T("Prev")))->OnClick.Handle(this, &JitCompareScreen::OnPrevBlock);
|
||||
leftColumn->Add(new Choice(dev->T("Next")))->OnClick.Handle(this, &JitCompareScreen::OnNextBlock);
|
||||
leftColumn->Add(new Choice(dev->T("Random")))->OnClick.Handle(this, &JitCompareScreen::OnRandomBlock);
|
||||
leftColumn->Add(new Choice(dev->T("FPU")))->OnClick.Handle(this, &JitCompareScreen::OnRandomFPUBlock);
|
||||
leftColumn->Add(new Choice(dev->T("VFPU")))->OnClick.Handle(this, &JitCompareScreen::OnRandomVFPUBlock);
|
||||
leftColumn->Add(new Choice(dev->T("Stats")))->OnClick.Handle(this, &JitCompareScreen::OnShowStats);
|
||||
leftColumn->Add(new Choice(di->T("Back")))->OnClick.Handle<UIScreen>(this, &UIScreen::OnBack);
|
||||
blockName_ = leftColumn->Add(new TextView(dev->T("No block")));
|
||||
blockAddr_ = leftColumn->Add(new TextEdit("", dev->T("Block address"), "", new LayoutParams(FILL_PARENT, WRAP_CONTENT)));
|
||||
blockAddr_->OnTextChange.Handle(this, &JitCompareScreen::OnAddressChange);
|
||||
blockStats_ = leftColumn->Add(new TextView(""));
|
||||
|
||||
EventParams ignore{};
|
||||
OnCurrentBlock(ignore);
|
||||
}
|
||||
|
||||
void JitCompareScreen::UpdateDisasm() {
|
||||
leftDisasm_->Clear();
|
||||
rightDisasm_->Clear();
|
||||
|
||||
using namespace UI;
|
||||
|
||||
if (!MIPSComp::jit) {
|
||||
return;
|
||||
}
|
||||
|
||||
JitBlockCacheDebugInterface *blockCacheDebug = MIPSComp::jit->GetBlockCacheDebugInterface();
|
||||
if (!blockCacheDebug->IsValidBlock(currentBlock_)) {
|
||||
return;
|
||||
}
|
||||
|
||||
char temp[256];
|
||||
snprintf(temp, sizeof(temp), "%i/%i", currentBlock_, blockCacheDebug->GetNumBlocks());
|
||||
blockName_->SetText(temp);
|
||||
|
||||
if (currentBlock_ < 0 || !blockCacheDebug || currentBlock_ >= blockCacheDebug->GetNumBlocks()) {
|
||||
auto dev = GetI18NCategory(I18NCat::DEVELOPER);
|
||||
leftDisasm_->Add(new TextView(dev->T("No block")));
|
||||
rightDisasm_->Add(new TextView(dev->T("No block")));
|
||||
blockStats_->SetText("");
|
||||
return;
|
||||
}
|
||||
|
||||
JitBlockDebugInfo debugInfo = blockCacheDebug->GetBlockDebugInfo(currentBlock_);
|
||||
|
||||
snprintf(temp, sizeof(temp), "%08x", debugInfo.originalAddress);
|
||||
blockAddr_->SetText(temp);
|
||||
|
||||
// Alright. First generate the MIPS disassembly.
|
||||
|
||||
// TODO: Need a way to communicate branch continuing.
|
||||
for (const auto &line : debugInfo.origDisasm) {
|
||||
leftDisasm_->Add(new TextView(line))->SetFocusable(true);
|
||||
}
|
||||
|
||||
// TODO : When we have both target and IR, need a third column.
|
||||
if (debugInfo.targetDisasm.size()) {
|
||||
for (const auto &line : debugInfo.targetDisasm) {
|
||||
rightDisasm_->Add(new TextView(line))->SetFocusable(true);
|
||||
}
|
||||
} else {
|
||||
for (const auto &line : debugInfo.irDisasm) {
|
||||
rightDisasm_->Add(new TextView(line))->SetFocusable(true);
|
||||
}
|
||||
}
|
||||
|
||||
int numMips = leftDisasm_->GetNumSubviews();
|
||||
int numHost = rightDisasm_->GetNumSubviews();
|
||||
|
||||
snprintf(temp, sizeof(temp), "%d to %d : %d%%", numMips, numHost, 100 * numHost / numMips);
|
||||
blockStats_->SetText(temp);
|
||||
}
|
||||
|
||||
UI::EventReturn JitCompareScreen::OnAddressChange(UI::EventParams &e) {
|
||||
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
|
||||
if (!MIPSComp::jit) {
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
JitBlockCacheDebugInterface *blockCache = MIPSComp::jit->GetBlockCacheDebugInterface();
|
||||
if (!blockCache)
|
||||
return UI::EVENT_DONE;
|
||||
u32 addr;
|
||||
if (blockAddr_->GetText().size() > 8)
|
||||
return UI::EVENT_DONE;
|
||||
if (1 == sscanf(blockAddr_->GetText().c_str(), "%08x", &addr)) {
|
||||
if (Memory::IsValidAddress(addr)) {
|
||||
currentBlock_ = blockCache->GetBlockNumberFromStartAddress(addr);
|
||||
UpdateDisasm();
|
||||
}
|
||||
}
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
UI::EventReturn JitCompareScreen::OnShowStats(UI::EventParams &e) {
|
||||
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
|
||||
if (!MIPSComp::jit) {
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
JitBlockCacheDebugInterface *blockCache = MIPSComp::jit->GetBlockCacheDebugInterface();
|
||||
if (!blockCache)
|
||||
return UI::EVENT_DONE;
|
||||
|
||||
BlockCacheStats bcStats;
|
||||
blockCache->ComputeStats(bcStats);
|
||||
NOTICE_LOG(JIT, "Num blocks: %i", bcStats.numBlocks);
|
||||
NOTICE_LOG(JIT, "Average Bloat: %0.2f%%", 100 * bcStats.avgBloat);
|
||||
NOTICE_LOG(JIT, "Min Bloat: %0.2f%% (%08x)", 100 * bcStats.minBloat, bcStats.minBloatBlock);
|
||||
NOTICE_LOG(JIT, "Max Bloat: %0.2f%% (%08x)", 100 * bcStats.maxBloat, bcStats.maxBloatBlock);
|
||||
|
||||
int ctr = 0, sz = (int)bcStats.bloatMap.size();
|
||||
for (auto iter : bcStats.bloatMap) {
|
||||
if (ctr < 10 || ctr > sz - 10) {
|
||||
NOTICE_LOG(JIT, "%08x: %f", iter.second, iter.first);
|
||||
} else if (ctr == 10) {
|
||||
NOTICE_LOG(JIT, "...");
|
||||
}
|
||||
ctr++;
|
||||
}
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
|
||||
UI::EventReturn JitCompareScreen::OnSelectBlock(UI::EventParams &e) {
|
||||
auto dev = GetI18NCategory(I18NCat::DEVELOPER);
|
||||
|
||||
auto addressPrompt = new AddressPromptScreen(dev->T("Block address"));
|
||||
addressPrompt->OnChoice.Handle(this, &JitCompareScreen::OnBlockAddress);
|
||||
screenManager()->push(addressPrompt);
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
UI::EventReturn JitCompareScreen::OnPrevBlock(UI::EventParams &e) {
|
||||
currentBlock_--;
|
||||
UpdateDisasm();
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
UI::EventReturn JitCompareScreen::OnNextBlock(UI::EventParams &e) {
|
||||
currentBlock_++;
|
||||
UpdateDisasm();
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
UI::EventReturn JitCompareScreen::OnBlockAddress(UI::EventParams &e) {
|
||||
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
|
||||
if (!MIPSComp::jit) {
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
JitBlockCacheDebugInterface *blockCache = MIPSComp::jit->GetBlockCacheDebugInterface();
|
||||
if (!blockCache)
|
||||
return UI::EVENT_DONE;
|
||||
|
||||
if (Memory::IsValidAddress(e.a)) {
|
||||
currentBlock_ = blockCache->GetBlockNumberFromStartAddress(e.a);
|
||||
} else {
|
||||
currentBlock_ = -1;
|
||||
}
|
||||
UpdateDisasm();
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
UI::EventReturn JitCompareScreen::OnRandomBlock(UI::EventParams &e) {
|
||||
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
|
||||
if (!MIPSComp::jit) {
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
JitBlockCacheDebugInterface *blockCache = MIPSComp::jit->GetBlockCacheDebugInterface();
|
||||
if (!blockCache)
|
||||
return UI::EVENT_DONE;
|
||||
|
||||
int numBlocks = blockCache->GetNumBlocks();
|
||||
if (numBlocks > 0) {
|
||||
int tries = 100;
|
||||
while (tries-- > 0) {
|
||||
currentBlock_ = rand() % numBlocks;
|
||||
if (blockCache->IsValidBlock(currentBlock_)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
UpdateDisasm();
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
UI::EventReturn JitCompareScreen::OnRandomVFPUBlock(UI::EventParams &e) {
|
||||
OnRandomBlock(IS_VFPU);
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
UI::EventReturn JitCompareScreen::OnRandomFPUBlock(UI::EventParams &e) {
|
||||
OnRandomBlock(IS_FPU);
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
void JitCompareScreen::OnRandomBlock(int flag) {
|
||||
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
|
||||
if (!MIPSComp::jit) {
|
||||
return;
|
||||
}
|
||||
JitBlockCacheDebugInterface *blockCache = MIPSComp::jit->GetBlockCacheDebugInterface();
|
||||
if (!blockCache)
|
||||
return;
|
||||
|
||||
int numBlocks = blockCache->GetNumBlocks();
|
||||
if (numBlocks > 0) {
|
||||
bool anyWanted = false;
|
||||
int tries = 0;
|
||||
while (!anyWanted && tries < numBlocks) {
|
||||
currentBlock_ = rand() % numBlocks;
|
||||
if (blockCache->IsValidBlock(currentBlock_)) {
|
||||
JitBlockDebugInfo b = blockCache->GetBlockDebugInfo(currentBlock_);
|
||||
u32 mipsBytes = (u32)b.origDisasm.size() * 4;
|
||||
for (u32 addr = b.originalAddress; addr < b.originalAddress + mipsBytes; addr += 4) {
|
||||
MIPSOpcode opcode = Memory::Read_Instruction(addr);
|
||||
if (MIPSGetInfo(opcode) & flag) {
|
||||
char temp[256];
|
||||
MIPSDisAsm(opcode, addr, temp, sizeof(temp));
|
||||
// INFO_LOG(HLE, "Stopping at random instruction: %08x %s", addr, temp);
|
||||
anyWanted = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
tries++;
|
||||
}
|
||||
|
||||
if (!anyWanted)
|
||||
currentBlock_ = -1;
|
||||
}
|
||||
UpdateDisasm();
|
||||
}
|
||||
|
||||
UI::EventReturn JitCompareScreen::OnCurrentBlock(UI::EventParams &e) {
|
||||
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
|
||||
if (!MIPSComp::jit) {
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
JitBlockCache *blockCache = MIPSComp::jit->GetBlockCache();
|
||||
if (!blockCache)
|
||||
return UI::EVENT_DONE;
|
||||
currentBlock_ = blockCache->GetBlockNumberFromAddress(currentMIPS->pc);
|
||||
UpdateDisasm();
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
int ShaderListScreen::ListShaders(DebugShaderType shaderType, UI::LinearLayout *view) {
|
||||
using namespace UI;
|
||||
std::vector<std::string> shaderIds_ = gpu->DebugGetShaderIDs(shaderType);
|
||||
|
||||
@@ -117,34 +117,6 @@ protected:
|
||||
void CreateInternalsTab(UI::ViewGroup *internals);
|
||||
};
|
||||
|
||||
class AddressPromptScreen : public PopupScreen {
|
||||
public:
|
||||
AddressPromptScreen(std::string_view title) : PopupScreen(title, "OK", "Cancel"), addrView_(NULL), addr_(0) {
|
||||
memset(buttons_, 0, sizeof(buttons_));
|
||||
}
|
||||
|
||||
const char *tag() const override { return "AddressPrompt"; }
|
||||
|
||||
bool key(const KeyInput &key) override;
|
||||
|
||||
UI::Event OnChoice;
|
||||
|
||||
protected:
|
||||
void CreatePopupContents(UI::ViewGroup *parent) override;
|
||||
void OnCompleted(DialogResult result) override;
|
||||
UI::EventReturn OnDigitButton(UI::EventParams &e);
|
||||
UI::EventReturn OnBackspace(UI::EventParams &e);
|
||||
|
||||
private:
|
||||
void AddDigit(int n);
|
||||
void BackspaceDigit();
|
||||
void UpdatePreviewDigits();
|
||||
|
||||
UI::TextView *addrView_;
|
||||
UI::Button *buttons_[16];
|
||||
unsigned int addr_;
|
||||
};
|
||||
|
||||
class GPIGPOScreen : public PopupScreen {
|
||||
public:
|
||||
GPIGPOScreen(std::string_view title) : PopupScreen(title, "OK") {}
|
||||
@@ -154,37 +126,6 @@ protected:
|
||||
void CreatePopupContents(UI::ViewGroup *parent) override;
|
||||
};
|
||||
|
||||
class JitCompareScreen : public UIDialogScreenWithBackground {
|
||||
public:
|
||||
void CreateViews() override;
|
||||
|
||||
const char *tag() const override { return "JitCompare"; }
|
||||
|
||||
private:
|
||||
void UpdateDisasm();
|
||||
UI::EventReturn OnRandomBlock(UI::EventParams &e);
|
||||
UI::EventReturn OnRandomFPUBlock(UI::EventParams &e);
|
||||
UI::EventReturn OnRandomVFPUBlock(UI::EventParams &e);
|
||||
void OnRandomBlock(int flag);
|
||||
|
||||
UI::EventReturn OnCurrentBlock(UI::EventParams &e);
|
||||
UI::EventReturn OnSelectBlock(UI::EventParams &e);
|
||||
UI::EventReturn OnPrevBlock(UI::EventParams &e);
|
||||
UI::EventReturn OnNextBlock(UI::EventParams &e);
|
||||
UI::EventReturn OnBlockAddress(UI::EventParams &e);
|
||||
UI::EventReturn OnAddressChange(UI::EventParams &e);
|
||||
UI::EventReturn OnShowStats(UI::EventParams &e);
|
||||
|
||||
int currentBlock_ = -1;
|
||||
|
||||
UI::TextView *blockName_;
|
||||
UI::TextEdit *blockAddr_;
|
||||
UI::TextView *blockStats_;
|
||||
|
||||
UI::LinearLayout *leftDisasm_;
|
||||
UI::LinearLayout *rightDisasm_;
|
||||
};
|
||||
|
||||
class ShaderListScreen : public UIDialogScreenWithBackground {
|
||||
public:
|
||||
void CreateViews() override;
|
||||
|
||||
@@ -0,0 +1,369 @@
|
||||
#include "UI/JitCompareScreen.h"
|
||||
|
||||
#include "Core/MemMap.h"
|
||||
#include "Core/MIPS/MIPSTables.h"
|
||||
#include "Core/MIPS/JitCommon/JitBlockCache.h"
|
||||
#include "Core/MIPS/JitCommon/JitCommon.h"
|
||||
#include "Core/MIPS/JitCommon/JitState.h"
|
||||
|
||||
// Three panes: Block chooser, MIPS view, ARM/x86 view
|
||||
void JitCompareScreen::CreateViews() {
|
||||
auto di = GetI18NCategory(I18NCat::DIALOG);
|
||||
auto dev = GetI18NCategory(I18NCat::DEVELOPER);
|
||||
|
||||
using namespace UI;
|
||||
|
||||
root_ = new LinearLayout(ORIENT_HORIZONTAL);
|
||||
|
||||
ScrollView *leftColumnScroll = root_->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0f)));
|
||||
LinearLayout *leftColumn = leftColumnScroll->Add(new LinearLayout(ORIENT_VERTICAL));
|
||||
|
||||
ScrollView *midColumnScroll = root_->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(2.0f)));
|
||||
LinearLayout *midColumn = midColumnScroll->Add(new LinearLayout(ORIENT_VERTICAL));
|
||||
midColumn->SetTag("JitCompareLeftDisasm");
|
||||
leftDisasm_ = midColumn->Add(new LinearLayout(ORIENT_VERTICAL));
|
||||
leftDisasm_->SetSpacing(0.0f);
|
||||
|
||||
ScrollView *rightColumnScroll = root_->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(2.0f)));
|
||||
rightColumnScroll->SetTag("JitCompareRightDisasm");
|
||||
LinearLayout *rightColumn = rightColumnScroll->Add(new LinearLayout(ORIENT_VERTICAL));
|
||||
rightDisasm_ = rightColumn->Add(new LinearLayout(ORIENT_VERTICAL));
|
||||
rightDisasm_->SetSpacing(0.0f);
|
||||
|
||||
leftColumn->Add(new Choice(dev->T("Current")))->OnClick.Handle(this, &JitCompareScreen::OnCurrentBlock);
|
||||
leftColumn->Add(new Choice(dev->T("By Address")))->OnClick.Handle(this, &JitCompareScreen::OnSelectBlock);
|
||||
leftColumn->Add(new Choice(dev->T("Prev")))->OnClick.Handle(this, &JitCompareScreen::OnPrevBlock);
|
||||
leftColumn->Add(new Choice(dev->T("Next")))->OnClick.Handle(this, &JitCompareScreen::OnNextBlock);
|
||||
leftColumn->Add(new Choice(dev->T("Random")))->OnClick.Handle(this, &JitCompareScreen::OnRandomBlock);
|
||||
leftColumn->Add(new Choice(dev->T("FPU")))->OnClick.Handle(this, &JitCompareScreen::OnRandomFPUBlock);
|
||||
leftColumn->Add(new Choice(dev->T("VFPU")))->OnClick.Handle(this, &JitCompareScreen::OnRandomVFPUBlock);
|
||||
leftColumn->Add(new Choice(dev->T("Stats")))->OnClick.Handle(this, &JitCompareScreen::OnShowStats);
|
||||
leftColumn->Add(new Choice(di->T("Back")))->OnClick.Handle<UIScreen>(this, &UIScreen::OnBack);
|
||||
blockName_ = leftColumn->Add(new TextView(dev->T("No block")));
|
||||
blockAddr_ = leftColumn->Add(new TextEdit("", dev->T("Block address"), "", new LayoutParams(FILL_PARENT, WRAP_CONTENT)));
|
||||
blockAddr_->OnTextChange.Handle(this, &JitCompareScreen::OnAddressChange);
|
||||
blockStats_ = leftColumn->Add(new TextView(""));
|
||||
|
||||
EventParams ignore{};
|
||||
OnCurrentBlock(ignore);
|
||||
}
|
||||
|
||||
void JitCompareScreen::UpdateDisasm() {
|
||||
leftDisasm_->Clear();
|
||||
rightDisasm_->Clear();
|
||||
|
||||
using namespace UI;
|
||||
|
||||
if (!MIPSComp::jit) {
|
||||
return;
|
||||
}
|
||||
|
||||
JitBlockCacheDebugInterface *blockCacheDebug = MIPSComp::jit->GetBlockCacheDebugInterface();
|
||||
if (!blockCacheDebug->IsValidBlock(currentBlock_)) {
|
||||
return;
|
||||
}
|
||||
|
||||
char temp[256];
|
||||
snprintf(temp, sizeof(temp), "%i/%i", currentBlock_, blockCacheDebug->GetNumBlocks());
|
||||
blockName_->SetText(temp);
|
||||
|
||||
if (currentBlock_ < 0 || !blockCacheDebug || currentBlock_ >= blockCacheDebug->GetNumBlocks()) {
|
||||
auto dev = GetI18NCategory(I18NCat::DEVELOPER);
|
||||
leftDisasm_->Add(new TextView(dev->T("No block")));
|
||||
rightDisasm_->Add(new TextView(dev->T("No block")));
|
||||
blockStats_->SetText("");
|
||||
return;
|
||||
}
|
||||
|
||||
JitBlockDebugInfo debugInfo = blockCacheDebug->GetBlockDebugInfo(currentBlock_);
|
||||
|
||||
snprintf(temp, sizeof(temp), "%08x", debugInfo.originalAddress);
|
||||
blockAddr_->SetText(temp);
|
||||
|
||||
// Alright. First generate the MIPS disassembly.
|
||||
|
||||
// TODO: Need a way to communicate branch continuing.
|
||||
for (const auto &line : debugInfo.origDisasm) {
|
||||
leftDisasm_->Add(new TextView(line))->SetFocusable(true);
|
||||
}
|
||||
|
||||
// TODO : When we have both target and IR, need a third column.
|
||||
if (debugInfo.targetDisasm.size()) {
|
||||
for (const auto &line : debugInfo.targetDisasm) {
|
||||
rightDisasm_->Add(new TextView(line))->SetFocusable(true);
|
||||
}
|
||||
} else {
|
||||
for (const auto &line : debugInfo.irDisasm) {
|
||||
rightDisasm_->Add(new TextView(line))->SetFocusable(true);
|
||||
}
|
||||
}
|
||||
|
||||
int numMips = leftDisasm_->GetNumSubviews();
|
||||
int numHost = rightDisasm_->GetNumSubviews();
|
||||
|
||||
snprintf(temp, sizeof(temp), "%d to %d : %d%%", numMips, numHost, 100 * numHost / numMips);
|
||||
blockStats_->SetText(temp);
|
||||
}
|
||||
|
||||
UI::EventReturn JitCompareScreen::OnAddressChange(UI::EventParams &e) {
|
||||
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
|
||||
if (!MIPSComp::jit) {
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
JitBlockCacheDebugInterface *blockCache = MIPSComp::jit->GetBlockCacheDebugInterface();
|
||||
if (!blockCache)
|
||||
return UI::EVENT_DONE;
|
||||
u32 addr;
|
||||
if (blockAddr_->GetText().size() > 8)
|
||||
return UI::EVENT_DONE;
|
||||
if (1 == sscanf(blockAddr_->GetText().c_str(), "%08x", &addr)) {
|
||||
if (Memory::IsValidAddress(addr)) {
|
||||
currentBlock_ = blockCache->GetBlockNumberFromStartAddress(addr);
|
||||
UpdateDisasm();
|
||||
}
|
||||
}
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
UI::EventReturn JitCompareScreen::OnShowStats(UI::EventParams &e) {
|
||||
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
|
||||
if (!MIPSComp::jit) {
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
JitBlockCacheDebugInterface *blockCache = MIPSComp::jit->GetBlockCacheDebugInterface();
|
||||
if (!blockCache)
|
||||
return UI::EVENT_DONE;
|
||||
|
||||
BlockCacheStats bcStats;
|
||||
blockCache->ComputeStats(bcStats);
|
||||
NOTICE_LOG(JIT, "Num blocks: %i", bcStats.numBlocks);
|
||||
NOTICE_LOG(JIT, "Average Bloat: %0.2f%%", 100 * bcStats.avgBloat);
|
||||
NOTICE_LOG(JIT, "Min Bloat: %0.2f%% (%08x)", 100 * bcStats.minBloat, bcStats.minBloatBlock);
|
||||
NOTICE_LOG(JIT, "Max Bloat: %0.2f%% (%08x)", 100 * bcStats.maxBloat, bcStats.maxBloatBlock);
|
||||
|
||||
int ctr = 0, sz = (int)bcStats.bloatMap.size();
|
||||
for (auto iter : bcStats.bloatMap) {
|
||||
if (ctr < 10 || ctr > sz - 10) {
|
||||
NOTICE_LOG(JIT, "%08x: %f", iter.second, iter.first);
|
||||
} else if (ctr == 10) {
|
||||
NOTICE_LOG(JIT, "...");
|
||||
}
|
||||
ctr++;
|
||||
}
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
|
||||
UI::EventReturn JitCompareScreen::OnSelectBlock(UI::EventParams &e) {
|
||||
auto dev = GetI18NCategory(I18NCat::DEVELOPER);
|
||||
|
||||
auto addressPrompt = new AddressPromptScreen(dev->T("Block address"));
|
||||
addressPrompt->OnChoice.Handle(this, &JitCompareScreen::OnBlockAddress);
|
||||
screenManager()->push(addressPrompt);
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
UI::EventReturn JitCompareScreen::OnPrevBlock(UI::EventParams &e) {
|
||||
currentBlock_--;
|
||||
UpdateDisasm();
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
UI::EventReturn JitCompareScreen::OnNextBlock(UI::EventParams &e) {
|
||||
currentBlock_++;
|
||||
UpdateDisasm();
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
UI::EventReturn JitCompareScreen::OnBlockAddress(UI::EventParams &e) {
|
||||
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
|
||||
if (!MIPSComp::jit) {
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
JitBlockCacheDebugInterface *blockCache = MIPSComp::jit->GetBlockCacheDebugInterface();
|
||||
if (!blockCache)
|
||||
return UI::EVENT_DONE;
|
||||
|
||||
if (Memory::IsValidAddress(e.a)) {
|
||||
currentBlock_ = blockCache->GetBlockNumberFromStartAddress(e.a);
|
||||
} else {
|
||||
currentBlock_ = -1;
|
||||
}
|
||||
UpdateDisasm();
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
UI::EventReturn JitCompareScreen::OnRandomBlock(UI::EventParams &e) {
|
||||
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
|
||||
if (!MIPSComp::jit) {
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
JitBlockCacheDebugInterface *blockCache = MIPSComp::jit->GetBlockCacheDebugInterface();
|
||||
if (!blockCache)
|
||||
return UI::EVENT_DONE;
|
||||
|
||||
int numBlocks = blockCache->GetNumBlocks();
|
||||
if (numBlocks > 0) {
|
||||
int tries = 100;
|
||||
while (tries-- > 0) {
|
||||
currentBlock_ = rand() % numBlocks;
|
||||
if (blockCache->IsValidBlock(currentBlock_)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
UpdateDisasm();
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
UI::EventReturn JitCompareScreen::OnRandomVFPUBlock(UI::EventParams &e) {
|
||||
OnRandomBlock(IS_VFPU);
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
UI::EventReturn JitCompareScreen::OnRandomFPUBlock(UI::EventParams &e) {
|
||||
OnRandomBlock(IS_FPU);
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
void JitCompareScreen::OnRandomBlock(int flag) {
|
||||
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
|
||||
if (!MIPSComp::jit) {
|
||||
return;
|
||||
}
|
||||
JitBlockCacheDebugInterface *blockCache = MIPSComp::jit->GetBlockCacheDebugInterface();
|
||||
if (!blockCache)
|
||||
return;
|
||||
|
||||
int numBlocks = blockCache->GetNumBlocks();
|
||||
if (numBlocks > 0) {
|
||||
bool anyWanted = false;
|
||||
int tries = 0;
|
||||
while (!anyWanted && tries < numBlocks) {
|
||||
currentBlock_ = rand() % numBlocks;
|
||||
if (blockCache->IsValidBlock(currentBlock_)) {
|
||||
JitBlockDebugInfo b = blockCache->GetBlockDebugInfo(currentBlock_);
|
||||
u32 mipsBytes = (u32)b.origDisasm.size() * 4;
|
||||
for (u32 addr = b.originalAddress; addr < b.originalAddress + mipsBytes; addr += 4) {
|
||||
MIPSOpcode opcode = Memory::Read_Instruction(addr);
|
||||
if (MIPSGetInfo(opcode) & flag) {
|
||||
char temp[256];
|
||||
MIPSDisAsm(opcode, addr, temp, sizeof(temp));
|
||||
// INFO_LOG(HLE, "Stopping at random instruction: %08x %s", addr, temp);
|
||||
anyWanted = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
tries++;
|
||||
}
|
||||
|
||||
if (!anyWanted)
|
||||
currentBlock_ = -1;
|
||||
}
|
||||
UpdateDisasm();
|
||||
}
|
||||
|
||||
UI::EventReturn JitCompareScreen::OnCurrentBlock(UI::EventParams &e) {
|
||||
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
|
||||
if (!MIPSComp::jit) {
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
JitBlockCache *blockCache = MIPSComp::jit->GetBlockCache();
|
||||
if (!blockCache)
|
||||
return UI::EVENT_DONE;
|
||||
currentBlock_ = blockCache->GetBlockNumberFromAddress(currentMIPS->pc);
|
||||
UpdateDisasm();
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
|
||||
void AddressPromptScreen::CreatePopupContents(UI::ViewGroup *parent) {
|
||||
using namespace UI;
|
||||
|
||||
auto dev = GetI18NCategory(I18NCat::DEVELOPER);
|
||||
|
||||
addrView_ = new TextView(dev->T("Enter address"), ALIGN_HCENTER, false);
|
||||
parent->Add(addrView_);
|
||||
|
||||
ViewGroup *grid = new GridLayout(GridLayoutSettings(60, 40));
|
||||
parent->Add(grid);
|
||||
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
char temp[16];
|
||||
snprintf(temp, 16, " %X ", i);
|
||||
buttons_[i] = new Button(temp);
|
||||
grid->Add(buttons_[i])->OnClick.Handle(this, &AddressPromptScreen::OnDigitButton);
|
||||
}
|
||||
|
||||
parent->Add(new Button(dev->T("Backspace")))->OnClick.Handle(this, &AddressPromptScreen::OnBackspace);
|
||||
}
|
||||
|
||||
void AddressPromptScreen::OnCompleted(DialogResult result) {
|
||||
if (result == DR_OK) {
|
||||
UI::EventParams e{};
|
||||
e.v = root_;
|
||||
e.a = addr_;
|
||||
OnChoice.Trigger(e);
|
||||
}
|
||||
}
|
||||
|
||||
UI::EventReturn AddressPromptScreen::OnDigitButton(UI::EventParams &e) {
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
if (buttons_[i] == e.v) {
|
||||
AddDigit(i);
|
||||
}
|
||||
}
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
UI::EventReturn AddressPromptScreen::OnBackspace(UI::EventParams &e) {
|
||||
BackspaceDigit();
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
void AddressPromptScreen::AddDigit(int n) {
|
||||
if ((addr_ & 0xF0000000) == 0) {
|
||||
addr_ = addr_ * 16 + n;
|
||||
}
|
||||
UpdatePreviewDigits();
|
||||
}
|
||||
|
||||
void AddressPromptScreen::BackspaceDigit() {
|
||||
addr_ /= 16;
|
||||
UpdatePreviewDigits();
|
||||
}
|
||||
|
||||
void AddressPromptScreen::UpdatePreviewDigits() {
|
||||
if (addr_ != 0) {
|
||||
char temp[32];
|
||||
snprintf(temp, 32, "%8X", addr_);
|
||||
addrView_->SetText(temp);
|
||||
} else {
|
||||
auto dev = GetI18NCategory(I18NCat::DEVELOPER);
|
||||
addrView_->SetText(dev->T("Enter address"));
|
||||
}
|
||||
}
|
||||
|
||||
bool AddressPromptScreen::key(const KeyInput &key) {
|
||||
if (key.flags & KEY_DOWN) {
|
||||
if (key.keyCode >= NKCODE_0 && key.keyCode <= NKCODE_9) {
|
||||
AddDigit(key.keyCode - NKCODE_0);
|
||||
} else if (key.keyCode >= NKCODE_A && key.keyCode <= NKCODE_F) {
|
||||
AddDigit(10 + key.keyCode - NKCODE_A);
|
||||
// NKCODE_DEL is backspace.
|
||||
} else if (key.keyCode == NKCODE_DEL) {
|
||||
BackspaceDigit();
|
||||
} else if (key.keyCode == NKCODE_ENTER) {
|
||||
TriggerFinish(DR_OK);
|
||||
} else {
|
||||
return UIDialogScreen::key(key);
|
||||
}
|
||||
} else {
|
||||
return UIDialogScreen::key(key);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
#pragma once
|
||||
#include "Common/UI/UIScreen.h"
|
||||
#include "UI/MiscScreens.h"
|
||||
|
||||
class JitCompareScreen : public UIDialogScreenWithBackground {
|
||||
public:
|
||||
void CreateViews() override;
|
||||
|
||||
const char *tag() const override { return "JitCompare"; }
|
||||
|
||||
private:
|
||||
void UpdateDisasm();
|
||||
UI::EventReturn OnRandomBlock(UI::EventParams &e);
|
||||
UI::EventReturn OnRandomFPUBlock(UI::EventParams &e);
|
||||
UI::EventReturn OnRandomVFPUBlock(UI::EventParams &e);
|
||||
void OnRandomBlock(int flag);
|
||||
|
||||
UI::EventReturn OnCurrentBlock(UI::EventParams &e);
|
||||
UI::EventReturn OnSelectBlock(UI::EventParams &e);
|
||||
UI::EventReturn OnPrevBlock(UI::EventParams &e);
|
||||
UI::EventReturn OnNextBlock(UI::EventParams &e);
|
||||
UI::EventReturn OnBlockAddress(UI::EventParams &e);
|
||||
UI::EventReturn OnAddressChange(UI::EventParams &e);
|
||||
UI::EventReturn OnShowStats(UI::EventParams &e);
|
||||
|
||||
int currentBlock_ = -1;
|
||||
|
||||
UI::TextView *blockName_;
|
||||
UI::TextEdit *blockAddr_;
|
||||
UI::TextView *blockStats_;
|
||||
|
||||
UI::LinearLayout *leftDisasm_;
|
||||
UI::LinearLayout *rightDisasm_;
|
||||
};
|
||||
|
||||
class AddressPromptScreen : public PopupScreen {
|
||||
public:
|
||||
AddressPromptScreen(std::string_view title) : PopupScreen(title, "OK", "Cancel") {}
|
||||
|
||||
const char *tag() const override { return "AddressPrompt"; }
|
||||
|
||||
bool key(const KeyInput &key) override;
|
||||
|
||||
UI::Event OnChoice;
|
||||
|
||||
protected:
|
||||
void CreatePopupContents(UI::ViewGroup *parent) override;
|
||||
void OnCompleted(DialogResult result) override;
|
||||
UI::EventReturn OnDigitButton(UI::EventParams &e);
|
||||
UI::EventReturn OnBackspace(UI::EventParams &e);
|
||||
|
||||
private:
|
||||
void AddDigit(int n);
|
||||
void BackspaceDigit();
|
||||
void UpdatePreviewDigits();
|
||||
|
||||
UI::TextView *addrView_ = nullptr;
|
||||
UI::Button *buttons_[16]{};
|
||||
unsigned int addr_ = 0;
|
||||
};
|
||||
@@ -51,6 +51,7 @@
|
||||
<ClCompile Include="GameScreen.cpp" />
|
||||
<ClCompile Include="GameSettingsScreen.cpp" />
|
||||
<ClCompile Include="GPUDriverTestScreen.cpp" />
|
||||
<ClCompile Include="JitCompareScreen.cpp" />
|
||||
<ClCompile Include="JoystickHistoryView.cpp" />
|
||||
<ClCompile Include="MainScreen.cpp" />
|
||||
<ClCompile Include="MemStickScreen.cpp" />
|
||||
@@ -90,6 +91,7 @@
|
||||
<ClInclude Include="GameSettingsScreen.h" />
|
||||
<ClInclude Include="CwCheatScreen.h" />
|
||||
<ClInclude Include="GPUDriverTestScreen.h" />
|
||||
<ClInclude Include="JitCompareScreen.h" />
|
||||
<ClInclude Include="JoystickHistoryView.h" />
|
||||
<ClInclude Include="MainScreen.h" />
|
||||
<ClInclude Include="MemStickScreen.h" />
|
||||
|
||||
@@ -95,6 +95,9 @@
|
||||
<ClCompile Include="DriverManagerScreen.cpp">
|
||||
<Filter>Screens</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="JitCompareScreen.cpp">
|
||||
<Filter>Screens</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="GameInfoCache.h" />
|
||||
@@ -190,6 +193,9 @@
|
||||
<ClInclude Include="DriverManagerScreen.h">
|
||||
<Filter>Screens</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="JitCompareScreen.h">
|
||||
<Filter>Screens</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Screens">
|
||||
|
||||
@@ -127,6 +127,7 @@
|
||||
<ClInclude Include="..\..\UI\GameSettingsScreen.h" />
|
||||
<ClInclude Include="..\..\UI\GPUDriverTestScreen.h" />
|
||||
<ClInclude Include="..\..\UI\InstallZipScreen.h" />
|
||||
<ClInclude Include="..\..\UI\JitCompareScreen.h" />
|
||||
<ClInclude Include="..\..\UI\JoystickHistoryView.h" />
|
||||
<ClInclude Include="..\..\UI\TabbedDialogScreen.h" />
|
||||
<ClInclude Include="..\..\UI\RetroAchievementScreens.h" />
|
||||
@@ -166,6 +167,7 @@
|
||||
<ClCompile Include="..\..\UI\GameSettingsScreen.cpp" />
|
||||
<ClCompile Include="..\..\UI\GPUDriverTestScreen.cpp" />
|
||||
<ClCompile Include="..\..\UI\InstallZipScreen.cpp" />
|
||||
<ClCompile Include="..\..\UI\JitCompareScreen.cpp" />
|
||||
<ClCompile Include="..\..\UI\JoystickHistoryView.cpp" />
|
||||
<ClCompile Include="..\..\UI\TabbedDialogScreen.cpp" />
|
||||
<ClCompile Include="..\..\UI\RetroAchievementScreens.cpp" />
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
<ClCompile Include="..\..\UI\RetroAchievementScreens.cpp" />
|
||||
<ClCompile Include="..\..\UI\DebugOverlay.cpp" />
|
||||
<ClCompile Include="..\..\UI\DriverManagerScreen.cpp" />
|
||||
<ClCompile Include="..\..\UI\JitCompareScreen.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h" />
|
||||
@@ -77,5 +78,6 @@
|
||||
<ClInclude Include="..\..\UI\RetroAchievementScreens.h" />
|
||||
<ClInclude Include="..\..\UI\DebugOverlay.h" />
|
||||
<ClInclude Include="..\..\UI\DriverManagerScreen.h" />
|
||||
<ClInclude Include="..\..\UI\JitCompareScreen.h" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -855,6 +855,7 @@ LOCAL_SRC_FILES := \
|
||||
$(SRC)/UI/TouchControlVisibilityScreen.cpp \
|
||||
$(SRC)/UI/CwCheatScreen.cpp \
|
||||
$(SRC)/UI/InstallZipScreen.cpp \
|
||||
$(SRC)/UI/JitCompareScreen.cpp \
|
||||
$(SRC)/UI/OnScreenDisplay.cpp \
|
||||
$(SRC)/UI/ProfilerDraw.cpp \
|
||||
$(SRC)/UI/NativeApp.cpp \
|
||||
|
||||
@@ -119,7 +119,7 @@ bool TestMultithreadedScheduling() {
|
||||
|
||||
threads.clear();
|
||||
|
||||
printf("Stress test elapsed: %0.2f", start.Elapsed());
|
||||
printf("Stress test elapsed: %0.2f", start.ElapsedSeconds());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user