mirror of
https://github.com/brl/mutter.git
synced 2025-07-10 04:34:31 +00:00
Add support for per-vertex point sizes
This adds a new function to enable per-vertex point size on a pipeline. This can be set with cogl_pipeline_set_per_vertex_point_size(). Once enabled the point size can be set either by drawing with an attribute named 'cogl_point_size_in' or by writing to the 'cogl_point_size_out' builtin from a snippet. There is a feature flag which must be checked for before using per-vertex point sizes. This will only be set on GL >= 2.0 or on GLES 2.0. GL will only let you set a per-vertex point size from GLSL by writing to gl_PointSize. This is only available in GL2 and not in the older GLSL extensions. The per-vertex point size has its own pipeline state flag so that it can be part of the state that affects vertex shader generation. Having to enable the per vertex point size with a separate function is a bit awkward. Ideally it would work like the color attribute where you can just set it for every vertex in your primitive with cogl_pipeline_set_color or set it per-vertex by just using the attribute. This is harder to get working with the point size because we need to generate a different vertex shader depending on what attributes are bound. I think if we wanted to make this work transparently we would still want to internally have a pipeline property describing whether the shader was generated with per-vertex support so that it would work with the shader cache correctly. Potentially we could make the per-vertex property internal and automatically make a weak pipeline whenever the attribute is bound. However we would then also need to automatically detect when an application is writing to cogl_point_size_out from a snippet. Reviewed-by: Robert Bragg <robert@linux.intel.com> (cherry picked from commit 8495d9c1c15ce389885a9356d965eabd97758115) Conflicts: cogl/cogl-context.c cogl/cogl-pipeline-private.h cogl/cogl-pipeline.c cogl/cogl-private.h cogl/driver/gl/cogl-pipeline-progend-fixed.c cogl/driver/gl/gl/cogl-pipeline-progend-fixed-arbfp.c
This commit is contained in:
@ -58,7 +58,9 @@
|
||||
#ifndef GL_CLAMP_TO_BORDER
|
||||
#define GL_CLAMP_TO_BORDER 0x812d
|
||||
#endif
|
||||
|
||||
#ifndef GL_PROGRAM_POINT_SIZE
|
||||
#define GL_PROGRAM_POINT_SIZE 0x8642
|
||||
#endif
|
||||
|
||||
static void
|
||||
texture_unit_init (CoglContext *ctx,
|
||||
@ -684,6 +686,21 @@ _cogl_pipeline_flush_color_blend_alpha_depth_state (
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_COGL_GL
|
||||
if ((ctx->private_feature_flags &
|
||||
COGL_PRIVATE_FEATURE_ENABLE_PROGRAM_POINT_SIZE) &&
|
||||
(pipelines_difference & COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE))
|
||||
{
|
||||
unsigned long state = COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE;
|
||||
CoglPipeline *authority = _cogl_pipeline_get_authority (pipeline, state);
|
||||
|
||||
if (authority->big_state->per_vertex_point_size)
|
||||
GE( ctx, glEnable (GL_PROGRAM_POINT_SIZE) );
|
||||
else
|
||||
GE( ctx, glDisable (GL_PROGRAM_POINT_SIZE) );
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pipeline->real_blend_enable != ctx->gl_blend_enable_cache)
|
||||
{
|
||||
if (pipeline->real_blend_enable)
|
||||
|
@ -64,6 +64,11 @@ _cogl_pipeline_progend_fixed_start (CoglPipeline *pipeline)
|
||||
if (cogl_pipeline_get_user_program (pipeline))
|
||||
return FALSE;
|
||||
|
||||
/* The fixed progend can't handle the per-vertex point size
|
||||
* attribute */
|
||||
if (cogl_pipeline_get_per_vertex_point_size (pipeline))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -290,12 +290,20 @@ _cogl_pipeline_vertend_glsl_start (CoglPipeline *pipeline,
|
||||
"cogl_generated_source ()\n"
|
||||
"{\n");
|
||||
|
||||
if (!(ctx->private_feature_flags &
|
||||
COGL_PRIVATE_FEATURE_BUILTIN_POINT_SIZE_UNIFORM))
|
||||
/* There is no builtin uniform for the pointsize on GLES2 so we need
|
||||
to copy it from the custom uniform in the vertex shader */
|
||||
g_string_append (shader_state->source,
|
||||
" cogl_point_size_out = cogl_point_size_in;\n");
|
||||
if (cogl_pipeline_get_per_vertex_point_size (pipeline))
|
||||
g_string_append (shader_state->header,
|
||||
"attribute float cogl_point_size_in;\n");
|
||||
else if (!(ctx->private_feature_flags &
|
||||
COGL_PRIVATE_FEATURE_BUILTIN_POINT_SIZE_UNIFORM))
|
||||
{
|
||||
/* There is no builtin uniform for the point size on GLES2 so we
|
||||
need to copy it from the custom uniform in the vertex shader if
|
||||
we're not using per-vertex point sizes */
|
||||
g_string_append (shader_state->header,
|
||||
"uniform float cogl_point_size_in;\n");
|
||||
g_string_append (shader_state->source,
|
||||
" cogl_point_size_out = cogl_point_size_in;\n");
|
||||
}
|
||||
}
|
||||
|
||||
static CoglBool
|
||||
@ -389,6 +397,8 @@ _cogl_pipeline_vertend_glsl_end (CoglPipeline *pipeline,
|
||||
GLuint shader;
|
||||
CoglPipelineSnippetData snippet_data;
|
||||
CoglPipelineSnippetList *vertex_snippets;
|
||||
CoglBool has_per_vertex_point_size =
|
||||
cogl_pipeline_get_per_vertex_point_size (pipeline);
|
||||
|
||||
COGL_STATIC_COUNTER (vertend_glsl_compile_counter,
|
||||
"glsl vertex compile counter",
|
||||
@ -407,7 +417,21 @@ _cogl_pipeline_vertend_glsl_end (CoglPipeline *pipeline,
|
||||
"}\n");
|
||||
|
||||
g_string_append (shader_state->source,
|
||||
" cogl_vertex_transform ();\n"
|
||||
" cogl_vertex_transform ();\n");
|
||||
|
||||
if (has_per_vertex_point_size)
|
||||
{
|
||||
g_string_append (shader_state->header,
|
||||
"void\n"
|
||||
"cogl_real_point_size_calculation ()\n"
|
||||
"{\n"
|
||||
" cogl_point_size_out = cogl_point_size_in;\n"
|
||||
"}\n");
|
||||
g_string_append (shader_state->source,
|
||||
" cogl_point_size_calculation ();\n");
|
||||
}
|
||||
|
||||
g_string_append (shader_state->source,
|
||||
" cogl_color_out = cogl_color_in;\n"
|
||||
"}\n");
|
||||
|
||||
@ -423,6 +447,19 @@ _cogl_pipeline_vertend_glsl_end (CoglPipeline *pipeline,
|
||||
snippet_data.source_buf = shader_state->header;
|
||||
_cogl_pipeline_snippet_generate_code (&snippet_data);
|
||||
|
||||
/* Add hooks for the point size calculation part */
|
||||
if (has_per_vertex_point_size)
|
||||
{
|
||||
memset (&snippet_data, 0, sizeof (snippet_data));
|
||||
snippet_data.snippets = vertex_snippets;
|
||||
snippet_data.hook = COGL_SNIPPET_HOOK_POINT_SIZE;
|
||||
snippet_data.chain_function = "cogl_real_point_size_calculation";
|
||||
snippet_data.final_name = "cogl_point_size_calculation";
|
||||
snippet_data.function_prefix = "cogl_point_size_calculation";
|
||||
snippet_data.source_buf = shader_state->header;
|
||||
_cogl_pipeline_snippet_generate_code (&snippet_data);
|
||||
}
|
||||
|
||||
/* Add all of the hooks for vertex processing */
|
||||
memset (&snippet_data, 0, sizeof (snippet_data));
|
||||
snippet_data.snippets = vertex_snippets;
|
||||
@ -487,6 +524,7 @@ _cogl_pipeline_vertend_glsl_end (CoglPipeline *pipeline,
|
||||
shader_state->gl_shader = shader;
|
||||
}
|
||||
|
||||
#ifdef HAVE_COGL_GL
|
||||
if ((ctx->private_feature_flags &
|
||||
COGL_PRIVATE_FEATURE_BUILTIN_POINT_SIZE_UNIFORM) &&
|
||||
(pipelines_difference & COGL_PIPELINE_STATE_POINT_SIZE))
|
||||
@ -496,6 +534,7 @@ _cogl_pipeline_vertend_glsl_end (CoglPipeline *pipeline,
|
||||
|
||||
GE( ctx, glPointSize (authority->big_state->point_size) );
|
||||
}
|
||||
#endif /* HAVE_COGL_GL */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -569,11 +569,23 @@ _cogl_driver_update_features (CoglContext *ctx,
|
||||
if (ctx->glGenSamplers)
|
||||
private_flags |= COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS;
|
||||
|
||||
|
||||
if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 3, 3) ||
|
||||
_cogl_check_extension ("GL_ARB_texture_swizzle", gl_extensions) ||
|
||||
_cogl_check_extension ("GL_EXT_texture_swizzle", gl_extensions))
|
||||
private_flags |= COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE;
|
||||
|
||||
/* The per-vertex point size is only available via GLSL with the
|
||||
* gl_PointSize builtin. This is only available in GL 2.0 (not the
|
||||
* GLSL extensions) */
|
||||
if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 0))
|
||||
{
|
||||
COGL_FLAGS_SET (ctx->features,
|
||||
COGL_FEATURE_ID_PER_VERTEX_POINT_SIZE,
|
||||
TRUE);
|
||||
private_flags |= COGL_PRIVATE_FEATURE_ENABLE_PROGRAM_POINT_SIZE;
|
||||
}
|
||||
|
||||
if (ctx->driver == COGL_DRIVER_GL)
|
||||
{
|
||||
int max_clip_planes = 0;
|
||||
|
@ -73,6 +73,11 @@ _cogl_pipeline_progend_fixed_arbfp_start (CoglPipeline *pipeline)
|
||||
_cogl_program_get_language (user_program) != COGL_SHADER_LANGUAGE_ARBFP)
|
||||
return FALSE;
|
||||
|
||||
/* The ARBfp progend can't handle the per-vertex point size
|
||||
* attribute */
|
||||
if (cogl_pipeline_get_per_vertex_point_size (pipeline))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -256,6 +256,8 @@ _cogl_driver_update_features (CoglContext *context,
|
||||
COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_DEPTH_RANGE, TRUE);
|
||||
COGL_FLAGS_SET (context->features,
|
||||
COGL_FEATURE_ID_MIRRORED_REPEAT, TRUE);
|
||||
COGL_FLAGS_SET (context->features,
|
||||
COGL_FEATURE_ID_PER_VERTEX_POINT_SIZE, TRUE);
|
||||
|
||||
private_flags |= COGL_PRIVATE_FEATURE_BLEND_CONSTANT;
|
||||
}
|
||||
|
Reference in New Issue
Block a user