GLSL to SPIR-V / SMOL-V Utility

GLSL to SPIR-V / SMOL-V Utility - Made with GeeXLab


Here is a small utility that generates SPIR-V and SMOL-V binary modules (for Vulkan and OpenGL applications) from a GLSL shader. SMOL-V is a compressor for SPIR-V shader modules:

SMOL-V encodes Vulkan/Khronos SPIR-V format programs into a form that is smoller, and is more compressible. Normally no changes to the programs are done; they decode into exactly same program as what was encoded. Optionally, debug information can be removed too.

SPIR-V is a very verbose format, several times larger than same programs expressed in other shader formats (e.g. DX11 bytecode, GLSL, DX9 bytecode etc.). The SSA-form with ever increasing IDs is not very appreciated by regular data compressors either. SMOL-V does several things to improve this:

– Many words, especially ones that most often have small values, are encoded using “varint” scheme (1-5 bytes per word, with just one byte for values in 0..127 range).

– Some IDs used in the program are delta-encoded, relative to previously seen IDs (e.g. Result IDs). Often instructions reference things that were computed just before, so this results in small deltas. These values are also encoded using “varint” scheme.

– Reordering instruction opcodes so that the most common ones are the smallest values, for smaller varint encoding.
– Encoding several instructions in a more compact form, e.g. the “typical <=4 component swizzle" shape of a VectorShuffle instruction, or sequences of MemberDecorate instructions.

SMOL-V is a tiny C/C++ library that can be easily embedded in any application. SMOL-V exposes two functions, one for encoding (SPIR-V to SMOL-V) and one for decoding (SMOL-V to SPIR-V).

I tested the compression with SMOL-V on the following vertex shader:

#version 450

layout (std140, binding = 2) uniform uniforms_t
  mat4 ViewProjectionMatrix;
  mat4 ModelMatrix;
} ub;

layout (location = 0) in vec4 vposition;
layout (location = 3) in vec4 vcolor;
layout (location = 0) out vec4 v_color;

out gl_PerVertex 
  vec4 gl_Position;

void main()
  vec4 P = ub.ModelMatrix * vposition;
  gl_Position = ub.ViewProjectionMatrix * P;
  v_color = vcolor;

And here are the results:

GLSL to SPIR-V / SMOL-V Utility

SMOL-V binaries are more or less 4 times smaller than SPIR-V binaries.