# Tinyshader **Lightweight, easy to embed HLSL to SPIR-V compiler written in C99** ## Using the command-line compiler The command-line compiler sources are located under the folder `tsc` and can be used as follows: ``` Usage: tsc --shader-stage | -T --entry-point | -E -o ``` ## Using the compiler as a library The compiler library sources are located under the folder `tinyshader` and can be used as follows: ```c #include "tinyshader.h" TsCompilerOptions *options = tsCompilerOptionsCreate(); tsCompilerOptionsSetStage(options, TS_SHADER_STAGE_VERTEX); const char *entry_point = "main"; tsCompilerOptionsSetEntryPoint(options, entry_point, strlen(entry_point)); tsCompilerOptionsSetSource( options, hlsl_source, strlen(hlsl_source), path, // optional, can be NULL strlen(path) // if path is NULL, this should be zero ); TsCompilerOutput *output = tsCompile(options); /* * 'errors' is a null-terminated string containing compiler error messages. * If it's NULL, compilation was successful. */ const char *errors = tsCompilerOutputGetErrors(output); if (errors) { printf("%s\n", errors); exit(1); } /* * Now we have SPIR-V code, ready to pass to Vulkan. * NOTE: the spirv pointer is owned by TsCompilerOutput and is freed when it's destroyed. */ size_t spirv_byte_size; const unsigned char *spirv = tsCompilerOutputGetSpirv(output, &spirv_byte_size); // Cleanup tsCompilerOutputDestroy(output); tsCompilerOptionsDestroy(options); ``` ## Compiling Compiling tinyshader is very simple, you just need to compile the `tinyshader/tinyshader_*.c` files (except `tinyshader/tinyshader_unity.c`), no complicated build system involved. Alternatively you can also compile `tinyshader/tinyshader_unity.c` to compile all of the files in one go. ## Goals and implemented features The goal of this compiler is to be as compatible as possible with [DXC](https://github.com/microsoft/DirectXShaderCompiler), implementing most of its features, while being very lightweight in terms of code size. So far, though, only a subset of HLSL features are supported. You can check out the progress in [this issue](https://github.com/felipeagc/tinyshader/issues/1). Regarding optimization and quality of the generated code, tinyshader is supposed to provide 80% of what you need for 10% of the code, so more advanced optimization is not planned as of now. ## Vulkan resource binding ### Descriptor set/binding mapping Descriptor binding information can either be automatic (using only descriptor set 0 and incremented bindings) or explicit through the `[[vk::binding(binding, set)]]` attribute. HLSL register bindings are currently ignored. Examples of resource binding: ```hlsl ConstantBuffer gInput; // Binding: 0, Set: 0 Texture2D gInput2; // Binding: 1, Set: 0 SamplerState gInput3; // Binding: 2, Set: 0 ``` ```hlsl [[vk::binding(0)]] ConstantBuffer gInput; // Binding: 0, Set: 0 [[vk::binding(1)]] Texture2D gInput2; // Binding: 1, Set: 0 [[vk::binding(2)]] SamplerState gInput3; // Binding: 2, Set: 0 ``` ```hlsl [[vk::binding(0)]] ConstantBuffer gInput; // Binding: 0, Set: 0 [[vk::binding(1, 0)]] Texture2D gInput2; // Binding: 1, Set: 0 [[vk::binding(2, 1)]] SamplerState gInput3; // Binding: 2, Set: 1 ``` ### Stage inputs/outputs You can either pass the stage inputs/outputs as individual parameters or put them in a struct, where each struct member occupies a location. You can also use the returned value of a function as the stage output. Examples of stage inputs/outputs: ```hlsl void main( in float4 pos : POSITION, // Input location: 0 in float2 uv : TEXCOORD0, // Input location: 1 out float4 out_color : SV_Target // Output location: 0 ) { out_color = 1.0f; } ``` ```hlsl struct PSInput { float4 pos : POSITION; // Input location: 0 float4 sv_pos : SV_Position; // Same as gl_FragCoord from GLSL, doesn't count as an input location float2 uv : TEXCOORD0; // Input location: 1 }; float4 main(in PSInput ps_in) : SV_Target { return float4(ps_in.uv, 0.0, 1.0); // Outputs to location 0 } ``` ## License This library is available to anybody free of charge, under the terms of MIT License (see [LICENSE](https://github.com/felipeagc/tinyshader/blob/master/LICENSE)).