Code Monkey home page Code Monkey logo

glsl-optimizer's Introduction

GLSL optimizer

⚠️ 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. ⚠️

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)

glsl-optimizer's People

Contributors

agd5f avatar airlied avatar anholt avatar aras-p avatar brianpaul avatar chrisforbes avatar curro avatar cworth-gh avatar evelikov avatar freedreno-zz avatar ianromanick avatar imirkin avatar jljusten2 avatar jrfonseca avatar kaydenl avatar krh avatar luca-barbieri avatar marekolsak avatar mattst88 avatar mcencora avatar mostawesomedude avatar nhaehnle avatar olvaffe avatar stereotype441 avatar tstellaramd avatar versalinyaa avatar vinsonlee avatar wallbraker avatar xhaihao avatar zackr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

glsl-optimizer's Issues

Do mat_op_to_vec optimizations

do_mat_op_to_vec could be called after constant folding. The kind of optimizations this does:

Original code: vec3 N = normalize((sys_WorldMatrix * vec4( vec3( 1.0, 0.0, 0.0 ), 0 )).xyz);
Current: tmpvar_1 = normalize((sys_WorldMatrix * vec4(1.0, 0.0, 0.0, 0.0)).xyz);
With mat_op_to_vec: tmpvar_1 = normalize(sys_WorldMatrix[0].xyz);

However just running that turns all matrix ops into vectors, which both looks long and (potentially?) has some downsides.

Find a way to only do the mat_op_to_vec when less than "all" results are used?

precision issue causes shader crash on nexus 7

I have a shader that, when optimised, crashes on Nexus 7.

It's caused by 'lowp' not being applied to a variable being passed to a function's out parameter.

Optimised result:

//Func decl
void FSMain (  in vec2 InTexCoord_1,  in vec4 InColour_2,  out lowp vec4 utColour_3)
//calling code:
  vec4 xlat_temp_OutColour_7; // some other stuff removed.
 FSMain (tmpvar_8, tmpvar_9, xlat_temp_OutColour_7);

I guess the result should be:

//Func decl
void FSMain (  in vec2 InTexCoord_1,  in vec4 InColour_2,  out lowp vec4 utColour_3)
//calling code:
  lowp vec4 xlat_temp_OutColour_7; // some other stuff removed.
 FSMain (tmpvar_8, tmpvar_9, xlat_temp_OutColour_7);

I tested this and my N7 seems happy with it.

Here's the shader that causes the woe:

#ifdef PROFILE_ES2
precision mediump float;
#endif // PROFILE_ES2
//
// Global variable definitions
//
uniform sampler2D _MainTex;
//
// Function declarations
//
void FSMain( in vec2 InTexCoord, in vec4 InColour, out vec4 OutColour );
//
// Function definitions
//
void FSMain( in vec2 InTexCoord, in vec4 InColour, out vec4 OutColour ) {
    OutColour = texture2D( _MainTex, InTexCoord);
    OutColour *= InColour;
}
//
// User varying
//
varying vec4 xlat_varying_TEXCOORD0;
varying vec4 xlat_varying_COLOR0;
//
// Translator's entry point
//
void main() {
    vec4 xlat_temp_OutColour;
    FSMain( vec2(xlat_varying_TEXCOORD0), vec4(xlat_varying_COLOR0), xlat_temp_OutColour);
    gl_FragData[0] = vec4( xlat_temp_OutColour);
;
}

Al.

Thread safety issues (was: calling glslopt_initialize/glslopt_cleanup many times)

We build the glsl optimizer source directly into an ios app and (perhaps not the best practice) create a new glslopt_ctx for each shader we compile at runtime. Recently (possibly as of Xcode 6) we seem to be dying sometimes inside glslopt_cleanup with memory errors, or glslopt_optimize starts failing with a lot of error messages about seemingly correct code.

Before I do a lot of digging to try to narrow down a test case I wondering if creating multiple glslopt contexts per process/GL context/whatever is even safe to do, or if there is global state being stored somewhere.

Compiling on Gentoo

Hi there,

I have trouble with compiling on Gentoo, I will probably do a fork and just fix this but also want to share.

[ 98%] Building CXX object CMakeFiles/glsl_compiler.dir/src/glsl/main.cpp.o
/usr/bin/x86_64-pc-linux-gnu-g++ -DNDEBUG -O2 -pipe -march=corei7-avx -fno-omit-frame-pointer -Os -DNDEBUG -I/tmp/portage/gfx-tools/glsl-optimizer-9999/work/glsl-optimizer-9999/include -I/tmp/portage/gfx-tools/glsl-optimizer-9999/work/glsl-optimizer-9999/src/mesa -I/tmp/portage/gfx-tools/glsl-optimizer-9999/work/glsl-optimizer-9999/src/mapi -I/tmp/portage/gfx-tools/glsl-optimizer-9999/work/glsl-optimizer-9999/src/glsl -I/tmp/portage/gfx-tools/glsl-optimizer-9999/work/glsl-optimizer-9999/src -o CMakeFiles/glsl_compiler.dir/src/glsl/main.cpp.o -c /tmp/portage/gfx-tools/glsl-optimizer-9999/work/glsl-optimizer-9999/src/glsl/main.cpp
Linking CXX executable glsl_compiler
/usr/bin/cmake -E cmake_link_script CMakeFiles/glsl_compiler.dir/link.txt --verbose=1
/usr/bin/x86_64-pc-linux-gnu-g++ -O2 -pipe -march=corei7-avx -fno-omit-frame-pointer -Os -DNDEBUG CMakeFiles/glsl_compiler.dir/src/glsl/main.cpp.o -o glsl_compiler -rdynamic libglsl_optimizer.a libglcpp-library.a libmesa.a
libglsl_optimizer.a(standalone_scaffolding.cpp.o): In function _mesa_error_no_memory': standalone_scaffolding.cpp:(.text+0xf): multiple definition of_mesa_error_no_memory'
CMakeFiles/glsl_compiler.dir/src/glsl/main.cpp.o:main.cpp:(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
make[2]: *** [glsl_compiler] Error 1
make[2]: Leaving directory /tmp/portage/gfx-tools/glsl-optimizer-9999/work/glsl-optimizer-9999_build' make[1]: *** [CMakeFiles/glsl_compiler.dir/all] Error 2 make[1]: Leaving directory/tmp/portage/gfx-tools/glsl-optimizer-9999/work/glsl-optimizer-9999_build'
make: *** [all] Error 2

Looks like the _mesa_error_no_memory function is defined in
src/glsl/main.cpp and in
src/glsl/standalone_scaffolding.cpp
and that causes an error while linking.

Regards,
Iegor

Linker error in VS 2013

Hi,
I'm having problems linking the static lib in a project.
I've added the glsl_optimizer_lib project as a reference, and the library builds fine. But then when I use
glslopt_ctx* ctx = glslopt_initialize(kGlslTargetOpenGLES20);

I get:
1>MainComponent.obj : error LNK2019: unresolved external symbol "class glslopt_ctx * __cdecl glslopt_initialize(enum glslopt_target)" (?glslopt_initialize@@YAPAVglslopt_ctx@@W4glslopt_target@@@z) referenced in function "public: __thiscall MainContentComponent::MainContentComponent(void)" (??0MainContentComponent@@QAE@XZ)

I've tried every possible way of adding the library: project reference, additional dependencies, etc.
I'm fairly sure that the compiler is finding the lib, but still. Is there something I'm missing? An extra dependency?
I've tried including the source directly but it won't build due to typedef clashes (my project also uses OpenGL) and before digging into that I thought I'd ask here.
Any help at all would be most appreciated.

Rob

Build error under Linux

I have compile error under Debian squize 64-bit:
[ 96%] Building C object CMakeFiles/glcpp.dir/src/glsl/glcpp/glcpp.c.o
In file included from /home/alex/src/glsl-optimizer-master/src/glsl/glcpp/glcpp.c:29:
/home/alex/src/glsl-optimizer-master/src/glsl/glcpp/../standalone_scaffolding.h:36: error: expected identifier or ‘(’ before string constant
/home/alex/src/glsl-optimizer-master/src/glsl/glcpp/../standalone_scaffolding.h:40: error: expected identifier or ‘(’ before string constant
/home/alex/src/glsl-optimizer-master/src/glsl/glcpp/../standalone_scaffolding.h:43: error: expected identifier or ‘(’ before string constant
make[2]: *** [CMakeFiles/glcpp.dir/src/glsl/glcpp/glcpp.c.o] Error 1
make[1]: *** [CMakeFiles/glcpp.dir/all] Error 2
make: *** [all] Error 2

if i try to enclose definitions in standalone_scaffolding.h like this:

ifdef _cplusplus

extern "C" {

endif

void _mesa_reference_shader(struct gl_context _ctx, struct gl_shader *_ptr,
struct gl_shader *sh);

ifdef _cplusplus

}

endif

i have another compilie error later:
[ 97%] Building CXX object CMakeFiles/glsl_compiler.dir/src/glsl/main.cpp.o
Linking CXX executable glsl_compiler
libglsl_optimizer.a(builtin_function.cpp.o): In function read_builtins(unsigned int, char const*, char const**, unsigned int)': builtin_function.cpp:(.text+0x74): undefined reference to_mesa_new_shader'
libglsl_optimizer.a(linker.cpp.o): In function link_shaders(gl_context*, gl_shader_program*)': linker.cpp:(.text+0x1dcb): undefined reference to_mesa_reference_shader'
linker.cpp:(.text+0x1e17): undefined reference to `_mesa_reference_shader'
collect2: ld returned 1 exit status
make[2]: *** [glsl_compiler] Error 1
make[1]: *** [CMakeFiles/glsl_compiler.dir/all] Error 2
make: *** [all] Error 2

Build error on OSX: 'util/ralloc.h' file not found

On OSX 10.10.1 I get the following build error trying to install the current HEAD of master:

$ npm install git+https://github.com/aras-p/glsl-optimizer.git
|
> [email protected] install ./node_modules/glsl-optimizer
> node-gyp rebuild

  CC(target) Release/obj.target/glsl_optimizer_lib/src/glsl/glcpp/glcpp-lex.o
In file included from src/glsl/glcpp/glcpp-lex.l:29:
../src/glsl/glcpp/glcpp.h:32:10: fatal error: 'util/ralloc.h' file not found
#include "util/ralloc.h"
         ^
1 error generated.
make: *** [Release/obj.target/glsl_optimizer_lib/src/glsl/glcpp/glcpp-lex.o] Error 1

context constants / limits

Why are all opengl context constants hardcoded?
Would be nice to set them after construction of the glsl context.

cmake issue

CMake Error at CMakeLists.txt:21 (list):
list sub-command REMOVE_ITEM requires two or more arguments.

-- Configuring incomplete, errors occurred!

Linux chris-LIFEBOOK-AH532 3.8.0-21-generic #32-Ubuntu SMP Tue May 14 22:16:46 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

Build on Linux+CMake is broken

Hi,

Here is the error I receive at the very beginning:

In file included from src/glsl/glcpp/glcpp-parse.y:31:0:
/home/noob/CoolCode/glsl-optimizer/src/glsl/glcpp/glcpp.h:32:25: fatal error: util/ralloc.h: No such file or directory
 #include "util/ralloc.h"
                         ^
compilation terminated.
CMakeFiles/glcpp-library.dir/build.make:54: recipe for target 'CMakeFiles/glcpp-library.dir/src/glsl/glcpp/glcpp-parse.c.o' failed
make[2]: *** [CMakeFiles/glcpp-library.dir/src/glsl/glcpp/glcpp-parse.c.o] Error 1
CMakeFiles/Makefile2:60: recipe for target 'CMakeFiles/glcpp-library.dir/all' failed
make[1]: *** [CMakeFiles/glcpp-library.dir/all] Error 2
Makefile:76: recipe for target 'all' failed
make: *** [all] Error 2

Tried with CMake in both a separate build directory, and an in-source build; neither worked. Running Gentoo.

all( ) and && operator inside

Hi,

I have something like that in my shader :

    bool InRect( vec2 uv ){
        return all( greaterThan( uv , vec2(1.0/1024.0) ) && lessThan( uv , vec2(1023.0/1024.0) ) );
    }

greaterThan and lessThan returns bvec2. So ( bvec2 && bvec2 ) return bvec2 too. Thats why I used all( bvec2 ).

glsl-optimizer sees ( bvec2 && bvec2 ) as regular bool && bool so the return type is bool. And all() doesn't allow to bool as an input, so the whole shader optimalization is broken.

BTW, is my solution enought good for testing for uv beeing inside rectangle ?

Invalid call of undeclared identifier 'csel_TODO'

I am getting following errors while using the optimised shader.

ERROR: 0:369: Invalid call of undeclared identifier 'csel_TODO'
WARNING: 0:478: Overflow in implicit constant conversion, minimum range for lowp float is (-2,2)
WARNING: 0:650: Overflow in implicit constant convers

The test app itself generates error when trying to compile the optimised shaders.
How can i fix the errors about 'csel_TODO'?

struct array uniform loses struct definition

This vertex shader:

#version 100
struct shadow_map_t
{
    mat4 transform;
};

uniform shadow_map_t ShadowMaps[1];
attribute vec3 _in_position;

void main()
{   
    gl_Position = ShadowMaps[0].transform * vec4(_in_position,1);
}

Turns into this after optimizing:

#version 100
attribute vec3 _in_position;
uniform shadow_map_t ShadowMaps[1];
void main ()
{
  vec4 tmpvar_1;
  tmpvar_1.w = 1.0;
  tmpvar_1.xyz = _in_position;
  gl_Position = (ShadowMaps[0].transform * tmpvar_1);
}

Notice the definition of the shadow_map_t struct has been lost. This was originally reproduced with a non-ES context and #version 130, but it happens for #version 100 ES as well.

EDIT:

It looks like not having an explicit reference to a variable of type "shadow_map_t" is the cause. If I change the source to:

shadow_map_t sm = ShadowMaps[0];
gl_Position = sm.transform * vec4(_in_position,1);

Then the shadow_map_t definition is preserved.

Precision of constant variables is dropped during operation.

We have a case where a constant variable in an operation is being replaced with it's literal representation, dropping the precision qualifier. This variable was the only highp value in the operation, which means that the whole operation is now performed at mediump.

Here's the case (note that gl_FragCoord is mediump):

highp float time = 1.0;
highp float dither = dot( vec2( 171.0, 231.0 ), gl_FragCoord.xy + vec2( time ) );

is optimized to:

highp float tmpvar_17;
tmpvar_17 = dot (vec2(171.0, 231.0), (gl_FragCoord.xy + vec2(1.0, 1.0)));

The tmpvar_17 calculation now contains only one variable with precision, mediump gl_FragCoord, so the calculation is performed at mediump. Replacing the 1.0 literals with a highp float initialized to 1.0 fixes the issue. The bug here seems to be that constants are being replaced by literals without considering precision.

struct definition appears before default precision statement

We're finding that for a fragment shader with a struct uniform, and a top-level default precision specifier, the optimizer output has the struct definition before the precision statement, leaving the precision of the struct fields undefined.

For instance given this input:

// #version 100
precision mediump float;

struct HColor {
  vec4 diffuse;
  vec4 specular;
};

uniform HColor MaterialColor;

void main ()
{
    gl_FragData[0] = MaterialColor.diffuse;
}

The optimizer produces this output:

struct HColor {
  vec4 diffuse;
  vec4 specular;
};
precision mediump float;
uniform HColor MaterialColor;
void main ()
{
  gl_FragData[0] = MaterialColor.diffuse;
}

Which does not compile.

sqrt(dot(v, v)) is slower than length(v) on Mali GPUs

sqrt(dot(v, v)) is slower than length(v) on Mali GPUs. (Confirmed with their offline binary compiler.)

How does one tweak the glsl optimizer to not replace certain functions? If you could point me at the relevant code, that would be awesome.

#version 130 2d array texture reads get converted to proj

Input:

#version 130

uniform sampler2DArray tilemap;

void main() {

        vec4 col = textureLod(tilemap, vec3(0.0), 0.0);

        gl_FragColor = col;
}

Output:

#version 130
uniform sampler2DArray tilemap;
void main ()
{
  gl_FragColor = textureProjLod (tilemap, vec3(0.0, 0.0, 0.0), 0.0);
}

It's obviously wrong, and won't even compile.

Build error

When I try to build master on Ubuntu 12/04, I get the following error:

behdad:glsl-optimizer 2 (master)$ make
[ 3%] Built target glcpp-library
[ 7%] Built target mesa
[ 97%] Built target glsl_optimizer
[ 98%] Built target glsl_compiler
[ 99%] Built target glsl_test
[100%] Building CXX object CMakeFiles/glslopt.dir/contrib/glslopt/Main.cpp.o
cc1plus: warning: /home/behdad/src/github/glsl-optimizer/src/mapi: No such file or directory [enabled by default]
/home/behdad/src/github/glsl-optimizer/contrib/glslopt/Main.cpp: In function ‘bool init()’:
/home/behdad/src/github/glsl-optimizer/contrib/glslopt/Main.cpp:20:37: error: cannot convert ‘bool’ to ‘glslopt_target’ for argument ‘1’ to ‘glslopt_ctx* glslopt_initialize(glslopt_target)’
compilation terminated due to -Wfatal-errors.
make[2]: *** [CMakeFiles/glslopt.dir/contrib/glslopt/Main.cpp.o] Error 1
make[1]: *** [CMakeFiles/glslopt.dir/all

-fPIC on linux x86_64?

-fPIC is basically a requirement for x64 libs. Consider adding it by default? Otherwise many users will repeat this headache.

gl_FragData[2] not support

Hi
error when use - gl_FragData[2] because index need < 2

but it is wrong, index 2 and 3 is valid and work perfect on devices who support ES 3.0

ir_set_program_inouts.cpp failing to compile

I'm getting this compiler error:

/home/glsl-optimizer/src/glsl/ir_set_program_inouts.cpp: In function ‘void mark(gl_program*, ir_variable*, int, int, bool)’:
/home/glsl-optimizer/src/glsl/ir_set_program_inouts.cpp:87:7: error: ‘GLbitfield64’ was not declared in this scope
/home/glsl-optimizer/src/glsl/ir_set_program_inouts.cpp:87:20: error: expected ‘;’ before ‘bitfield’
/home/glsl-optimizer/src/glsl/ir_set_program_inouts.cpp:89:9: error: ‘struct gl_program’ has no member named ‘InputsRead’
/home/glsl-optimizer/src/glsl/ir_set_program_inouts.cpp:89:23: error: ‘bitfield’ was not declared in this scope
/home/glsl-optimizer/src/glsl/ir_set_program_inouts.cpp:91:13: error: ‘gl_fragment_program’ was not declared in this scope
/home/glsl-optimizer/src/glsl/ir_set_program_inouts.cpp:91:34: error: ‘fprog’ was not declared in this scope
/home/glsl-optimizer/src/glsl/ir_set_program_inouts.cpp:91:64: error: expected primary-expression before ‘)’ token
/home/glsl-optimizer/src/glsl/ir_set_program_inouts.cpp:91:66: error: expected ‘;’ before ‘prog’
/home/glsl-optimizer/src/glsl/ir_set_program_inouts.cpp:98:16: error: ‘struct gl_program’ has no member named ‘SystemValuesRead’
/home/glsl-optimizer/src/glsl/ir_set_program_inouts.cpp:98:36: error: ‘bitfield’ was not declared in this scope
/home/glsl-optimizer/src/glsl/ir_set_program_inouts.cpp:100:9: error: ‘struct gl_program’ has no member named ‘OutputsWritten’
/home/glsl-optimizer/src/glsl/ir_set_program_inouts.cpp:100:27: error: ‘bitfield’ was not declared in this scope
/home/glsl-optimizer/src/glsl/ir_set_program_inouts.cpp: In member function ‘virtual ir_visitor_status ir_set_program_inouts_visitor::visit_enter(ir_expression*)’:
/home/glsl-optimizer/src/glsl/ir_set_program_inouts.cpp:178:7: error: ‘gl_fragment_program’ was not declared in this scope
/home/glsl-optimizer/src/glsl/ir_set_program_inouts.cpp:178:28: error: ‘fprog’ was not declared in this scope
/home/glsl-optimizer/src/glsl/ir_set_program_inouts.cpp:178:58: error: expected primary-expression before ‘)’ token
/home/glsl-optimizer/src/glsl/ir_set_program_inouts.cpp:178:60: error: expected ‘;’ before ‘prog’
/home/glsl-optimizer/src/glsl/ir_set_program_inouts.cpp: In member function ‘virtual ir_visitor_status ir_set_program_inouts_visitor::visit_enter(ir_discard*)’:
/home/glsl-optimizer/src/glsl/ir_set_program_inouts.cpp:190:4: error: ‘gl_fragment_program’ was not declared in this scope
/home/glsl-optimizer/src/glsl/ir_set_program_inouts.cpp:190:25: error: ‘fprog’ was not declared in this scope
/home/glsl-optimizer/src/glsl/ir_set_program_inouts.cpp:190:55: error: expected primary-expression before ‘)’ token
/home/glsl-optimizer/src/glsl/ir_set_program_inouts.cpp:190:57: error: expected ‘;’ before ‘prog’
/home/glsl-optimizer/src/glsl/ir_set_program_inouts.cpp: In function ‘void do_set_program_inouts(exec_list*, gl_program*, bool)’:
/home/glsl-optimizer/src/glsl/ir_set_program_inouts.cpp:202:10: error: ‘struct gl_program’ has no member named ‘InputsRead’
/home/glsl-optimizer/src/glsl/ir_set_program_inouts.cpp:203:10: error: ‘struct gl_program’ has no member named ‘OutputsWritten’
/home/glsl-optimizer/src/glsl/ir_set_program_inouts.cpp:204:10: error: ‘struct gl_program’ has no member named ‘SystemValuesRead’
/home/glsl-optimizer/src/glsl/ir_set_program_inouts.cpp:206:7: error: ‘gl_fragment_program’ was not declared in this scope
/home/glsl-optimizer/src/glsl/ir_set_program_inouts.cpp:206:28: error: ‘fprog’ was not declared in this scope
/home/glsl-optimizer/src/glsl/ir_set_program_inouts.cpp:206:58: error: expected primary-expression before ‘)’ token
/home/glsl-optimizer/src/glsl/ir_set_program_inouts.cpp:206:60: error: expected ‘;’ before ‘prog’
make[2]: *** [CMakeFiles/glsl_optimizer.dir/src/glsl/ir_set_program_inouts.cpp.o] Error 1
make[1]: *** [CMakeFiles/glsl_optimizer.dir/all] Error 2
make: *** [all] Error 2

I'm running on Ubuntu 12.04 LTS, 64-bit.

[Android] Build failed with ndk-r10d

After migration from ndk-r9d to ndk-r10d I have some link errors:

src/glsl/glsl_lexer.cpp:3167: error: undefined reference to '__srget'
src/glsl/glcpp/glcpp-lex.c:1887: error: undefined reference to '__srget'

Failed to compile shaders that has nested struct

Hi aras,
I found the optimizer cannot correctly dealing with nested structure.
e.g, the following code:

struct fragInput {
highp vec4 baseTC;
}
struct fragPass {
fragInput IN;
}

will be interpreted by the optimizer as:

fragInput tmpvar_1;
tmpvar_1 = fragInput(vec4(0.0, 0.0, 0.0, 0.0));

but, struct fragInput's declaration is missing. How to solve this problem?

thanks a lot.

For-loop counter not being assigned initial value correctly.

Noticing something odd with for-loops when passing through output from hlsl2glsl. The optimised output doesn't seem to be assigning the initial value of the index at all. Noticed this as I was having glDrawArrays lock up on shaders using for loops.

For state in question (in source HLSL):

    for ( int index = 0 ; index < sampleNum ; index += 4 ) 

In GLSL after running through HLSL2GLSL

    int index = 0;
    for ( ; (index < sampleNum); index += 4) {
    ...
    }

Raw glsloptimiser output:

  tmpvar_254 = 0;
  index_230 = tmpvar_254;
  while (true) {
    ...
    if (!((index_230 < sampleNum_226))) {
      break;
    };
   ...
    int tmpvar_322;
    tmpvar_322 = (index_230 + 4);
    index_230 = tmpvar_322;
    }

Optimised glsloptimiser output:

  for (int index_5; index_5 < sampleNum_2; index_5 += 4) {
  ...
  }

The initial value is completely lost. Changing this to a non-zero value yields the same results, initially I thought it may just be an assumption on the optimisers part, but it seems to be more than that.

precision issues on iOS

The problem is that the precision that the optimizer sticks to the temporary variables is causing the draw call to fail sometimes, with error 0x502.

This is a snippet from the shader without optimization:

precision mediump int;
precision mediump float;
uniform float normal_mult;
varying vec3 vertex_interp;
varying vec3 normal_interp;
attribute highp vec4 vertex_attrib;
attribute vec3 normal_attrib;
uniform highp mat4 world_transform;
uniform highp mat4 camera_inverse_transform;
void main ()
{
    highp mat4 modelview = (camera_inverse_transform * world_transform);
    highp vec4 vertex_in = vertex_attrib;
    vertex_interp = (modelview * vertex_in).xyz;
    vec3 normal_in = normal_attrib;
    normal_in*=normal_mult;
    normal_interp = normalize((modelview * vec4(normal_in,0.0)).xyz);
}

Which is optimized into this:

precision mediump float;
precision mediump int;
uniform float normal_mult;
varying highp vec3 vertex_interp;
varying highp vec3 normal_interp;
attribute highp vec4 vertex_attrib;
attribute vec3 normal_attrib;
uniform highp mat4 world_transform;
uniform highp mat4 camera_inverse_transform;
void main ()
{
    highp mat4 tmpvar_1;
    tmpvar_1 = (camera_inverse_transform * world_transform);
    vertex_interp = (tmpvar_1 * vertex_attrib).xyz;
    vec4 tmpvar_2;
    tmpvar_2.w = 0.0;
    tmpvar_2.xyz = (normal_attrib * normal_mult);
    normal_interp = normalize((tmpvar_1 * tmpvar_2).xyz);
}

If I use the optimized shader as is, the call to glDrawElements fails with error 0x502 (a.k.a. invalid operation)

If I set tmpvar_2.w to a value other than zero, or change the declaration of tmpvar_2 to highp vec4 tmpvar_2; the shader works ok.

The optimized shader is causing troubles on the iPod touch 5g running iOS 7.1.2, although it's running ok on the simulator.

I have to modify programmatically the optimized shader after the optimization, so my question is whether as a rule of thumb it's ok to propagate the precision of the variable holding the result to those temporary variables involved in the calculation.

For instance since normal_interp have highp, both tmpvar_1 and tmpvar_2 should be highp too, since those are temporary variables.

Hangs in glsl_test and glsl_compiler

When I build and try to run "glsl_test tests/" or glsl_compiler on my own shader, the thing keeps working and never finishes.

Sample:

$ ./glsl_test tests/

** running vertex tests for OpenGL ES 2.0...

top shows that glsl_test is consuming 100% CPU, but never returns. Memory usage is stable. Same with glsl_compiler.

Uniform buffer object declarations not being emitted correctly.

(I am wandering through the print visitors at this moment to find root cause / possible action, but figured I would submit an issue in case I am missing something obvious.)

Observed: The output stage (post-optimization) does not appear to emit GLSL uniform buffer objects that appear to be properly tracked during optimization.

E.g.:, a vertex shader that starts with:

version 300 es

layout (std140) uniform ModelViewProjectionConstantBuffer
{
mat4 model;
mat4 view;
mat4 projection;
} mvp;

. . . with requisite access to mvp.model, mvp.view, mvp.projection in the shader body . . .
. . . results in a shader that begins with:

version 300 es

uniform ModelViewProjectionConstantBuffer mvp;

. . . losing the layout definition entirely, resulting in errors if the resulting shader is compiled. The declaration is no longer valid.

The ir appears to track the definition okay (base type GLSL_TYPE_INTERFACE, name "ModelViewProjectionConstantBuffer", length of 3, first entry in the "fields" union is a seemingly valid representation of a mat4 named "model".

I suspect that this is an issue with the print-visiting only, will dig into it further.

output layout qualifiers are lost for version 300 es fragment shader

When rendering to multiple render targets in ES 3.0, all output locations must be explicitly specified in the fragment shader (since there is nothing like glBindFragDataLocation to control it from the application code). These qualifiers appear to be getting stripped out by the optimizer though.

For example this shader:

#version 300 es
precision mediump float;

layout(location=0) out vec4 final_color0;
layout(location=1) out vec4 final_color1;
layout(location=2) out vec4 final_color2;

void main()
{
    final_color0 = vec4(1,0,0,1);
    final_color1 = vec4(0,1,0,1);
    final_color2 = vec4(0,0,1,1);
}

Turns into this after optimizing:

#version 300
precision mediump float;
out vec4 final_color0;
out vec4 final_color1;
out vec4 final_color2;
void main ()
{
    final_color0 = vec4(1.0, 0.0, 0.0, 1.0);
    final_color1 = vec4(0.0, 1.0, 0.0, 1.0);
    final_color2 = vec4(0.0, 0.0, 1.0, 1.0);
}

Where the layout locations are now missing. The #version string also lost the "es" qualifier but that already been reported in issue 34.

I am getting two errors compiling my oil pain frag shader.

The errors:

"./builtincompiler --glsl-es OilPaint.frag
Info log for OilPaint.frag:
0:0(0): error: no matching function for call to texture2D(sampler2D, vec2)' 0:0(0): error: no matching function for call tomin(float, float)'"

The fragment shader code:

//
// Shader.fsh
// Test
//
// Created by Ofer Rubinshtein on 12/2/12.
// Copyright (c) 2012 Ofer Rubinshtein. All rights reserved.
//

varying highp vec2 texOut1;
uniform sampler2D baseTexture;
uniform sampler2D overlayTexture1;
uniform highp float alpha;
uniform highp float radius;
uniform highp vec2 pixelRatio;
//uniform int step;

void main()
{
int rx = 2;
int ry = 2;
highp float lumCount[13];
highp float averageR[13];
highp float averageG[13];
highp float averageB[13];
for (int i=0; i<13; i++)
{
lumCount[i] = 0.;
averageR[i] = 0.;
averageG[i] = 0.;
averageB[i] = 0.;
}

// highp float tempMax = 0.0;
for (int i=0; i<(2_ry+1); i++)
{
int y =i;
y-=ry;
for (int j=0; j<(2_rx+1); j++)
{
int x =j;
x-=rx;
//highp float b = max(1.0-(sqrt(float(x_x+y_y))/radius), 0.0);
// highp float b = 1.0/(1.0+float(rx_rx+ry_ry));//float(r+1-abs(x))/step;
highp float b = 1.0;
highp vec2 delta = vec2(float(x)_pixelRatio.x_radius, float(y)_pixelRatio.y_radius);
highp vec2 uv = texOut1+delta;
highp vec4 rgb = texture2D(baseTexture, uv);
highp float intensity = min(((rgb.r+rgb.g+rgb.b)/3.0)_13.0, 12.0);
int curIntensity = int(intensity);
lumCount[curIntensity]+=b;
averageR[curIntensity] += rgb.r;//_b;
averageG[curIntensity] += rgb.g;//_b;
averageB[curIntensity] += rgb.b;//_b;
}
}
int maxIndex = 0;
highp float curMax;
curMax = 0.0;
for (int i=0; i<13; i++)
if (lumCount[i] > curMax)
{
curMax = lumCount[i];
maxIndex = i;
}
gl_FragColor = vec4(averageR[maxIndex] / curMax, averageG[maxIndex] / curMax, averageB[maxIndex] / curMax, 1.0);
}

Any idea what I am doing wrong? I couldn't find a lot of documentation about it.

Visual Studio build errors on commit 7827f32ffd372a1767b69ebee75228ba18b29faa

Error:

e:\glsl-opt\src\glsl\builtin_functions.cpp(2668): error C2065: 'M_PI_2': nichtdeklarierter Bezeichner
e:\glsl-opt\src\glsl\builtin_functions.cpp(2670): error C2065: 'M_PI_2': nichtdeklarierter Bezeichner
e:\glsl-opt\src\glsl\builtin_functions.cpp(2672): error C2065: 'M_PI_4': nichtdeklarierter Bezeichner
e:\glsl-opt\src\glsl\builtin_functions.cpp(2715): error C2065: 'M_PI_2': nichtdeklarierter Bezeichner
e:\glsl-opt\src\glsl\builtin_functions.cpp(2754): error C2065: 'M_PI_2': nichtdeklarierter Bezeichner
e:\glsl-opt\src\glsl\builtin_functions.cpp(2809): error C2065: 'M_PI_2': nichtdeklarierter Bezeichner

Fix:

diff --git a/src/mesa/main/compiler.h b/src/mesa/main/compiler.h
index 34671dc..ce85e8f 100644
--- a/src/mesa/main/compiler.h
+++ b/src/mesa/main/compiler.h
@@ -247,6 +247,14 @@ static inline GLuint CPU_TO_LE32(GLuint x)
 #define M_PI (3.14159265358979323846)
 #endif

+#ifndef M_PI_2
+#define M_PI_2 (1.57079632679489661923)
+#endif
+
+#ifndef M_PI_4
+#define M_PI_4 (0.785398163397448309616)
+#endif
+
 #ifndef M_E
 #define M_E (2.7182818284590452354)
 #endif

Error:

e:\glsl-opt\src\glsl\ir_function.cpp(331): error C2065: 'func': nichtdeklarierter Bezeichner
e:\glsl-opt\src\glsl\link_atomics.cpp(65): error C2065: 'func': nichtdeklarierter Bezeichner
e:\glsl-opt\src\glsl\link_uniform_blocks.cpp(189): error C2065: 'func': nichtdeklarierter Bezeichner
e:\glsl-opt\src\glsl\link_varyings.cpp(323): error C2065: 'func': nichtdeklarierter Bezeichner
e:\glsl-opt\src\glsl\linker.cpp(1735): error C2065: 'func': nichtdeklarierter Bezeichner

Fix:

diff --git a/include/c99_compat.h b/include/c99_compat.h
index 429c601..e03e9c1 100644
--- a/include/c99_compat.h
+++ b/include/c99_compat.h
@@ -108,6 +108,10 @@
 /*
  * C99 __func__ macro
  */
+#if defined(_MSC_VER) && !defined(__func__)
+#  define __func__ __FUNCTION__
+#endif
+
 #ifndef __func__
 #  if (__STDC_VERSION__ >= 199901L)
      /* C99 */
diff --git a/src/mesa/main/errors.h b/src/mesa/main/errors.h
index 2cb7505..54d364d 100644
--- a/src/mesa/main/errors.h
+++ b/src/mesa/main/errors.h
@@ -34,7 +34,7 @@

 #ifndef ERRORS_H
 #define ERRORS_H
-
+#include "c99_compat.h"


 #ifdef __cplusplus

Link-time optimizations?

Being able to optimize individual shaders is great, but it would be even better if a fragment and vertex shader could be optimized at the same time - this would allow, for example, removing vertex shader code that writes to a varying that's not read by the fragment shader.

I don't know if Mesa's shader compiler/linker does this at all, but if so it'd be great to have that functionality exposed in glsl-optimizer.

#version 130 case statements are mishandled

The optimized output from a case statement is missing an 'if' and sequential assignments have commas missing.

Here is a typical output for a case:

bool tmpvar_3;
tmpvar_3 = bool(0);
bool tmpvar_4;
tmpvar_4 = bool(0);
(918 == style) tmpvar_3 = bool(1);
tmpvar_4 tmpvar_3 = bool(0);
if (tmpvar_3) {
float angle_5;
angle_5 = -(rotation_radians);
float tmpvar_6;
tmpvar_6 = cos(angle_5);
float tmpvar_7;
tmpvar_7 = sin(angle_5);
vec2 tmpvar_8;
tmpvar_8.x = tmpvar_6;
tmpvar_8.y = tmpvar_7;
vec2 tmpvar_9;
tmpvar_9.x = -(tmpvar_7);
tmpvar_9.y = tmpvar_6;
mat2 tmpvar_10;
tmpvar_10[0u] = tmpvar_8;
tmpvar_10[1u] = tmpvar_9;
vec3 tmpvar_11;
tmpvar_11.xy = (normal_2.xy * tmpvar_10);
tmpvar_11.z = normal_2.z;
vec3 tmpvar_12;
tmpvar_12 = normalize(diffuse_direction);
vec3 I_13;
I_13 = -(tmpvar_12);
color_1.xyz = (((ads_lighting.x * input_color.xyz) + (
(ads_lighting.y * max (dot (tmpvar_11, tmpvar_12), 0.0))
* input_color.xyz)) + ((ads_lighting.z *
pow (max (0.0, (I_13 - (2.0 *
(dot (tmpvar_11, I_13) * tmpvar_11)
)).z), 128.0)
) * vec3(1.0, 0.945, 0.878)));
tmpvar_4 = bool(1);
};

Metal output has user struct definitions after definition of xlatMtlShaderUniform

It appears that when optimizing a glsl shader that has a struct uniform, the metal output ends up with the definition of the struct appearing after the definition of xlatMtlShaderUniform which references the, at that point undefined, struct type.

For example input like this:

struct MyStruct
{
    vec4 v1;
    vec4 v2;
};

uniform MyStruct s1;

Ends up producing output like this:

struct xlatMtlShaderUniform {
  MyStruct s1;
};
;
struct MyStruct {
  float4 v1;
  float4 v2;
};

Full test shader is here https://gist.github.com/eodabash/28a01d147cbc496d14ad.

Problems with OES_EGL_image_external

I found a couple problems with optimization of shaders that make use of OES_EGL_image_external functionality. The first is that "#extension GL_OES_EGL_image_external : enable" statements don't get printed back in the optimizer output. The second is that texture sampling calls that use a samplerExternalOES sampler seem to get converted to "textureExternal" calls which as far as I can tell is not the correct way to sample from such a sampler (the spec refers to this being an obsolete syntax that was dropped in favor of the existing sampling functions like texture2D).

A test input shader can be found here:
https://www.dropbox.com/s/vggjoa1p33uel5n/imageExternal-inES.txt?dl=0

Segfault on nodejs build

Steps to reproduce:

  • Clone repo
  • Run npm install to trigger build (will call node-gyp rebuild internally)
  • Run build/Release/glslOptimizer.node
  • Segfault!

Fiddling around with gdb I'm able to get:

(gdb) run
Starting program: glsl-optimizer/build/Release/obj.target/glslOptimizer.node 

Program received signal SIGSEGV, Segmentation fault.
_mesa_glsl_parse_state::has_uniform_buffer_objects (this=0x0) at ../src/glsl/glsl_parser_extras.h:197
197           return ARB_uniform_buffer_object_enable || is_version(140, 300);
(gdb) quit

On a related note, #92 is reproducible on my machine (Debian 8, quadcore i5, linux kernel v4.0.0-1-amd64) . I somehow suspect a bad build via cmake might be related to a segfault-y build via gyp.

Failing to build with gcc 4.7

Hello,

My build failed with the error:

aras-p-glsl-optimizer-f2217b0/tests/glsl_optimizer_tests.cpp:250:22: error: ‘unlink’ was not declared in this scope
make[2]: *** [CMakeFiles/glsl_test.dir/tests/glsl_optimizer_tests.cpp.o] Error 1
make[1]: *** [CMakeFiles/glsl_test.dir/all] Error 2
make: *** [all] Error 2

Fix: add unistd.h to /tests/glsl_optimizer_tests.cpp for non-windows builds

http://gcc.gnu.org/gcc-4.7/porting_to.html

Cheers

Feature request: packing/unpacking varyings

It could be added an option to pack/unpack varyings to be able to surpass the 8 varyings limitation in some devices. For instance four floats into one vec4, two vec2 into one vec4, and so on.

atan doesn't go through?

If you use atan, it is replaced by an if statement and other slow looking arithmetic. How can we get atan to be passed through?

ES 3.0 support?

Hi Aras,

What is the current status of ES 3.0 support? I see there's a recent commit mentioning it but after getting the latest changes all our "#version 300 es" lines seem to get turned into just "#version 300" which doesn't compile.

I can submit a test case, but I'm wondering if you even intended this to be ready yet, since the "add initial OpenGL ES 3.0 support" commit doesn't look like it touched a lot of code.

Thanks,

Evan

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.