sokol-tools

repository·master·Indexed 43 days ago

https://github.com/floooh/sokol-tools

Command line tools for sokol headers, featuring sokol_shdc, a shader cross-compiler and code-generator for sokol_gfx.h. It translates annotated GLSL (Vulkan-style version 450) into various shader dialects and language-specific headers for C, Zig, Rust, Odin, and others.

Tokens
4.9K
Snippets
12
Records
20
Agent score
55%

What's inside sokol-tools

  1. What is sokol-shdc?

    master
    sokol-shdc is a shader cross-compiler and code generator. It takes 'annotated GLSL' source files (Vulkan-style GLSL version 450) and translates them into various shader dialects and language-specific headers (C, Zig, Rust, Odin, etc.) for use with sokol-gfx or other language bindings.
  2. How to annotate GLSL for sokol-shdc

    master

    To use sokol-shdc, you must annotate your GLSL source with @-tags. These tags allow you to pack multiple shader stages (vertex, fragment, etc.) into a single file and define shader programs.

    Common tags:

    • @vs [name]: Marks the start of a vertex shader stage.
    • @fs [name]: Marks the start of a fragment shader stage.
    • @end: Marks the end of a shader stage.
    • @program [name] [vs_name] [fs_name]: Defines a shader program by linking a vertex shader and a fragment shader.

    For compatibility with other GLSL parsers, you can prefix tags with #pragma sokol (e.g., #pragma sokol @program ...).

    @vs vs
    layout(binding=0) uniform vs_params {
        mat4 mvp;
    };
    
    in vec4 position;
    in vec2 texcoord0;
    
    out vec2 uv;
    
    void main() {
        gl_Position = mvp * position;
        uv = texcoord0;
    }
    @end
    
    @fs fs
    layout(binding=0) uniform texture2D tex;
    layout(binding=0) uniform sampler smp;
    
    in vec2 uv;
    out vec4 frag_color;
    
    void main() {
        frag_color = texture(sampler2D(tex,smp), uv);
    }
    @end
    
    @program texcube vs fs
  3. sokol_shdc: Shader cross-compiler and code-generator

    master
    The sokol_shdc tool is a shader cross-compiler and code-generator specifically designed for use with sokol_gfx.h. Detailed documentation for this tool can be found in docs/sokol-shdc.md.
  4. Map GLSL types to C math libraries using @ctype

    master

    By default, sokol-shdc maps GLSL types to standard C types (e.g., mat4 to float[16]). If you use a math library like GLM or HandmadeMath, use the @ctype tag at the top of your GLSL file to map types to your library's specific types. This ensures the generated C structs are directly compatible with your math types.

    Supported GLSL types for mapping: float, vec2, vec3, vec4, int, int2, int3, int4, and mat4.

    Requirement: Mapped C/C++ types must match these byte sizes:

    • mat4: 64 bytes
    • vec4, int4: 16 bytes
    • vec3, int3: 12 bytes
    • vec2, int2: 8 bytes
    • float, int: 4 bytes
    @ctype mat4 hmm_mat4
    @ctype vec4 hmm_vec4
    
    @vs my_vs
    layout(binding=0) uniform shape_uniforms {
        mat4 mvp;
        mat4 model;
        vec4 shape_color;
        vec4 light_dir;
        vec4 eye_pos;
    };
    @end
  5. Define and bind resource slots in GLSL

    master

    All resources must use explicit layout(binding=N) annotations. These bindings map to specific indices in the sokol-gfx API. Bindings must be unique within their respective spaces for a given @program.

    Binding Spaces and Ranges

    • Uniform Blocks: layout(binding=N) uniform { ... } where 0 <= N < 8. Maps to ub_slot in sg_apply_uniforms(N, ...).
    • Textures, Storage Images, and Storage Buffers: layout(binding=N) texture2D ... or layout(binding=N) buffer ... where 0 <= N < 32. Maps to the index in sg_bindings.views[N].
    • Samplers: layout(binding=N) sampler ... where 0 <= N < 12. Maps to the index in sg_bindings.samplers[N].

    Usage Example

    // Uniform Block
    layout(binding=0) uniform vs_params { mat4 mvp; };
    
    // Texture and Sampler
    layout(binding=1) uniform texture2D tex;
    layout(binding=1) uniform sampler smp;
    
    // Storage Buffer
    layout(binding=2) readonly buffer in_ssbo { vec4 data[]; };
  6. How to link shader stages into a program

    master

    To create a usable shader program, you must use the @program tag to link your defined stages. The name provided to @program determines the name of the generated C function used to retrieve the sg_shader_desc and the prefix for generated constants.

    For a vertex-fragment pair:

    @vs my_vertex_shader
    ...
    @end
    
    @fs my_fragment_shader
    ...
    @end
    
    @program my_program my_vertex_shader my_fragment_shader

    This generates a C function:

    static const sg_shader_desc* my_program_shader_desc(sg_backend backend);
    @program my_program my_vertex_shader my_fragment_shader
  7. Configure build for IDE debugging

    master

    To debug the tools using an IDE, use ./fibs config to select a specific debug configuration for your platform and editor, then use ./fibs open to launch the project.

    # Select a debug configuration
    ./fibs config macos-xcode-debug
    ./fibs config macos-vscode-debug
    ./fibs config win-vstudio-debug
    ./fibs config win-vscode-debug
    ./fibs config linux-vscode-debug
    
    # Launch the project in your IDE
    ./fibs open
  8. Integrate sokol-shdc with fips build systems

    master

    For fips projects, sokol-shdc can be integrated directly into the build process.

    1. Add sokol-tools-bin to your fips.yml imports:
      imports:
          sokol-tools-bin:
              git: https://github.com/floooh/sokol-tools-bin
    2. Run ./fips fetch and ./fips update.
    3. Use the sokol_shader() macro in your CMakeLists.txt for each GLSL file:
      fips_begin_app(triangle windowed)
          sokol_shader(triangle.glsl ${slang})
      fips_end_app()

    Note: The ${slang} variable should be set based on your target platform (e.g., glsl300es for GLES3, hlsl5 for D3D11, metal_macos for Metal).

    # Example of setting the slang variable based on platform
    if (SOKOL_USE_D3D11)
        add_definitions(-DSOKOL_D3D11)
        set(slang "hlsl5")
    elseif (SOKOL_USE_METAL)
        add_definitions(-DSOKOL_METAL)
        set(slang "metal_macos")
    endif()
  9. Conditional compilation for target shader languages

    master

    You can use preprocessor checks in your GLSL source to write code that behaves differently depending on the target language (GLSL, HLSL, MSL, or WGSL). These checks are evaluated during the initial compiler pass and should be used inside @vs, @fs, or @block blocks.

    #if SOKOL_GLSL
        // target shader language is a GLSL dialect
    #endif
    
    #if SOKOL_HLSL
        // target shader language is HLSL
    #endif
    
    #if SOKOL_MSL
        // target shader language is MetalSL
    #endif
    
    #if SOKOL_WGSL
        // target shader language is WGSL
    #endif
    #if SOKOL_GLSL
        // target shader language is a GLSL dialect
    #endif
  10. Use sokol-shdc standalone via CLI

    master

    You can run sokol-shdc as an offline tool from the command line. Precompiled 64-bit binaries for Windows, Linux, and macOS are available in the sokol-tools-bin repository.

    Basic Usage Example: To convert a file named shd.glsl into a C header shd.h supporting multiple dialects:

    ./sokol-shdc --input shd.glsl --output shd.h --slang glsl430:hlsl5:metal_macos