Add new shader viewing tool
This commit is contained in:
parent
09cc80f413
commit
7f4e473e8c
25 changed files with 565 additions and 211 deletions
|
@ -67,6 +67,7 @@ void DevMenu::CreatePopupContents(UI::ViewGroup *parent) {
|
|||
parent->Add(new Choice(dev->T("Logging Channels")))->OnClick.Handle(this, &DevMenu::OnLogConfig);
|
||||
parent->Add(new Choice(sy->T("Developer Tools")))->OnClick.Handle(this, &DevMenu::OnDeveloperTools);
|
||||
parent->Add(new Choice(dev->T("Jit Compare")))->OnClick.Handle(this, &DevMenu::OnJitCompare);
|
||||
parent->Add(new Choice(dev->T("Shader Viewer")))->OnClick.Handle(this, &DevMenu::OnShaderView);
|
||||
parent->Add(new Choice(dev->T("Toggle Freeze")))->OnClick.Handle(this, &DevMenu::OnFreezeFrame);
|
||||
parent->Add(new Choice(dev->T("Dump Frame GPU Commands")))->OnClick.Handle(this, &DevMenu::OnDumpFrame);
|
||||
parent->Add(new Choice(dev->T("Toggle Audio Debug")))->OnClick.Handle(this, &DevMenu::OnToggleAudioDebug);
|
||||
|
@ -110,6 +111,14 @@ UI::EventReturn DevMenu::OnJitCompare(UI::EventParams &e) {
|
|||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
UI::EventReturn DevMenu::OnShaderView(UI::EventParams &e) {
|
||||
UpdateUIState(UISTATE_PAUSEMENU);
|
||||
screenManager()->push(new ShaderListScreen());
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
UI::EventReturn DevMenu::OnFreezeFrame(UI::EventParams &e) {
|
||||
if (PSP_CoreParameter().frozen) {
|
||||
PSP_CoreParameter().frozen = false;
|
||||
|
@ -761,7 +770,6 @@ void JitCompareScreen::OnRandomBlock(int flag) {
|
|||
UpdateDisasm();
|
||||
}
|
||||
|
||||
|
||||
UI::EventReturn JitCompareScreen::OnCurrentBlock(UI::EventParams &e) {
|
||||
if (!MIPSComp::jit) {
|
||||
return UI::EVENT_DONE;
|
||||
|
@ -778,173 +786,74 @@ UI::EventReturn JitCompareScreen::OnCurrentBlock(UI::EventParams &e) {
|
|||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
static const uint32_t nice_colors[] = {
|
||||
0xFF8040,
|
||||
0x80FF40,
|
||||
0x8040FF,
|
||||
0xFFFF40,
|
||||
|
||||
0x40FFFF,
|
||||
0xFF70FF,
|
||||
0xc0c0c0,
|
||||
0xb040c0,
|
||||
|
||||
0x184099,
|
||||
0xCC3333,
|
||||
0xFF99CC,
|
||||
0x3399CC,
|
||||
|
||||
0x990000,
|
||||
0x003366,
|
||||
0xF8F8F8,
|
||||
0x33FFFF,
|
||||
};
|
||||
|
||||
enum ProfileCatStatus {
|
||||
PROFILE_CAT_VISIBLE = 0,
|
||||
PROFILE_CAT_IGNORE = 1,
|
||||
PROFILE_CAT_NOLEGEND = 2,
|
||||
};
|
||||
|
||||
void DrawProfile(UIContext &ui) {
|
||||
#ifdef USE_PROFILER
|
||||
int numCategories = Profiler_GetNumCategories();
|
||||
int historyLength = Profiler_GetHistoryLength();
|
||||
|
||||
ui.SetFontStyle(ui.theme->uiFont);
|
||||
|
||||
static float lastMaxVal = 1.0f / 60.0f;
|
||||
float legendMinVal = lastMaxVal * (1.0f / 120.0f);
|
||||
|
||||
std::vector<float> history;
|
||||
std::vector<ProfileCatStatus> catStatus;
|
||||
history.resize(historyLength);
|
||||
catStatus.resize(numCategories);
|
||||
|
||||
float rowH = 30.0f;
|
||||
float legendHeight = 0.0f;
|
||||
float legendWidth = 80.0f;
|
||||
for (int i = 0; i < numCategories; i++) {
|
||||
const char *name = Profiler_GetCategoryName(i);
|
||||
if (!strcmp(name, "timing")) {
|
||||
catStatus[i] = PROFILE_CAT_IGNORE;
|
||||
continue;
|
||||
}
|
||||
|
||||
Profiler_GetHistory(i, &history[0], historyLength);
|
||||
catStatus[i] = PROFILE_CAT_NOLEGEND;
|
||||
for (int j = 0; j < historyLength; ++j) {
|
||||
if (history[j] > legendMinVal) {
|
||||
catStatus[i] = PROFILE_CAT_VISIBLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// So they don't move horizontally, we always measure.
|
||||
float w = 0.0f, h = 0.0f;
|
||||
ui.MeasureText(ui.GetFontStyle(), name, &w, &h);
|
||||
if (w > legendWidth) {
|
||||
legendWidth = w;
|
||||
}
|
||||
legendHeight += rowH;
|
||||
void ShaderListScreen::ListShaders(DebugShaderType shaderType, UI::LinearLayout *view) {
|
||||
using namespace UI;
|
||||
std::vector<std::string> shaderIds_ = gpu->DebugGetShaderIDs(shaderType);
|
||||
for (auto id : shaderIds_) {
|
||||
Choice *choice = view->Add(new Choice(gpu->DebugGetShaderString(id, shaderType, SHADER_STRING_SHORT_DESC)));
|
||||
choice->SetTag(id);
|
||||
choice->OnClick.Handle(this, &ShaderListScreen::OnShaderClick);
|
||||
}
|
||||
legendWidth += 20.0f;
|
||||
|
||||
float legendStartY = legendHeight > ui.GetBounds().centerY() ? ui.GetBounds().y2() - legendHeight : ui.GetBounds().centerY();
|
||||
float legendStartX = ui.GetBounds().x2() - std::min(legendWidth, 200.0f);
|
||||
|
||||
const uint32_t opacity = 140 << 24;
|
||||
|
||||
int legendNum = 0;
|
||||
for (int i = 0; i < numCategories; i++) {
|
||||
const char *name = Profiler_GetCategoryName(i);
|
||||
uint32_t color = nice_colors[i % ARRAY_SIZE(nice_colors)];
|
||||
|
||||
if (catStatus[i] == PROFILE_CAT_VISIBLE) {
|
||||
float y = legendStartY + legendNum++ * rowH;
|
||||
ui.FillRect(UI::Drawable(opacity | color), Bounds(legendStartX, y, rowH - 2, rowH - 2));
|
||||
ui.DrawTextShadow(name, legendStartX + rowH + 2, y, 0xFFFFFFFF, ALIGN_VBASELINE);
|
||||
}
|
||||
}
|
||||
|
||||
float graphWidth = ui.GetBounds().x2() - legendWidth - 20.0f;
|
||||
float graphHeight = ui.GetBounds().h * 0.8f;
|
||||
|
||||
float dx = graphWidth / historyLength;
|
||||
|
||||
/*
|
||||
ui.Flush();
|
||||
|
||||
ui.BeginNoTex();
|
||||
*/
|
||||
|
||||
bool area = true;
|
||||
float minVal = 0.0f;
|
||||
float maxVal = lastMaxVal; // TODO - adjust to frame length
|
||||
if (maxVal < 0.001f)
|
||||
maxVal = 0.001f;
|
||||
if (maxVal > 1.0f / 15.0f)
|
||||
maxVal = 1.0f / 15.0f;
|
||||
|
||||
float scale = (graphHeight) / (maxVal - minVal);
|
||||
|
||||
float y_60th = ui.GetBounds().y2() - 10 - (1.0f / 60.0f) * scale;
|
||||
float y_1ms = ui.GetBounds().y2() - 10 - (1.0f / 1000.0f) * scale;
|
||||
|
||||
ui.FillRect(UI::Drawable(0x80FFFF00), Bounds(0, y_60th, graphWidth, 2));
|
||||
ui.FillRect(UI::Drawable(0x80FFFF00), Bounds(0, y_1ms, graphWidth, 2));
|
||||
ui.DrawTextShadow("1/60s", 5, y_60th, 0x80FFFF00);
|
||||
ui.DrawTextShadow("1ms", 5, y_1ms, 0x80FFFF00);
|
||||
|
||||
std::vector<float> total;
|
||||
total.resize(historyLength);
|
||||
|
||||
maxVal = 0.0f;
|
||||
float maxTotal = 0.0f;
|
||||
for (int i = 0; i < numCategories; i++) {
|
||||
if (catStatus[i] == PROFILE_CAT_IGNORE) {
|
||||
continue;
|
||||
}
|
||||
Profiler_GetHistory(i, &history[0], historyLength);
|
||||
|
||||
float x = 10;
|
||||
uint32_t col = nice_colors[i % ARRAY_SIZE(nice_colors)];
|
||||
if (area)
|
||||
col = opacity | (col & 0xFFFFFF);
|
||||
UI::Drawable color(col);
|
||||
UI::Drawable outline((opacity >> 1) | 0xFFFFFF);
|
||||
|
||||
if (area) {
|
||||
for (int n = 0; n < historyLength; n++) {
|
||||
float val = history[n];
|
||||
float valY1 = ui.GetBounds().y2() - 10 - (val + total[n]) * scale;
|
||||
float valY2 = ui.GetBounds().y2() - 10 - total[n] * scale;
|
||||
ui.FillRect(outline, Bounds(x, valY2, dx, 1.0f));
|
||||
ui.FillRect(color, Bounds(x, valY1, dx, valY2 - valY1));
|
||||
x += dx;
|
||||
total[n] += val;
|
||||
}
|
||||
} else {
|
||||
for (int n = 0; n < historyLength; n++) {
|
||||
float val = history[n];
|
||||
if (val > maxVal)
|
||||
maxVal = val;
|
||||
float valY = ui.GetBounds().y2() - 10 - history[n] * scale;
|
||||
ui.FillRect(color, Bounds(x, valY, dx, 5));
|
||||
x += dx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int n = 0; n < historyLength; n++) {
|
||||
if (total[n] > maxTotal)
|
||||
maxTotal = total[n];
|
||||
}
|
||||
|
||||
if (area) {
|
||||
maxVal = maxTotal;
|
||||
}
|
||||
|
||||
lastMaxVal = lastMaxVal * 0.95f + maxVal * 0.05f;
|
||||
#endif
|
||||
}
|
||||
|
||||
void ShaderListScreen::CreateViews() {
|
||||
using namespace UI;
|
||||
|
||||
LinearLayout *layout = new LinearLayout(ORIENT_VERTICAL);
|
||||
root_ = layout;
|
||||
|
||||
tabs_ = new TabHolder(ORIENT_HORIZONTAL, 40, new LinearLayoutParams(1.0));
|
||||
layout->Add(tabs_);
|
||||
layout->Add(new Button("Back"))->OnClick.Handle<UIScreen>(this, &UIScreen::OnBack);
|
||||
|
||||
ScrollView *vs_scroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0));
|
||||
ScrollView *fs_scroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0));
|
||||
|
||||
LinearLayout *vshaderList = new LinearLayout(ORIENT_VERTICAL, new LayoutParams(FILL_PARENT, WRAP_CONTENT));
|
||||
LinearLayout *fshaderList = new LinearLayout(ORIENT_VERTICAL, new LayoutParams(FILL_PARENT, WRAP_CONTENT));
|
||||
|
||||
ListShaders(SHADER_TYPE_VERTEX, vshaderList);
|
||||
ListShaders(SHADER_TYPE_FRAGMENT, fshaderList);
|
||||
|
||||
vs_scroll->Add(vshaderList);
|
||||
fs_scroll->Add(fshaderList);
|
||||
|
||||
tabs_->AddTab("Vertex", vs_scroll);
|
||||
tabs_->AddTab("Fragment", fs_scroll);
|
||||
}
|
||||
|
||||
UI::EventReturn ShaderListScreen::OnShaderClick(UI::EventParams &e) {
|
||||
using namespace UI;
|
||||
std::string id = e.v->Tag();
|
||||
DebugShaderType type = SHADER_TYPE_VERTEX;
|
||||
if (tabs_->GetCurrentTab() == 1) {
|
||||
type = SHADER_TYPE_FRAGMENT;
|
||||
}
|
||||
screenManager()->push(new ShaderViewScreen(id, type));
|
||||
return EVENT_DONE;
|
||||
}
|
||||
|
||||
void ShaderViewScreen::CreateViews() {
|
||||
using namespace UI;
|
||||
|
||||
LinearLayout *layout = new LinearLayout(ORIENT_VERTICAL);
|
||||
root_ = layout;
|
||||
|
||||
layout->Add(new TextView(gpu->DebugGetShaderString(id_, type_, SHADER_STRING_SHORT_DESC)));
|
||||
|
||||
ScrollView *scroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0));
|
||||
layout->Add(scroll);
|
||||
|
||||
LinearLayout *lineLayout = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT));
|
||||
lineLayout->SetSpacing(0.0);
|
||||
scroll->Add(lineLayout);
|
||||
|
||||
std::vector<std::string> lines;
|
||||
SplitString(gpu->DebugGetShaderString(id_, type_, SHADER_STRING_SOURCE_CODE), '\n', lines);
|
||||
|
||||
for (auto line : lines) {
|
||||
lineLayout->Add(new TextView(line, FLAG_DYNAMIC_ASCII, true));
|
||||
}
|
||||
|
||||
layout->Add(new Button("Back"))->OnClick.Handle<UIScreen>(this, &UIScreen::OnBack);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue