After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 656426 - Improve the generated GLSL code
Improve the generated GLSL code
Status: RESOLVED FIXED
Product: cogl
Classification: Platform
Component: general
unspecified
Other Linux
: Normal normal
: ---
Assigned To: Cogl maintainer(s)
Cogl maintainer(s)
Depends on:
Blocks:
 
 
Reported: 2011-08-12 21:51 UTC by Neil Roberts
Modified: 2011-09-05 19:49 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
fragend-glsl: Don't generate code for ignored layers (15.57 KB, patch)
2011-08-12 21:55 UTC, Neil Roberts
none Details | Review
cogl-pipeline-fragend-glsl: Cache the results of texture lookups (7.45 KB, patch)
2011-08-12 21:55 UTC, Neil Roberts
none Details | Review

Description Neil Roberts 2011-08-12 21:51:25 UTC
The code generated by the GLSL fragend isn't at all optimized and totally relies on the compiler to optimize out redundant code.

For example, here is reasonably common use of a material which can interpolate between two textures based on the alpha channel of a third texture:

  /* Attach the two images to the first two layers. We need these layers
     for the texture but we're not actually going to use the combine mode
     from it */
  cogl_material_set_layer (priv->material, 0, tex);
  cogl_material_set_layer (priv->material, 1, another_tex);

  /* The third layer has the interpolation texture and sets up a combine layer
     which accesses the textures from the previous directly */
  cogl_material_set_layer (priv->material, 2, mask);
  cogl_material_set_layer_combine (priv->material,
                                   2, /* layer_index */
                                   "RGBA = INTERPOLATE (TEXTURE_0,"
                                   "                    TEXTURE_1,"
                                   "                    TEXTURE[A])",
                                   NULL);

This generates the following code (with added comments):

void
main ()
{
  /* This does a texture lookup to calculate the first layer */
  cogl_color_out.rgba =
    (cogl_color_in.rgba) *
    (texture2D (_cogl_sampler_0, cogl_tex_coord_in[0].st).rgba);

  /* This does another texture lookup for the second layer */
  cogl_color_out.rgba =
    (cogl_color_out.rgba) *
    (texture2D (_cogl_sampler_1, cogl_tex_coord_in[1].st).rgba);

  /* This discards the two previous layers to calculate the third
     layer. Note that it also does the texture lookups again and also
     does a lookup for the third texure twice */

  cogl_color_out.rgba =
    texture2D (_cogl_sampler_0, cogl_tex_coord_in[0].st).rgba) *
    texture2D (_cogl_sampler_2, cogl_tex_coord_in[2].st).aaaa) +
    (texture2D (_cogl_sampler_1, cogl_tex_coord_in[1].st).rgba) *
    (vec4(1.0, 1.0, 1.0, 1.0).rgba -
     (texture2D (_cogl_sampler_2, cogl_tex_coord_in[2].st).aaaa));
}
Comment 1 Neil Roberts 2011-08-12 21:55:45 UTC
Created attachment 193732 [details] [review]
fragend-glsl: Don't generate code for ignored layers

This patch changes it so that code for each layer is generated on
demand instead of directly in the add_layer implementation. The
pipeline only explicitly generates code for the last layer. If this
layer references the result from any other layers, these will also be
recursively generated. This means that if a layer is using 'REPLACE'
then it won't redundantly generate the code for the previous
layers.

The result for each layer is generated into a variable called layer%i
where %i is the layer index (not the unit index). Therefore to get the
result from layer n we just have to refer to the varible layern.
Comment 2 Neil Roberts 2011-08-12 21:55:47 UTC
Created attachment 193733 [details] [review]
cogl-pipeline-fragend-glsl: Cache the results of texture lookups

Whenever a texture lookup is performed for a layer the result is now
stored in a variable and used repeatedly instead of generating the
code for the lookup every time it is accessed. This means for example
when using the INTERPOLATE function with a texture lookup for the
third parameter it will only generate one texture lookup instead of
two.
Comment 3 Neil Roberts 2011-08-12 22:00:21 UTC
With the patches, the generated code is:

void
main ()
{
  vec4 layer2;
  vec4 texel0 = texture2D (_cogl_sampler_0, cogl_tex_coord_in[0].st);
  vec4 texel1 = texture2D (_cogl_sampler_1, cogl_tex_coord_in[1].st);
  vec4 texel2 = texture2D (_cogl_sampler_2, cogl_tex_coord_in[2].st);
  layer2.rgba = (texel0.rgba) * (texel2.aaaa) +
                (texel1.rgba) * (vec4(1.0, 1.0, 1.0, 1.0).rgba - (texel2.aaaa));
  cogl_color_out = layer2;
}
Comment 4 Robert Bragg 2011-09-05 19:49:08 UTC
thanks these have landed in master now