11import { parseArgs } from 'jsr:@std/cli@^1/parse-args' ;
22
3- type Shader = { filename : string , prefix : string , prog : string } ;
4- type Header = { path : string , shaders : Shader [ ] } ;
5-
6- const headers : Header [ ] = [
7- // sokol_gl.h
8- {
9- path : '../util/sokol_gl.h' ,
10- shaders : [ { filename : 'sokol_gl.glsl' , prefix : '_sgl' , prog : 'shd' } ] ,
11- } ,
12- // sokol_debugtext.h
13- {
14- path : '../util/sokol_debugtext.h' ,
15- shaders : [ { filename : 'sokol_debugtext.glsl' , prefix : '_sdtx' , prog : 'shd' } ] ,
16- } ,
17- // sokol_fontstash.h
18- {
19- path : '../util/sokol_fontstash.h' ,
20- shaders : [ { filename : 'sokol_fontstash.glsl' , prefix : '_sfons' , prog : 'shd' } ] ,
21- } ,
22- // sokol_imgui.h
23- {
24- path : '../util/sokol_imgui.h' ,
25- shaders : [ { filename : 'sokol_imgui.glsl' , prefix : '_simgui' , prog : 'shd' } ] ,
26- } ,
27- // sokol_nuklear.h
28- {
29- path : '../util/sokol_nuklear.h' ,
30- shaders : [ { filename : 'sokol_nuklear.glsl' , prefix : '_snk' , prog : 'shd' } ] ,
31- } ,
32- // sokol_spine.h
33- {
34- path : '../util/sokol_spine.h' ,
35- shaders : [ { filename : 'sokol_spine.glsl' , prefix : '_sspine' , prog : 'shd' } ] ,
36- } ,
37- ] ;
38-
393const denoArgs = parseArgs ( Deno . args , {
40- boolean : [ 'hlsl' ] ,
41- string : [ 'shdcroot' , 'branch' ] ,
4+ boolean : [ 'hlsl' , 'local' ] ,
5+ string : [ 'shdcroot' , 'branch' , 'only' ] ,
426 default : {
437 hlsl : false ,
8+ local : false ,
449 shdcroot : '../../sokol-tools-bin' ,
4510 branch : 'master' ,
11+ only : null ,
4612 } ,
4713} ) ;
4814
15+ type Item = { header : string , shader : string , prefix : string , progs : string [ ] } ;
16+
17+ const items : Item [ ] = [
18+ { header : '../util/sokol_gl.h' , shader : 'sokol_gl.glsl' , prefix : '_sgl' , progs : [ 'shd' ] } ,
19+ { header : '../util/sokol_debugtext.h' , shader : 'sokol_debugtext.glsl' , prefix : '_sdtx' , progs : [ 'shd' ] } ,
20+ { header : '../util/sokol_fontstash.h' , shader : 'sokol_fontstash.glsl' , prefix : '_sfons' , progs : [ 'shd' ] } ,
21+ { header : '../util/sokol_imgui.h' , shader : 'sokol_imgui.glsl' , prefix : '_simgui' , progs : [ 'shd' ] } ,
22+ { header : '../util/sokol_nuklear.h' , shader : 'sokol_nuklear.glsl' , prefix : '_snk' , progs : [ 'shd' ] } ,
23+ { header : '../util/sokol_spine.h' , shader : 'sokol_spine.glsl' , prefix : '_sspine' , progs : [ 'shd' ] } ,
24+ {
25+ header : '../util/sokol_framebuffer.h' ,
26+ shader : 'sokol_framebuffer.glsl' ,
27+ prefix : '_sfb' ,
28+ progs : [ 'rgba8' , 'palette8' , 'render' ] ,
29+ }
30+ ] ;
31+
4932function dirExists ( path : string ) : boolean {
5033 try {
5134 return Deno . statSync ( path ) . isDirectory ;
@@ -62,34 +45,47 @@ async function main(): Promise<void> {
6245
6346 if ( denoArgs . hlsl ) {
6447 // only compile hlsl shaders into binaries (runs on CI)
65- for ( const hdr of headers ) {
66- for ( const shd of hdr . shaders ) {
67- await compile ( shd , true ) ;
68- }
48+ for ( const item of items ) {
49+ await compile ( item ) ;
6950 }
7051 } else {
7152 // compile non-HLSL shader locally, and HLSL by triggering a remote Github CI run
72- await compileHlslRemote ( ) ;
73- for ( const hdr of headers ) {
53+ if ( ! denoArgs . local ) {
54+ await compileHlslRemote ( ) ;
55+ }
56+ for ( const item of items ) {
57+ await compile ( item ) ;
7458 const outp : string [ ] = [ ]
75- for ( const shd of hdr . shaders ) {
76- await compile ( shd , false ) ;
77- outp . push ( ...gatherShader ( shd ) ) ;
59+ for ( const prog of item . progs ) {
60+ outp . push ( ...gatherShader ( item , prog ) ) ;
7861 }
79- inject ( hdr . path , outp ) ;
62+ if ( denoArgs . only && ! item . header . includes ( denoArgs . only ) ) {
63+ continue ;
64+ }
65+ inject ( item . header , outp ) ;
8066 }
8167 }
8268}
8369
84- async function compile ( shd : Shader , hlsl : boolean ) : Promise < void > {
85- await shdc ( [
86- '-i' , shd . filename ,
87- '-o' , `out/${ shd . filename } ` ,
70+ async function compile ( item : Item ) : Promise < void > {
71+ let slangs : string ;
72+ if ( denoArgs . hlsl ) {
73+ slangs = 'hlsl4' ;
74+ } else {
75+ slangs = 'glsl410:glsl300es:metal_macos:metal_ios:metal_sim:wgsl:spirv_vk' ;
76+ if ( denoArgs . local ) {
77+ slangs += ':hlsl4' ;
78+ }
79+ }
80+ const args = [
81+ '-i' , item . shader ,
8882 '-t' , 'out/tmpdir' ,
89- '-l' , hlsl ? 'hlsl4' : 'glsl410:glsl300es:metal_macos:metal_ios:metal_sim:wgsl:spirv_vk' ,
90- '-f' , 'bare_yaml' ,
83+ '-l' , slangs ,
9184 '-b' ,
92- ] ) ;
85+ ] ;
86+ // compile once as regular C header and once as bare_yaml
87+ await shdc ( [ ...args , '-o' , `out/${ item . shader } .h` ] ) ;
88+ await shdc ( [ ...args , '-o' , `out/${ item . shader } ` , '-f' , 'bare_yaml' ] ) ;
9389}
9490
9591function bytesToCArray ( name : string , bytes : Uint8Array ) : string [ ] {
@@ -104,41 +100,45 @@ function bytesToCArray(name: string, bytes: Uint8Array): string[] {
104100 return lines ;
105101}
106102
107- function gatherSlang ( shd : Shader , slang : string , ext : string , isBinary : boolean ) : string [ ] {
103+ function gatherSlang ( item : Item , prog : string , slang : string , ext : string , isBinary : boolean ) : string [ ] {
108104 const res : string [ ] = [ ] ;
109105 for ( const stage of [ 'vertex' , 'fragment' ] ) {
110- const path = `out/${ shd . filename } _${ shd . prog } _${ slang } _${ stage } ${ ext } ` ;
106+ const path = `out/${ item . shader } _${ prog } _${ slang } _${ stage } ${ ext } ` ;
111107 let bytes : Uint8Array = Deno . readFileSync ( path ) ;
112108 if ( ! isBinary ) {
113109 // for source code, append a terminating zero
114110 bytes = new Uint8Array ( [ ...bytes , 0 ] ) ;
115111 }
116- const cArrayName = `${ shd . prefix } _${ shd . prog } _${ stage === 'vertex' ?'vs' :'fs' } _${ isBinary ?'bytecode' :'source' } _${ slang } ` ;
112+ const cArrayName = `${ item . prefix } _${ prog } _${ stage === 'vertex' ?'vs' :'fs' } _${ isBinary ?'bytecode' :'source' } _${ slang } ` ;
117113 const cArray = bytesToCArray ( cArrayName , bytes ) ;
118114 res . push ( ...cArray ) ;
119115 }
120116 return res ;
121117}
122118
123- function gatherShader ( shd : Shader ) : string [ ] {
119+ function gatherShader ( item : Item , prog : string ) : string [ ] {
124120 const res : string [ ] = [ ] ;
125121 res . push ( '#if defined(SOKOL_GLCORE)' ) ;
126- res . push ( ...gatherSlang ( shd , 'glsl410' , '.glsl' , false ) ) ;
122+ res . push ( ...gatherSlang ( item , prog , 'glsl410' , '.glsl' , false ) ) ;
127123 res . push ( '#elif defined(SOKOL_GLES3)' ) ;
128- res . push ( ...gatherSlang ( shd , 'glsl300es' , '.glsl' , false ) ) ;
124+ res . push ( ...gatherSlang ( item , prog , 'glsl300es' , '.glsl' , false ) ) ;
129125 res . push ( '#elif defined(SOKOL_METAL)' ) ;
130- res . push ( ...gatherSlang ( shd , 'metal_macos' , '.metallib' , true ) ) ;
131- res . push ( ...gatherSlang ( shd , 'metal_ios' , '.metallib' , true ) ) ;
132- res . push ( ...gatherSlang ( shd , 'metal_sim' , '.metal' , false ) ) ;
126+ res . push ( ...gatherSlang ( item , prog , 'metal_macos' , '.metallib' , true ) ) ;
127+ res . push ( ...gatherSlang ( item , prog , 'metal_ios' , '.metallib' , true ) ) ;
128+ res . push ( ...gatherSlang ( item , prog , 'metal_sim' , '.metal' , false ) ) ;
133129 res . push ( '#elif defined(SOKOL_D3D11)' ) ;
134- res . push ( ...gatherSlang ( shd , 'hlsl4' , '.fxc' , true ) ) ;
130+ if ( denoArgs . local ) {
131+ res . push ( ...gatherSlang ( item , prog , 'hlsl4' , '.hlsl' , false ) ) ;
132+ } else {
133+ res . push ( ...gatherSlang ( item , prog , 'hlsl4' , '.fxc' , true ) ) ;
134+ }
135135 res . push ( '#elif defined(SOKOL_WGPU)' ) ;
136- res . push ( ...gatherSlang ( shd , 'wgsl' , '.wgsl' , false ) ) ;
136+ res . push ( ...gatherSlang ( item , prog , 'wgsl' , '.wgsl' , false ) ) ;
137137 res . push ( '#elif defined(SOKOL_VULKAN)' ) ;
138- res . push ( ...gatherSlang ( shd , 'spirv_vk' , '' , true ) ) ;
138+ res . push ( ...gatherSlang ( item , prog , 'spirv_vk' , '' , true ) ) ;
139139 res . push ( '#elif defined(SOKOL_DUMMY_BACKEND)' ) ;
140- res . push ( `static const char* ${ shd . prefix } _vs_source_dummy = "";` ) ;
141- res . push ( `static const char* ${ shd . prefix } _fs_source_dummy = "";` ) ;
140+ res . push ( `static const char* ${ item . prefix } _ ${ prog } _vs_source_dummy = "";` ) ;
141+ res . push ( `static const char* ${ item . prefix } _ ${ prog } _fs_source_dummy = "";` ) ;
142142 res . push ( '#else' ) ;
143143 res . push ( '#error "Please define one of SOKOL_GLCORE, SOKOL_GLES3, SOKOL_D3D11, SOKOL_METAL, SOKOL_WGPU, SOKOL_VULKAN or SOKOL_DUMMY_BACKEND!"' ) ;
144144 res . push ( '#endif' ) ;
0 commit comments