Add hardware debug tracing for GPU comparison

This commit is contained in:
moonpower
2026-04-07 22:20:58 +02:00
parent 96c2afa81a
commit 2d22264db4
3 changed files with 218 additions and 63 deletions
+6
View File
@@ -24,6 +24,7 @@ SDL_LIBS_STATIC ?= $(shell $(SDL_CONFIG) --static-libs 2>/dev/null || $(SDL_CONF
SDL_STATIC ?= 1
WASM_LDFLAGS ?=
USE_HARDWARE ?= 0
HW_DEBUG ?= 0
PLATFORM := $(shell uname -s)
ifeq ($(WASM_TARGET),wasm)
@@ -99,6 +100,11 @@ ifeq ($(USE_HARDWARE),1)
BASE_CXXFLAGS += -DUSE_HARDWARE
endif
ifeq ($(HW_DEBUG),1)
BASE_CFLAGS += -DHW_DEBUG
BASE_CXXFLAGS += -DHW_DEBUG
endif
ifeq ($(UWP_TARGET),1)
BASE_CFLAGS += -DUWP_TARGET
BASE_CXXFLAGS += -DUWP_TARGET
+4
View File
@@ -10,12 +10,16 @@
static int g_hw_trace_mode = -1;
static bool hw_trace_enabled(void) {
#if !defined(HW_DEBUG)
return false;
#else
if (g_hw_trace_mode < 0) {
const char* env = getenv("ARMSX_HW_TRACE");
g_hw_trace_mode = (env && env[0] && env[0] != '0') ? 1 : 0;
}
return g_hw_trace_mode != 0;
#endif
}
static void hw_tracef(const char* fmt, ...) {
+208 -63
View File
@@ -3,10 +3,16 @@
#include <string.h>
#include <math.h>
#include "gpu.h"
#include "../log.h"
#define SE10(v) ((int16_t)((v) << 5) >> 5)
#include "gpu.h"
#include "../log.h"
#define SE10(v) ((int16_t)((v) << 5) >> 5)
#if defined(HW_DEBUG)
#define GPU_HW_DEBUG(...) psxe_diag_logf("gpu", __VA_ARGS__)
#else
#define GPU_HW_DEBUG(...) do { } while (0)
#endif
int g_psx_gpu_dither_kernel[] = {
-4, +0, -3, +1,
@@ -652,16 +658,29 @@ void gpu_render_flat_line(psx_gpu_t* gpu, vertex_t v0, vertex_t v1, uint32_t col
plotLine(gpu, v0.x, v0.y, v1.x, v1.y, color);
}
void gpu_render_flat_rectangle(psx_gpu_t* gpu, vertex_t v, uint32_t w, uint32_t h, uint32_t color) {
/* Offset coordinates */
v.x += gpu->off_x;
v.y += gpu->off_y;
void gpu_render_flat_rectangle(psx_gpu_t* gpu, vertex_t v, uint32_t w, uint32_t h, uint32_t color) {
/* Offset coordinates */
v.x += gpu->off_x;
v.y += gpu->off_y;
/* Calculate bounding box */
int xmin = max(v.x, gpu->draw_x1);
int ymin = max(v.y, gpu->draw_y1);
int xmax = min(xmin + w, gpu->draw_x2);
int ymax = min(ymin + h, gpu->draw_y2);
int xmax = min(xmin + w, gpu->draw_x2);
int ymax = min(ymin + h, gpu->draw_y2);
GPU_HW_DEBUG(
"soft-flat-rect color=%08x origin=(%d,%d) size=%ux%u bounds=(%d,%d)-(%d,%d)",
color,
v.x,
v.y,
w,
h,
xmin,
ymin,
xmax,
ymax
);
for (uint32_t y = ymin; y < ymax; y++) {
for (uint32_t x = xmin; x < xmax; x++) {
@@ -676,7 +695,7 @@ void gpu_render_flat_rectangle(psx_gpu_t* gpu, vertex_t v, uint32_t w, uint32_t
}
}
void gpu_render_textured_rectangle(psx_gpu_t* gpu, vertex_t v, uint32_t w, uint32_t h, uint16_t clutx, uint16_t cluty, uint32_t color) {
void gpu_render_textured_rectangle(psx_gpu_t* gpu, vertex_t v, uint32_t w, uint32_t h, uint16_t clutx, uint16_t cluty, uint32_t color) {
vertex_t a = v;
a.x += gpu->off_x;
@@ -685,9 +704,26 @@ void gpu_render_textured_rectangle(psx_gpu_t* gpu, vertex_t v, uint32_t w, uint3
int xmin = max(a.x, gpu->draw_x1);
int ymin = max(a.y, gpu->draw_y1);
int xmax = min(xmin + w, gpu->draw_x2);
int ymax = min(ymin + h, gpu->draw_y2);
uint32_t xc = 0, yc = 0;
int ymax = min(ymin + h, gpu->draw_y2);
uint32_t xc = 0, yc = 0;
GPU_HW_DEBUG(
"soft-textured-rect color=%08x origin=(%d,%d) size=%ux%u page=(%u,%u) clut=(%u,%u) bounds=(%d,%d)-(%d,%d)",
color,
v.x,
v.y,
w,
h,
gpu->texp_x,
gpu->texp_y,
clutx,
cluty,
xmin,
ymin,
xmax,
ymax
);
for (int y = ymin; y < ymax; y++) {
for (int x = xmin; x < xmax; x++) {
@@ -731,10 +767,25 @@ void gpu_render_flat_triangle(psx_gpu_t* gpu, vertex_t v0, vertex_t v1, vertex_t
c.x += gpu->off_x;
c.y += gpu->off_y;
int xmin = max(min(min(a.x, b.x), c.x), gpu->draw_x1);
int ymin = max(min(min(a.y, b.y), c.y), gpu->draw_y1);
int xmax = min(max(max(a.x, b.x), c.x), gpu->draw_x2);
int ymax = min(max(max(a.y, b.y), c.y), gpu->draw_y2);
int xmin = max(min(min(a.x, b.x), c.x), gpu->draw_x1);
int ymin = max(min(min(a.y, b.y), c.y), gpu->draw_y1);
int xmax = min(max(max(a.x, b.x), c.x), gpu->draw_x2);
int ymax = min(max(max(a.y, b.y), c.y), gpu->draw_y2);
GPU_HW_DEBUG(
"soft-flat-tri color=%08x bounds=(%d,%d)-(%d,%d) vertices=(%d,%d)-(%d,%d)-(%d,%d)",
color,
xmin,
ymin,
xmax,
ymax,
a.x,
a.y,
b.x,
b.y,
c.x,
c.y
);
for (int y = ymin; y < ymax; y++) {
for (int x = xmin; x < xmax; x++) {
@@ -770,12 +821,30 @@ void gpu_render_shaded_triangle(psx_gpu_t* gpu, vertex_t v0, vertex_t v1, vertex
c.x += gpu->off_x;
c.y += gpu->off_y;
int xmin = max(min(min(a.x, b.x), c.x), gpu->draw_x1);
int ymin = max(min(min(a.y, b.y), c.y), gpu->draw_y1);
int xmax = min(max(max(a.x, b.x), c.x), gpu->draw_x2);
int ymax = min(max(max(a.y, b.y), c.y), gpu->draw_y2);
int area = EDGE(a, b, c);
int xmin = max(min(min(a.x, b.x), c.x), gpu->draw_x1);
int ymin = max(min(min(a.y, b.y), c.y), gpu->draw_y1);
int xmax = min(max(max(a.x, b.x), c.x), gpu->draw_x2);
int ymax = min(max(max(a.y, b.y), c.y), gpu->draw_y2);
int area = EDGE(a, b, c);
GPU_HW_DEBUG(
"soft-shaded-tri bounds=(%d,%d)-(%d,%d) area=%d v0=(%d,%d c=%08x) v1=(%d,%d c=%08x) v2=(%d,%d c=%08x)",
xmin,
ymin,
xmax,
ymax,
area,
a.x,
a.y,
a.c,
b.x,
b.y,
b.c,
c.x,
c.y,
c.c
);
for (int y = ymin; y < ymax; y++) {
for (int x = xmin; x < xmax; x++) {
@@ -845,10 +914,39 @@ void gpu_render_textured_triangle(psx_gpu_t* gpu, vertex_t v0, vertex_t v1, vert
int xmin = max(min(min(a.x, b.x), c.x), gpu->draw_x1);
int ymin = max(min(min(a.y, b.y), c.y), gpu->draw_y1);
int xmax = min(max(max(a.x, b.x), c.x), gpu->draw_x2);
int ymax = min(max(max(a.y, b.y), c.y), gpu->draw_y2);
uint32_t area = EDGE(a, b, c);
int xmax = min(max(max(a.x, b.x), c.x), gpu->draw_x2);
int ymax = min(max(max(a.y, b.y), c.y), gpu->draw_y2);
uint32_t area = EDGE(a, b, c);
GPU_HW_DEBUG(
"soft-textured-tri page=(%u,%u) clut=(%u,%u) depth=%d bounds=(%d,%d)-(%d,%d) area=%u v0=(%d,%d c=%08x tx=%u ty=%u) v1=(%d,%d c=%08x tx=%u ty=%u) v2=(%d,%d c=%08x tx=%u ty=%u)",
tpx,
tpy,
clutx,
cluty,
depth,
xmin,
ymin,
xmax,
ymax,
area,
a.x,
a.y,
a.c,
a.tx,
a.ty,
b.x,
b.y,
b.c,
b.tx,
b.ty,
c.x,
c.y,
c.c,
c.tx,
c.ty
);
for (int y = ymin; y < ymax; y++) {
for (int x = xmin; x < xmax; x++) {
@@ -885,14 +983,22 @@ void gpu_render_textured_triangle(psx_gpu_t* gpu, vertex_t v0, vertex_t v1, vert
void gpu_rect(psx_gpu_t* gpu) {
switch (gpu->state) {
case GPU_STATE_RECV_CMD: {
gpu->state = GPU_STATE_RECV_ARGS;
int size = (gpu->buf[0] >> 27) & 3;
int textured = (gpu->buf[0] & 0x04000000) != 0;
gpu->cmd_args_remaining = 1 + (size == RS_VARIABLE) + textured;
} break;
case GPU_STATE_RECV_CMD: {
gpu->state = GPU_STATE_RECV_ARGS;
int size = (gpu->buf[0] >> 27) & 3;
int textured = (gpu->buf[0] & 0x04000000) != 0;
GPU_HW_DEBUG(
"rect-cmd raw=0x%08x attrib=0x%02x size=%d textured=%s",
gpu->buf[0],
gpu->buf[0] >> 24,
size,
textured ? "true" : "false"
);
gpu->cmd_args_remaining = 1 + (size == RS_VARIABLE) + textured;
} break;
case GPU_STATE_RECV_ARGS: {
if (!gpu->cmd_args_remaining) {
@@ -915,10 +1021,25 @@ void gpu_rect(psx_gpu_t* gpu) {
rect.width = gpu->buf[size_offset] & 0xffff;
rect.height = gpu->buf[size_offset] >> 16;
if (textured && raw)
rect.v0.c = 0x808080;
gpu_render_rect(gpu, rect);
if (textured && raw)
rect.v0.c = 0x808080;
GPU_HW_DEBUG(
"rect-dispatch attrib=0x%02x v0=(%d,%d c=%08x tx=%u ty=%u) clut=0x%04x size=%ux%u raw=%s textured=%s",
rect.attrib,
rect.v0.x,
rect.v0.y,
rect.v0.c,
rect.v0.tx,
rect.v0.ty,
rect.clut,
rect.width,
rect.height,
raw ? "true" : "false",
textured ? "true" : "false"
);
gpu_render_rect(gpu, rect);
gpu->state = GPU_STATE_RECV_CMD;
}
@@ -928,15 +1049,23 @@ void gpu_rect(psx_gpu_t* gpu) {
void gpu_poly(psx_gpu_t* gpu) {
switch (gpu->state) {
case GPU_STATE_RECV_CMD: {
gpu->state = GPU_STATE_RECV_ARGS;
int shaded = (gpu->buf[0] & 0x10000000) != 0;
int quad = (gpu->buf[0] & 0x08000000) != 0;
int textured = (gpu->buf[0] & 0x04000000) != 0;
int fields_per_vertex = 1 + shaded + textured;
int vertices = 3 + quad;
case GPU_STATE_RECV_CMD: {
gpu->state = GPU_STATE_RECV_ARGS;
int shaded = (gpu->buf[0] & 0x10000000) != 0;
int quad = (gpu->buf[0] & 0x08000000) != 0;
int textured = (gpu->buf[0] & 0x04000000) != 0;
GPU_HW_DEBUG(
"poly-cmd raw=0x%08x shaded=%s quad=%s textured=%s",
gpu->buf[0],
shaded ? "true" : "false",
quad ? "true" : "false",
textured ? "true" : "false"
);
int fields_per_vertex = 1 + shaded + textured;
int vertices = 3 + quad;
gpu->cmd_args_remaining = (fields_per_vertex * vertices) - shaded;
} break;
@@ -956,20 +1085,36 @@ void gpu_poly(psx_gpu_t* gpu) {
int texc_offset = textured * (2 + shaded);
int texp_offset = textured * (4 + shaded);
poly.clut = gpu->buf[2] >> 16;
poly.texp = gpu->buf[texp_offset] >> 16;
// Undocumented behavior?
// Fixes Mortal Kombat II, Bubble Bobble, Driver 1 & 2
if (textured) {
gpu->texp_x = (poly.texp & 0xf) << 6;
gpu->texp_y = (poly.texp & 0x10) << 4;
gpu->texp_d = (poly.texp >> 7) & 0x3;
gpu->gpustat &= 0xfffffe00;
gpu->gpustat |= poly.texp & 0x1ff;
}
poly.v[0].c = gpu->buf[0+0*color_offset] & 0xffffff;
poly.clut = gpu->buf[2] >> 16;
poly.texp = gpu->buf[texp_offset] >> 16;
const bool poly_quad = (poly.attrib & PA_QUAD) != 0;
// Undocumented behavior?
// Fixes Mortal Kombat II, Bubble Bobble, Driver 1 & 2
if (textured) {
gpu->texp_x = (poly.texp & 0xf) << 6;
gpu->texp_y = (poly.texp & 0x10) << 4;
gpu->texp_d = (poly.texp >> 7) & 0x3;
gpu->gpustat &= 0xfffffe00;
gpu->gpustat |= poly.texp & 0x1ff;
}
GPU_HW_DEBUG(
"poly-dispatch attrib=0x%02x shaded=%s quad=%s textured=%s clut=0x%04x texp=0x%04x "
"v0=(%d,%d c=%08x tx=%u ty=%u) v1=(%d,%d c=%08x tx=%u ty=%u) v2=(%d,%d c=%08x tx=%u ty=%u) v3=(%d,%d c=%08x tx=%u ty=%u)",
poly.attrib,
shaded ? "true" : "false",
poly_quad ? "true" : "false",
textured ? "true" : "false",
poly.clut,
poly.texp,
poly.v[0].x, poly.v[0].y, poly.v[0].c, poly.v[0].tx, poly.v[0].ty,
poly.v[1].x, poly.v[1].y, poly.v[1].c, poly.v[1].tx, poly.v[1].ty,
poly.v[2].x, poly.v[2].y, poly.v[2].c, poly.v[2].tx, poly.v[2].ty,
poly.v[3].x, poly.v[3].y, poly.v[3].c, poly.v[3].tx, poly.v[3].ty
);
poly.v[0].c = gpu->buf[0+0*color_offset] & 0xffffff;
poly.v[1].c = gpu->buf[0+1*color_offset] & 0xffffff;
poly.v[2].c = gpu->buf[0+2*color_offset] & 0xffffff;
poly.v[3].c = gpu->buf[0+3*color_offset] & 0xffffff;