Files
psxrecomp/runtime/include/gpu_render.h
T
Matthew Stanley c6dc87fdfa native-wide GL: fix center-blit double-buffer artifact + add GL wide_full TCP tool
- wide_blit_center now copies the canonical column into the wide-surface CENTRE
  over the FULL VRAM height, not just [disp_y, disp_h]. Ape vertical-double-
  buffers (display_y 0<->256, both bands in one wide surface); a scrolling
  cutscene (the cityscape intro) exposed centre rows outside the display band,
  which the disp_h-only blit left black -> horizontal black-band tearing. Full-
  height blit makes the wide centre bit-identical to the full-mirror output for
  every band. Fixes the regression; keeps the perf win.
- sticky gte_game_mode threshold/hysteresis retained (cutscene flicker fix).
- New GL wide-surface inspection over TCP: wide_dump_full backend method
  (glb_wide_dump_full) so the `wide_full` command dumps the ENTIRE GL compositor
  surface (both double-buffer bands + margins), matching the SW path. wide_shot
  (displayed band) already worked on GL. Lets native-wide be debugged entirely
  over the TCP server, no window focus.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 19:30:10 -07:00

183 lines
8.9 KiB
C

#ifndef PSX_GPU_RENDER_H
#define PSX_GPU_RENDER_H
/* Renderer facade. gpu.c (command processing) and main.cpp (present) call
* these gr_* entry points instead of a specific backend. The facade
* dispatches to a selected backend: the software rasterizer (gpu_sw_renderer.c,
* the default + fallback) or a hardware OpenGL backend (gpu_gl_renderer.c).
*
* The gr_* signatures mirror the software renderer's interface exactly, so a
* backend is just a table of the same functions. Select the backend with
* gr_set_backend() BEFORE gr_init(); gr_backend() reports the EFFECTIVE backend
* (a requested backend that fails to initialize falls back to software). */
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
GR_BACKEND_SOFTWARE = 0,
GR_BACKEND_OPENGL = 1,
GR_BACKEND_VULKAN = 2
} GrBackend;
void gr_set_backend(GrBackend backend); /* call before gr_init() */
GrBackend gr_backend(void); /* effective backend after init */
/* Lifecycle / global state */
void gr_init(uint16_t *vram);
void gr_set_scale(int scale);
int gr_scale(void);
void gr_set_texture_filter(int bilinear);
int gr_texture_filter(void);
/* Per-primitive draw state */
void gr_set_semi_transparency(int enabled, int mode);
void gr_set_mask_bits(int set_bit, int check_bit);
void gr_set_texture_window(uint32_t raw);
void gr_set_color_modulation(int r, int g, int b, int raw_texture);
/* Primitives */
void gr_fill_rect(int x, int y, int w, int h, uint16_t color);
void gr_copy_rect(int src_x, int src_y, int dst_x, int dst_y, int w, int h);
void gr_draw_flat_triangle(int x0, int y0, int x1, int y1, int x2, int y2,
uint16_t color);
void gr_draw_gouraud_triangle(int x0, int y0, uint16_t c0,
int x1, int y1, uint16_t c1,
int x2, int y2, uint16_t c2);
void gr_draw_textured_triangle(int x0, int y0, int u0, int v0,
int x1, int y1, int u1, int v1,
int x2, int y2, int u2, int v2,
uint16_t clut_x, uint16_t clut_y,
uint16_t texpage);
void gr_draw_shaded_textured_triangle(int x0, int y0, int u0, int v0,
uint32_t color0,
int x1, int y1, int u1, int v1,
uint32_t color1,
int x2, int y2, int u2, int v2,
uint32_t color2,
uint16_t clut_x, uint16_t clut_y,
uint16_t texpage, int raw_texture);
void gr_draw_flat_rect(int x, int y, int w, int h, uint16_t color);
void gr_draw_textured_rect(int x, int y, int w, int h,
int u, int v,
uint16_t clut_x, uint16_t clut_y,
uint16_t texpage);
void gr_draw_textured_rect_scaled(int x, int y, int w, int h,
int u0, int v0, int u1, int v1,
uint16_t clut_x, uint16_t clut_y,
uint16_t texpage);
void gr_draw_line(int x0, int y0, int x1, int y1, uint16_t color);
void gr_draw_shaded_line(int x0, int y0, uint16_t c0,
int x1, int y1, uint16_t c1);
/* Display readout (present path) */
int gr_render_display(uint32_t *out_pixels, int out_pitch,
int disp_x, int disp_y, int disp_w, int disp_h);
int gr_render_display_hires(uint32_t *out_pixels, int out_pitch,
int disp_x, int disp_y, int disp_w, int disp_h);
/* VRAM transfers */
void gr_vram_write(int x, int y, uint16_t pixel);
uint16_t gr_vram_read(int x, int y);
void gr_vram_transfer_in(int x, int y, int w, int h, const uint16_t *data);
void gr_vram_transfer_out(int x, int y, int w, int h, uint16_t *data);
/* Draw area / offset */
void gr_set_draw_area(int x1, int y1, int x2, int y2);
void gr_get_draw_area(int *x1, int *y1, int *x2, int *y2);
void gr_set_draw_offset(int x, int y);
/* Native-wide compositor. gr_wide_supported() reports whether the active
* backend implements it; if not, the others are no-ops and the caller keeps
* the canonical present path. */
int gr_wide_supported(void);
void gr_wide_configure(int wide_w, int offset);
void gr_wide_set_target(int base_x);
void gr_wide_disable_target(void);
void gr_wide_clear(int base_x, int y, int h, uint16_t color);
int gr_wide_dump_full(uint32_t *out, int cap_pixels, int *ow, int *oh, int base_x);
int gr_render_wide_display(uint32_t *out, int pitch, int base_x,
int disp_y, int disp_h);
/* ---- Backend vtable -----------------------------------------------------
* A backend supplies the same set of functions. gpu_gl_renderer.c (Phase 2)
* provides gl_backend_get(); until it does, requesting OpenGL falls back to
* software. Members mirror the gr_* / sw_* signatures 1:1. */
typedef struct GpuRenderBackend {
const char *name;
void (*init)(uint16_t *vram);
void (*set_scale)(int scale);
int (*scale)(void);
void (*set_texture_filter)(int bilinear);
int (*texture_filter)(void);
void (*set_semi_transparency)(int enabled, int mode);
void (*set_mask_bits)(int set_bit, int check_bit);
void (*set_texture_window)(uint32_t raw);
void (*set_color_modulation)(int r, int g, int b, int raw_texture);
void (*fill_rect)(int x, int y, int w, int h, uint16_t color);
void (*copy_rect)(int src_x, int src_y, int dst_x, int dst_y, int w, int h);
void (*draw_flat_triangle)(int x0, int y0, int x1, int y1, int x2, int y2,
uint16_t color);
void (*draw_gouraud_triangle)(int x0, int y0, uint16_t c0,
int x1, int y1, uint16_t c1,
int x2, int y2, uint16_t c2);
void (*draw_textured_triangle)(int x0, int y0, int u0, int v0,
int x1, int y1, int u1, int v1,
int x2, int y2, int u2, int v2,
uint16_t clut_x, uint16_t clut_y,
uint16_t texpage);
void (*draw_shaded_textured_triangle)(int x0, int y0, int u0, int v0,
uint32_t color0,
int x1, int y1, int u1, int v1,
uint32_t color1,
int x2, int y2, int u2, int v2,
uint32_t color2,
uint16_t clut_x, uint16_t clut_y,
uint16_t texpage, int raw_texture);
void (*draw_flat_rect)(int x, int y, int w, int h, uint16_t color);
void (*draw_textured_rect)(int x, int y, int w, int h, int u, int v,
uint16_t clut_x, uint16_t clut_y,
uint16_t texpage);
void (*draw_textured_rect_scaled)(int x, int y, int w, int h,
int u0, int v0, int u1, int v1,
uint16_t clut_x, uint16_t clut_y,
uint16_t texpage);
void (*draw_line)(int x0, int y0, int x1, int y1, uint16_t color);
void (*draw_shaded_line)(int x0, int y0, uint16_t c0,
int x1, int y1, uint16_t c1);
int (*render_display)(uint32_t *out, int pitch,
int dx, int dy, int dw, int dh);
int (*render_display_hires)(uint32_t *out, int pitch,
int dx, int dy, int dw, int dh);
void (*vram_write)(int x, int y, uint16_t pixel);
uint16_t (*vram_read)(int x, int y);
void (*vram_transfer_in)(int x, int y, int w, int h, const uint16_t *data);
void (*vram_transfer_out)(int x, int y, int w, int h, uint16_t *data);
void (*set_draw_area)(int x1, int y1, int x2, int y2);
void (*get_draw_area)(int *x1, int *y1, int *x2, int *y2);
void (*set_draw_offset)(int x, int y);
/* Native-wide compositor (optional; NULL on backends without it — the
* facade then reports gr_wide_supported() == 0 and the caller keeps the
* canonical present). */
void (*wide_configure)(int wide_w, int offset);
void (*wide_set_target)(int base_x);
void (*wide_disable_target)(void);
void (*wide_clear)(int base_x, int y, int h, uint16_t color);
int (*render_wide_display)(uint32_t *out, int pitch, int base_x,
int disp_y, int disp_h);
/* Dump the ENTIRE wide compositor surface for base_x (all double-buffer
* bands + both margins), g_wide_w x VRAM_H. Debug/inspection only; returns
* pixel count, writes width/height to ow/oh. NULL if unsupported. */
int (*wide_dump_full)(uint32_t *out, int cap_pixels, int *ow, int *oh,
int base_x);
} GpuRenderBackend;
#ifdef __cplusplus
}
#endif
#endif /* PSX_GPU_RENDER_H */