Commit4a3c86c1Recorded19 Sep 2026Repositorysigil-graphics

Set the uniform block to 512 bytes (128 floats)

Message

David's ruling at review: 512 B over 1 KiB. sokol_gp's uniform pool is max_commands copies of the per-draw struct, so this is an 8.4 MB pool rather than 16.8 MB, on every target including wasm linear memory. SIGIL_GFX_UNIFORM_BUFFER_SIZE and SGP_UNIFORM_CONTENT_SLOTS move together; the block-overflow probe fills it with eight mat4 instead of sixteen.

Changed
 README.md                                                |  2 +-
 src/c/graphics.c                                         |  9 +++++----
 src/c/sokol-graphics.c                                   | 12 ++++++------
 test/test-shader-limits/src/test-shader-limits/scene.sgl |  6 +++---
 4 files changed, 15 insertions(+), 14 deletions(-)
Diff
README.mdmodified
@@ -58,7 +58,7 @@ both prefixes the version line under `cond-expand`.
58
`load-shader` scans the fragment source for `uniform` declarations of `float`,
59
`vec2`, `vec3`, `vec4` and `mat4`, scalar or array (`uniform vec4 palette[8];`, a
60
literal count; a `lowp`/`mediump`/`highp` qualifier is fine). `sampler2D` is not a
−61
uniform-block entry. Up to 16 declarations (an array is one) and 1 KiB in total,
+61
uniform-block entry. Up to 16 declarations (an array is one) and 512 bytes in total,
62
both checked by `load-shader` (the error names the limit); a GLSL compile error
63
is an error too, with sokol's log line before it. Entries are
64
packed in declaration order.
src/c/graphics.cmodified
@@ -149,15 +149,16 @@ typedef struct {
149
*
150
* SIGIL_GFX_UNIFORM_BUFFER_SIZE must equal SGP_UNIFORM_CONTENT_SLOTS *
151
* sizeof(float) (see sokol-graphics.c): sgp_set_uniform asserts the
−152
* pushed size fits its per-draw slot. 1 KiB holds 16 members of up to
−153
* `vec4 name[16]` each, minus the auto-uniforms; a larger block costs
−154
* sokol_gp `max_commands` (16384) copies of it in its uniform pool.
+152
* pushed size fits its per-draw slot. 512 B holds `vec4 name[8]` arrays four
+153
* times over beside the auto-uniforms; a larger block costs sokol_gp
+154
* `max_commands` (16384) copies of it in its uniform pool (David, 2026-09-19:
+155
* 512 B over 1 KiB, an 8.4 MB pool over 16.8 MB).
156
*
157
* sokol_gfx caps a uniform block at SG_MAX_UNIFORMBLOCK_MEMBERS (16)
158
* declared members; an array counts as one member, so the 16 here is
159
* that cap, not a float budget. */
160
#define SIGIL_GFX_MAX_UNIFORMS 16
−160
#define SIGIL_GFX_UNIFORM_BUFFER_SIZE 1024 /* matches SGP_UNIFORM_CONTENT_SLOTS=256 floats */
+161
#define SIGIL_GFX_UNIFORM_BUFFER_SIZE 512 /* matches SGP_UNIFORM_CONTENT_SLOTS=128 floats */
162
#define SIGIL_GFX_UNIFORM_NAME_MAX 64
163
164
typedef struct {
src/c/sokol-graphics.cmodified
@@ -16,18 +16,18 @@
16
* is not linked on web.
17
*/
18
−19
/* sgp's per-draw uniform buffer: 256 floats (1 KiB). Must equal
+19
/* sgp's per-draw uniform buffer: 128 floats (512 B). Must equal
20
* SIGIL_GFX_UNIFORM_BUFFER_SIZE / sizeof(float) in graphics.c, which
21
* mirrors the block on the CPU side and asserts nothing larger is pushed.
22
* sokol_gp's default is 8 floats (32 bytes), too small for even the
23
* auto-uniforms (u_time, u_resolution) plus one vec4; 64 floats (v0.10)
−24
* held a handful of vec4s; 256 floats holds uniform arrays such as
−25
* `vec4 palette[16]` beside them. Cost: sokol_gp keeps max_commands
+24
* held a handful of vec4s; 128 floats holds uniform arrays such as
+25
* `vec4 palette[8]` beside them. Cost: sokol_gp keeps max_commands
26
* (16384) copies of the sgp_uniform struct in its pool, so the pool goes
−27
* from 4.3 MB to 16.8 MB, allocated and zeroed once in sgp_setup; per draw
−28
* under a custom shader it memcmps one 1 KiB struct. Default-pipeline
+27
* from 4.3 MB to 8.4 MB, allocated and zeroed once in sgp_setup; per draw
+28
* under a custom shader it memcmps one 512 B struct. Default-pipeline
29
* draws (no shader bound) skip the uniform path entirely. */
−30
#define SGP_UNIFORM_CONTENT_SLOTS 256
+30
#define SGP_UNIFORM_CONTENT_SLOTS 128
31
32
#if defined(__wasm__)
33
test/test-shader-limits/src/test-shader-limits/scene.sglmodified
@@ -322,10 +322,10 @@
322
;; failed sg_make_shader still returns an id)
323
(expect-error "shader-compile-error"
324
(lambda () (load-shader VERT-SOURCE (string-append GLSL-PREFIX "out vec4 fragColor;\nvoid main() { fragColor = ; }\n"))))
−325
;; the block caps are errors, not silent drops: 16 mat4 fill the
−326
;; 1 KiB exactly, so u_resolution after them does not fit
+325
;; the block caps are errors, not silent drops: 8 mat4 fill the
+326
;; 512 B exactly, so u_resolution after them does not fit
327
(expect-error "uniform-block-too-large"
−328
(lambda () (load-shader VERT-SOURCE (string-append GLSL-PREFIX "uniform mat4 m[16];\nuniform vec2 u_resolution;\nout vec4 fragColor;\nvoid main() { fragColor = m[3][0] * u_resolution.x; }\n"))))
+328
(lambda () (load-shader VERT-SOURCE (string-append GLSL-PREFIX "uniform mat4 m[8];\nuniform vec2 u_resolution;\nout vec4 fragColor;\nvoid main() { fragColor = m[3][0] * u_resolution.x; }\n"))))
329
(expect-error "uniform-too-many"
330
(lambda () (load-shader VERT-SOURCE (string-append GLSL-PREFIX SEVENTEEN-FLOATS "out vec4 fragColor;\nvoid main() { fragColor = vec4(f0 + f16); }\n"))))
331
(expect-ok "uniform-nested"