From a131b697d982da5406f11ae72552d1a10fca6fa6 Mon Sep 17 00:00:00 2001 From: Neil Roberts Date: Tue, 26 Feb 2013 18:29:36 +0000 Subject: [PATCH] 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 (cherry picked from commit 1824df902bbb9995cae6ffb7a413913f2df35eef) Conflicts: cogl/driver/gl/cogl-pipeline-fragend-glsl.c cogl/driver/gl/cogl-pipeline-vertend-glsl.c --- cogl/driver/gl/cogl-pipeline-fragend-glsl.c | 94 ++++++++------------- cogl/driver/gl/cogl-pipeline-vertend-glsl.c | 32 +++++++ cogl/driver/gl/cogl-util-gl-private.h | 8 +- cogl/driver/gl/cogl-util-gl.c | 40 ++++++++- 4 files changed, 113 insertions(+), 61 deletions(-) diff --git a/cogl/driver/gl/cogl-pipeline-fragend-glsl.c b/cogl/driver/gl/cogl-pipeline-fragend-glsl.c index d09d245c4..795bdd4d5 100644 --- a/cogl/driver/gl/cogl-pipeline-fragend-glsl.c +++ b/cogl/driver/gl/cogl-pipeline-fragend-glsl.c @@ -207,6 +207,37 @@ 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, + "uniform sampler%s cogl_sampler%i;\n", + 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) @@ -330,6 +361,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, @@ -355,44 +387,6 @@ add_constant_lookup (CoglPipelineShaderState *shader_state, layer->index, swizzle); } -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, @@ -410,9 +404,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; @@ -1009,24 +1003,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, - "uniform sampler%s cogl_sampler%i;\n", - 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 da4ed4bc2..742346d26 100644 --- a/cogl/driver/gl/cogl-pipeline-vertend-glsl.c +++ b/cogl/driver/gl/cogl-pipeline-vertend-glsl.c @@ -140,6 +140,37 @@ 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, + "uniform sampler%s cogl_sampler%i;\n", + 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) @@ -251,6 +282,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, diff --git a/cogl/driver/gl/cogl-util-gl-private.h b/cogl/driver/gl/cogl-util-gl-private.h index 2abd6cb20..b47f301fb 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 aadfb54a0..7a4ec0cd6 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; +}