1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 02:32:36 +01:00

Introducing RSX debugger entry (main debugger)

This commit is contained in:
Eladash 2021-01-15 20:28:45 +02:00 committed by Ivan
parent 62cb532460
commit dbecf0fa50
14 changed files with 1685 additions and 1220 deletions

View File

@ -5,6 +5,7 @@
#include "Emu/Cell/RawSPUThread.h"
#include "Emu/Cell/lv2/sys_mmapper.h"
#include "Emu/Cell/lv2/sys_event.h"
#include "Emu/RSX/RSXThread.h"
#include "Thread.h"
#include "Utilities/JIT.h"
#include <typeinfo>
@ -104,6 +105,32 @@ void fmt_class_string<std::thread::id>::format(std::string& out, u64 arg)
out += ss.str();
}
std::string dump_useful_thread_info()
{
thread_local volatile bool guard = false;
std::string result;
// In case the dumping function was the cause for the exception/access violation
// Avoid recursion
if (std::exchange(guard, true))
{
return result;
}
if (auto cpu = get_current_cpu_thread())
{
result = cpu->dump_all();
}
else if (auto render = rsx::get_current_renderer(); render && render->is_current_thread())
{
result = render->dump_regs();
}
guard = false;
return result;
}
#ifndef _WIN32
bool IsDebuggerPresent()
{
@ -1531,7 +1558,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) no
{
if (!g_tls_access_violation_recovered)
{
vm_log.notice("\n%s", cpu->dump_all());
vm_log.notice("\n%s", dump_useful_thread_info());
vm_log.error("Access violation %s location 0x%x (%s) [type=u%u]", is_writing ? "writing" : "reading", addr, (is_writing && vm::check_addr(addr)) ? "read-only memory" : "unmapped memory", d_size * 8);
}
@ -1560,9 +1587,9 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) no
Emu.Pause();
if (cpu && !g_tls_access_violation_recovered)
if (!g_tls_access_violation_recovered)
{
vm_log.notice("\n%s", cpu->dump_all());
vm_log.notice("\n%s", dump_useful_thread_info());
}
// Note: a thread may access violate more than once after hack_alloc recovery
@ -1647,10 +1674,7 @@ static LONG exception_filter(PEXCEPTION_POINTERS pExp) noexcept
{
fmt::append(msg, "Emu Thread Name: '%s'.\n", thread_ctrl::get_name());
if (const auto cpu = get_current_cpu_thread())
{
sys_log.notice("\n%s", cpu->dump_all());
}
sys_log.notice("\n%s", dump_useful_thread_info());
}
// TODO: Report full thread name if not an emu thread
@ -1775,16 +1799,12 @@ static void signal_handler(int sig, siginfo_t* info, void* uct) noexcept
}
}
if (const auto cpu = get_current_cpu_thread())
{
sys_log.notice("\n%s", cpu->dump_all());
}
std::string msg = fmt::format("Segfault %s location %p at %p.\n", cause, info->si_addr, RIP(context));
if (thread_ctrl::get_current())
{
fmt::append(msg, "Emu Thread Name: '%s'.\n", thread_ctrl::get_name());
sys_log.notice("\n%s", dump_useful_thread_info());
}
// TODO: Report full thread name if not an emu thread
@ -2391,6 +2411,11 @@ u64 thread_base::get_cycles()
[[noreturn]] void thread_ctrl::emergency_exit(std::string_view reason)
{
if (std::string info = dump_useful_thread_info(); !info.empty())
{
sys_log.notice("\%s", info);
}
sig_log.fatal("Thread terminated due to fatal error: %s", reason);
std::fprintf(stderr, "Thread '%s' terminated due to fatal error: %s\n", g_tls_log_prefix().c_str(), std::string(reason).c_str());

View File

@ -531,7 +531,7 @@ void cpu_thread::operator()()
{
if (_this)
{
sys_log.warning("CPU Thread '%s' terminated abnormally:\n%s", name, _this->dump_all());
sys_log.warning("CPU Thread '%s' terminated abnormally!", name);
cleanup();
}
}

View File

@ -10,6 +10,7 @@
#include "Capture/rsx_capture.h"
#include "rsx_methods.h"
#include "rsx_utils.h"
#include "gcm_printing.h"
#include "Emu/Cell/lv2/sys_event.h"
#include "Emu/Cell/Modules/cellGcmSys.h"
#include "Overlays/overlay_perf_metrics.h"
@ -469,7 +470,7 @@ namespace rsx
if (capture_current_frame)
{
u32 element_count = rsx::method_registers.current_draw_clause.get_elements_count();
capture_frame("Draw " + rsx::to_string(rsx::method_registers.current_draw_clause.primitive) + std::to_string(element_count));
capture_frame(fmt::format("Draw %s %d", rsx::method_registers.current_draw_clause.primitive, element_count));
}
}
@ -524,8 +525,6 @@ namespace rsx
g_fxo->get<rsx::dma_manager>()->init();
on_init_thread();
method_registers.init();
if (!zcull_ctrl)
{
//Backend did not provide an implementation, provide NULL object
@ -2018,11 +2017,13 @@ namespace rsx
void thread::init(u32 ctrlAddress)
{
method_registers.init();
dma_address = ctrlAddress;
ctrl = vm::_ptr<RsxDmaControl>(ctrlAddress);
flip_status = CELL_GCM_DISPLAY_FLIP_STATUS_DONE;
memset(display_buffers, 0, sizeof(display_buffers));
std::memset(display_buffers, 0, sizeof(display_buffers));
on_init_rsx();
m_rsx_thread_exiting = false;
@ -2565,6 +2566,18 @@ namespace rsx
recovered_fifo_cmds_history.push({fifo_ctrl->last_cmd(), current_time});
}
std::vector<std::pair<u32, u32>> thread::dump_callstack() const
{
std::vector<std::pair<u32, u32>> result;
if (u32 addr = fifo_ret_addr; addr != RSX_CALL_STACK_EMPTY)
{
result.emplace_back(addr, 0);
}
return result;
}
void thread::fifo_wake_delay(u64 div)
{
// TODO: Nanoseconds accuracy
@ -2626,6 +2639,48 @@ namespace rsx
return fifo_ctrl->last_cmd();
}
void invalid_method(thread*, u32, u32);
std::string thread::dump_regs() const
{
std::string result;
for (u32 i = 0; i < 1 << 14; i++)
{
if (rsx::methods[i] == &invalid_method)
{
continue;
}
switch (i)
{
case NV4097_NO_OPERATION:
case NV4097_INVALIDATE_L2:
case NV4097_INVALIDATE_VERTEX_FILE:
case NV4097_INVALIDATE_VERTEX_CACHE_FILE:
case NV4097_INVALIDATE_ZCULL:
case NV4097_WAIT_FOR_IDLE:
case NV4097_PM_TRIGGER:
case NV4097_ZCULL_SYNC:
continue;
default:
{
if (i >= NV308A_COLOR && i < NV3089_SET_OBJECT)
{
continue;
}
break;
}
}
fmt::append(result, "[%04x] %s\n", i, ensure(rsx::get_pretty_printing_function(i))(i, method_registers.registers[i]));
}
return result;
}
flags32_t thread::read_barrier(u32 memory_address, u32 memory_range, bool unconditional)
{
flags32_t zcull_flags = (unconditional)? reports::sync_none : reports::sync_defer_copy;

View File

@ -615,6 +615,8 @@ namespace rsx
// FIFO
public:
std::unique_ptr<FIFO::FIFO_control> fifo_ctrl;
std::vector<std::pair<u32, u32>> dump_callstack() const;
protected:
FIFO::flattening_helper m_flattener;
u32 fifo_ret_addr = RSX_CALL_STACK_EMPTY;
@ -652,6 +654,8 @@ namespace rsx
void recover_fifo();
static void fifo_wake_delay(u64 div = 1);
u32 get_fifo_cmd() const;
std::string dump_regs() const;
// Performance approximation counters
struct

File diff suppressed because it is too large Load Diff

View File

@ -466,12 +466,6 @@ enum
CELL_GCM_DISPLAY_FLIP_STATUS_WAITING = 1,
};
enum
{
CELL_GCM_LOCATION_LOCAL = 0,
CELL_GCM_LOCATION_MAIN = 1,
};
enum
{
CELL_GCM_FREQUENCY_MODULO = 1,
@ -511,7 +505,7 @@ enum
};
// GCM Texture
enum
enum CellGcmTexture : u32
{
// Color Flag
CELL_GCM_TEXTURE_B8 = 0x81,
@ -815,8 +809,11 @@ enum
};
// GPU Class Handles
enum
enum CellGcmLocation : u32
{
CELL_GCM_LOCATION_LOCAL = 0,
CELL_GCM_LOCATION_MAIN = 1,
CELL_GCM_CONTEXT_DMA_MEMORY_FRAME_BUFFER = 0xFEED0000, // Local memory
CELL_GCM_CONTEXT_DMA_MEMORY_HOST_BUFFER = 0xFEED0001, // Main memory
CELL_GCM_CONTEXT_DMA_REPORT_LOCATION_LOCAL = 0x66626660,
@ -830,7 +827,7 @@ enum
CELL_GCM_CONTEXT_DMA_DEVICE_R = 0x56616661
};
enum
enum CellGcmMethod : u16
{
// NV40_CHANNEL_DMA (NV406E)
NV406E_SET_REFERENCE = 0x00000050 >> 2,

View File

@ -6,62 +6,69 @@
namespace
{
constexpr u32 opcode_list[] = {NV4097_SET_VIEWPORT_HORIZONTAL, NV4097_SET_VIEWPORT_VERTICAL,
NV4097_SET_SCISSOR_HORIZONTAL, NV4097_SET_SCISSOR_VERTICAL, NV4097_SET_SURFACE_CLIP_HORIZONTAL,
NV4097_SET_SURFACE_CLIP_VERTICAL, NV4097_SET_CLEAR_RECT_HORIZONTAL,
NV4097_SET_CLEAR_RECT_VERTICAL, NV3089_CLIP_POINT, NV3089_CLIP_SIZE, NV3089_IMAGE_OUT_POINT,
NV3089_IMAGE_OUT_SIZE, NV3089_IMAGE_IN_SIZE, NV3062_SET_PITCH, NV308A_POINT,
NV4097_SET_DEPTH_TEST_ENABLE, NV4097_SET_DEPTH_MASK, NV4097_SET_ALPHA_TEST_ENABLE,
NV4097_SET_STENCIL_TEST_ENABLE, NV4097_SET_RESTART_INDEX_ENABLE,
NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE, NV4097_SET_LOGIC_OP_ENABLE, NV4097_SET_DITHER_ENABLE,
NV4097_SET_BLEND_ENABLE, NV4097_SET_LINE_SMOOTH_ENABLE, NV4097_SET_POLY_OFFSET_POINT_ENABLE,
NV4097_SET_POLY_OFFSET_LINE_ENABLE, NV4097_SET_POLY_OFFSET_FILL_ENABLE,
NV4097_SET_CULL_FACE_ENABLE, NV4097_SET_POLY_SMOOTH_ENABLE,
NV4097_SET_TWO_SIDED_STENCIL_TEST_ENABLE, NV4097_SET_TWO_SIDE_LIGHT_EN,
NV4097_SET_RESTART_INDEX, NV4097_SET_SURFACE_COLOR_AOFFSET, NV4097_SET_SURFACE_COLOR_BOFFSET,
NV4097_SET_SURFACE_COLOR_COFFSET, NV4097_SET_SURFACE_COLOR_DOFFSET, NV4097_SET_SURFACE_PITCH_A,
NV4097_SET_SURFACE_PITCH_B, NV4097_SET_SURFACE_PITCH_C, NV4097_SET_SURFACE_PITCH_D,
NV4097_SET_SURFACE_ZETA_OFFSET, NV4097_SET_SURFACE_PITCH_Z,
NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK, NV4097_SET_SHADER_CONTROL,
NV4097_SET_VERTEX_DATA_BASE_OFFSET, NV4097_SET_INDEX_ARRAY_ADDRESS,
NV4097_SET_VERTEX_DATA_BASE_INDEX, NV4097_SET_SHADER_PROGRAM,
NV4097_SET_TRANSFORM_PROGRAM_START, NV406E_SET_CONTEXT_DMA_SEMAPHORE, NV406E_SEMAPHORE_OFFSET, NV4097_SET_SEMAPHORE_OFFSET,
NV3089_IMAGE_IN_OFFSET, NV3062_SET_OFFSET_DESTIN, NV309E_SET_OFFSET, NV3089_DS_DX, NV3089_DT_DY,
NV0039_PITCH_IN, NV0039_PITCH_OUT, NV0039_LINE_LENGTH_IN, NV0039_LINE_COUNT, NV0039_OFFSET_OUT,
NV0039_OFFSET_IN, NV4097_SET_VERTEX_ATTRIB_INPUT_MASK, NV4097_SET_FREQUENCY_DIVIDER_OPERATION,
NV4097_SET_DEPTH_BOUNDS_MIN, NV4097_SET_DEPTH_BOUNDS_MAX, NV4097_SET_FOG_PARAMS,
NV4097_SET_FOG_PARAMS + 1, NV4097_SET_CLIP_MIN, NV4097_SET_CLIP_MAX,
NV4097_SET_POLYGON_OFFSET_SCALE_FACTOR, NV4097_SET_POLYGON_OFFSET_BIAS,
NV4097_SET_VIEWPORT_SCALE, NV4097_SET_VIEWPORT_SCALE + 1, NV4097_SET_VIEWPORT_SCALE + 2,
NV4097_SET_VIEWPORT_SCALE + 3, NV4097_SET_VIEWPORT_OFFSET, NV4097_SET_VIEWPORT_OFFSET + 1,
NV4097_SET_VIEWPORT_OFFSET + 2, NV4097_SET_VIEWPORT_OFFSET + 3, NV4097_SET_DEPTH_FUNC,
NV4097_SET_STENCIL_FUNC, NV4097_SET_BACK_STENCIL_FUNC, NV4097_SET_STENCIL_OP_FAIL,
NV4097_SET_STENCIL_OP_ZFAIL, NV4097_SET_STENCIL_OP_ZPASS, NV4097_SET_BACK_STENCIL_OP_FAIL,
NV4097_SET_BACK_STENCIL_OP_ZFAIL, NV4097_SET_BACK_STENCIL_OP_ZPASS, NV4097_SET_LOGIC_OP,
NV4097_SET_FRONT_FACE, NV4097_SET_CULL_FACE, NV4097_SET_SURFACE_COLOR_TARGET,
NV4097_SET_FOG_MODE, NV4097_SET_ALPHA_FUNC, NV4097_SET_BEGIN_END, NV3089_SET_OPERATION,
NV3089_SET_COLOR_FORMAT, NV3089_SET_CONTEXT_SURFACE, NV3062_SET_COLOR_FORMAT,
NV4097_SET_STENCIL_FUNC_REF, NV4097_SET_BACK_STENCIL_FUNC_REF, NV4097_SET_STENCIL_FUNC_MASK,
NV4097_SET_BACK_STENCIL_FUNC_MASK, NV4097_SET_ALPHA_REF, NV4097_SET_COLOR_CLEAR_VALUE,
NV4097_SET_STENCIL_MASK, NV4097_SET_BACK_STENCIL_MASK, NV4097_SET_BLEND_EQUATION,
NV4097_SET_BLEND_FUNC_SFACTOR, NV4097_SET_BLEND_FUNC_DFACTOR, NV4097_SET_COLOR_MASK,
NV4097_SET_SHADER_WINDOW, NV4097_SET_BLEND_ENABLE_MRT, NV4097_SET_USER_CLIP_PLANE_CONTROL,
NV4097_SET_LINE_WIDTH, NV4097_SET_SURFACE_FORMAT, NV4097_SET_WINDOW_OFFSET,
NV4097_SET_ZSTENCIL_CLEAR_VALUE, NV4097_SET_INDEX_ARRAY_DMA, NV4097_SET_CONTEXT_DMA_COLOR_A,
NV4097_SET_CONTEXT_DMA_COLOR_B, NV4097_SET_CONTEXT_DMA_COLOR_C, NV4097_SET_CONTEXT_DMA_COLOR_D,
NV4097_SET_CONTEXT_DMA_ZETA, NV3089_SET_CONTEXT_DMA_IMAGE, NV3062_SET_CONTEXT_DMA_IMAGE_DESTIN,
NV309E_SET_CONTEXT_DMA_IMAGE, NV0039_SET_CONTEXT_DMA_BUFFER_OUT,
NV0039_SET_CONTEXT_DMA_BUFFER_IN, NV4097_SET_CONTEXT_DMA_REPORT, NV3089_IMAGE_IN_FORMAT,
NV309E_SET_FORMAT, NV0039_FORMAT, NV4097_SET_BLEND_COLOR2, NV4097_SET_BLEND_COLOR,
NV3089_IMAGE_IN, NV4097_NO_OPERATION, NV4097_INVALIDATE_VERTEX_CACHE_FILE,
NV4097_INVALIDATE_VERTEX_FILE, NV4097_SET_ANTI_ALIASING_CONTROL, NV4097_SET_FRONT_POLYGON_MODE,
NV4097_SET_BACK_POLYGON_MODE,
EXPAND_RANGE_16(0, DECLARE_VERTEX_DATA_ARRAY_FORMAT)
EXPAND_RANGE_16(0, DECLARE_VERTEX_DATA_ARRAY_OFFSET)
EXPAND_RANGE_32(0, DECLARE_TRANSFORM_CONSTANT) NV4097_SET_TRANSFORM_CONSTANT_LOAD,
NV4097_DRAW_ARRAYS, NV4097_DRAW_INDEX_ARRAY,
EXPAND_RANGE_512(0, DECLARE_TRANSFORM_PROGRAM) NV4097_SET_TRANSFORM_PROGRAM_LOAD};
NV4097_SET_SCISSOR_HORIZONTAL, NV4097_SET_SCISSOR_VERTICAL, NV4097_SET_SURFACE_CLIP_HORIZONTAL,
NV4097_SET_SURFACE_CLIP_VERTICAL, NV4097_SET_CLEAR_RECT_HORIZONTAL,
NV4097_SET_CLEAR_RECT_VERTICAL, NV3089_CLIP_POINT, NV3089_CLIP_SIZE, NV3089_IMAGE_OUT_POINT,
NV3089_IMAGE_OUT_SIZE, NV3089_IMAGE_IN_SIZE, NV3062_SET_PITCH, NV308A_POINT,
NV4097_SET_DEPTH_TEST_ENABLE, NV4097_SET_DEPTH_MASK, NV4097_SET_ALPHA_TEST_ENABLE,
NV4097_SET_STENCIL_TEST_ENABLE, NV4097_SET_RESTART_INDEX_ENABLE,
NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE, NV4097_SET_LOGIC_OP_ENABLE, NV4097_SET_DITHER_ENABLE,
NV4097_SET_BLEND_ENABLE, NV4097_SET_LINE_SMOOTH_ENABLE, NV4097_SET_POLY_OFFSET_POINT_ENABLE,
NV4097_SET_POLY_OFFSET_LINE_ENABLE, NV4097_SET_POLY_OFFSET_FILL_ENABLE,
NV4097_SET_CULL_FACE_ENABLE, NV4097_SET_POLY_SMOOTH_ENABLE,
NV4097_SET_TWO_SIDED_STENCIL_TEST_ENABLE, NV4097_SET_TWO_SIDE_LIGHT_EN,
NV4097_SET_RESTART_INDEX, NV4097_SET_SURFACE_COLOR_AOFFSET, NV4097_SET_SURFACE_COLOR_BOFFSET,
NV4097_SET_SURFACE_COLOR_COFFSET, NV4097_SET_SURFACE_COLOR_DOFFSET, NV4097_SET_SURFACE_PITCH_A,
NV4097_SET_SURFACE_PITCH_B, NV4097_SET_SURFACE_PITCH_C, NV4097_SET_SURFACE_PITCH_D,
NV4097_SET_SURFACE_ZETA_OFFSET, NV4097_SET_SURFACE_PITCH_Z,
NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK, NV4097_SET_SHADER_CONTROL,
NV4097_SET_VERTEX_DATA_BASE_OFFSET, NV4097_SET_INDEX_ARRAY_ADDRESS,
NV4097_SET_VERTEX_DATA_BASE_INDEX, NV4097_SET_SHADER_PROGRAM,
NV4097_SET_TRANSFORM_PROGRAM_START, NV406E_SET_CONTEXT_DMA_SEMAPHORE, NV406E_SEMAPHORE_OFFSET, NV4097_SET_SEMAPHORE_OFFSET,
NV3089_IMAGE_IN_OFFSET, NV3062_SET_OFFSET_DESTIN, NV309E_SET_OFFSET, NV3089_DS_DX, NV3089_DT_DY,
NV0039_PITCH_IN, NV0039_PITCH_OUT, NV0039_LINE_LENGTH_IN, NV0039_LINE_COUNT, NV0039_OFFSET_OUT,
NV0039_OFFSET_IN, NV4097_SET_VERTEX_ATTRIB_INPUT_MASK, NV4097_SET_FREQUENCY_DIVIDER_OPERATION,
NV4097_SET_DEPTH_BOUNDS_MIN, NV4097_SET_DEPTH_BOUNDS_MAX, NV4097_SET_FOG_PARAMS,
NV4097_SET_FOG_PARAMS + 1, NV4097_SET_CLIP_MIN, NV4097_SET_CLIP_MAX,
NV4097_SET_POLYGON_OFFSET_SCALE_FACTOR, NV4097_SET_POLYGON_OFFSET_BIAS,
NV4097_SET_VIEWPORT_SCALE, NV4097_SET_VIEWPORT_SCALE + 1, NV4097_SET_VIEWPORT_SCALE + 2,
NV4097_SET_VIEWPORT_SCALE + 3, NV4097_SET_VIEWPORT_OFFSET, NV4097_SET_VIEWPORT_OFFSET + 1,
NV4097_SET_VIEWPORT_OFFSET + 2, NV4097_SET_VIEWPORT_OFFSET + 3, NV4097_SET_DEPTH_FUNC,
NV4097_SET_STENCIL_FUNC, NV4097_SET_BACK_STENCIL_FUNC, NV4097_SET_STENCIL_OP_FAIL,
NV4097_SET_STENCIL_OP_ZFAIL, NV4097_SET_STENCIL_OP_ZPASS, NV4097_SET_BACK_STENCIL_OP_FAIL,
NV4097_SET_BACK_STENCIL_OP_ZFAIL, NV4097_SET_BACK_STENCIL_OP_ZPASS, NV4097_SET_LOGIC_OP,
NV4097_SET_FRONT_FACE, NV4097_SET_CULL_FACE, NV4097_SET_SURFACE_COLOR_TARGET,
NV4097_SET_FOG_MODE, NV4097_SET_ALPHA_FUNC, NV4097_SET_BEGIN_END, NV3089_SET_OPERATION,
NV3089_SET_COLOR_FORMAT, NV3089_SET_CONTEXT_SURFACE, NV3062_SET_COLOR_FORMAT,
NV4097_SET_STENCIL_FUNC_REF, NV4097_SET_BACK_STENCIL_FUNC_REF, NV4097_SET_STENCIL_FUNC_MASK,
NV4097_SET_BACK_STENCIL_FUNC_MASK, NV4097_SET_ALPHA_REF, NV4097_SET_COLOR_CLEAR_VALUE,
NV4097_SET_STENCIL_MASK, NV4097_SET_BACK_STENCIL_MASK, NV4097_SET_BLEND_EQUATION,
NV4097_SET_BLEND_FUNC_SFACTOR, NV4097_SET_BLEND_FUNC_DFACTOR, NV4097_SET_COLOR_MASK,
NV4097_SET_SHADER_WINDOW, NV4097_SET_BLEND_ENABLE_MRT, NV4097_SET_USER_CLIP_PLANE_CONTROL,
NV4097_SET_LINE_WIDTH, NV4097_SET_SURFACE_FORMAT, NV4097_SET_WINDOW_OFFSET,
NV4097_SET_ZSTENCIL_CLEAR_VALUE, NV4097_SET_INDEX_ARRAY_DMA, NV4097_SET_CONTEXT_DMA_COLOR_A,
NV4097_SET_CONTEXT_DMA_COLOR_B, NV4097_SET_CONTEXT_DMA_COLOR_C, NV4097_SET_CONTEXT_DMA_COLOR_D,
NV4097_SET_CONTEXT_DMA_ZETA, NV3089_SET_CONTEXT_DMA_IMAGE, NV3062_SET_CONTEXT_DMA_IMAGE_DESTIN,
NV309E_SET_CONTEXT_DMA_IMAGE, NV0039_SET_CONTEXT_DMA_BUFFER_OUT,
NV0039_SET_CONTEXT_DMA_BUFFER_IN, NV4097_SET_CONTEXT_DMA_REPORT, NV3089_IMAGE_IN_FORMAT,
NV309E_SET_FORMAT, NV0039_FORMAT, NV4097_SET_BLEND_COLOR2, NV4097_SET_BLEND_COLOR,
NV3089_IMAGE_IN, NV4097_NO_OPERATION, NV4097_INVALIDATE_VERTEX_CACHE_FILE,
NV4097_INVALIDATE_VERTEX_FILE, NV4097_SET_ANTI_ALIASING_CONTROL, NV4097_SET_FRONT_POLYGON_MODE,
NV4097_SET_BACK_POLYGON_MODE, NV406E_SET_REFERENCE, NV406E_SEMAPHORE_RELEASE, NV406E_SEMAPHORE_ACQUIRE,
NV4097_SET_ZCULL_EN, NV4097_SET_ZCULL_STATS_ENABLE, NV4097_SET_ZPASS_PIXEL_COUNT_ENABLE,
EXPAND_RANGE_16(0, DECLARE_VERTEX_DATA_ARRAY_FORMAT)
EXPAND_RANGE_16(0, DECLARE_VERTEX_DATA_ARRAY_OFFSET)
EXPAND_RANGE_32(0, DECLARE_TRANSFORM_CONSTANT) NV4097_SET_TRANSFORM_CONSTANT_LOAD,
NV4097_DRAW_ARRAYS, NV4097_DRAW_INDEX_ARRAY,
EXPAND_RANGE_32(0, DECLARE_TRANSFORM_PROGRAM) NV4097_SET_TRANSFORM_PROGRAM_LOAD,
EXPAND_RANGE_16(0, DECLARE_TEXTURE_OFFSET) EXPAND_RANGE_16(0, DECLARE_TEXTURE_FORMAT)
EXPAND_RANGE_16(0, DECLARE_TEXTURE_IMAGE_RECT) EXPAND_RANGE_16(0, DECLARE_TEXTURE_CONTROL0)
EXPAND_RANGE_16(0, DECLARE_TEXTURE_CONTROL3) EXPAND_RANGE_4(0, DECLARE_VERTEX_TEXTURE_CONTROL0)};
const std::unordered_map<u32, const char*> methods_name = {
#define KEY_STR(key) { key, #key }
const std::unordered_map<u32, std::string_view> methods_name =
{
{NV406E_SET_REFERENCE, "NV406E_SET_REFERENCE"},
{NV406E_SET_CONTEXT_DMA_SEMAPHORE, "NV406E_SET_CONTEXT_DMA_SEMAPHORE"},
{NV406E_SEMAPHORE_OFFSET, "NV406E_SEMAPHORE_OFFSET"},
@ -321,7 +328,37 @@ namespace
{NV4097_SET_EDGE_FLAG, "NV4097_SET_EDGE_FLAG"},
{NV4097_SET_USER_CLIP_PLANE_CONTROL, "NV4097_SET_USER_CLIP_PLANE_CONTROL"},
{NV4097_SET_POLYGON_STIPPLE, "NV4097_SET_POLYGON_STIPPLE"},
{NV4097_SET_POLYGON_STIPPLE_PATTERN, "NV4097_SET_POLYGON_STIPPLE_PATTERN"},
KEY_STR(NV4097_SET_POLYGON_STIPPLE_PATTERN),
KEY_STR(NV4097_SET_POLYGON_STIPPLE_PATTERN + 1),
KEY_STR(NV4097_SET_POLYGON_STIPPLE_PATTERN + 2),
KEY_STR(NV4097_SET_POLYGON_STIPPLE_PATTERN + 3),
KEY_STR(NV4097_SET_POLYGON_STIPPLE_PATTERN + 4),
KEY_STR(NV4097_SET_POLYGON_STIPPLE_PATTERN + 5),
KEY_STR(NV4097_SET_POLYGON_STIPPLE_PATTERN + 6),
KEY_STR(NV4097_SET_POLYGON_STIPPLE_PATTERN + 7),
KEY_STR(NV4097_SET_POLYGON_STIPPLE_PATTERN + 8),
KEY_STR(NV4097_SET_POLYGON_STIPPLE_PATTERN + 9),
KEY_STR(NV4097_SET_POLYGON_STIPPLE_PATTERN + 10),
KEY_STR(NV4097_SET_POLYGON_STIPPLE_PATTERN + 11),
KEY_STR(NV4097_SET_POLYGON_STIPPLE_PATTERN + 12),
KEY_STR(NV4097_SET_POLYGON_STIPPLE_PATTERN + 13),
KEY_STR(NV4097_SET_POLYGON_STIPPLE_PATTERN + 14),
KEY_STR(NV4097_SET_POLYGON_STIPPLE_PATTERN + 15),
KEY_STR(NV4097_SET_POLYGON_STIPPLE_PATTERN + 16),
KEY_STR(NV4097_SET_POLYGON_STIPPLE_PATTERN + 17),
KEY_STR(NV4097_SET_POLYGON_STIPPLE_PATTERN + 18),
KEY_STR(NV4097_SET_POLYGON_STIPPLE_PATTERN + 19),
KEY_STR(NV4097_SET_POLYGON_STIPPLE_PATTERN + 20),
KEY_STR(NV4097_SET_POLYGON_STIPPLE_PATTERN + 21),
KEY_STR(NV4097_SET_POLYGON_STIPPLE_PATTERN + 22),
KEY_STR(NV4097_SET_POLYGON_STIPPLE_PATTERN + 23),
KEY_STR(NV4097_SET_POLYGON_STIPPLE_PATTERN + 24),
KEY_STR(NV4097_SET_POLYGON_STIPPLE_PATTERN + 25),
KEY_STR(NV4097_SET_POLYGON_STIPPLE_PATTERN + 26),
KEY_STR(NV4097_SET_POLYGON_STIPPLE_PATTERN + 28),
KEY_STR(NV4097_SET_POLYGON_STIPPLE_PATTERN + 29),
KEY_STR(NV4097_SET_POLYGON_STIPPLE_PATTERN + 30),
KEY_STR(NV4097_SET_POLYGON_STIPPLE_PATTERN + 31),
{NV4097_SET_VERTEX_DATA3F_M, "NV4097_SET_VERTEX_DATA3F_M"},
{NV4097_SET_VERTEX_DATA3F_M + 4 / 4, "NV4097_SET_VERTEX_DATA3F_M + 4"},
{NV4097_SET_VERTEX_DATA3F_M + 8 / 4, "NV4097_SET_VERTEX_DATA3F_M + 8"},
@ -853,149 +890,36 @@ namespace
{NV3089_IMAGE_IN_FORMAT, "NV3089_IMAGE_IN_FORMAT"},
{NV3089_IMAGE_IN_OFFSET, "NV3089_IMAGE_IN_OFFSET"},
{NV3089_IMAGE_IN, "NV3089_IMAGE_IN"},
{GCM_SET_DRIVER_OBJECT, "GCM_SET_DRIVER_OBJECT"},
{GCM_DRIVER_QUEUE, "GCM_DRIVER_QUEUE + 0x0"},
{GCM_DRIVER_QUEUE+1, "GCM_DRIVER_QUEUE + 0x4"},
{GCM_FLIP_HEAD, "GCM_FLIP_HEAD"},
{GCM_FLIP_HEAD+1, "GCM_FLIP_HEAD + 0x4"},
{GCM_SET_USER_COMMAND, "GCM_SET_USER_COMMAND"},
{GCM_FLIP_COMMAND, "GCM_FLIP_COMMAND"},
{GCM_SET_DRIVER_OBJECT, "SET_DRIVER_OBJECT"},
{GCM_DRIVER_QUEUE, "DRIVER_QUEUE + 0x0"},
{GCM_DRIVER_QUEUE+1, "DRIVER_QUEUE + 0x4"},
{GCM_FLIP_HEAD, "FLIP_HEAD"},
{GCM_FLIP_HEAD+1, "FLIP_HEAD + 0x4"},
{GCM_SET_USER_COMMAND, "SET_USER_COMMAND"},
{GCM_FLIP_COMMAND, "FLIP_COMMAND"},
};
#undef KEY_STR
}
std::string rsx::get_method_name(const u32 id)
{
auto found = methods_name.find(id);
if (found != methods_name.end()) {
return std::string("CELL_GCM_") + found->second;
const auto found = methods_name.find(id);
if (found != methods_name.end())
{
std::string prefix("CELL_GCM_"sv);
prefix.append(found->second.data(), found->second.size());
return prefix;
}
return fmt::format("Unknown/illegal method [0x%04x]", id << 2);
return fmt::format("Unnamed method 0x%04x", id);
}
// Various parameter pretty printing function
namespace
{
std::string ptr_to_string(u32 ptr)
{
return fmt::format("0x%08x", ptr);
}
std::string dma_mode(u32 arg)
{
switch (arg)
{
case CELL_GCM_LOCATION_LOCAL:
case CELL_GCM_CONTEXT_DMA_MEMORY_FRAME_BUFFER: return "Local memory";
case CELL_GCM_LOCATION_MAIN:
case CELL_GCM_CONTEXT_DMA_MEMORY_HOST_BUFFER: return "Main memory";
}
return "Error";
}
std::string texture_dimension(u8 dim)
{
switch (rsx::to_texture_dimension(dim))
{
case rsx::texture_dimension::dimension1d: return "1D";
case rsx::texture_dimension::dimension2d: return "2D";
case rsx::texture_dimension::dimension3d: return "3D";
}
return "";
}
std::string get_vertex_attribute_format(u8 type)
{
switch (rsx::to_vertex_base_type(type))
{
case rsx::vertex_base_type::s1: return "Signed short normalized";
case rsx::vertex_base_type::f: return "Float";
case rsx::vertex_base_type::sf: return "Half float";
case rsx::vertex_base_type::ub: return "Unsigned byte normalized";
case rsx::vertex_base_type::s32k: return "Signed short unormalized";
case rsx::vertex_base_type::cmp: return "CMP";
case rsx::vertex_base_type::ub256: return "Unsigned byte unormalized";
}
return "";
}
std::string unpack_vertex_format(u32 arg)
{
u32 frequency = arg >> 16;
u32 stride = (arg >> 8) & 0xff;
u32 size = (arg >> 4) & 0xf;
u32 type = arg & 0xf;
if (size == 0) return "(disabled)";
return "Type = " + get_vertex_attribute_format(type) + " size = " + std::to_string(size) +
" stride = " + std::to_string(stride) + " frequency = " + std::to_string(frequency);
}
std::string transform_constant(usz index, u32 arg)
{
return "Transform constant " + std::to_string(index) + ": " + std::to_string(arg) + "/" +
std::to_string(std::bit_cast<f32>(arg));
}
std::string texture_offset(usz index, u32 arg)
{
return "Texture " + std::to_string(index) + ": Offset @" + ptr_to_string(arg);
}
std::string texture_size(usz index, u32 arg)
{
return "Texture " + std::to_string(index) + ": width = " + std::to_string(arg & 0xffff) +
" height = " + std::to_string(arg >> 16);
}
static std::string get_texture_format_name(u32 format)
{
switch (format)
{
case CELL_GCM_TEXTURE_COMPRESSED_HILO8: return "CELL_GCM_TEXTURE_COMPRESSED_HILO8";
case CELL_GCM_TEXTURE_COMPRESSED_HILO_S8: return "CELL_GCM_TEXTURE_COMPRESSED_HILO_S8";
case CELL_GCM_TEXTURE_B8: return "CELL_GCM_TEXTURE_B8";
case CELL_GCM_TEXTURE_A1R5G5B5: return "CELL_GCM_TEXTURE_A1R5G5B5";
case CELL_GCM_TEXTURE_A4R4G4B4: return "CELL_GCM_TEXTURE_A4R4G4B4";
case CELL_GCM_TEXTURE_R5G6B5: return "CELL_GCM_TEXTURE_R5G6B5";
case CELL_GCM_TEXTURE_A8R8G8B8: return "CELL_GCM_TEXTURE_A8R8G8B8";
case CELL_GCM_TEXTURE_COMPRESSED_DXT1: return "CELL_GCM_TEXTURE_COMPRESSED_DXT1";
case CELL_GCM_TEXTURE_COMPRESSED_DXT23: return "CELL_GCM_TEXTURE_COMPRESSED_DXT23";
case CELL_GCM_TEXTURE_COMPRESSED_DXT45: return "CELL_GCM_TEXTURE_COMPRESSED_DXT45";
case CELL_GCM_TEXTURE_G8B8: return "CELL_GCM_TEXTURE_G8B8";
case CELL_GCM_TEXTURE_R6G5B5: return "CELL_GCM_TEXTURE_R6G5B5";
case CELL_GCM_TEXTURE_DEPTH24_D8: return "CELL_GCM_TEXTURE_DEPTH24_D8";
case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: return "CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT";
case CELL_GCM_TEXTURE_DEPTH16: return "CELL_GCM_TEXTURE_DEPTH16";
case CELL_GCM_TEXTURE_DEPTH16_FLOAT: return "CELL_GCM_TEXTURE_DEPTH16_FLOAT";
case CELL_GCM_TEXTURE_X16: return "CELL_GCM_TEXTURE_X16";
case CELL_GCM_TEXTURE_Y16_X16: return "CELL_GCM_TEXTURE_Y16_X16";
case CELL_GCM_TEXTURE_R5G5B5A1: return "CELL_GCM_TEXTURE_R5G5B5A1";
case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: return "CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT";
case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: return "CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT";
case CELL_GCM_TEXTURE_X32_FLOAT: return "CELL_GCM_TEXTURE_X32_FLOAT";
case CELL_GCM_TEXTURE_D1R5G5B5: return "CELL_GCM_TEXTURE_D1R5G5B5";
case CELL_GCM_TEXTURE_D8R8G8B8: return "CELL_GCM_TEXTURE_D8R8G8B8";
case CELL_GCM_TEXTURE_Y16_X16_FLOAT: return "CELL_GCM_TEXTURE_Y16_X16_FLOAT";
case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: return "CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8";
case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: return "CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8";
}
return "Error";
}
std::string texture_format(usz index, u32 arg)
{
int format = ((arg >> 8) & 0xFF);
return "Texture " + std::to_string(index) + ": location = " + ptr_to_string((arg & 0x3) - 1) +
(((arg >> 2) & 0x1) ? " cubemap " : "") + " border type = " +
std::to_string((arg >> 3) & 0x1) + " dimension = " + std::to_string((arg >> 4) & 0xF) +
" format = " +
get_texture_format_name(format & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN)) +
((format & CELL_GCM_TEXTURE_LN) ? "" : " swizzled") +
((format & CELL_GCM_TEXTURE_UN) ? " unormalized coordinates" : "") + " mipmap levels = " +
std::to_string((arg >> 16) & 0xFFFF);
}
/*
std::string get_texture_wrap_mode(u8 wrap)
{
switch (rsx::to_texture_wrap_mode(wrap))
@ -1012,22 +936,6 @@ namespace
return "Error";
}
std::string get_zfunc_name(u8 op)
{
switch (op)
{
case 0: return "Never";
case 1: return "Less";
case 2: return "Equal";
case 3: return "LEqual";
case 4: return "Greater";
case 5: return "NotEqual";
case 6: return "GreaterOrEqual";
case 7: return "Always";
}
return "Error";
}
std::string texture_address(usz index, u32 arg)
{
return "Texture " + std::to_string(index) + ": wrap_s = " + get_texture_wrap_mode(arg & 0xF) +
@ -1038,36 +946,6 @@ namespace
std::to_string((arg >> 4) & 0xF) + " signed remap = " + std::to_string((arg >> 24) & 0xF);
}
std::string get_texture_max_aniso_name(u8 aniso)
{
switch (rsx::to_texture_max_anisotropy(aniso))
{
case rsx::texture_max_anisotropy::x1: return "1";
case rsx::texture_max_anisotropy::x2: return "2";
case rsx::texture_max_anisotropy::x4: return "4";
case rsx::texture_max_anisotropy::x6: return "6";
case rsx::texture_max_anisotropy::x8: return "8";
case rsx::texture_max_anisotropy::x10: return "10";
case rsx::texture_max_anisotropy::x12: return "12";
case rsx::texture_max_anisotropy::x16: return "16";
}
return "Error";
}
std::string texture_control0(usz index, u32 arg)
{
std::string result = "Texture " + std::to_string(index);
if ((arg >> 31) & 0x1) {
result += " min lod = " + std::to_string((arg >> 19) & 0xFFF) + " max lod = " +
std::to_string((arg >> 7) & 0xFFF) + " max aniso = " +
get_texture_max_aniso_name((arg >> 4) & 0x7) + " alpha kill = " +
(((arg >> 2) & 0x1) ? "true" : "false");
}
else
result += " (disabled)";
return result;
}
std::string get_remap_channel(u8 op) noexcept
{
switch (op)
@ -1088,12 +966,6 @@ namespace
get_remap_channel((arg >> 6) & 0x3);
}
std::string texture_control3(usz index, u32 arg)
{
return "Texture " + std::to_string(index) + " depth = " + std::to_string(arg >> 20) +
" pitch = " + std::to_string(arg & 0xFFFFF);
}
std::string texture_border_color(usz index, u32 arg)
{
return "Texture " + std::to_string(index) + " border color = " + std::to_string(arg);
@ -1107,32 +979,33 @@ namespace
std::to_string((arg >> 13) & 0xF) + " a_signed = " + std::to_string((arg >> 28) & 0x1) +
" r_signed = " + std::to_string((arg >> 29) & 0x1) + " g_signed = " +
std::to_string((arg >> 30) & 0x1) + " b_signed = " + std::to_string((arg >> 31) & 0x1);
}
}*/
namespace
{
template <u32 opcode>
auto register_pretty_printing(u32 arg)
template <u32 Opcode>
std::string register_pretty_function(u32 /*id*/, u32 arg)
{
typename rsx::registers_decoder<opcode>::decoded_type decoded_value(arg);
return rsx::registers_decoder<opcode>::dump(std::move(arg));
return rsx::registers_decoder<Opcode>::dump(arg);
}
template <typename T, T... Index>
auto create_printing_table(std::integer_sequence<T, Index...> seq)
std::array<std::string(*)(u32, u32), 1 << 14> create_printing_table(std::integer_sequence<T, Index...> seq)
{
std::unordered_map<u32, std::string (*)(u32)> result;
(result.insert({
{opcode_list[Index * 5 + 0], &register_pretty_printing<opcode_list[Index * 5 + 0]>},
{opcode_list[Index * 5 + 1], &register_pretty_printing<opcode_list[Index * 5 + 1]>},
{opcode_list[Index * 5 + 2], &register_pretty_printing<opcode_list[Index * 5 + 2]>},
{opcode_list[Index * 5 + 3], &register_pretty_printing<opcode_list[Index * 5 + 3]>},
{opcode_list[Index * 5 + 4], &register_pretty_printing<opcode_list[Index * 5 + 4]>}}), ...);
std::array<std::string(*)(u32, u32), 1 << 14> result{};
((result[opcode_list[Index * 5 + 0]] = &register_pretty_function<opcode_list[Index * 5 + 0]>,
result[opcode_list[Index * 5 + 1]] = &register_pretty_function<opcode_list[Index * 5 + 1]>,
result[opcode_list[Index * 5 + 2]] = &register_pretty_function<opcode_list[Index * 5 + 2]>,
result[opcode_list[Index * 5 + 3]] = &register_pretty_function<opcode_list[Index * 5 + 3]>,
result[opcode_list[Index * 5 + 4]] = &register_pretty_function<opcode_list[Index * 5 + 4]>
), ...);
return result;
}
}
const std::unordered_map<u32, std::string (*)(u32)> printing_functions =
const auto printing_functions =
create_printing_table(std::make_index_sequence<std::size(opcode_list) / 5>());
static_assert(std::size(opcode_list) % 5 == 0);
@ -1141,8 +1014,6 @@ namespace
1) + " vertex starting from " + std::to_string(arg & 0xFFFFFF); } },
{ NV4097_DRAW_INDEX_ARRAY, [](u32 arg) -> std::string { return "Draw " + std::to_string((arg >>
24) + 1) + " index starting from " + std::to_string(arg & 0xFFFFFF); } },
{ NV4097_SET_SEMAPHORE_OFFSET, [](u32 arg) -> std::string { return "Semaphore: @ " +
ptr_to_string(arg); } },
{ NV4097_TEXTURE_READ_SEMAPHORE_RELEASE, [](u32 arg) -> std::string { return "Write semaphore
value " + std::to_string(arg); } },
{ NV4097_CLEAR_SURFACE, [](u32 arg) -> std::string { return "Clear surface " + std::string(arg &
@ -1151,12 +1022,20 @@ namespace
};*/
}
std::function<std::string(u32)> rsx::get_pretty_printing_function(u32 id)
std::add_pointer_t<std::string(u32, u32)> rsx::get_pretty_printing_function(u32 id)
{
auto found = printing_functions.find(id);
if (found != printing_functions.end()) {
return found->second;
const auto found = id < printing_functions.size() ? printing_functions[id] : nullptr;
if (found)
{
return found;
}
return [=](u32 v) { return fmt::format("%s : 0x%08x", rsx::get_method_name(id), v); };
return [](u32 id, u32 v)
{
const std::string name = rsx::get_method_name(id);
const std::string_view view = name, prefix = "CELL_GCM_"sv;
return fmt::format("%s: 0x%08x", name.starts_with("CELL_GCM_"sv) ? view.substr(prefix.size()) : view, v);
};
}

View File

@ -8,5 +8,5 @@ namespace rsx
{
std::string get_method_name(u32 id);
std::function<std::string(u32)> get_pretty_printing_function(u32 id);
std::add_pointer_t<std::string(u32, u32)> get_pretty_printing_function(u32 id);
}

File diff suppressed because it is too large Load Diff

View File

@ -25,7 +25,7 @@ namespace rsx
rsx->recover_fifo();
}
void trace_method(thread* rsx, u32 _reg, u32 arg)
static void trace_method(thread* rsx, u32 _reg, u32 arg)
{
// For unknown yet valid methods
rsx_log.trace("RSX method 0x%x (arg=0x%x)", _reg << 2, arg);

View File

@ -11,6 +11,7 @@
#include "Emu/System.h"
#include "Emu/IdManager.h"
#include "Emu/RSX/RSXThread.h"
#include "Emu/Cell/PPUDisAsm.h"
#include "Emu/Cell/PPUThread.h"
#include "Emu/Cell/SPUDisAsm.h"
@ -337,13 +338,32 @@ void debugger_frame::keyPressEvent(QKeyEvent* event)
}
}
rsx::thread* debugger_frame::get_rsx()
{
// m_rsx is raw pointer, when emulation is stopped it won't be cleared
// Therefore need to do invalidation checks manually
if (g_fxo->get<rsx::thread>() != m_rsx)
{
m_rsx = nullptr;
}
if (m_rsx && !m_rsx->ctrl)
{
m_rsx = nullptr;
}
return m_rsx;
}
void debugger_frame::UpdateUI()
{
UpdateUnitList();
const auto cpu = this->cpu.lock();
const auto rsx = this->get_rsx();
if (!cpu)
if (!cpu && !rsx)
{
if (m_last_pc != umax || !m_last_query_state.empty())
{
@ -351,10 +371,15 @@ void debugger_frame::UpdateUI()
m_last_pc = -1;
DoUpdate();
}
m_btn_run->setEnabled(false);
m_btn_step->setEnabled(false);
m_btn_step_over->setEnabled(false);
}
else if (rsx)
{
if (m_last_pc != rsx->ctrl->get || !m_last_query_state.empty())
{
m_last_query_state.clear();
m_last_pc = rsx->ctrl->get;
DoUpdate();
}
}
else
{
@ -387,6 +412,7 @@ void debugger_frame::UpdateUI()
}
Q_DECLARE_METATYPE(std::weak_ptr<cpu_thread>);
Q_DECLARE_METATYPE(::rsx::thread*);
void debugger_frame::UpdateUnitList()
{
@ -424,6 +450,13 @@ void debugger_frame::UpdateUnitList()
idm::select<named_thread<ppu_thread>>(on_select);
idm::select<named_thread<spu_thread>>(on_select);
if (auto render = g_fxo->get<rsx::thread>(); render && render->ctrl)
{
QVariant var_cpu = QVariant::fromValue<rsx::thread*>(render);
m_choice_units->addItem("RSX[0x55555555]", var_cpu);
if (old_cpu == var_cpu) m_choice_units->setCurrentIndex(m_choice_units->count() - 1);
}
}
OnSelectUnit();
@ -436,15 +469,22 @@ void debugger_frame::OnSelectUnit()
if (m_choice_units->count() < 1) return;
const auto weak = m_choice_units->currentData().value<std::weak_ptr<cpu_thread>>();
const auto render = m_choice_units->currentData().value<rsx::thread*>();
if (!weak.owner_before(cpu) && !cpu.owner_before(weak))
if (!render && !weak.owner_before(cpu) && !cpu.owner_before(weak))
{
// They match, nothing to do.
return;
}
if (render && render == this->get_rsx())
{
return;
}
m_disasm.reset();
cpu.reset();
m_rsx = nullptr;
if (!weak.expired())
{
@ -468,6 +508,10 @@ void debugger_frame::OnSelectUnit()
}
}
}
else
{
m_rsx = render;
}
EnableButtons(true);
@ -494,8 +538,9 @@ void debugger_frame::DoUpdate()
void debugger_frame::WritePanels()
{
const auto cpu = this->cpu.lock();
const auto rsx = this->get_rsx();
if (!cpu)
if (!cpu && !rsx)
{
m_misc_state->clear();
m_regs->clear();
@ -506,15 +551,15 @@ void debugger_frame::WritePanels()
loc = m_misc_state->verticalScrollBar()->value();
m_misc_state->clear();
m_misc_state->setText(qstr(cpu->dump_misc()));
m_misc_state->setText(qstr(rsx ? "" : cpu->dump_misc()));
m_misc_state->verticalScrollBar()->setValue(loc);
loc = m_regs->verticalScrollBar()->value();
m_regs->clear();
m_regs->setText(qstr(cpu->dump_regs()));
m_regs->setText(qstr(rsx ? rsx->dump_regs() : cpu->dump_regs()));
m_regs->verticalScrollBar()->setValue(loc);
Q_EMIT CallStackUpdateRequested(cpu->dump_callstack_list());
Q_EMIT CallStackUpdateRequested(rsx ? rsx->dump_callstack() : cpu->dump_callstack_list());
}
void debugger_frame::ShowGotoAddressDialog()
@ -581,16 +626,16 @@ void debugger_frame::ShowGotoAddressDialog()
u64 debugger_frame::EvaluateExpression(const QString& expression)
{
auto thread = cpu.lock();
if (!thread) return 0;
bool ok = false;
// Parse expression(or at least used to, was nuked to remove the need for QtJsEngine)
const QString fixed_expression = QRegExp("^[A-Fa-f0-9]+$").exactMatch(expression) ? "0x" + expression : expression;
const u64 res = static_cast<u64>(fixed_expression.toULong(&ok, 16));
return ok ? res : thread->get_pc();
if (ok) return res;
if (auto thread = get_rsx()) return thread->ctrl->get;
if (auto thread = cpu.lock()) return thread->get_pc();
return 0;
}
void debugger_frame::ClearBreakpoints()
@ -606,7 +651,11 @@ void debugger_frame::ClearCallStack()
void debugger_frame::ShowPC()
{
const auto cpu0 = cpu.lock();
m_debugger_list->ShowAddress(cpu0 ? cpu0->get_pc() : 0);
const u32 pc = get_rsx() ? +m_rsx->ctrl->get
: (cpu0 ? cpu0->get_pc() : 0);
m_debugger_list->ShowAddress(pc);
}
void debugger_frame::DoStep(bool stepOver)

View File

@ -20,6 +20,11 @@ class breakpoint_list;
class breakpoint_handler;
class call_stack_list;
namespace rsx
{
class thread;
}
class debugger_frame : public custom_dock_widget
{
Q_OBJECT
@ -50,6 +55,7 @@ class debugger_frame : public custom_dock_widget
std::shared_ptr<CPUDisAsm> m_disasm;
std::weak_ptr<cpu_thread> cpu;
rsx::thread* m_rsx = nullptr;
breakpoint_list* m_breakpoint_list;
breakpoint_handler* m_breakpoint_handler;
@ -58,6 +64,7 @@ class debugger_frame : public custom_dock_widget
std::shared_ptr<gui_settings> xgui_settings;
rsx::thread* get_rsx(); // Do not read m_rsx directy, use this instead.
public:
explicit debugger_frame(std::shared_ptr<gui_settings> settings, QWidget *parent = 0);

View File

@ -645,11 +645,12 @@ void rsx_debugger::GetMemory()
}
std::string dump;
u32 cmd_i = 0;
for (u32 i = 0; i < frame_debug.command_queue.size(); i++)
for (const auto& command : frame_debug.command_queue)
{
const std::string& str = rsx::get_pretty_printing_function(frame_debug.command_queue[i].first)(frame_debug.command_queue[i].second);
m_list_captured_frame->setItem(i, 0, new QTableWidgetItem(qstr(str)));
const std::string str = rsx::get_pretty_printing_function(command.first)(command.first, command.second);
m_list_captured_frame->setItem(cmd_i++, 0, new QTableWidgetItem(qstr(str)));
dump += str;
dump += '\n';
@ -739,93 +740,6 @@ void rsx_debugger::GetBuffers()
//m_buffer_tex->showImage(QImage(buffer, m_text_width, m_text_height, QImage::Format_RGB32));
}
const char* rsx_debugger::ParseGCMEnum(u32 value, u32 type)
{
switch(type)
{
case CELL_GCM_ENUM:
{
switch(value)
{
case 0x0200: return "Never";
case 0x0201: return "Less";
case 0x0202: return "Equal";
case 0x0203: return "Less or Equal";
case 0x0204: return "Greater";
case 0x0205: return "Not Equal";
case 0x0206: return "Greater or Equal";
case 0x0207: return "Always";
case 0x0: return "Zero";
case 0x1: return "One";
case 0x0300: return "SRC_COLOR";
case 0x0301: return "1 - SRC_COLOR";
case 0x0302: return "SRC_ALPHA";
case 0x0303: return "1 - SRC_ALPHA";
case 0x0304: return "DST_ALPHA";
case 0x0305: return "1 - DST_ALPHA";
case 0x0306: return "DST_COLOR";
case 0x0307: return "1 - DST_COLOR";
case 0x0308: return "SRC_ALPHA_SATURATE";
case 0x8001: return "CONSTANT_COLOR";
case 0x8002: return "1 - CONSTANT_COLOR";
case 0x8003: return "CONSTANT_ALPHA";
case 0x8004: return "1 - CONSTANT_ALPHA";
case 0x8006: return "Add";
case 0x8007: return "Min";
case 0x8008: return "Max";
case 0x800A: return "Substract";
case 0x800B: return "Reverse Substract";
case 0xF005: return "Reverse Substract Signed";
case 0xF006: return "Add Signed";
case 0xF007: return "Reverse Add Signed";
default: return "Wrong Value!";
}
}
case CELL_GCM_PRIMITIVE_ENUM:
{
switch(value)
{
case 1: return "POINTS";
case 2: return "LINES";
case 3: return "LINE_LOOP";
case 4: return "LINE_STRIP";
case 5: return "TRIANGLES";
case 6: return "TRIANGLE_STRIP";
case 7: return "TRIANGLE_FAN";
case 8: return "QUADS";
case 9: return "QUAD_STRIP";
case 10: return "POLYGON";
default: return "Wrong Value!";
}
}
default: return "Unknown!";
}
}
#define case_16(a, m) \
case a + m: \
case a + m * 2: \
case a + m * 3: \
case a + m * 4: \
case a + m * 5: \
case a + m * 6: \
case a + m * 7: \
case a + m * 8: \
case a + m * 9: \
case a + m * 10: \
case a + m * 11: \
case a + m * 12: \
case a + m * 13: \
case a + m * 14: \
case a + m * 15: \
index = (cmd - a) / m; \
[[fallthrough]]; \
case a \
QString rsx_debugger::DisAsmCommand(u32 cmd, u32 count, u32 ioAddr)
{
std::string disasm;
@ -874,30 +788,10 @@ QString rsx_debugger::DisAsmCommand(u32 cmd, u32 count, u32 ioAddr)
DISASM("Flip and change current buffer: %d", args[0]);
break;
}
case_16(NV4097_SET_TEXTURE_OFFSET, 0x20):
{
DISASM("Texture Offset[%d]: %07x", index, args[0]);
switch ((args[1] & 0x3) - 1)
{
case CELL_GCM_LOCATION_LOCAL: DISASM("(Local memory);"); break;
case CELL_GCM_LOCATION_MAIN: DISASM("(Main memory);"); break;
default: DISASM("(Bad location!);"); break;
}
DISASM(" Cubemap:%s; Dimension:0x%x; Format:0x%x; Mipmap:0x%x",
(((args[1] >> 2) & 0x1) ? "True" : "False"),
((args[1] >> 4) & 0xf),
((args[1] >> 8) & 0xff),
((args[1] >> 16) & 0xffff));
break;
}
case NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE:
{
DISASM("Depth bounds test: %s", args[0] ? "Enable" : "Disable");
break;
}
default:
{
std::string str = rsx::get_pretty_printing_function((cmd & 0x3ffff) >> 2)(args[0]);
const u32 id = (cmd & 0x3ffff) >> 2;
std::string str = rsx::get_pretty_printing_function(id)(id, args[0]);
DISASM("%s", str.c_str());
break;
}

View File

@ -72,7 +72,6 @@ public:
virtual void GetMemory();
virtual void GetBuffers();
const char* ParseGCMEnum(u32 value, u32 type);
QString DisAsmCommand(u32 cmd, u32 count, u32 ioAddr);
void SetPC(const uint pc);