1# LumeShaderCompiler 2 3LumeShaderCompiler is a shader compiler for preprocessing shaders used with LumeEngine. Source GLSL files are compiled into SPIR-V, optionally optimized, and stored as `<input>.spv`. The SPIR-V is reflected and reflection stored as `<input>.lsb`. 4 5## Commandline options: 6`--source`, path where source GLSL files are located. 7 8`--destination`, path where output is written. Source path is used if destination is not specified. 9 10`--include`, path where to look for include files. Multipla include paths can be given. 11 12`--optimize`, generate optimized SPIR-V binary. 13 14`--monitor`, keep monitoring the source path for file changes and recompile modified shaders. 15 16# LSB format, version 0 17 18## Header: 19``` 20uint8[4] tag 21uint16 offsetPushConstants 22uint16 offsetSpecializationConstants 23uint16 offsetDescriptorSets 24uint16 offsetInputs 25uint16 offsetLocalSize 26``` 27tag[0] = 'r', tag[1] = 'f', tag[2] = 'l', tag[3] = 0 28 29offsetPushConstants, if non-zero offset to PushConstants 30 31offsetSpecializationConstants, if non-zero offset to SpecializationConstants 32 33offsetDescriptorSets, if non-zero offset to DescriptorSets 34 35offsetInputs, if non-zero offset to Inputs 36 37offsetLocalSize, if non-zero offset to LocalSize 38 39## PushConstants: 40``` 41uint8 count 42uint16[count] byteSizes 43``` 44count, number of push constants 45 46byteSizes[], size of push constant in bytes 47 48## SpecializationConstants: 49``` 50uint32 count 51{ 52 uint32 id, 53 uint32 byteSize 54}[count] constants 55``` 56count, number of specialization constants 57 58constants[].id, ID of the constant 59 60constants[].byteSize, size of push constant in bytes 61 62## DescriptorSets: 63``` 64uint16 count 65{ 66 uint16 set, 67 uint16 bindingCount 68 { 69 uint16 index, 70 uint16 type, 71 uint16 count 72 }[bindingCount] bindings 73}[count] sets 74``` 75count, number of descriptor sets 76 77sets[].set, ID of the descriptor set 78 79sets[].bindingCount, number of descriptor bindings in the set 80 81sets[].bindings[].index, index where resource is bound 82 83sets[].bindings[].type, type of the bound resource 84 85sets[].bindings[].count, number of resources 86 87## Inputs: 88``` 89uint16 count 90{ 91 uint16 location, 92 uint16 format 93}[count] inputs 94``` 95count, number of inputs 96 97inputs[].location, location where input is bound 98 99inputs[].format, expected input format (matches CORE_NS::Format) 100 101## LocalSize: 102``` 103uint32 localX 104uint32 localY 105uint32 localZ 106``` 107localX, x dimension of shader execution local size 108 109localY, y dimension of shader execution local size 110 111localZ, z dimension of shader execution local size 112 113# LumeSnippetCompiler 114 115LumeSnippetCompiler generates GLSL files based on shader template and snippet blocks. The tool loads shader configuration files from the `source` path and writes GLSL files to `destination` path. 116 117## Shader configuration 118A shader configuration file is a JSON file containing: 119``` 120{ 121 "target" : "<output file name .frag>" 122 "template" : "<shader template .json>" 123 "types": [<array of objects>] 124 "uniforms" : [<array of objects>] 125 "blocks" : [<array of objects>] 126} 127``` 128### `target` 129Final shader will be written to `target`. The template used for creating the final shader is specified by `template`. 130 131### `types` 132Each custom struct in the `types` array is defined as follows: 133``` 134{ 135 "name" : "<name of the struct type>" 136 "members" : [ 137 { 138 "type" : "<GLSL type of the struct member>" 139 "name" : "<name of the struct member>" 140 } 141 ] 142} 143``` 144 145### `uniforms` 146Each uniform variable in the `uniforms` array is defined as follows: 147``` 148{ 149 "type" : "<GLSL type of the uniform variable>" 150 "name" : "<name of the uniform variable>" 151} 152``` 153 154### `blocks` 155A snippet block in the `blocks` array is defined as follows: 156``` 157{ 158 "name" : "<identifier where to inject in the shader template>" 159 "function" : "<name of the function to call>" 160 "inputs" : [<array of objects>] 161 "outputs" : [<array of objects>] 162} 163``` 164`name` should match one of the names listed in `//>DECLARATIONS_<name list>` and `//>FUNCTIONS_<name list>` tag comments in the template. 165 166Each parameter in the `inputs` and `outputs` arrays is defined as follows: 167``` 168{ 169 "type" : "<GLSL type of the variable passed as a parameter>" 170 "name" : "<name of the variable passed as a parameter, optional for inputs with value>" 171 "value" : "<optional intial value>" 172} 173``` 174Parameters are expected to be defined either in the template config, or uniform variable list. 175 176## Template configuration 177A template configuration file is a JSON file containing: 178``` 179{ 180 "template" : "<shader template .h>" 181 "pipelineLayout": "<pipline layout .json>", 182 "types": [<array of objects>] 183 "variables": { 184 "inputs" : [<array of objects>] 185 "outputs" : [<array of objects>] 186 }, 187 "templateBlocks": [<array of objects>] 188} 189``` 190 191### `template` 192Shader template is a GLSL shader with specific tag comments: `//>DECLARATIONS_<name list>` and `//>FUNCTIONS_<name list>`. The tool injects uniforms and function definitions above the maching `DECLARATIONS` tag and function calls above the matching `FUNCTIONS` tag in the order they appear in the configuration file. The applicable snippet block groups names are separated by whitespaces. 193 194### `pipelineLayout` 195The pipeline layout JSON defines the descriptor set bindings for the shader. If a pipeline layout is given for the template, any uniform variables introduced in the shader configuration will be added to the next free descriptor set. If layout was not defined, descriptor set 0 will be used. Pipeline layout for the shader configuration will be written in `<target>_pipeline.json` with the original file extension removed. 196 197### `types` 198The `types` array follows the same structure as in the [shader configuration](#types) JSON. 199 200### `variables` 201Each variable in `variables.inputs` and `variables.outputs` is defined as follows: 202``` 203{ 204 "type" : "<GLSL type of the variable>" 205 "name" : "<name of the variable>" 206} 207``` 208 209### `templateBlocks` 210The `templateBlocks` array defines which snippet block groups can be used with the template. Group names are used to identify in which `//>DECLARATIONS_<name list>` and `//>FUNCTIONS_<name list>` the group can be used. 211Each snippet block group in `templateBlocks` is defined as follows: 212``` 213{ 214 "name" : "<name of the group>" 215 "source" : "<snippet block group .json>" 216} 217``` 218 219## Snippet block group configuration 220A snippet block group configuration file is a JSON file containing: 221``` 222{ 223 "source" : "<snippet .h containing definitions of all the listed function snippets>" 224 "blocks": [<array of objects> 225``` 226A snippet block in the `blocks` array is defined as follows: 227``` 228{ 229 "function" : "<name of the function to call>" 230 "inputs" : [<array of objects>] 231 "outputs" : [<array of objects>] 232} 233``` 234 235Each parameter in the `inputs` and `outputs` arrays is defined as follows: 236``` 237{ 238 "type" : "<GLSL type of the variable passed as a parameter>" 239 "description" : "<optional description of the parameter>" 240} 241``` 242 243## Commandline options: 244`--source`, path where shader configuration files are located. 245 246`--destination`, path where output is written. Source path is used if destination is not specified. 247 248## TODO 249- With current data some amount of type matching could be done. 250- For a perfect type matching all includes would have to be resolved and GLSL parsed. This might help also variable definitions. 251