mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-02 15:02:11 +00:00
RSX Debugger: Shader program editor
* Added checkbox in the Settings dialog for logging/editing shader programs. * Added "Programs" tab to the RSX Debugger. Double-click on the entries to view/edit the shaders. Click on "Yes" after closing the editor will recompile your program even if no changes were done. * Replaced "Ctrl+C" shortcut for running the emulator with "Ctrl+E" to avoid accidentally unpausing the emulator when copying text. * Added glDetachShader to GLProcTable.tbl NOTE: There is a known bug: For some reason, certain shaders refuse to compile again, even if you save the original shader as the "new" one.
This commit is contained in:
parent
51613df455
commit
b85a86b225
@ -1,6 +1,7 @@
|
||||
#include "stdafx.h"
|
||||
#include "GLGSRender.h"
|
||||
#include "Emu/Cell/PPCInstrTable.h"
|
||||
#include "Gui/RSXDebugger.h"
|
||||
|
||||
#define CMD_DEBUG 0
|
||||
#define DUMP_VERTEX_DATA 0
|
||||
@ -428,6 +429,34 @@ bool GLGSRender::LoadProgram()
|
||||
|
||||
if(m_program.id)
|
||||
{
|
||||
// RSX Debugger: Check if this program was modified and update it
|
||||
if (Ini.GSLogPrograms.GetValue())
|
||||
{
|
||||
for(auto& program : m_debug_programs)
|
||||
{
|
||||
if (program.id == m_program.id && program.modified)
|
||||
{
|
||||
// TODO: This isn't working perfectly. Is there any better/shorter way to update the program.
|
||||
glDetachShader(m_program.id, m_vertex_prog.id);
|
||||
glDetachShader(m_program.id, m_shader_prog.id);
|
||||
m_vertex_prog.shader = program.vp_shader;
|
||||
m_shader_prog.shader = program.fp_shader;
|
||||
m_vertex_prog.Wait();
|
||||
m_vertex_prog.Compile();
|
||||
checkForGlError("m_vertex_prog.Compile");
|
||||
m_shader_prog.Wait();
|
||||
m_shader_prog.Compile();
|
||||
checkForGlError("m_shader_prog.Compile");
|
||||
glAttachShader(m_program.id, m_vertex_prog.id);
|
||||
glAttachShader(m_program.id, m_shader_prog.id);
|
||||
glLinkProgram(m_program.id);
|
||||
checkForGlError("glLinkProgram");
|
||||
program.vp_id = m_vertex_prog.id;
|
||||
program.fp_id = m_shader_prog.id;
|
||||
program.modified = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_program.Use();
|
||||
}
|
||||
else
|
||||
@ -437,6 +466,18 @@ bool GLGSRender::LoadProgram()
|
||||
m_prog_buffer.Add(m_program, m_shader_prog, *m_cur_shader_prog, m_vertex_prog, *m_cur_vertex_prog);
|
||||
checkForGlError("m_prog_buffer.Add");
|
||||
m_program.Use();
|
||||
|
||||
// RSX Debugger
|
||||
if (Ini.GSLogPrograms.GetValue())
|
||||
{
|
||||
RSXDebuggerProgram program = RSXDebuggerProgram();
|
||||
program.id = m_program.id;
|
||||
program.vp_id = m_vertex_prog.id;
|
||||
program.fp_id = m_shader_prog.id;
|
||||
program.vp_shader = m_vertex_prog.shader;
|
||||
program.fp_shader = m_shader_prog.shader;
|
||||
m_debug_programs.push_back(program);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -20,6 +20,7 @@ OPENGL_PROC(PFNGLGETSHADERINFOLOGPROC, GetShaderInfoLog);
|
||||
OPENGL_PROC(PFNGLCREATEPROGRAMPROC, CreateProgram);
|
||||
OPENGL_PROC(PFNGLDELETEPROGRAMPROC, DeleteProgram);
|
||||
OPENGL_PROC(PFNGLATTACHSHADERPROC, AttachShader);
|
||||
OPENGL_PROC(PFNGLDETACHSHADERPROC, DetachShader);
|
||||
OPENGL_PROC(PFNGLGETATTRIBLOCATIONPROC, GetAttribLocation);
|
||||
OPENGL_PROC(PFNGLLINKPROGRAMPROC, LinkProgram);
|
||||
//OPENGL_PROC(PFNGLBINDFRAGDATALOCATIONPROC, BindFragDataLocation);
|
||||
|
@ -375,6 +375,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
|
||||
wxComboBox* cbox_audio_out = new wxComboBox(&diag, wxID_ANY);
|
||||
|
||||
wxCheckBox* chbox_cpu_ignore_rwerrors = new wxCheckBox(&diag, wxID_ANY, "Ignore Read/Write errors");
|
||||
wxCheckBox* chbox_gs_log_prog = new wxCheckBox(&diag, wxID_ANY, "Log vertex/fragment programs");
|
||||
wxCheckBox* chbox_gs_dump_depth = new wxCheckBox(&diag, wxID_ANY, "Dump Depth Buffer");
|
||||
wxCheckBox* chbox_gs_dump_color = new wxCheckBox(&diag, wxID_ANY, "Dump Color Buffers");
|
||||
wxCheckBox* chbox_gs_vsync = new wxCheckBox(&diag, wxID_ANY, "VSync");
|
||||
@ -411,6 +412,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
|
||||
cbox_audio_out->Append("Null");
|
||||
|
||||
chbox_cpu_ignore_rwerrors->SetValue(Ini.CPUIgnoreRWErrors.GetValue());
|
||||
chbox_gs_log_prog->SetValue(Ini.GSLogPrograms.GetValue());
|
||||
chbox_gs_dump_depth->SetValue(Ini.GSDumpDepthBuffer.GetValue());
|
||||
chbox_gs_dump_color->SetValue(Ini.GSDumpColorBuffers.GetValue());
|
||||
chbox_gs_vsync->SetValue(Ini.GSVSyncEnable.GetValue());
|
||||
@ -435,6 +437,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
|
||||
s_round_gs->Add(s_round_gs_render, wxSizerFlags().Border(wxALL, 5).Expand());
|
||||
s_round_gs->Add(s_round_gs_res, wxSizerFlags().Border(wxALL, 5).Expand());
|
||||
s_round_gs->Add(s_round_gs_aspect, wxSizerFlags().Border(wxALL, 5).Expand());
|
||||
s_round_gs->Add(chbox_gs_log_prog, wxSizerFlags().Border(wxALL, 5));
|
||||
s_round_gs->Add(chbox_gs_dump_depth, wxSizerFlags().Border(wxALL, 5));
|
||||
s_round_gs->Add(chbox_gs_dump_color, wxSizerFlags().Border(wxALL, 5));
|
||||
s_round_gs->Add(chbox_gs_vsync, wxSizerFlags().Border(wxALL, 5));
|
||||
@ -478,6 +481,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
|
||||
Ini.GSResolution.SetValue(ResolutionNumToId(cbox_gs_resolution->GetSelection() + 1));
|
||||
Ini.GSAspectRatio.SetValue(cbox_gs_aspect->GetSelection() + 1);
|
||||
Ini.GSVSyncEnable.SetValue(chbox_gs_vsync->GetValue());
|
||||
Ini.GSLogPrograms.SetValue(chbox_gs_log_prog->GetValue());
|
||||
Ini.GSDumpDepthBuffer.SetValue(chbox_gs_dump_depth->GetValue());
|
||||
Ini.GSDumpColorBuffers.SetValue(chbox_gs_dump_color->GetValue());
|
||||
Ini.PadHandlerMode.SetValue(cbox_pad_handler->GetSelection());
|
||||
@ -805,7 +809,7 @@ void MainFrame::OnKeyDown(wxKeyEvent& event)
|
||||
{
|
||||
switch(event.GetKeyCode())
|
||||
{
|
||||
case 'C': case 'c': if(Emu.IsPaused()) Emu.Resume(); else if(Emu.IsReady()) Emu.Run(); return;
|
||||
case 'E': case 'e': if(Emu.IsPaused()) Emu.Resume(); else if(Emu.IsReady()) Emu.Run(); return;
|
||||
case 'P': case 'p': if(Emu.IsRunning()) Emu.Pause(); return;
|
||||
case 'S': case 's': if(!Emu.IsStopped()) Emu.Stop(); return;
|
||||
case 'R': case 'r': if(!Emu.m_path.IsEmpty()) {Emu.Stop(); Emu.Run();} return;
|
||||
|
@ -5,6 +5,9 @@
|
||||
|
||||
#include "MemoryViewer.h"
|
||||
|
||||
// TODO: Clear the object when restarting the emulator
|
||||
std::vector<RSXDebuggerProgram> m_debug_programs;
|
||||
|
||||
enum GCMEnumTypes
|
||||
{
|
||||
CELL_GCM_ENUM,
|
||||
@ -68,12 +71,14 @@ RSXDebugger::RSXDebugger(wxWindow* parent)
|
||||
wxNotebook* nb_rsx = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxSize(482,475));
|
||||
wxPanel* p_commands = new wxPanel(nb_rsx, wxID_ANY);
|
||||
wxPanel* p_flags = new wxPanel(nb_rsx, wxID_ANY);
|
||||
wxPanel* p_programs = new wxPanel(nb_rsx, wxID_ANY);
|
||||
wxPanel* p_lightning = new wxPanel(nb_rsx, wxID_ANY);
|
||||
wxPanel* p_texture = new wxPanel(nb_rsx, wxID_ANY);
|
||||
wxPanel* p_settings = new wxPanel(nb_rsx, wxID_ANY);
|
||||
|
||||
nb_rsx->AddPage(p_commands, wxT("RSX Commands"));
|
||||
nb_rsx->AddPage(p_flags, wxT("Flags"));
|
||||
nb_rsx->AddPage(p_programs, wxT("Programs"));
|
||||
nb_rsx->AddPage(p_lightning, wxT("Lightning"));
|
||||
nb_rsx->AddPage(p_texture, wxT("Texture"));
|
||||
nb_rsx->AddPage(p_settings, wxT("Settings"));
|
||||
@ -81,6 +86,7 @@ RSXDebugger::RSXDebugger(wxWindow* parent)
|
||||
//Tabs: Lists
|
||||
m_list_commands = new wxListView(p_commands, wxID_ANY, wxPoint(1,3), wxSize(470,444));
|
||||
m_list_flags = new wxListView(p_flags, wxID_ANY, wxPoint(1,3), wxSize(470,444));
|
||||
m_list_programs = new wxListView(p_programs, wxID_ANY, wxPoint(1,3), wxSize(470,444));
|
||||
m_list_lightning = new wxListView(p_lightning, wxID_ANY, wxPoint(1,3), wxSize(470,444));
|
||||
m_list_texture = new wxListView(p_texture, wxID_ANY, wxPoint(1,3), wxSize(470,444));
|
||||
m_list_settings = new wxListView(p_settings, wxID_ANY, wxPoint(1,3), wxSize(470,444));
|
||||
@ -88,6 +94,7 @@ RSXDebugger::RSXDebugger(wxWindow* parent)
|
||||
//Tabs: List Style
|
||||
m_list_commands ->SetFont(wxFont(8, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
|
||||
m_list_flags ->SetFont(wxFont(8, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
|
||||
m_list_programs ->SetFont(wxFont(8, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
|
||||
m_list_lightning->SetFont(wxFont(8, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
|
||||
m_list_texture ->SetFont(wxFont(8, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
|
||||
m_list_settings ->SetFont(wxFont(8, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
|
||||
@ -99,6 +106,11 @@ RSXDebugger::RSXDebugger(wxWindow* parent)
|
||||
m_list_commands->InsertColumn(3, "Count", 0, 40);
|
||||
m_list_flags->InsertColumn(0, "Name", 0, 170);
|
||||
m_list_flags->InsertColumn(1, "Value", 0, 270);
|
||||
m_list_programs->InsertColumn(0, "ID", 0, 70);
|
||||
m_list_programs->InsertColumn(1, "VP ID", 0, 70);
|
||||
m_list_programs->InsertColumn(2, "FP ID", 0, 70);
|
||||
m_list_programs->InsertColumn(3, "VP Length", 0, 110);
|
||||
m_list_programs->InsertColumn(4, "FP Length", 0, 110);
|
||||
m_list_lightning->InsertColumn(0, "Name", 0, 170);
|
||||
m_list_lightning->InsertColumn(1, "Value", 0, 270);
|
||||
|
||||
@ -131,10 +143,10 @@ RSXDebugger::RSXDebugger(wxWindow* parent)
|
||||
//Buffers
|
||||
wxBoxSizer& s_buffers1 = *new wxBoxSizer(wxVERTICAL);
|
||||
wxBoxSizer& s_buffers2 = *new wxBoxSizer(wxVERTICAL);
|
||||
wxStaticBoxSizer& s_buffers_colorA = *new wxStaticBoxSizer(wxHORIZONTAL, this, "Color Buffer A");
|
||||
wxStaticBoxSizer& s_buffers_colorB = *new wxStaticBoxSizer(wxHORIZONTAL, this, "Color Buffer B");
|
||||
wxStaticBoxSizer& s_buffers_colorC = *new wxStaticBoxSizer(wxHORIZONTAL, this, "Color Buffer C");
|
||||
wxStaticBoxSizer& s_buffers_colorD = *new wxStaticBoxSizer(wxHORIZONTAL, this, "Color Buffer D");
|
||||
wxStaticBoxSizer& s_buffers_colorA = *new wxStaticBoxSizer(wxHORIZONTAL, this, "Color Buffer A");
|
||||
wxStaticBoxSizer& s_buffers_colorB = *new wxStaticBoxSizer(wxHORIZONTAL, this, "Color Buffer B");
|
||||
wxStaticBoxSizer& s_buffers_colorC = *new wxStaticBoxSizer(wxHORIZONTAL, this, "Color Buffer C");
|
||||
wxStaticBoxSizer& s_buffers_colorD = *new wxStaticBoxSizer(wxHORIZONTAL, this, "Color Buffer D");
|
||||
wxStaticBoxSizer& s_buffers_depth = *new wxStaticBoxSizer(wxHORIZONTAL, this, "Depth Buffer");
|
||||
wxStaticBoxSizer& s_buffers_stencil = *new wxStaticBoxSizer(wxHORIZONTAL, this, "Stencil Buffer");
|
||||
wxStaticBoxSizer& s_buffers_text = *new wxStaticBoxSizer(wxHORIZONTAL, this, "Texture");
|
||||
@ -207,6 +219,7 @@ RSXDebugger::RSXDebugger(wxWindow* parent)
|
||||
|
||||
m_list_commands->Connect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(RSXDebugger::OnScrollMemory), nullptr, this);
|
||||
m_list_flags->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(RSXDebugger::SetFlags), nullptr, this);
|
||||
m_list_programs->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(RSXDebugger::SetPrograms), nullptr, this);
|
||||
|
||||
m_list_texture->Connect(wxID_ANY, wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(RSXDebugger::OnSelectTexture), nullptr, this);
|
||||
|
||||
@ -331,6 +344,7 @@ void RSXDebugger::UpdateInformation()
|
||||
GetMemory();
|
||||
GetBuffers();
|
||||
GetFlags();
|
||||
GetPrograms();
|
||||
GetLightning();
|
||||
GetTexture();
|
||||
GetSettings();
|
||||
@ -476,6 +490,23 @@ void RSXDebugger::GetFlags()
|
||||
#undef LIST_FLAGS_ADD
|
||||
}
|
||||
|
||||
void RSXDebugger::GetPrograms()
|
||||
{
|
||||
if (!RSXReady()) return;
|
||||
m_list_programs->DeleteAllItems();
|
||||
|
||||
int i=0;
|
||||
for (auto& program : m_debug_programs)
|
||||
{
|
||||
m_list_programs->InsertItem(i, wxString::Format("%d", program.id));
|
||||
m_list_programs->SetItem(i, 1, wxString::Format("%d", program.vp_id));
|
||||
m_list_programs->SetItem(i, 2, wxString::Format("%d", program.fp_id));
|
||||
m_list_programs->SetItem(i, 3, wxString::Format("%d", program.vp_shader.length()));
|
||||
m_list_programs->SetItem(i, 4, wxString::Format("%d", program.fp_shader.length()));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void RSXDebugger::GetLightning()
|
||||
{
|
||||
if (!RSXReady()) return;
|
||||
@ -615,6 +646,44 @@ void RSXDebugger::SetFlags(wxListEvent& event)
|
||||
UpdateInformation();
|
||||
}
|
||||
|
||||
void RSXDebugger::SetPrograms(wxListEvent& event)
|
||||
{
|
||||
if (!RSXReady()) return;
|
||||
GSRender& render = Emu.GetGSManager().GetRender();
|
||||
RSXDebuggerProgram& program = m_debug_programs[event.m_itemIndex];
|
||||
|
||||
// Program Editor
|
||||
wxString title = wxString::Format("Program ID: %d (VP:%d, FP:%d)", program.id, program.vp_id, program.fp_id);
|
||||
wxDialog* d_editor = new wxDialog(this, wxID_ANY, title, wxDefaultPosition, wxSize(800,500),
|
||||
wxDEFAULT_DIALOG_STYLE | wxMINIMIZE_BOX | wxMAXIMIZE_BOX | wxRESIZE_BORDER);
|
||||
|
||||
wxBoxSizer& s_panel = *new wxBoxSizer(wxHORIZONTAL);
|
||||
wxStaticBoxSizer& s_vp_box = *new wxStaticBoxSizer(wxHORIZONTAL, d_editor, "Vertex Program");
|
||||
wxStaticBoxSizer& s_fp_box = *new wxStaticBoxSizer(wxHORIZONTAL, d_editor, "Fragment Program");
|
||||
wxTextCtrl* t_vp_edit = new wxTextCtrl(d_editor, -1, program.vp_shader, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
|
||||
wxTextCtrl* t_fp_edit = new wxTextCtrl(d_editor, -1, program.fp_shader, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
|
||||
t_vp_edit->SetFont(wxFont(8, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
|
||||
t_fp_edit->SetFont(wxFont(8, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
|
||||
s_vp_box.Add(t_vp_edit, 1, wxEXPAND);
|
||||
s_fp_box.Add(t_fp_edit, 1, wxEXPAND);
|
||||
s_panel.Add(&s_vp_box, 1, wxEXPAND);
|
||||
s_panel.Add(&s_fp_box, 1, wxEXPAND);
|
||||
d_editor->SetSizer(&s_panel);
|
||||
|
||||
// Show editor and open Save Dialog when closing
|
||||
if (d_editor->ShowModal())
|
||||
{
|
||||
wxMessageDialog* d_save = new wxMessageDialog(d_editor, "Save changes and compile shaders?", title, wxYES_NO|wxCENTRE);
|
||||
if(d_save->ShowModal() == wxID_YES)
|
||||
{
|
||||
program.modified = true;
|
||||
program.vp_shader = t_vp_edit->GetValue();
|
||||
program.fp_shader = t_fp_edit->GetValue();
|
||||
}
|
||||
}
|
||||
UpdateInformation();
|
||||
}
|
||||
|
||||
void RSXDebugger::OnSelectTexture(wxListEvent& event)
|
||||
{
|
||||
if(event.GetIndex() >= 0)
|
||||
|
@ -2,6 +2,23 @@
|
||||
|
||||
#include <wx/listctrl.h>
|
||||
|
||||
struct RSXDebuggerProgram
|
||||
{
|
||||
u32 id;
|
||||
u32 vp_id;
|
||||
u32 fp_id;
|
||||
std::string vp_shader;
|
||||
std::string fp_shader;
|
||||
bool modified;
|
||||
|
||||
RSXDebuggerProgram()
|
||||
: modified(false)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
extern std::vector<RSXDebuggerProgram> m_debug_programs;
|
||||
|
||||
class RSXDebugger : public wxFrame
|
||||
{
|
||||
AppConnector m_app_connector;
|
||||
@ -18,6 +35,7 @@ class RSXDebugger : public wxFrame
|
||||
u32 m_item_count;
|
||||
wxListView* m_list_commands;
|
||||
wxListView* m_list_flags;
|
||||
wxListView* m_list_programs;
|
||||
wxListView* m_list_lightning;
|
||||
wxListView* m_list_texture;
|
||||
wxListView* m_list_settings;
|
||||
@ -52,11 +70,13 @@ public:
|
||||
virtual void GetMemory();
|
||||
virtual void GetBuffers();
|
||||
virtual void GetFlags();
|
||||
virtual void GetPrograms();
|
||||
virtual void GetLightning();
|
||||
virtual void GetTexture();
|
||||
virtual void GetSettings();
|
||||
|
||||
virtual void SetFlags(wxListEvent& event);
|
||||
virtual void SetPrograms(wxListEvent& event);
|
||||
virtual void OnSelectTexture(wxListEvent& event);
|
||||
|
||||
wxString ParseGCMEnum(u32 value, u32 type);
|
||||
|
@ -98,6 +98,7 @@ public:
|
||||
IniEntry<int> GSResolution;
|
||||
IniEntry<u8> GSAspectRatio;
|
||||
IniEntry<bool> GSVSyncEnable;
|
||||
IniEntry<bool> GSLogPrograms;
|
||||
IniEntry<bool> GSDumpColorBuffers;
|
||||
IniEntry<bool> GSDumpDepthBuffer;
|
||||
IniEntry<u8> PadHandlerMode;
|
||||
@ -137,6 +138,7 @@ public:
|
||||
GSResolution.Init("Resolution", path);
|
||||
GSAspectRatio.Init("AspectRatio", path);
|
||||
GSVSyncEnable.Init("VSyncEnable", path);
|
||||
GSLogPrograms.Init("LogPrograms", path);
|
||||
GSDumpColorBuffers.Init("DumpColorBuffers", path);
|
||||
GSDumpDepthBuffer.Init("DumpDepthBuffer", path);
|
||||
|
||||
@ -178,6 +180,7 @@ public:
|
||||
GSResolution.Load(4);
|
||||
GSAspectRatio.Load(2);
|
||||
GSVSyncEnable.Load(false);
|
||||
GSLogPrograms.Load(false);
|
||||
GSDumpColorBuffers.Load(true);
|
||||
GSDumpDepthBuffer.Load(true);
|
||||
PadHandlerMode.Load(1);
|
||||
@ -212,6 +215,7 @@ public:
|
||||
GSResolution.Save();
|
||||
GSAspectRatio.Save();
|
||||
GSVSyncEnable.Save();
|
||||
GSLogPrograms.Save();
|
||||
GSDumpColorBuffers.Save();
|
||||
GSDumpDepthBuffer.Save();
|
||||
PadHandlerMode.Save();
|
||||
|
Loading…
Reference in New Issue
Block a user