Files
psxrecomp/runtime/include/gpu_render.h
T
Matthew Stanley 72799bda93 gl-renderer phase 1: renderer facade + [video] renderer config option
Foundation for a selectable hardware (OpenGL) renderer alongside the software
rasterizer. No behavior change: software remains the default and routes through
the facade to the exact same sw_* functions.

- config: [video] renderer = "software" (default) | "opengl" (config_loader).
- gpu_render.h/.c: gr_* facade + GpuRenderBackend vtable. gpu.c (50 call sites)
  and main.cpp (present/scale/filter) now call gr_* instead of sw_* directly.
  The software backend table points straight at sw_*, so the SW path is
  byte-identical.
- gpu_gl_renderer.c: Phase-1 stub. gl_backend_get() returns NULL, so
  requesting renderer="opengl" logs a notice and falls back to software.
- main.cpp: selects the backend (gr_set_backend) before gpu_init().

Phase 2 (next) builds the real GL backend: SDL GL context, VRAM-as-texture/FBO,
shader rasterization at internal resolution, present. Phase 3: coherency,
transparency/dither/mask, then default-with-fallback.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 11:14:06 -07:00

156 lines
7.5 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
} 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);
/* ---- 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);
} GpuRenderBackend;
#ifdef __cplusplus
}
#endif
#endif /* PSX_GPU_RENDER_H */