[cogl] Add the layer's sampler and uniform declarations at the start



commit 1824df902bbb9995cae6ffb7a413913f2df35eef
Author: Neil Roberts <neil linux intel com>
Date:   Tue Feb 26 18:29:36 2013 +0000

    Add the layer's sampler and uniform declarations at the start
    
    Previously the sampler uniform declarations such as cogl_sampler0 were
    generated by walking the list of layers in the shader state. This had
    two problems. Firstly it would only generate the declarations for
    layers that have been referenced. If a layer has a combine mode of
    replace then the samplers from previous layers couldn't be used by
    custom snippets. Secondly it meant that the samplers couldn't be
    referenced by functions in the declarations sections because the
    samplers are declared too late.
    
    This patch fixes it to generate the layer declarations in the backend
    start function using all of the layers on the pipeline instead. In
    addition it adds the sampler declarations to the vertex shader as they
    were previously missing.
    
    Reviewed-by: Robert Bragg <robert linux intel com>

 cogl/driver/gl/cogl-pipeline-fragend-glsl.c |  104 ++++++++++----------------
 cogl/driver/gl/cogl-pipeline-vertend-glsl.c |   48 ++++++++++---
 cogl/driver/gl/cogl-util-gl-private.h       |    8 ++-
 cogl/driver/gl/cogl-util-gl.c               |   40 ++++++++++-
 4 files changed, 125 insertions(+), 75 deletions(-)
---
diff --git a/cogl/driver/gl/cogl-pipeline-fragend-glsl.c b/cogl/driver/gl/cogl-pipeline-fragend-glsl.c
index 85bc8d3..f432a0c 100644
--- a/cogl/driver/gl/cogl-pipeline-fragend-glsl.c
+++ b/cogl/driver/gl/cogl-pipeline-fragend-glsl.c
@@ -204,6 +204,42 @@ has_replace_hook (CoglPipelineLayer *layer,
   return FALSE;
 }
 
+static CoglBool
+add_layer_declaration_cb (CoglPipelineLayer *layer,
+                          void *user_data)
+{
+  CoglPipelineShaderState *shader_state = user_data;
+  CoglTextureType texture_type =
+    _cogl_pipeline_layer_get_texture_type (layer);
+  const char *target_string;
+
+  _cogl_gl_util_get_texture_target_string (texture_type, &target_string, NULL);
+
+  g_string_append_printf (shader_state->header,
+                          "varying vec4 _cogl_tex_coord%i;\n"
+                          "#define cogl_tex_coord%i_in _cogl_tex_coord%i\n"
+                          "uniform sampler%s cogl_sampler%i;\n",
+                          layer->index,
+                          layer->index,
+                          layer->index,
+                          target_string,
+                          layer->index);
+
+  return TRUE;
+}
+
+static void
+add_layer_declarations (CoglPipeline *pipeline,
+                        CoglPipelineShaderState *shader_state)
+{
+  /* We always emit sampler uniforms in case there will be custom
+   * layer snippets that want to sample arbitrary layers. */
+
+  _cogl_pipeline_foreach_layer_internal (pipeline,
+                                         add_layer_declaration_cb,
+                                         shader_state);
+}
+
 static void
 add_global_declarations (CoglPipeline *pipeline,
                          CoglPipelineShaderState *shader_state)
@@ -311,6 +347,7 @@ _cogl_pipeline_fragend_glsl_start (CoglPipeline *pipeline,
   shader_state->source = ctx->codegen_source_buffer;
   COGL_LIST_INIT (&shader_state->layers);
 
+  add_layer_declarations (pipeline, shader_state);
   add_global_declarations (pipeline, shader_state);
 
   g_string_append (shader_state->source,
@@ -337,44 +374,6 @@ add_constant_lookup (CoglPipelineShaderState *shader_state,
 }
 
 static void
-get_texture_target_string (CoglTextureType texture_type,
-                           const char **target_string_out,
-                           const char **swizzle_out)
-{
-  const char *target_string, *tex_coord_swizzle;
-
-  switch (texture_type)
-    {
-#if 0 /* TODO */
-    case COGL_TEXTURE_TYPE_1D:
-      target_string = "1D";
-      tex_coord_swizzle = "s";
-      break;
-#endif
-
-    case COGL_TEXTURE_TYPE_2D:
-      target_string = "2D";
-      tex_coord_swizzle = "st";
-      break;
-
-    case COGL_TEXTURE_TYPE_3D:
-      target_string = "3D";
-      tex_coord_swizzle = "stp";
-      break;
-
-    case COGL_TEXTURE_TYPE_RECTANGLE:
-      target_string = "2DRect";
-      tex_coord_swizzle = "st";
-      break;
-    }
-
-  if (target_string_out)
-    *target_string_out = target_string;
-  if (swizzle_out)
-    *swizzle_out = tex_coord_swizzle;
-}
-
-static void
 ensure_texture_lookup_generated (CoglPipelineShaderState *shader_state,
                                  CoglPipeline *pipeline,
                                  CoglPipelineLayer *layer)
@@ -391,9 +390,9 @@ ensure_texture_lookup_generated (CoglPipelineShaderState *shader_state,
 
   texture_type =
     _cogl_pipeline_layer_get_texture_type (layer);
-  get_texture_target_string (texture_type,
-                             &target_string,
-                             &tex_coord_swizzle);
+  _cogl_gl_util_get_texture_target_string (texture_type,
+                                           &target_string,
+                                           &tex_coord_swizzle);
 
   shader_state->unit_state[unit_index].sampled = TRUE;
 
@@ -990,29 +989,6 @@ _cogl_pipeline_fragend_glsl_end (CoglPipeline *pipeline,
           CoglPipelineLayer *last_layer;
           LayerData *layer_data, *tmp;
 
-          /* We always emit sampler uniforms in case there will be custom
-           * layer snippets that want to sample arbitrary layers. */
-
-          COGL_LIST_FOREACH (layer_data, &shader_state->layers, list_node)
-            {
-              CoglPipelineLayer *layer = layer_data->layer;
-              CoglTextureType texture_type =
-                _cogl_pipeline_layer_get_texture_type (layer);
-              const char *target_string;
-
-              get_texture_target_string (texture_type, &target_string, NULL);
-
-              g_string_append_printf (shader_state->header,
-                                      "varying vec4 _cogl_tex_coord%i;\n"
-                                      "#define cogl_tex_coord%i_in _cogl_tex_coord%i\n"
-                                      "uniform sampler%s cogl_sampler%i;\n",
-                                      layer->index,
-                                      layer->index,
-                                      layer->index,
-                                      target_string,
-                                      layer->index);
-            }
-
           last_layer = COGL_LIST_FIRST (&shader_state->layers)->layer;
 
           ensure_layer_generated (pipeline, last_layer->index);
diff --git a/cogl/driver/gl/cogl-pipeline-vertend-glsl.c b/cogl/driver/gl/cogl-pipeline-vertend-glsl.c
index 3a2b155..9ae4a83 100644
--- a/cogl/driver/gl/cogl-pipeline-vertend-glsl.c
+++ b/cogl/driver/gl/cogl-pipeline-vertend-glsl.c
@@ -139,6 +139,44 @@ get_layer_vertex_snippets (CoglPipelineLayer *layer)
   return &layer->big_state->vertex_snippets;
 }
 
+static CoglBool
+add_layer_declaration_cb (CoglPipelineLayer *layer,
+                          void *user_data)
+{
+  CoglPipelineShaderState *shader_state = user_data;
+  CoglTextureType texture_type =
+    _cogl_pipeline_layer_get_texture_type (layer);
+  const char *target_string;
+
+  _cogl_gl_util_get_texture_target_string (texture_type, &target_string, NULL);
+
+  g_string_append_printf (shader_state->header,
+                          "attribute vec4 cogl_tex_coord%i_in;\n"
+                          "varying vec4 _cogl_tex_coord%i;\n"
+                          "#define cogl_tex_coord%i_out _cogl_tex_coord%i\n"
+                          "uniform sampler%s cogl_sampler%i;\n",
+                          layer->index,
+                          layer->index,
+                          layer->index,
+                          layer->index,
+                          target_string,
+                          layer->index);
+
+  return TRUE;
+}
+
+static void
+add_layer_declarations (CoglPipeline *pipeline,
+                        CoglPipelineShaderState *shader_state)
+{
+  /* We always emit sampler uniforms in case there will be custom
+   * layer snippets that want to sample arbitrary layers. */
+
+  _cogl_pipeline_foreach_layer_internal (pipeline,
+                                         add_layer_declaration_cb,
+                                         shader_state);
+}
+
 static void
 add_global_declarations (CoglPipeline *pipeline,
                          CoglPipelineShaderState *shader_state)
@@ -233,6 +271,7 @@ _cogl_pipeline_vertend_glsl_start (CoglPipeline *pipeline,
   shader_state->header = ctx->codegen_header_buffer;
   shader_state->source = ctx->codegen_source_buffer;
 
+  add_layer_declarations (pipeline, shader_state);
   add_global_declarations (pipeline, shader_state);
 
   g_string_append (shader_state->source,
@@ -265,15 +304,6 @@ _cogl_pipeline_vertend_glsl_add_layer (CoglPipeline *pipeline,
   if (shader_state->source == NULL)
     return TRUE;
 
-  g_string_append_printf (shader_state->header,
-                          "attribute vec4 cogl_tex_coord%i_in;\n"
-                          "varying vec4 _cogl_tex_coord%i;\n"
-                          "#define cogl_tex_coord%i_out _cogl_tex_coord%i\n",
-                          layer_index,
-                          layer_index,
-                          layer_index,
-                          layer_index);
-
   /* Hook to transform the texture coordinates. By default this just
    * directly uses the texture coordinates.
    */
diff --git a/cogl/driver/gl/cogl-util-gl-private.h b/cogl/driver/gl/cogl-util-gl-private.h
index 2abd6cb..b47f301 100644
--- a/cogl/driver/gl/cogl-util-gl-private.h
+++ b/cogl/driver/gl/cogl-util-gl-private.h
@@ -3,7 +3,7 @@
  *
  * An object oriented GL/GLES Abstraction/Utility Layer
  *
- * Copyright (C) 2012 Intel Corporation.
+ * Copyright (C) 2012, 2013 Intel Corporation.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -28,6 +28,7 @@
 #include "cogl-types.h"
 #include "cogl-context.h"
 #include "cogl-gl-header.h"
+#include "cogl-texture.h"
 
 #ifdef COGL_GL_DEBUG
 
@@ -66,4 +67,9 @@ _cogl_gl_error_to_string (GLenum error_code);
 CoglBool
 _cogl_gl_util_catch_out_of_memory (CoglContext *ctx, CoglError **error);
 
+void
+_cogl_gl_util_get_texture_target_string (CoglTextureType texture_type,
+                                         const char **target_string_out,
+                                         const char **swizzle_out);
+
 #endif /* _COGL_UTIL_GL_PRIVATE_H_ */
diff --git a/cogl/driver/gl/cogl-util-gl.c b/cogl/driver/gl/cogl-util-gl.c
index aadfb54..7a4ec0c 100644
--- a/cogl/driver/gl/cogl-util-gl.c
+++ b/cogl/driver/gl/cogl-util-gl.c
@@ -3,7 +3,7 @@
  *
  * An object oriented GL/GLES Abstraction/Utility Layer
  *
- * Copyright (C) 2012 Intel Corporation.
+ * Copyright (C) 2012, 2013 Intel Corporation.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -101,3 +101,41 @@ _cogl_gl_util_catch_out_of_memory (CoglContext *ctx, CoglError **error)
 
   return FALSE;
 }
+
+void
+_cogl_gl_util_get_texture_target_string (CoglTextureType texture_type,
+                                         const char **target_string_out,
+                                         const char **swizzle_out)
+{
+  const char *target_string, *tex_coord_swizzle;
+
+  switch (texture_type)
+    {
+#if 0 /* TODO */
+    case COGL_TEXTURE_TYPE_1D:
+      target_string = "1D";
+      tex_coord_swizzle = "s";
+      break;
+#endif
+
+    case COGL_TEXTURE_TYPE_2D:
+      target_string = "2D";
+      tex_coord_swizzle = "st";
+      break;
+
+    case COGL_TEXTURE_TYPE_3D:
+      target_string = "3D";
+      tex_coord_swizzle = "stp";
+      break;
+
+    case COGL_TEXTURE_TYPE_RECTANGLE:
+      target_string = "2DRect";
+      tex_coord_swizzle = "st";
+      break;
+    }
+
+  if (target_string_out)
+    *target_string_out = target_string;
+  if (swizzle_out)
+    *swizzle_out = tex_coord_swizzle;
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]