refactor(render3d): programs, GPU timers and the context behind gpu.ludic

The last of milestone 1: no OpenGL call is left in render3d outside gpu.ludic but the clock
and the CPU-side buffer helpers.

- gpu_program builds a program and remembers the variant it came from (vertex, fragment and
  defines as one line - the SPIR-V manifest's key), so a backend that cannot compile at run
  time finds the pipeline for the same handle. gpu_use_program and gpu_program_free replace
  32 uses and 2 frees; the overlay's program is recorded under overlay.vert|overlay.frag.
- gpu_query_new / _begin / _end / _result carry R3D_PROF's timers.
- gpu_open, gpu_vsync, gpu_renderer_name and gpu_resize_check carry the context.
- r3d_program_tess is gone: nothing called it and no tessellation shader exists.
- R3D_GLCHECK also checks after framebuffer and renderbuffer changes, viewport, draw buffers,
  program use, texture parameters, the resize check and between frames.

OpenGL frames are byte-identical at the five viewpoints; 59 self-tests pass with and without
R3D_GLCHECK, with no GL error; ludic-dev test 140 passed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-15 11:33:01 +03:00
parent 447acc11bd
commit ce3986bb02
12 changed files with 109 additions and 59 deletions

View file

@ -56,14 +56,6 @@ function r3d_shader_src(name: string, defines: string, is_frag: bool) -> string
return s + r3d_shader_file(name)
}
# Build a program with tessellation control/evaluation between vertex and fragment.
function r3d_program_tess(vs: string, tcs: string, tes: string, fs: string, defines: string) -> int {
let p = gl_program5(r3d_shader_src(vs, defines, false), r3d_shader_src(tcs, defines, false),
r3d_shader_src(tes, defines, false), null, r3d_shader_src(fs, defines, true))
if p == 0 { print(`r3d: tess program failed: {vs} + {tcs} + {tes} + {fs}`) }
return p
}
# Build a program from a vertex + fragment file pair (defines apply to both).
# R3D_PROGRAMS_LOG=<file>: append every program built (vertex, fragment, defines) - the list a
# backend that cannot compile shaders at run time (Vulkan: SPIR-V is built ahead) must cover
@ -81,7 +73,7 @@ function r3d_program_log(vs: string, fs: string, defines: string) -> void {
}
function r3d_program(vs: string, fs: string, defines: string) -> int {
r3d_program_log(vs, fs, defines)
let p = gl_program(r3d_shader_src(vs, defines, false), r3d_shader_src(fs, defines, true))
let p = gpu_program(r3d_shader_src(vs, defines, false), r3d_shader_src(fs, defines, true), vs, fs, `{r3d_global_defs}{defines}`)
if p == 0 { print(`r3d: program failed: {vs} + {fs}`) }
return p
}