[Cogl] [PATCH 1/2] Add fragment and vertex snippet hooks for global declarations
Robert Bragg
robert at sixbynine.org
Tue Feb 26 12:29:02 PST 2013
This looks good to land to me:
Reviewed-by: Robert Bragg <robert at linux.intel.com>
thanks,
- Robert
On Tue, Feb 26, 2013 at 7:56 PM, Neil Roberts <neil at linux.intel.com> wrote:
> This adds hook points to add global function and variable declarations
> to either the fragment or vertex shader. The declarations can then be
> used by subsequent snippets. Only the ‘declarations’ string of the
> snippet is used and the code is directly put in the global scope near
> the top of the shader.
>
> The reason this is necessary rather than just adding a normal snippet
> with the declarations is that for the other hooks Cogl assumes that
> the snippets are independent of each other. That means if a snippet
> has a replace string then it will assume that it doesn't even need to
> generate the code for earlier hooks which means the global
> declarations would be lost.
> ---
> cogl/cogl-pipeline-snippet-private.h | 7 +-
> cogl/cogl-pipeline-snippet.c | 19 ++++-
> cogl/cogl-snippet.h | 34 ++++++++-
> cogl/driver/gl/cogl-pipeline-fragend-glsl.c | 19 ++++-
> cogl/driver/gl/cogl-pipeline-vertend-glsl.c | 19 ++++-
> tests/conform/test-snippets.c | 114 +++++++++++++++++++++++++++-
> 6 files changed, 204 insertions(+), 8 deletions(-)
>
> diff --git a/cogl/cogl-pipeline-snippet-private.h b/cogl/cogl-pipeline-snippet-private.h
> index b10b6ca..02dee35 100644
> --- a/cogl/cogl-pipeline-snippet-private.h
> +++ b/cogl/cogl-pipeline-snippet-private.h
> @@ -3,7 +3,7 @@
> *
> * An object oriented GL/GLES Abstraction/Utility Layer
> *
> - * Copyright (C) 2011 Intel Corporation.
> + * Copyright (C) 2011, 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
> @@ -90,6 +90,11 @@ void
> _cogl_pipeline_snippet_generate_code (const CoglPipelineSnippetData *data);
>
> void
> +_cogl_pipeline_snippet_generate_declarations (GString *declarations_buf,
> + CoglSnippetHook hook,
> + CoglPipelineSnippetList *list);
> +
> +void
> _cogl_pipeline_snippet_list_free (CoglPipelineSnippetList *list);
>
> void
> diff --git a/cogl/cogl-pipeline-snippet.c b/cogl/cogl-pipeline-snippet.c
> index 2d5e4c2..0e0f620 100644
> --- a/cogl/cogl-pipeline-snippet.c
> +++ b/cogl/cogl-pipeline-snippet.c
> @@ -3,7 +3,7 @@
> *
> * An object oriented GL/GLES Abstraction/Utility Layer
> *
> - * Copyright (C) 2011 Intel Corporation.
> + * Copyright (C) 2011, 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
> @@ -183,6 +183,23 @@ _cogl_pipeline_snippet_generate_code (const CoglPipelineSnippetData *data)
> }
> }
>
> +void
> +_cogl_pipeline_snippet_generate_declarations (GString *declarations_buf,
> + CoglSnippetHook hook,
> + CoglPipelineSnippetList *snippets)
> +{
> + CoglPipelineSnippet *snippet;
> +
> + COGL_LIST_FOREACH (snippet, snippets, list_node)
> + if (snippet->snippet->hook == hook)
> + {
> + const char *source;
> +
> + if ((source = cogl_snippet_get_declarations (snippet->snippet)))
> + g_string_append (declarations_buf, source);
> + }
> +}
> +
> static void
> _cogl_pipeline_snippet_free (CoglPipelineSnippet *pipeline_snippet)
> {
> diff --git a/cogl/cogl-snippet.h b/cogl/cogl-snippet.h
> index fcf9af2..d6de2a4 100644
> --- a/cogl/cogl-snippet.h
> +++ b/cogl/cogl-snippet.h
> @@ -3,7 +3,7 @@
> *
> * An object oriented GL/GLES Abstraction/Utility Layer
> *
> - * Copyright (C) 2011 Intel Corporation.
> + * Copyright (C) 2011, 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
> @@ -302,6 +302,12 @@ typedef struct _CoglSnippet CoglSnippet;
> to within a pipeline. */
> /**
> * CoglSnippetHook:
> + * @COGL_SNIPPET_HOOK_VERTEX_GLOBALS: A hook for declaring global data
> + * that can be shared with all other snippets that are on a vertex
> + * hook.
> + * @COGL_SNIPPET_HOOK_FRAGMENT_GLOBALS: A hook for declaring global
> + * data wthat can be shared with all other snippets that are on a
> + * fragment hook.
> * @COGL_SNIPPET_HOOK_VERTEX: A hook for the entire vertex processing
> * stage of the pipeline.
> * @COGL_SNIPPET_HOOK_VERTEX_TRANSFORM: A hook for the vertex transformation.
> @@ -320,6 +326,30 @@ typedef struct _CoglSnippet CoglSnippet;
> *
> * <glosslist>
> * <glossentry>
> + * <glossterm>%COGL_SNIPPET_HOOK_VERTEX_GLOBALS</glossterm>
> + * <glossdef>
> + * <para>
> + * Adds a shader snippet at the beginning of the global section of the
> + * shader for the vertex processing. Any declarations here can be
> + * shared with all other snippets that are attached to a vertex hook.
> + * Only the ‘declarations’ string is used and the other strings are
> + * ignored.
> + * </para>
> + * </glossdef>
> + * </glossentry>
> + * <glossentry>
> + * <glossterm>%COGL_SNIPPET_HOOK_FRAGMENT_GLOBALS</glossterm>
> + * <glossdef>
> + * <para>
> + * Adds a shader snippet at the beginning of the global section of the
> + * shader for the fragment processing. Any declarations here can be
> + * shared with all other snippets that are attached to a fragment
> + * hook. Only the ‘declarations’ string is used and the other strings
> + * are ignored.
> + * </para>
> + * </glossdef>
> + * </glossentry>
> + * <glossentry>
> * <glossterm>%COGL_SNIPPET_HOOK_VERTEX</glossterm>
> * <glossdef>
> * <para>
> @@ -539,9 +569,11 @@ typedef enum {
> /* Per pipeline vertex hooks */
> COGL_SNIPPET_HOOK_VERTEX = 0,
> COGL_SNIPPET_HOOK_VERTEX_TRANSFORM,
> + COGL_SNIPPET_HOOK_VERTEX_GLOBALS,
>
> /* Per pipeline fragment hooks */
> COGL_SNIPPET_HOOK_FRAGMENT = 2048,
> + COGL_SNIPPET_HOOK_FRAGMENT_GLOBALS,
>
> /* Per layer vertex hooks */
> COGL_SNIPPET_HOOK_TEXTURE_COORD_TRANSFORM = 4096,
> diff --git a/cogl/driver/gl/cogl-pipeline-fragend-glsl.c b/cogl/driver/gl/cogl-pipeline-fragend-glsl.c
> index 6ea64c6..85bc8d3 100644
> --- a/cogl/driver/gl/cogl-pipeline-fragend-glsl.c
> +++ b/cogl/driver/gl/cogl-pipeline-fragend-glsl.c
> @@ -3,7 +3,7 @@
> *
> * An object oriented GL/GLES Abstraction/Utility Layer
> *
> - * Copyright (C) 2008,2009,2010 Intel Corporation.
> + * Copyright (C) 2008,2009,2010,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
> @@ -205,6 +205,21 @@ has_replace_hook (CoglPipelineLayer *layer,
> }
>
> static void
> +add_global_declarations (CoglPipeline *pipeline,
> + CoglPipelineShaderState *shader_state)
> +{
> + CoglSnippetHook hook = COGL_SNIPPET_HOOK_FRAGMENT_GLOBALS;
> + CoglPipelineSnippetList *snippets = get_fragment_snippets (pipeline);
> +
> + /* Add the global data hooks. All of the code in these snippets is
> + * always added and only the declarations data is used */
> +
> + _cogl_pipeline_snippet_generate_declarations (shader_state->header,
> + hook,
> + snippets);
> +}
> +
> +static void
> _cogl_pipeline_fragend_glsl_start (CoglPipeline *pipeline,
> int n_layers,
> unsigned long pipelines_difference)
> @@ -296,6 +311,8 @@ _cogl_pipeline_fragend_glsl_start (CoglPipeline *pipeline,
> shader_state->source = ctx->codegen_source_buffer;
> COGL_LIST_INIT (&shader_state->layers);
>
> + add_global_declarations (pipeline, shader_state);
> +
> g_string_append (shader_state->source,
> "void\n"
> "cogl_generated_source ()\n"
> diff --git a/cogl/driver/gl/cogl-pipeline-vertend-glsl.c b/cogl/driver/gl/cogl-pipeline-vertend-glsl.c
> index a298145..3a2b155 100644
> --- a/cogl/driver/gl/cogl-pipeline-vertend-glsl.c
> +++ b/cogl/driver/gl/cogl-pipeline-vertend-glsl.c
> @@ -3,7 +3,7 @@
> *
> * An object oriented GL/GLES Abstraction/Utility Layer
> *
> - * Copyright (C) 2010 Intel Corporation.
> + * Copyright (C) 2010,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
> @@ -140,6 +140,21 @@ get_layer_vertex_snippets (CoglPipelineLayer *layer)
> }
>
> static void
> +add_global_declarations (CoglPipeline *pipeline,
> + CoglPipelineShaderState *shader_state)
> +{
> + CoglSnippetHook hook = COGL_SNIPPET_HOOK_VERTEX_GLOBALS;
> + CoglPipelineSnippetList *snippets = get_vertex_snippets (pipeline);
> +
> + /* Add the global data hooks. All of the code in these snippets is
> + * always added and only the declarations data is used */
> +
> + _cogl_pipeline_snippet_generate_declarations (shader_state->header,
> + hook,
> + snippets);
> +}
> +
> +static void
> _cogl_pipeline_vertend_glsl_start (CoglPipeline *pipeline,
> int n_layers,
> unsigned long pipelines_difference)
> @@ -218,6 +233,8 @@ _cogl_pipeline_vertend_glsl_start (CoglPipeline *pipeline,
> shader_state->header = ctx->codegen_header_buffer;
> shader_state->source = ctx->codegen_source_buffer;
>
> + add_global_declarations (pipeline, shader_state);
> +
> g_string_append (shader_state->source,
> "void\n"
> "cogl_generated_source ()\n"
> diff --git a/tests/conform/test-snippets.c b/tests/conform/test-snippets.c
> index df85042..07a99a1 100644
> --- a/tests/conform/test-snippets.c
> +++ b/tests/conform/test-snippets.c
> @@ -6,7 +6,7 @@
>
> typedef struct _TestState
> {
> - int padding;
> + int fb_width, fb_height;
> } TestState;
>
> typedef void (* SnippetTestFunc) (TestState *state);
> @@ -525,6 +525,109 @@ test_vertex_transform_hook (TestState *state)
> }
>
> static void
> +test_global_vertex_hook (TestState *state)
> +{
> + CoglPipeline *pipeline;
> + CoglSnippet *snippet;
> +
> + pipeline = cogl_pipeline_new (test_ctx);
> +
> + /* Creates a function in the global declarations hook which is used
> + * by a subsequent snippet. The subsequent snippets replace any
> + * previous snippets but this shouldn't prevent the global
> + * declarations from being generated */
> +
> + snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX_GLOBALS,
> + /* declarations */
> + "float\n"
> + "multiply_by_two (float number)\n"
> + "{\n"
> + " return number * 2.0;\n"
> + "}\n",
> + /* post */
> + "This string shouldn't be used so "
> + "we can safely put garbage in here.");
> + cogl_snippet_set_pre (snippet,
> + "This string shouldn't be used so "
> + "we can safely put garbage in here.");
> + cogl_snippet_set_replace (snippet,
> + "This string shouldn't be used so "
> + "we can safely put garbage in here.");
> + cogl_pipeline_add_snippet (pipeline, snippet);
> + cogl_object_unref (snippet);
> +
> + snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX,
> + NULL, /* declarations */
> + NULL /* replace */);
> + cogl_snippet_set_replace (snippet,
> + "cogl_color_out.r = multiply_by_two (0.5);\n"
> + "cogl_color_out.gba = vec3 (0.0, 0.0, 1.0);\n"
> + "cogl_position_out = cogl_position_in;\n");
> + cogl_pipeline_add_snippet (pipeline, snippet);
> + cogl_object_unref (snippet);
> +
> + cogl_framebuffer_draw_rectangle (test_fb,
> + pipeline,
> + -1, 1,
> + 10.0f * 2.0f / state->fb_width - 1.0f,
> + 10.0f * 2.0f / state->fb_height - 1.0f);
> +
> + cogl_object_unref (pipeline);
> +
> + test_utils_check_pixel (test_fb, 5, 5, 0xff0000ff);
> +}
> +
> +static void
> +test_global_fragment_hook (TestState *state)
> +{
> + CoglPipeline *pipeline;
> + CoglSnippet *snippet;
> +
> + pipeline = cogl_pipeline_new (test_ctx);
> +
> + /* Creates a function in the global declarations hook which is used
> + * by a subsequent snippet. The subsequent snippets replace any
> + * previous snippets but this shouldn't prevent the global
> + * declarations from being generated */
> +
> + snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT_GLOBALS,
> + /* declarations */
> + "float\n"
> + "multiply_by_four (float number)\n"
> + "{\n"
> + " return number * 4.0;\n"
> + "}\n",
> + /* post */
> + "This string shouldn't be used so "
> + "we can safely put garbage in here.");
> + cogl_snippet_set_pre (snippet,
> + "This string shouldn't be used so "
> + "we can safely put garbage in here.");
> + cogl_snippet_set_replace (snippet,
> + "This string shouldn't be used so "
> + "we can safely put garbage in here.");
> + cogl_pipeline_add_snippet (pipeline, snippet);
> + cogl_object_unref (snippet);
> +
> + snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
> + NULL, /* declarations */
> + NULL /* replace */);
> + cogl_snippet_set_replace (snippet,
> + "cogl_color_out.r = multiply_by_four (0.25);\n"
> + "cogl_color_out.gba = vec3 (0.0, 0.0, 1.0);\n");
> + cogl_pipeline_add_snippet (pipeline, snippet);
> + cogl_object_unref (snippet);
> +
> + cogl_framebuffer_draw_rectangle (test_fb,
> + pipeline,
> + 0, 0, 10, 10);
> +
> + cogl_object_unref (pipeline);
> +
> + test_utils_check_pixel (test_fb, 5, 5, 0xff0000ff);
> +}
> +
> +static void
> test_snippet_order (TestState *state)
> {
> CoglPipeline *pipeline;
> @@ -660,6 +763,8 @@ tests[] =
> test_modify_vertex_layer,
> test_replace_vertex_layer,
> test_vertex_transform_hook,
> + test_global_fragment_hook,
> + test_global_vertex_hook,
> test_snippet_order,
> test_naming_texture_units,
> test_snippet_properties
> @@ -685,10 +790,13 @@ test_snippets (void)
> {
> TestState state;
>
> + state.fb_width = cogl_framebuffer_get_width (test_fb);
> + state.fb_height = cogl_framebuffer_get_height (test_fb);
> +
> cogl_framebuffer_orthographic (test_fb,
> 0, 0,
> - cogl_framebuffer_get_width (test_fb),
> - cogl_framebuffer_get_height (test_fb),
> + state.fb_width,
> + state.fb_height,
> -1,
> 100);
>
> --
> 1.7.11.3.g3c3efa5
>
> _______________________________________________
> Cogl mailing list
> Cogl at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/cogl
More information about the Cogl
mailing list