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>

(cherry picked from commit 1824df902bbb9995cae6ffb7a413913f2df35eef)

Conflicts:
	cogl/driver/gl/cogl-pipeline-fragend-glsl.c
	cogl/driver/gl/cogl-pipeline-vertend-glsl.c
This commit is contained in:
Neil Roberts 2013-02-26 18:29:36 +00:00
parent 956d39ac30
commit a131b697d9
4 changed files with 113 additions and 61 deletions

View File

@ -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,7 +404,7 @@ ensure_texture_lookup_generated (CoglPipelineShaderState *shader_state,
texture_type =
_cogl_pipeline_layer_get_texture_type (layer);
get_texture_target_string (texture_type,
_cogl_gl_util_get_texture_target_string (texture_type,
&target_string,
&tex_coord_swizzle);
@ -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);

View File

@ -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,

View File

@ -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_ */

View File

@ -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;
}