code wiki / (root) / nx_wgsl_gate.nx

nx_wgsl_gate.nx

buildroot/runtime/nx_wgsl_gate.nx

77340 B752 linesdepth 3pulls 4 transitivereach 0 importersview sourcekind gate/prooftopic wgsl
docsdependenciesstructsconstsfunctions

about

nx_wgsl_gate.nx -- IS THE SHADER BACKEND REAL, OR A RUBBER STAMP? SUBJECT: ./nx_wgsl.elf by default, or ./nx_wgsl.sov.elf.new with `staged`. Both modes execute the actual binary; e2e fork, never an in-process re-derive -- an in-process gate would prove the SOURCE compiles, not that the SHIPPED artifact behaves). THE PRE-DECLARED ACCEPT RULE (written before the backend was built): the SAME NishiLang source compiled to BOTH dialects must produce the SAME RESULT. On this box that cannot be proven at the pixel level -- headless WebGPU wedges inside requestAdapter/createShaderModule (measured; it is why nx_game_page_emit carries a GPU_BOOT_MS race at all) -- so equivalence is asserted at the EMITTED-IR level and the pixel gap is DECLARED, never papered over: * TRACE IDENTITY: each backend records the node ids it emits, in order. Two backends that consumed the same source completely produce identical traces. * NON-VACUITY: a module with one statement removed must NOT trace the same. Without this leg trace identity would be satisfied by two backends that both emit nothing. * REFUSAL: a construct outside the covered subset must refuse BY NAME. A silent mistranslation in a shader backend compiles, links, runs, and draws the wrong picture. * DIALECT SEPARATION: the GLSL output must carry GLSL's own spelling and the WGSL output WGSL's -- proving each backend emitted its dialect rather than copying the other. * SHIPPING EQUIVALENCE: the emitted GLSL must carry the same operators and operands as the hand-written VSH that ships in nx_game_page_emit today, which is the migration reference. * DECLARATION REFUSALS (S1, 2026-09-04): a texture-typed uniform, a K_ATTRIB and a fragment K_VARY each REFUSE BY NAME in WGSL (they used to be emitted wrong with no refusal), and a scalar uniform is still ADMITTED by the same pass -- the positive control a deny-guard must carry. * UNIFORM QUALIFICATION (S2, 2026-09-04): WGSL reads a uniform as `u.<name>` (it lives in struct U), GLSL reads it bare; a parameter or local of the same name shadows the uniform and stays bare in both. Trace identity must survive a uniform being in play. * TEXTURES ARE THEIR OWN KIND (S3, 2026-09-04): K_TEXTURE emits a @group/@binding var OUTSIDE struct U in WGSL and a sampler uniform in GLSL, read bare in both; the deprecated texture-typed K_UNIFORM refuses in BOTH dialects naming K_TEXTURE; texture_2d<f32> and a binding collision refuse by name. * DERIVED FRAGMENT SIGNATURE (S4, 2026-09-04): a sir_param_position parameter yields `@fragment fn main(@builtin(position) pos:vec4f)->@location(0) vec4f{` and GLSL reads it as gl_FragCoord; zero parameters derive to the old literal exactly; a position READ with no declared parameter and a plain (unbound) fragment parameter refuse by name -- an undeclared input is never a placeholder. WHAT THIS GATE DOES NOT MEASURE, STATED SO IT CANNOT BE MISREAD: no tooth renders a frame. GREEN here means the two dialects are emitted from one source and agree structurally. It does NOT mean a GPU drew the same pixels from both. That is nx_wgsl_pixel_gate, and it is OWED.

dependencies 3 imports · 0 importers

nx_syscalls.nx nx_gate_verdict.nx nx_gatekit_lib.nx nx_wgsl_gate.nx

imports: nx_syscalls.nxnx_gate_verdict.nxnx_gatekit_lib.nx

imported by: nobody (leaf or entry point)

structs

none

consts

44const WGG_ELF: *u8 = "./nx_wgsl.elf"
52const WGG_CAP: i64 = 1048576
57const WGG_PACKER_FLOATS: i64 = 96
58const WGG_PACKER_PAL_F: i64 = 28
59const WGG_PACKER_PALF_F: i64 = 76
60const WGG_FLOAT_BYTES: i64 = 4
64const WGG_R_TEXUNIFORM: *u8 = "texuniform_named=wgsl: texture-typed uniform"
68const WGG_R_ATTRIB: *u8 = "attrib_named=wgsl: vertex attribute declaration (K_ATTRIB)"
69const WGG_R_FRAGVARY: *u8 = "fragvary_named=wgsl: varying declaration (K_VARY) reached in a fragment stage"
74const WGG_TEX_LAYOUT: *u8 = "struct U{\nscale:f32,\n}\n@group(0)@binding(0)var<uniform> u:U;\n@group(0)@binding(1)var vox:texture_3d<u32>;\n"
75const WGG_TEX_WGSL_DECL: *u8 = "@group(0)@binding(1)var vox:texture_3d<u32>;\n"
76const WGG_TEX_GLSL_DECL: *u8 = "uniform highp usampler3D vox;\n"
77const WGG_TEX_WGSL_READ: *u8 = "return textureLoad(vox,vec3i(x,y,z),0).x;\n"
78const WGG_TEX_GLSL_READ: *u8 = "return texelFetch(vox,ivec3(x,y,z),0).x;\n"
79const WGG_R_TEXUNIFORM_GL: *u8 = "texuniform_glsl_named=glsl: texture-typed uniform"
80const WGG_R_TEX2D_WG: *u8 = "tex2d_wgsl_named=wgsl: texture type outside the covered subset"
81const WGG_R_TEX2D_GL: *u8 = "tex2d_glsl_named=glsl: texture type outside the covered subset"
82const WGG_R_TEXCOLLIDE: *u8 = "texcollide_named=wgsl: derived texture binding collides"
85const WGG_FRAGPOS_SIG: *u8 = "@fragment fn main(@builtin(position) pos:vec4f)->@location(0) vec4f{\n"
86const WGG_FRAGPOS_WGSL_BODY: *u8 = "return vec4f(pos.x,pos.y,0.0,1.0);\n"
87const WGG_FRAGPOS_GLSL_BODY: *u8 = "vec4(gl_FragCoord.x,gl_FragCoord.y,0.0,1.0)"
88const WGG_FRAGCONST_SIG: *u8 = "@fragment fn main()->@location(0) vec4f{\n"
89const WGG_R_FRAGUNDECL: *u8 = "fragundecl_named=wgsl: @builtin(position) read without a declared entry parameter"
90const WGG_R_FRAGPLAIN_WG: *u8 = "fragplain_wgsl_named=wgsl: fragment entry parameter that is not the @builtin(position) input"
91const WGG_R_FRAGPLAIN_GL: *u8 = "fragplain_glsl_named=glsl: entry-point parameter that is not the @builtin(position) input"
98const WGG_FRAGOUT_GLSL: *u8 = "out vec4 fc;\nvoid main(){\nfc=vec4(1.0,0.0,0.0,1.0);\n}\n"
99const WGG_FRAGOUT_GLSL_DECL: *u8 = "out vec4 fc;\n"
101const WGG_FRAGOUT_WGSL: *u8 = "@fragment fn main()->@location(0) vec4f{\nreturn vec4f(1.0,0.0,0.0,1.0);\n}\n"
103const WGG_FRAGLOC2_GLSL: *u8 = "layout(location=2) out vec4 fc;\n"
104const WGG_FRAGLOC2_WGSL: *u8 = "@fragment fn main()->@location(2) vec4f{\n"
106const WGG_FRAGDISCARD_WGSL: *u8 = "@fragment fn main(){\ndiscard;\n}\n"
107const WGG_FRAGDISCARD_GLSL: *u8 = "void main(){\ndiscard;\n}\n"
108const WGG_R_FRAGNOOUT_GL: *u8 = "fragnoout_glsl_named=glsl: fragment entry returns a value with no declared fragment output"
109const WGG_R_FRAGNOOUT_WG: *u8 = "fragnoout_wgsl_named=wgsl: fragment entry returns a value with no declared fragment output"
110const WGG_R_VERTFRAGOUT_GL: *u8 = "vertfragout_glsl_named=glsl: fragment output declaration (K_FRAGOUT) outside a fragment stage"
111const WGG_R_VERTFRAGOUT_WG: *u8 = "vertfragout_wgsl_named=wgsl: fragment output declaration (K_FRAGOUT) outside a fragment stage"
112const WGG_R_TWOOUT_GL: *u8 = "fragtwoout_glsl_named=glsl: more than one fragment output declared"
113const WGG_R_TWOOUT_WG: *u8 = "fragtwoout_wgsl_named=wgsl: more than one fragment output declared"
116const WGG_R_TEXSAMPLE_WG: *u8 = "texsample_wgsl_named=wgsl: sampled texture read (E_TEXSAMPLE)"
117const WGG_TEXSAMPLE_GLSL: *u8 = "return texture(vox,uv);\n"
201const WGG_C_TILDE: i64 = 126
202const WGG_C_BANG: i64 = 33

functions

119func wgg_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
121func wgg_has(buf: *u8, n: i64, ned: *u8) -> i64
139func wgg_count(buf: *u8, n: i64, ned: *u8) -> i64
158func wgg_num_after(buf: *u8, n: i64, key: *u8) -> i64
203func wgg_bang(s: *u8) -> *u8
218func main(argc: i64, argv: *i64) -> i64