glsl-optimizer
GLSL optimizer based on Mesa's GLSL compiler. Used to be used in Unity for mobile shader optimization.
Top Related Projects
Khronos-reference front end for GLSL/ESSL, partial front end for HLSL, and a SPIR-V generator.
A collection of tools, libraries, and tests for Vulkan shader compilation.
This repo hosts the source for the DirectX Shader Compiler which is based on LLVM/Clang.
Tool suite for Texture and 3D Model Compression, Optimization and Analysis using CPUs, GPUs and APUs
Quick Overview
GLSL-Optimizer is a C++ library and standalone tool designed to optimize OpenGL Shading Language (GLSL) shaders. It aims to improve shader performance and reduce code size by applying various optimization techniques. The project is particularly useful for game developers and graphics programmers working with GLSL shaders.
Pros
- Improves shader performance and reduces code size
- Supports both vertex and fragment shaders
- Can be used as a standalone tool or integrated into existing projects
- Actively maintained and regularly updated
Cons
- Limited to GLSL shaders only, not applicable to other shading languages
- May not always produce optimal results for all shader types
- Requires some understanding of GLSL and shader optimization techniques
- Documentation could be more comprehensive
Code Examples
- Basic usage of the optimizer:
#include "glsl_optimizer.h"
const char* shaderSource = R"(
#version 330
uniform mat4 MVP;
in vec3 position;
void main() {
gl_Position = MVP * vec4(position, 1.0);
}
)";
glslopt_ctx* ctx = glslopt_initialize(kGlslTargetOpenGL);
glslopt_shader* shader = glslopt_optimize(ctx, kGlslOptShaderVertex, shaderSource, 0);
if (glslopt_get_status(shader)) {
const char* optimizedSource = glslopt_get_output(shader);
// Use optimizedSource...
} else {
const char* errorLog = glslopt_get_log(shader);
// Handle error...
}
glslopt_shader_delete(shader);
glslopt_cleanup(ctx);
- Optimizing a fragment shader:
const char* fragmentShaderSource = R"(
#version 330
in vec2 texCoord;
uniform sampler2D mainTex;
out vec4 fragColor;
void main() {
vec4 color = texture(mainTex, texCoord);
fragColor = color * vec4(1.0, 0.5, 0.2, 1.0);
}
)";
glslopt_shader* fragShader = glslopt_optimize(ctx, kGlslOptShaderFragment, fragmentShaderSource, 0);
// ... (similar to previous example)
- Using the standalone tool:
./glsl_optimizer --version 330 --type vertex input_shader.glsl
Getting Started
-
Clone the repository:
git clone https://github.com/aras-p/glsl-optimizer.git
-
Build the project:
cd glsl-optimizer mkdir build && cd build cmake .. make
-
Include the necessary headers and link against the library in your project:
#include "glsl_optimizer.h" // ... (see code examples for usage)
-
Compile your project with the GLSL-Optimizer library.
Competitor Comparisons
Khronos-reference front end for GLSL/ESSL, partial front end for HLSL, and a SPIR-V generator.
Pros of glslang
- Official Khronos Group reference compiler for GLSL and ESSL
- Supports a wider range of GLSL versions and extensions
- More actively maintained with frequent updates
Cons of glslang
- Larger codebase, potentially more complex to integrate
- May have higher overhead for simple optimization tasks
- Primarily focused on validation and compilation, less on optimization
Code Comparison
glslang:
#include "glslang/Public/ShaderLang.h"
// Initialize glslang
glslang::InitializeProcess();
// Compile and link shaders
glslang::TShader shader(EShLangVertex);
shader.setStrings(&shaderSource, 1);
shader.setEnvInput(glslang::EShSourceGlsl, EShLangVertex, glslang::EShClientVulkan, 100);
shader.setEnvClient(glslang::EShClientVulkan, glslang::EShTargetVulkan_1_0);
shader.setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_0);
glsl-optimizer:
#include "glsl_optimizer.h"
// Initialize optimizer
glslopt_ctx* ctx = glslopt_initialize(kGlslTargetOpenGL);
// Optimize shader
glslopt_shader* shader = glslopt_optimize(ctx, kGlslOptShaderVertex, shaderSource, 0);
const char* optimizedSource = glslopt_get_output(shader);
glslang offers more comprehensive GLSL support and validation, while glsl-optimizer focuses on quick and simple optimizations for specific targets.
A collection of tools, libraries, and tests for Vulkan shader compilation.
Pros of shaderc
- More comprehensive toolset for shader compilation and optimization
- Better integration with Vulkan ecosystem and SPIR-V
- Active development and maintenance by Google
Cons of shaderc
- Larger codebase and potentially more complex setup
- May have higher resource requirements for compilation
Code Comparison
glsl-optimizer:
void main() {
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_FrontColor = gl_Color;
}
shaderc:
#version 450
layout(location = 0) in vec4 position;
layout(location = 1) in vec4 color;
layout(location = 0) out vec4 fragColor;
void main() {
gl_Position = position;
fragColor = color;
}
Key Differences
- glsl-optimizer focuses on GLSL optimization for OpenGL ES 2.0 and 3.0
- shaderc provides a more comprehensive toolchain for modern graphics APIs
- glsl-optimizer is lighter and more focused, while shaderc offers broader functionality
- shaderc has better support for cross-compilation and multiple shader languages
Use Cases
- glsl-optimizer: Mobile and web-based OpenGL ES applications
- shaderc: Modern graphics applications, especially those using Vulkan or requiring SPIR-V output
This repo hosts the source for the DirectX Shader Compiler which is based on LLVM/Clang.
Pros of DirectXShaderCompiler
- More comprehensive and actively maintained by Microsoft
- Supports DirectX Intermediate Language (DXIL) and HLSL
- Integrates with the DirectX ecosystem and toolchain
Cons of DirectXShaderCompiler
- Larger and more complex codebase
- Primarily focused on DirectX, less versatile for other graphics APIs
- Steeper learning curve for contributors
Code Comparison
glsl-optimizer:
void glsl_optimize(glslopt_ctx* ctx, glslopt_shader_type type, const char* shaderSource, unsigned options) {
// Optimization logic for GLSL shaders
}
DirectXShaderCompiler:
HRESULT WINAPI DxcCompile(
LPCWSTR pFileName,
LPCWSTR const* pArguments,
UINT32 argCount,
IDxcIncludeHandler* pIncludeHandler,
REFIID riid,
void** ppResult
) {
// Compilation and optimization for HLSL shaders
}
Summary
glsl-optimizer is a lightweight, focused tool for optimizing GLSL shaders, while DirectXShaderCompiler is a more comprehensive solution for DirectX shader compilation and optimization. The choice between them depends on the specific graphics API and ecosystem requirements of your project.
Tool suite for Texture and 3D Model Compression, Optimization and Analysis using CPUs, GPUs and APUs
Pros of Compressonator
- Broader scope: Supports various texture compression formats and image processing tasks
- Active development: Regularly updated with new features and improvements
- Comprehensive toolset: Includes GUI and command-line tools for texture compression and analysis
Cons of Compressonator
- Larger codebase: More complex and potentially harder to integrate into existing projects
- Steeper learning curve: Requires more time to understand and utilize all features effectively
- Platform-specific: Primarily focused on Windows, with limited support for other platforms
Code Comparison
glsl-optimizer:
void glsl_optimize(glslopt_ctx* ctx, glslopt_shader_type type, const char* shader) {
// Optimization logic here
}
Compressonator:
CMP_ERROR CompressTexture(CMP_MipSet* pMipSetIn, CMP_MipSet* pMipSetOut, const CMP_CompressOptions* pOptions) {
// Compression logic here
}
The code snippets demonstrate the different focus areas of each project. glsl-optimizer is centered around shader optimization, while Compressonator provides a more comprehensive texture compression API.
Pros of SPIRV-Tools
- Supports a wider range of shader languages and APIs, including Vulkan and OpenCL
- Actively maintained by Khronos Group, ensuring up-to-date compatibility with latest standards
- Provides comprehensive tooling for SPIR-V manipulation, including validation and optimization
Cons of SPIRV-Tools
- More complex to use and integrate, requiring deeper understanding of SPIR-V
- Larger codebase and potentially higher resource usage
- May have a steeper learning curve for developers new to SPIR-V
Code Comparison
SPIRV-Tools (C++):
spv_context context = spvContextCreate(SPV_ENV_UNIVERSAL_1_5);
spv_diagnostic diagnostic = nullptr;
spv_result_t result = spvValidate(context, module, &diagnostic);
spvContextDestroy(context);
glsl-optimizer (C):
glslopt_ctx* ctx = glslopt_initialize(kGlslTargetOpenGL);
glslopt_shader* shader = glslopt_optimize(ctx, kGlslOptShaderFragment, shaderSource, 0);
const char* optimizedSource = glslopt_get_output(shader);
glslopt_shader_delete(shader);
glslopt_cleanup(ctx);
Summary
SPIRV-Tools offers broader language support and more comprehensive tooling for SPIR-V, while glsl-optimizer focuses specifically on GLSL optimization. SPIRV-Tools is more complex but provides greater flexibility, whereas glsl-optimizer is simpler to use for GLSL-specific tasks.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
GLSL optimizer
:warning: As of mid-2016, the project is unlikely to have any significant developments. At Unity we are moving to a different shader compilation pipeline, with glsl-optimizer is not used. So from my side there won't be significant work done on it. :warning:
A C++ library that takes GLSL shaders, does some GPU-independent optimizations on them and outputs GLSL or Metal source back. Optimizations are function inlining, dead code removal, copy propagation, constant folding, constant propagation, arithmetic optimizations and so on.
Apparently quite a few mobile platforms are pretty bad at optimizing shaders; and unfortunately they also lack offline shader compilers. So using a GLSL optimizer offline before can make the shader run much faster on a platform like that. See performance numbers in this blog post.
Even for drivers that have decent shader optimization, GLSL optimizer could be useful to just strip away dead code, make shaders smaller and do uniform/input reflection offline.
Almost all actual code is Mesa 3D's GLSL compiler; all this library does is spits out optimized GLSL or Metal back, and adds GLES type precision handling to the optimizer.
This GLSL optimizer is made for Unity's purposes and is built-in starting with Unity 3.0.
GLSL Optimizer is licensed according to the terms of the MIT license.
See change log here.
Usage
Visual Studio 2010 (Windows, x86/x64) and Xcode 5+ (Mac, i386) project files for a static
library are provided in projects/vs2010/glsl_optimizer.sln
and projects/xcode5/glsl_optimizer_lib
respectively.
Note: only the VS and Xcode project files are maintained and should work at any time. There's also a cmake and gyp build system for Linux et al., and some stuff in contrib folder - all that may or might not work.
For Linux you can use cmake. Just type "cmake . && make" in the root directory. This will build the optimizer library and some executable binaries.
Interface for the library is src/glsl/glsl_optimizer.h
. General usage is:
ctx = glslopt_initialize(targetVersion);
for (lots of shaders) {
shader = glslopt_optimize (ctx, shaderType, shaderSource, options);
if (glslopt_get_status (shader)) {
newSource = glslopt_get_output (shader);
} else {
errorLog = glslopt_get_log (shader);
}
glslopt_shader_delete (shader);
}
glslopt_cleanup (ctx);
Tests
There's a testing suite for catching regressions, see tests
folder. In VS, build
and run glsl_optimizer_tests
project; in Xcode use projects/xcode5/glsl_optimizer_tests
project. The test executable requires path to the tests
folder as an argument.
Each test comes as three text files; input, expected IR dump and expected optimized GLSL dump. GLES3 tests are also converted into Metal.
If you're making changes to the project and want pull requests accepted easier, I'd appreciate if there would be no test suite regressions. If you are implementing a feature, it would be cool to add tests to cover it as well!
Notes
- GLSL versions 1.10 and 1.20 are supported. 1.10 is the default, use #version 120 to specify 1.20. Higher GLSL versions might work, but aren't tested now.
- GLSL ES versions 1.00 and 3.00 are supported.
Dev Notes
Pulling Mesa upstream:
git fetch upstream
git merge upstream/master
sh removeDeletedByUs.sh
# inspect files, git rm unneeded ones, fix conflicts etc.
# git commit
Rebuilding flex/bison parsers:
- When .y/.l files are changed, the parsers are not rebuilt automatically,
- Run ./generateParsers.sh to do that. You'll need bison & flex (on Mac, do "Install Command Line Tools" from Xcode)
- I use bison 2.3 and flex 2.5.35 (in OS X 10.8/10.9)
Top Related Projects
Khronos-reference front end for GLSL/ESSL, partial front end for HLSL, and a SPIR-V generator.
A collection of tools, libraries, and tests for Vulkan shader compilation.
This repo hosts the source for the DirectX Shader Compiler which is based on LLVM/Clang.
Tool suite for Texture and 3D Model Compression, Optimization and Analysis using CPUs, GPUs and APUs
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot