mirror of
https://github.com/brl/mutter.git
synced 2024-11-21 15:40:41 -05:00
cogl: Move some GL-specific GLSL details into the driver
_cogl_shader_set_source_with_boilerplate and _cogl_shader_compile_real have enough GL assumptions that it makes sense to push them into the backend. Taken together their only callers are under driver/gl, so. https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1194
This commit is contained in:
parent
1285619bcf
commit
462df7e61a
@ -1,41 +0,0 @@
|
|||||||
/*
|
|
||||||
* Cogl
|
|
||||||
*
|
|
||||||
* A Low Level GPU Graphics and Utilities API
|
|
||||||
*
|
|
||||||
* Copyright (C) 2012 Intel Corporation.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person
|
|
||||||
* obtaining a copy of this software and associated documentation
|
|
||||||
* files (the "Software"), to deal in the Software without
|
|
||||||
* restriction, including without limitation the rights to use, copy,
|
|
||||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
||||||
* of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
||||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _COGL_GLSL_SHADER_PRIVATE_H_
|
|
||||||
#define _COGL_GLSL_SHADER_PRIVATE_H_
|
|
||||||
|
|
||||||
void
|
|
||||||
_cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx,
|
|
||||||
GLuint shader_gl_handle,
|
|
||||||
GLenum shader_gl_type,
|
|
||||||
CoglPipeline *pipeline,
|
|
||||||
GLsizei count_in,
|
|
||||||
const char **strings_in,
|
|
||||||
const GLint *lengths_in);
|
|
||||||
|
|
||||||
#endif /* _COGL_GLSL_SHADER_PRIVATE_H_ */
|
|
@ -1,189 +0,0 @@
|
|||||||
/*
|
|
||||||
* Cogl
|
|
||||||
*
|
|
||||||
* A Low Level GPU Graphics and Utilities API
|
|
||||||
*
|
|
||||||
* Copyright (C) 2012 Intel Corporation.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person
|
|
||||||
* obtaining a copy of this software and associated documentation
|
|
||||||
* files (the "Software"), to deal in the Software without
|
|
||||||
* restriction, including without limitation the rights to use, copy,
|
|
||||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
||||||
* of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
||||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Robert Bragg <robert@linux.intel.com>
|
|
||||||
* Neil Roberts <neil@linux.intel.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "cogl-config.h"
|
|
||||||
|
|
||||||
#include "cogl-context-private.h"
|
|
||||||
#include "cogl-glsl-shader-private.h"
|
|
||||||
#include "cogl-glsl-shader-boilerplate.h"
|
|
||||||
#include "driver/gl/cogl-util-gl-private.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <glib.h>
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
add_layer_vertex_boilerplate_cb (CoglPipelineLayer *layer,
|
|
||||||
void *user_data)
|
|
||||||
{
|
|
||||||
GString *layer_declarations = user_data;
|
|
||||||
int unit_index = _cogl_pipeline_layer_get_unit_index (layer);
|
|
||||||
g_string_append_printf (layer_declarations,
|
|
||||||
"attribute vec4 cogl_tex_coord%d_in;\n"
|
|
||||||
"#define cogl_texture_matrix%i cogl_texture_matrix[%i]\n"
|
|
||||||
"#define cogl_tex_coord%i_out _cogl_tex_coord[%i]\n",
|
|
||||||
layer->index,
|
|
||||||
layer->index,
|
|
||||||
unit_index,
|
|
||||||
layer->index,
|
|
||||||
unit_index);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
add_layer_fragment_boilerplate_cb (CoglPipelineLayer *layer,
|
|
||||||
void *user_data)
|
|
||||||
{
|
|
||||||
GString *layer_declarations = user_data;
|
|
||||||
g_string_append_printf (layer_declarations,
|
|
||||||
"#define cogl_tex_coord%i_in _cogl_tex_coord[%i]\n",
|
|
||||||
layer->index,
|
|
||||||
_cogl_pipeline_layer_get_unit_index (layer));
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
_cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx,
|
|
||||||
GLuint shader_gl_handle,
|
|
||||||
GLenum shader_gl_type,
|
|
||||||
CoglPipeline *pipeline,
|
|
||||||
GLsizei count_in,
|
|
||||||
const char **strings_in,
|
|
||||||
const GLint *lengths_in)
|
|
||||||
{
|
|
||||||
const char *vertex_boilerplate;
|
|
||||||
const char *fragment_boilerplate;
|
|
||||||
|
|
||||||
const char **strings = g_alloca (sizeof (char *) * (count_in + 4));
|
|
||||||
GLint *lengths = g_alloca (sizeof (GLint) * (count_in + 4));
|
|
||||||
char *version_string;
|
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
int n_layers;
|
|
||||||
|
|
||||||
vertex_boilerplate = _COGL_VERTEX_SHADER_BOILERPLATE;
|
|
||||||
fragment_boilerplate = _COGL_FRAGMENT_SHADER_BOILERPLATE;
|
|
||||||
|
|
||||||
version_string = g_strdup_printf ("#version %i\n\n",
|
|
||||||
ctx->glsl_version_to_use);
|
|
||||||
strings[count] = version_string;
|
|
||||||
lengths[count++] = -1;
|
|
||||||
|
|
||||||
if (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_EGL_IMAGE_EXTERNAL))
|
|
||||||
{
|
|
||||||
static const char image_external_extension[] =
|
|
||||||
"#extension GL_OES_EGL_image_external : require\n";
|
|
||||||
strings[count] = image_external_extension;
|
|
||||||
lengths[count++] = sizeof (image_external_extension) - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shader_gl_type == GL_VERTEX_SHADER)
|
|
||||||
{
|
|
||||||
strings[count] = vertex_boilerplate;
|
|
||||||
lengths[count++] = strlen (vertex_boilerplate);
|
|
||||||
}
|
|
||||||
else if (shader_gl_type == GL_FRAGMENT_SHADER)
|
|
||||||
{
|
|
||||||
strings[count] = fragment_boilerplate;
|
|
||||||
lengths[count++] = strlen (fragment_boilerplate);
|
|
||||||
}
|
|
||||||
|
|
||||||
n_layers = cogl_pipeline_get_n_layers (pipeline);
|
|
||||||
if (n_layers)
|
|
||||||
{
|
|
||||||
GString *layer_declarations = ctx->codegen_boilerplate_buffer;
|
|
||||||
g_string_set_size (layer_declarations, 0);
|
|
||||||
|
|
||||||
g_string_append_printf (layer_declarations,
|
|
||||||
"varying vec4 _cogl_tex_coord[%d];\n",
|
|
||||||
n_layers);
|
|
||||||
|
|
||||||
if (shader_gl_type == GL_VERTEX_SHADER)
|
|
||||||
{
|
|
||||||
g_string_append_printf (layer_declarations,
|
|
||||||
"uniform mat4 cogl_texture_matrix[%d];\n",
|
|
||||||
n_layers);
|
|
||||||
|
|
||||||
_cogl_pipeline_foreach_layer_internal (pipeline,
|
|
||||||
add_layer_vertex_boilerplate_cb,
|
|
||||||
layer_declarations);
|
|
||||||
}
|
|
||||||
else if (shader_gl_type == GL_FRAGMENT_SHADER)
|
|
||||||
{
|
|
||||||
_cogl_pipeline_foreach_layer_internal (pipeline,
|
|
||||||
add_layer_fragment_boilerplate_cb,
|
|
||||||
layer_declarations);
|
|
||||||
}
|
|
||||||
|
|
||||||
strings[count] = layer_declarations->str;
|
|
||||||
lengths[count++] = -1; /* null terminated */
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy (strings + count, strings_in, sizeof (char *) * count_in);
|
|
||||||
if (lengths_in)
|
|
||||||
memcpy (lengths + count, lengths_in, sizeof (GLint) * count_in);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < count_in; i++)
|
|
||||||
lengths[count + i] = -1; /* null terminated */
|
|
||||||
}
|
|
||||||
count += count_in;
|
|
||||||
|
|
||||||
if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_SHOW_SOURCE)))
|
|
||||||
{
|
|
||||||
GString *buf = g_string_new (NULL);
|
|
||||||
int i;
|
|
||||||
|
|
||||||
g_string_append_printf (buf,
|
|
||||||
"%s shader:\n",
|
|
||||||
shader_gl_type == GL_VERTEX_SHADER ?
|
|
||||||
"vertex" : "fragment");
|
|
||||||
for (i = 0; i < count; i++)
|
|
||||||
if (lengths[i] != -1)
|
|
||||||
g_string_append_len (buf, strings[i], lengths[i]);
|
|
||||||
else
|
|
||||||
g_string_append (buf, strings[i]);
|
|
||||||
|
|
||||||
g_message ("%s", buf->str);
|
|
||||||
|
|
||||||
g_string_free (buf, TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
GE( ctx, glShaderSource (shader_gl_handle, count,
|
|
||||||
(const char **) strings, lengths) );
|
|
||||||
|
|
||||||
g_free (version_string);
|
|
||||||
}
|
|
@ -47,16 +47,4 @@ struct _CoglShader
|
|||||||
char *source;
|
char *source;
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
|
||||||
_cogl_shader_compile_real (CoglHandle handle,
|
|
||||||
CoglPipeline *pipeline);
|
|
||||||
|
|
||||||
void
|
|
||||||
_cogl_shader_set_source_with_boilerplate (GLuint shader_gl_handle,
|
|
||||||
GLenum shader_gl_type,
|
|
||||||
int n_tex_coord_attribs,
|
|
||||||
GLsizei count_in,
|
|
||||||
const char **strings_in,
|
|
||||||
const GLint *lengths_in);
|
|
||||||
|
|
||||||
#endif /* __COGL_SHADER_H */
|
#endif /* __COGL_SHADER_H */
|
||||||
|
@ -32,7 +32,6 @@
|
|||||||
|
|
||||||
#include "cogl-context-private.h"
|
#include "cogl-context-private.h"
|
||||||
#include "cogl-object-private.h"
|
#include "cogl-object-private.h"
|
||||||
#include "cogl-glsl-shader-private.h"
|
|
||||||
#include "cogl-glsl-shader-boilerplate.h"
|
#include "cogl-glsl-shader-boilerplate.h"
|
||||||
#include "driver/gl/cogl-util-gl-private.h"
|
#include "driver/gl/cogl-util-gl-private.h"
|
||||||
#include "deprecated/cogl-shader-private.h"
|
#include "deprecated/cogl-shader-private.h"
|
||||||
@ -45,13 +44,6 @@ static void _cogl_shader_free (CoglShader *shader);
|
|||||||
|
|
||||||
COGL_HANDLE_DEFINE (Shader, shader);
|
COGL_HANDLE_DEFINE (Shader, shader);
|
||||||
|
|
||||||
#ifndef GL_FRAGMENT_SHADER
|
|
||||||
#define GL_FRAGMENT_SHADER 0x8B30
|
|
||||||
#endif
|
|
||||||
#ifndef GL_VERTEX_SHADER
|
|
||||||
#define GL_VERTEX_SHADER 0x8B31
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_cogl_shader_free (CoglShader *shader)
|
_cogl_shader_free (CoglShader *shader)
|
||||||
{
|
{
|
||||||
@ -91,23 +83,6 @@ cogl_create_shader (CoglShaderType type)
|
|||||||
return _cogl_shader_handle_new (shader);
|
return _cogl_shader_handle_new (shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
delete_shader (CoglShader *shader)
|
|
||||||
{
|
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
|
||||||
|
|
||||||
if (shader->gl_handle)
|
|
||||||
GE (ctx, glDeleteShader (shader->gl_handle));
|
|
||||||
|
|
||||||
shader->gl_handle = 0;
|
|
||||||
|
|
||||||
if (shader->compilation_pipeline)
|
|
||||||
{
|
|
||||||
cogl_object_unref (shader->compilation_pipeline);
|
|
||||||
shader->compilation_pipeline = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
cogl_shader_source (CoglHandle handle,
|
cogl_shader_source (CoglHandle handle,
|
||||||
const char *source)
|
const char *source)
|
||||||
@ -124,77 +99,6 @@ cogl_shader_source (CoglHandle handle,
|
|||||||
shader->source = g_strdup (source);
|
shader->source = g_strdup (source);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
_cogl_shader_compile_real (CoglHandle handle,
|
|
||||||
CoglPipeline *pipeline)
|
|
||||||
{
|
|
||||||
CoglShader *shader = handle;
|
|
||||||
GLenum gl_type;
|
|
||||||
GLint status;
|
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
|
||||||
|
|
||||||
if (shader->gl_handle)
|
|
||||||
{
|
|
||||||
CoglPipeline *prev = shader->compilation_pipeline;
|
|
||||||
|
|
||||||
/* XXX: currently the only things that will affect the
|
|
||||||
* boilerplate for user shaders, apart from driver features,
|
|
||||||
* are the pipeline layer-indices and texture-unit-indices
|
|
||||||
*/
|
|
||||||
if (pipeline == prev ||
|
|
||||||
_cogl_pipeline_layer_and_unit_numbers_equal (prev, pipeline))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shader->gl_handle)
|
|
||||||
delete_shader (shader);
|
|
||||||
|
|
||||||
switch (shader->type)
|
|
||||||
{
|
|
||||||
case COGL_SHADER_TYPE_VERTEX:
|
|
||||||
gl_type = GL_VERTEX_SHADER;
|
|
||||||
break;
|
|
||||||
case COGL_SHADER_TYPE_FRAGMENT:
|
|
||||||
gl_type = GL_FRAGMENT_SHADER;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
g_assert_not_reached ();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
shader->gl_handle = ctx->glCreateShader (gl_type);
|
|
||||||
|
|
||||||
_cogl_glsl_shader_set_source_with_boilerplate (ctx,
|
|
||||||
shader->gl_handle,
|
|
||||||
gl_type,
|
|
||||||
pipeline,
|
|
||||||
1,
|
|
||||||
(const char **)
|
|
||||||
&shader->source,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
GE (ctx, glCompileShader (shader->gl_handle));
|
|
||||||
|
|
||||||
shader->compilation_pipeline = cogl_object_ref (pipeline);
|
|
||||||
|
|
||||||
GE (ctx, glGetShaderiv (shader->gl_handle, GL_COMPILE_STATUS, &status));
|
|
||||||
if (!status)
|
|
||||||
{
|
|
||||||
char buffer[512];
|
|
||||||
int len = 0;
|
|
||||||
|
|
||||||
ctx->glGetShaderInfoLog (shader->gl_handle, 511, &len, buffer);
|
|
||||||
buffer[len] = '\0';
|
|
||||||
|
|
||||||
g_warning ("Failed to compile GLSL program:\n"
|
|
||||||
"src:\n%s\n"
|
|
||||||
"error:\n%s\n",
|
|
||||||
shader->source,
|
|
||||||
buffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CoglShaderType
|
CoglShaderType
|
||||||
cogl_shader_get_type (CoglHandle handle)
|
cogl_shader_get_type (CoglHandle handle)
|
||||||
{
|
{
|
||||||
|
@ -43,11 +43,11 @@
|
|||||||
#include "cogl-snippet-private.h"
|
#include "cogl-snippet-private.h"
|
||||||
#include "cogl-list.h"
|
#include "cogl-list.h"
|
||||||
#include "driver/gl/cogl-util-gl-private.h"
|
#include "driver/gl/cogl-util-gl-private.h"
|
||||||
|
#include "driver/gl/cogl-pipeline-opengl-private.h"
|
||||||
|
|
||||||
#include "cogl-context-private.h"
|
#include "cogl-context-private.h"
|
||||||
#include "cogl-object-private.h"
|
#include "cogl-object-private.h"
|
||||||
#include "cogl-pipeline-cache.h"
|
#include "cogl-pipeline-cache.h"
|
||||||
#include "cogl-glsl-shader-private.h"
|
|
||||||
#include "driver/gl/cogl-pipeline-fragend-glsl-private.h"
|
#include "driver/gl/cogl-pipeline-fragend-glsl-private.h"
|
||||||
#include "deprecated/cogl-shader-private.h"
|
#include "deprecated/cogl-shader-private.h"
|
||||||
#include "deprecated/cogl-program-private.h"
|
#include "deprecated/cogl-program-private.h"
|
||||||
|
@ -146,5 +146,14 @@ _cogl_pipeline_flush_gl_state (CoglContext *context,
|
|||||||
gboolean skip_gl_state,
|
gboolean skip_gl_state,
|
||||||
gboolean unknown_color_alpha);
|
gboolean unknown_color_alpha);
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx,
|
||||||
|
GLuint shader_gl_handle,
|
||||||
|
GLenum shader_gl_type,
|
||||||
|
CoglPipeline *pipeline,
|
||||||
|
GLsizei count_in,
|
||||||
|
const char **strings_in,
|
||||||
|
const GLint *lengths_in);
|
||||||
|
|
||||||
#endif /* __COGL_PIPELINE_OPENGL_PRIVATE_H */
|
#endif /* __COGL_PIPELINE_OPENGL_PRIVATE_H */
|
||||||
|
|
||||||
|
@ -633,6 +633,82 @@ _cogl_pipeline_progend_glsl_start (CoglPipeline *pipeline)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cogl_shader_compile_real (CoglHandle handle,
|
||||||
|
CoglPipeline *pipeline)
|
||||||
|
{
|
||||||
|
CoglShader *shader = handle;
|
||||||
|
GLenum gl_type;
|
||||||
|
GLint status;
|
||||||
|
|
||||||
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
|
if (shader->gl_handle)
|
||||||
|
{
|
||||||
|
CoglPipeline *prev = shader->compilation_pipeline;
|
||||||
|
|
||||||
|
/* XXX: currently the only things that will affect the
|
||||||
|
* boilerplate for user shaders, apart from driver features,
|
||||||
|
* are the pipeline layer-indices and texture-unit-indices
|
||||||
|
*/
|
||||||
|
if (pipeline == prev ||
|
||||||
|
_cogl_pipeline_layer_and_unit_numbers_equal (prev, pipeline))
|
||||||
|
return;
|
||||||
|
|
||||||
|
GE (ctx, glDeleteShader (shader->gl_handle));
|
||||||
|
shader->gl_handle = 0;
|
||||||
|
|
||||||
|
if (shader->compilation_pipeline)
|
||||||
|
{
|
||||||
|
cogl_object_unref (shader->compilation_pipeline);
|
||||||
|
shader->compilation_pipeline = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (shader->type)
|
||||||
|
{
|
||||||
|
case COGL_SHADER_TYPE_VERTEX:
|
||||||
|
gl_type = GL_VERTEX_SHADER;
|
||||||
|
break;
|
||||||
|
case COGL_SHADER_TYPE_FRAGMENT:
|
||||||
|
gl_type = GL_FRAGMENT_SHADER;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
shader->gl_handle = ctx->glCreateShader (gl_type);
|
||||||
|
|
||||||
|
_cogl_glsl_shader_set_source_with_boilerplate (ctx,
|
||||||
|
shader->gl_handle,
|
||||||
|
gl_type,
|
||||||
|
pipeline,
|
||||||
|
1,
|
||||||
|
(const char **)
|
||||||
|
&shader->source,
|
||||||
|
NULL);
|
||||||
|
GE (ctx, glCompileShader (shader->gl_handle));
|
||||||
|
|
||||||
|
shader->compilation_pipeline = cogl_object_ref (pipeline);
|
||||||
|
|
||||||
|
GE (ctx, glGetShaderiv (shader->gl_handle, GL_COMPILE_STATUS, &status));
|
||||||
|
if (!status)
|
||||||
|
{
|
||||||
|
char buffer[512];
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
|
ctx->glGetShaderInfoLog (shader->gl_handle, 511, &len, buffer);
|
||||||
|
buffer[len] = '\0';
|
||||||
|
|
||||||
|
g_warning ("Failed to compile GLSL program:\n"
|
||||||
|
"src:\n%s\n"
|
||||||
|
"error:\n%s\n",
|
||||||
|
shader->source,
|
||||||
|
buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_cogl_pipeline_progend_glsl_end (CoglPipeline *pipeline,
|
_cogl_pipeline_progend_glsl_end (CoglPipeline *pipeline,
|
||||||
unsigned long pipelines_difference)
|
unsigned long pipelines_difference)
|
||||||
|
@ -45,7 +45,7 @@
|
|||||||
#include "cogl-context-private.h"
|
#include "cogl-context-private.h"
|
||||||
#include "cogl-object-private.h"
|
#include "cogl-object-private.h"
|
||||||
#include "cogl-pipeline-state-private.h"
|
#include "cogl-pipeline-state-private.h"
|
||||||
#include "cogl-glsl-shader-private.h"
|
#include "cogl-glsl-shader-boilerplate.h"
|
||||||
#include "driver/gl/cogl-pipeline-vertend-glsl-private.h"
|
#include "driver/gl/cogl-pipeline-vertend-glsl-private.h"
|
||||||
#include "deprecated/cogl-program-private.h"
|
#include "deprecated/cogl-program-private.h"
|
||||||
|
|
||||||
@ -132,6 +132,150 @@ dirty_shader_state (CoglPipeline *pipeline)
|
|||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
add_layer_vertex_boilerplate_cb (CoglPipelineLayer *layer,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
GString *layer_declarations = user_data;
|
||||||
|
int unit_index = _cogl_pipeline_layer_get_unit_index (layer);
|
||||||
|
g_string_append_printf (layer_declarations,
|
||||||
|
"attribute vec4 cogl_tex_coord%d_in;\n"
|
||||||
|
"#define cogl_texture_matrix%i cogl_texture_matrix[%i]\n"
|
||||||
|
"#define cogl_tex_coord%i_out _cogl_tex_coord[%i]\n",
|
||||||
|
layer->index,
|
||||||
|
layer->index,
|
||||||
|
unit_index,
|
||||||
|
layer->index,
|
||||||
|
unit_index);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
add_layer_fragment_boilerplate_cb (CoglPipelineLayer *layer,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
GString *layer_declarations = user_data;
|
||||||
|
g_string_append_printf (layer_declarations,
|
||||||
|
"#define cogl_tex_coord%i_in _cogl_tex_coord[%i]\n",
|
||||||
|
layer->index,
|
||||||
|
_cogl_pipeline_layer_get_unit_index (layer));
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx,
|
||||||
|
GLuint shader_gl_handle,
|
||||||
|
GLenum shader_gl_type,
|
||||||
|
CoglPipeline *pipeline,
|
||||||
|
GLsizei count_in,
|
||||||
|
const char **strings_in,
|
||||||
|
const GLint *lengths_in)
|
||||||
|
{
|
||||||
|
const char *vertex_boilerplate;
|
||||||
|
const char *fragment_boilerplate;
|
||||||
|
|
||||||
|
const char **strings = g_alloca (sizeof (char *) * (count_in + 4));
|
||||||
|
GLint *lengths = g_alloca (sizeof (GLint) * (count_in + 4));
|
||||||
|
char *version_string;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
int n_layers;
|
||||||
|
|
||||||
|
vertex_boilerplate = _COGL_VERTEX_SHADER_BOILERPLATE;
|
||||||
|
fragment_boilerplate = _COGL_FRAGMENT_SHADER_BOILERPLATE;
|
||||||
|
|
||||||
|
version_string = g_strdup_printf ("#version %i\n\n",
|
||||||
|
ctx->glsl_version_to_use);
|
||||||
|
strings[count] = version_string;
|
||||||
|
lengths[count++] = -1;
|
||||||
|
|
||||||
|
if (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_EGL_IMAGE_EXTERNAL))
|
||||||
|
{
|
||||||
|
static const char image_external_extension[] =
|
||||||
|
"#extension GL_OES_EGL_image_external : require\n";
|
||||||
|
strings[count] = image_external_extension;
|
||||||
|
lengths[count++] = sizeof (image_external_extension) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shader_gl_type == GL_VERTEX_SHADER)
|
||||||
|
{
|
||||||
|
strings[count] = vertex_boilerplate;
|
||||||
|
lengths[count++] = strlen (vertex_boilerplate);
|
||||||
|
}
|
||||||
|
else if (shader_gl_type == GL_FRAGMENT_SHADER)
|
||||||
|
{
|
||||||
|
strings[count] = fragment_boilerplate;
|
||||||
|
lengths[count++] = strlen (fragment_boilerplate);
|
||||||
|
}
|
||||||
|
|
||||||
|
n_layers = cogl_pipeline_get_n_layers (pipeline);
|
||||||
|
if (n_layers)
|
||||||
|
{
|
||||||
|
GString *layer_declarations = ctx->codegen_boilerplate_buffer;
|
||||||
|
g_string_set_size (layer_declarations, 0);
|
||||||
|
|
||||||
|
g_string_append_printf (layer_declarations,
|
||||||
|
"varying vec4 _cogl_tex_coord[%d];\n",
|
||||||
|
n_layers);
|
||||||
|
|
||||||
|
if (shader_gl_type == GL_VERTEX_SHADER)
|
||||||
|
{
|
||||||
|
g_string_append_printf (layer_declarations,
|
||||||
|
"uniform mat4 cogl_texture_matrix[%d];\n",
|
||||||
|
n_layers);
|
||||||
|
|
||||||
|
_cogl_pipeline_foreach_layer_internal (pipeline,
|
||||||
|
add_layer_vertex_boilerplate_cb,
|
||||||
|
layer_declarations);
|
||||||
|
}
|
||||||
|
else if (shader_gl_type == GL_FRAGMENT_SHADER)
|
||||||
|
{
|
||||||
|
_cogl_pipeline_foreach_layer_internal (pipeline,
|
||||||
|
add_layer_fragment_boilerplate_cb,
|
||||||
|
layer_declarations);
|
||||||
|
}
|
||||||
|
|
||||||
|
strings[count] = layer_declarations->str;
|
||||||
|
lengths[count++] = -1; /* null terminated */
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy (strings + count, strings_in, sizeof (char *) * count_in);
|
||||||
|
if (lengths_in)
|
||||||
|
memcpy (lengths + count, lengths_in, sizeof (GLint) * count_in);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < count_in; i++)
|
||||||
|
lengths[count + i] = -1; /* null terminated */
|
||||||
|
}
|
||||||
|
count += count_in;
|
||||||
|
|
||||||
|
if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_SHOW_SOURCE)))
|
||||||
|
{
|
||||||
|
GString *buf = g_string_new (NULL);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
g_string_append_printf (buf,
|
||||||
|
"%s shader:\n",
|
||||||
|
shader_gl_type == GL_VERTEX_SHADER ?
|
||||||
|
"vertex" : "fragment");
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
if (lengths[i] != -1)
|
||||||
|
g_string_append_len (buf, strings[i], lengths[i]);
|
||||||
|
else
|
||||||
|
g_string_append (buf, strings[i]);
|
||||||
|
|
||||||
|
g_message ("%s", buf->str);
|
||||||
|
|
||||||
|
g_string_free (buf, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
GE( ctx, glShaderSource (shader_gl_handle, count,
|
||||||
|
(const char **) strings, lengths) );
|
||||||
|
|
||||||
|
g_free (version_string);
|
||||||
|
}
|
||||||
GLuint
|
GLuint
|
||||||
_cogl_pipeline_vertend_glsl_get_shader (CoglPipeline *pipeline)
|
_cogl_pipeline_vertend_glsl_get_shader (CoglPipeline *pipeline)
|
||||||
{
|
{
|
||||||
|
@ -274,8 +274,6 @@ cogl_sources = [
|
|||||||
'cogl-pipeline-layer-state.c',
|
'cogl-pipeline-layer-state.c',
|
||||||
'cogl-pipeline-state-private.h',
|
'cogl-pipeline-state-private.h',
|
||||||
'cogl-pipeline-debug.c',
|
'cogl-pipeline-debug.c',
|
||||||
'cogl-glsl-shader.c',
|
|
||||||
'cogl-glsl-shader-private.h',
|
|
||||||
'cogl-glsl-shader-boilerplate.h',
|
'cogl-glsl-shader-boilerplate.h',
|
||||||
'cogl-pipeline-snippet-private.h',
|
'cogl-pipeline-snippet-private.h',
|
||||||
'cogl-pipeline-snippet.c',
|
'cogl-pipeline-snippet.c',
|
||||||
|
Loading…
Reference in New Issue
Block a user