ngl: move uniform key mapping into uniform state

Previously, we translated the uniform key (an enum) into a location within
the shader program in GskNglProgram. A number of performance improvements
were focused around having low nubers for the uniform locations. Generally
this is the case, but some drivers such as old Intel drivers on Windows
may use rather large numbers for those.

To combat this, we can push the translation of uniform keys into locations
at the GskNglUniformState level so that we work with unranslated keys
through the process until applying them.

Fixes #3780
This commit is contained in:
Christian Hergert 2021-03-23 12:10:12 -07:00
parent 1f6b556972
commit f8a6a09896
9 changed files with 287 additions and 335 deletions

View File

@ -272,24 +272,23 @@ snapshot_uniforms (GskNglUniformState *state,
GskNglUniformProgram *program,
GskNglCommandUniforms *array)
{
GskNglCommandUniform *uniform = gsk_ngl_command_uniforms_append_n (array, program->n_sparse);
GskNglCommandUniform *uniform = gsk_ngl_command_uniforms_append_n (array, program->n_mappings);
guint count = 0;
for (guint i = 0; i < program->n_sparse; i++)
for (guint i = 0; i < program->n_mappings; i++)
{
guint location = program->sparse[i];
const GskNglUniformInfo *info = &program->uniforms[location].info;
const GskNglUniformMapping *mapping = &program->mappings[i];
if (!info->initial)
if (!mapping->info.initial && mapping->location > -1)
{
uniform[count].location = location;
uniform[count].info = *info;
uniform[count].location = mapping->location;
uniform[count].info = mapping->info;
count++;
}
}
if (count != program->n_sparse)
array->len -= program->n_sparse - count;
if (count != program->n_mappings)
array->len -= program->n_mappings - count;
return count;
}

View File

@ -153,7 +153,7 @@ G_STATIC_ASSERT (sizeof (GskNglCommandClear) == 20);
typedef struct _GskNglCommandUniform
{
GskNglUniformInfo info;
guint location;
guint location;
} GskNglCommandUniform;
G_STATIC_ASSERT (sizeof (GskNglCommandUniform) == 8);

View File

@ -226,14 +226,14 @@ gsk_ngl_driver_dispose (GObject *object)
#define GSK_NGL_NO_UNIFORMS
#define GSK_NGL_ADD_UNIFORM(pos, KEY, name)
#define GSK_NGL_DEFINE_PROGRAM(name, resource, uniforms) \
GSK_NGL_DELETE_PROGRAM(name); \
GSK_NGL_DELETE_PROGRAM(name ## _no_clip); \
GSK_NGL_DELETE_PROGRAM(name); \
GSK_NGL_DELETE_PROGRAM(name ## _no_clip); \
GSK_NGL_DELETE_PROGRAM(name ## _rect_clip);
#define GSK_NGL_DELETE_PROGRAM(name) \
G_STMT_START { \
if (self->name) \
#define GSK_NGL_DELETE_PROGRAM(name) \
G_STMT_START { \
if (self->name) \
gsk_ngl_program_delete (self->name); \
g_clear_object (&self->name); \
g_clear_object (&self->name); \
} G_STMT_END;
# include "gsknglprograms.defs"
#undef GSK_NGL_NO_UNIFORMS
@ -356,10 +356,10 @@ gsk_ngl_driver_load_programs (GskNglDriver *self,
#define GSK_NGL_ADD_UNIFORM(pos, KEY, name) \
gsk_ngl_program_add_uniform (program, #name, UNIFORM_##KEY);
#define GSK_NGL_DEFINE_PROGRAM(name, resource, uniforms) \
gsk_ngl_compiler_set_source_from_resource (compiler, GSK_NGL_COMPILER_ALL, resource); \
GSK_NGL_COMPILE_PROGRAM(name ## _no_clip, uniforms, "#define NO_CLIP 1\n"); \
GSK_NGL_COMPILE_PROGRAM(name ## _rect_clip, uniforms, "#define RECT_CLIP 1\n"); \
GSK_NGL_COMPILE_PROGRAM(name, uniforms, "");
gsk_ngl_compiler_set_source_from_resource (compiler, GSK_NGL_COMPILER_ALL, resource); \
GSK_NGL_COMPILE_PROGRAM(name ## _no_clip, uniforms, "#define NO_CLIP 1\n"); \
GSK_NGL_COMPILE_PROGRAM(name ## _rect_clip, uniforms, "#define RECT_CLIP 1\n"); \
GSK_NGL_COMPILE_PROGRAM(name, uniforms, "");
#define GSK_NGL_COMPILE_PROGRAM(name, uniforms, clip) \
G_STMT_START { \
GskNglProgram *program; \
@ -1046,26 +1046,26 @@ gsk_ngl_driver_lookup_shader (GskNglDriver *self,
int n_uniforms;
uniforms = gsk_gl_shader_get_uniforms (shader, &n_uniforms);
if (n_uniforms > G_N_ELEMENTS (program->args_locations))
if (n_uniforms > GSK_NGL_PROGRAM_MAX_CUSTOM_ARGS)
{
g_set_error (error,
GDK_GL_ERROR,
GDK_GL_ERROR_UNSUPPORTED_FORMAT,
"Tried to use %d uniforms, while only %d is supported",
n_uniforms,
(int)G_N_ELEMENTS (program->args_locations));
GSK_NGL_PROGRAM_MAX_CUSTOM_ARGS);
return NULL;
}
n_required_textures = gsk_gl_shader_get_n_textures (shader);
if (n_required_textures > G_N_ELEMENTS (program->texture_locations))
if (n_required_textures > GSK_NGL_PROGRAM_MAX_CUSTOM_TEXTURES)
{
g_set_error (error,
GDK_GL_ERROR,
GDK_GL_ERROR_UNSUPPORTED_FORMAT,
"Tried to use %d textures, while only %d is supported",
n_required_textures,
(int)(G_N_ELEMENTS (program->texture_locations)));
GSK_NGL_PROGRAM_MAX_CUSTOM_TEXTURES);
return NULL;
}
@ -1108,18 +1108,10 @@ gsk_ngl_driver_lookup_shader (GskNglDriver *self,
gsk_ngl_program_add_uniform (program, "u_texture2", UNIFORM_CUSTOM_TEXTURE2);
gsk_ngl_program_add_uniform (program, "u_texture3", UNIFORM_CUSTOM_TEXTURE3);
gsk_ngl_program_add_uniform (program, "u_texture4", UNIFORM_CUSTOM_TEXTURE4);
for (guint i = 0; i < n_uniforms; i++)
gsk_ngl_program_add_uniform (program, uniforms[i].name, UNIFORM_CUSTOM_LAST+i);
program->size_location = gsk_ngl_program_get_uniform_location (program, UNIFORM_CUSTOM_SIZE);
program->texture_locations[0] = gsk_ngl_program_get_uniform_location (program, UNIFORM_CUSTOM_TEXTURE1);
program->texture_locations[1] = gsk_ngl_program_get_uniform_location (program, UNIFORM_CUSTOM_TEXTURE2);
program->texture_locations[2] = gsk_ngl_program_get_uniform_location (program, UNIFORM_CUSTOM_TEXTURE3);
program->texture_locations[3] = gsk_ngl_program_get_uniform_location (program, UNIFORM_CUSTOM_TEXTURE4);
/* Custom arguments (max is 8) */
for (guint i = 0; i < n_uniforms; i++)
program->args_locations[i] = gsk_ngl_program_get_uniform_location (program, UNIFORM_CUSTOM_LAST+i);
for (guint i = n_uniforms; i < G_N_ELEMENTS (program->args_locations); i++)
program->args_locations[i] = -1;
gsk_ngl_program_add_uniform (program, uniforms[i].name, UNIFORM_CUSTOM_ARG0+i);
gsk_ngl_program_uniforms_added (program, TRUE);

View File

@ -45,6 +45,14 @@ enum {
UNIFORM_CUSTOM_TEXTURE2,
UNIFORM_CUSTOM_TEXTURE3,
UNIFORM_CUSTOM_TEXTURE4,
UNIFORM_CUSTOM_ARG0,
UNIFORM_CUSTOM_ARG1,
UNIFORM_CUSTOM_ARG2,
UNIFORM_CUSTOM_ARG3,
UNIFORM_CUSTOM_ARG4,
UNIFORM_CUSTOM_ARG5,
UNIFORM_CUSTOM_ARG6,
UNIFORM_CUSTOM_ARG7,
UNIFORM_CUSTOM_LAST
};

View File

@ -40,7 +40,7 @@ gsk_ngl_program_new (GskNglDriver *driver,
self->id = program_id;
self->name = g_strdup (name);
self->driver = g_object_ref (driver);
self->n_uniforms = 0;
self->n_mappings = 0;
return self;
}
@ -74,8 +74,8 @@ gsk_ngl_program_init (GskNglProgram *self)
{
self->id = -1;
for (guint i = 0; i < G_N_ELEMENTS (self->uniform_locations); i++)
self->uniform_locations[i] = -1;
for (guint i = 0; i < G_N_ELEMENTS (self->mappings); i++)
self->mappings[i].location = -1;
}
/**
@ -114,22 +114,22 @@ gsk_ngl_program_add_uniform (GskNglProgram *self,
g_return_val_if_fail (GSK_IS_NGL_PROGRAM (self), FALSE);
g_return_val_if_fail (name != NULL, FALSE);
g_return_val_if_fail (key < 1024, FALSE);
g_return_val_if_fail (key < G_N_ELEMENTS (self->mappings), FALSE);
if (-1 == (location = glGetUniformLocation (self->id, name)))
return FALSE;
location = glGetUniformLocation (self->id, name);
self->uniform_locations[key] = location;
if (location >= self->n_uniforms)
self->n_uniforms = location + 1;
/* Register the information even if unused */
self->mappings[key].name = g_intern_string (name);
self->mappings[key].location = location;
if (key >= self->n_mappings)
self->n_mappings = key + 1;
#if 0
g_print ("program [%d] %s uniform %s at location %d.\n",
self->id, self->name, name, location);
g_print ("program [%d] %s uniform %s [%u of %u] at location %d.\n",
self->id, self->name, name, key, self->n_mappings, location);
#endif
return TRUE;
return location > -1;
}
/**
@ -171,6 +171,6 @@ gsk_ngl_program_uniforms_added (GskNglProgram *self,
g_return_if_fail (self->uniforms == NULL);
self->uniforms = self->driver->command_queue->uniforms;
self->program_info = gsk_ngl_uniform_state_get_program (self->uniforms, self->id, self->n_uniforms);
self->program_info = gsk_ngl_uniform_state_get_program (self->uniforms, self->id, self->mappings, self->n_mappings);
self->program_info->has_attachments = has_attachments;
}

View File

@ -23,12 +23,15 @@
#include "gskngltypesprivate.h"
#include "gsknglattachmentstateprivate.h"
#include "gsknglcommandqueueprivate.h"
#include "gskngldriverprivate.h"
G_BEGIN_DECLS
#define GSK_TYPE_GL_PROGRAM (gsk_ngl_program_get_type())
#define GSK_NGL_PROGRAM_MAX_CUSTOM_TEXTURES 4
#define GSK_NGL_PROGRAM_MAX_CUSTOM_ARGS 8
G_DECLARE_FINAL_TYPE (GskNglProgram, gsk_ngl_program, GSK, NGL_PROGRAM, GObject)
@ -40,23 +43,13 @@ struct _GskNglProgram
char *name;
GskNglDriver *driver;
/* In reality, this is the largest uniform position
* as returned after linking so that we can use direct
* indexes based on location.
*/
guint n_uniforms;
/* Cached pointer to avoid lots of pointer chasing/lookups */
GskNglUniformState *uniforms;
GskNglUniformProgram *program_info;
/* For custom programs */
int texture_locations[4];
int args_locations[8];
int size_location;
/* Static array for key->location transforms */
int uniform_locations[32];
GskNglUniformMapping mappings[32];
guint n_mappings;
};
GskNglProgram *gsk_ngl_program_new (GskNglDriver *driver,
@ -69,8 +62,6 @@ void gsk_ngl_program_uniforms_added (GskNglProgram *self,
gboolean has_attachments);
void gsk_ngl_program_delete (GskNglProgram *self);
#define gsk_ngl_program_get_uniform_location(s,k) ((s)->uniform_locations[(k)])
static inline void
gsk_ngl_program_set_uniform1fv (GskNglProgram *self,
guint key,
@ -79,8 +70,10 @@ gsk_ngl_program_set_uniform1fv (GskNglProgram *self,
const float *values)
{
gsk_ngl_uniform_state_set1fv (self->uniforms, self->program_info,
gsk_ngl_program_get_uniform_location (self, key),
stamp, count, values);
key,
stamp,
count,
values);
}
static inline void
@ -91,8 +84,10 @@ gsk_ngl_program_set_uniform2fv (GskNglProgram *self,
const float *values)
{
gsk_ngl_uniform_state_set2fv (self->uniforms, self->program_info,
gsk_ngl_program_get_uniform_location (self, key),
stamp, count, values);
key,
stamp,
count,
values);
}
static inline void
@ -103,8 +98,10 @@ gsk_ngl_program_set_uniform4fv (GskNglProgram *self,
const float *values)
{
gsk_ngl_uniform_state_set4fv (self->uniforms, self->program_info,
gsk_ngl_program_get_uniform_location (self, key),
stamp, count, values);
key,
stamp,
count,
values);
}
static inline void
@ -114,8 +111,9 @@ gsk_ngl_program_set_uniform_rounded_rect (GskNglProgram *self,
const GskRoundedRect *rounded_rect)
{
gsk_ngl_uniform_state_set_rounded_rect (self->uniforms, self->program_info,
gsk_ngl_program_get_uniform_location (self, key),
stamp, rounded_rect);
key,
stamp,
rounded_rect);
}
static inline void
@ -126,8 +124,9 @@ gsk_ngl_program_set_uniform1i (GskNglProgram *self,
{
gsk_ngl_uniform_state_set1i (self->uniforms,
self->program_info,
gsk_ngl_program_get_uniform_location (self, key),
stamp, value0);
key,
stamp,
value0);
}
static inline void
@ -139,8 +138,9 @@ gsk_ngl_program_set_uniform2i (GskNglProgram *self,
{
gsk_ngl_uniform_state_set2i (self->uniforms,
self->program_info,
gsk_ngl_program_get_uniform_location (self, key),
stamp, value0, value1);
key,
stamp,
value0, value1);
}
static inline void
@ -153,8 +153,9 @@ gsk_ngl_program_set_uniform3i (GskNglProgram *self,
{
gsk_ngl_uniform_state_set3i (self->uniforms,
self->program_info,
gsk_ngl_program_get_uniform_location (self, key),
stamp, value0, value1, value2);
key,
stamp,
value0, value1, value2);
}
static inline void
@ -168,8 +169,9 @@ gsk_ngl_program_set_uniform4i (GskNglProgram *self,
{
gsk_ngl_uniform_state_set4i (self->uniforms,
self->program_info,
gsk_ngl_program_get_uniform_location (self, key),
stamp, value0, value1, value2, value3);
key,
stamp,
value0, value1, value2, value3);
}
static inline void
@ -180,8 +182,9 @@ gsk_ngl_program_set_uniform1f (GskNglProgram *self,
{
gsk_ngl_uniform_state_set1f (self->uniforms,
self->program_info,
gsk_ngl_program_get_uniform_location (self, key),
stamp, value0);
key,
stamp,
value0);
}
static inline void
@ -193,8 +196,9 @@ gsk_ngl_program_set_uniform2f (GskNglProgram *self,
{
gsk_ngl_uniform_state_set2f (self->uniforms,
self->program_info,
gsk_ngl_program_get_uniform_location (self, key),
stamp, value0, value1);
key,
stamp,
value0, value1);
}
static inline void
@ -207,8 +211,9 @@ gsk_ngl_program_set_uniform3f (GskNglProgram *self,
{
gsk_ngl_uniform_state_set3f (self->uniforms,
self->program_info,
gsk_ngl_program_get_uniform_location (self, key),
stamp, value0, value1, value2);
key,
stamp,
value0, value1, value2);
}
static inline void
@ -222,8 +227,9 @@ gsk_ngl_program_set_uniform4f (GskNglProgram *self,
{
gsk_ngl_uniform_state_set4f (self->uniforms,
self->program_info,
gsk_ngl_program_get_uniform_location (self, key),
stamp, value0, value1, value2, value3);
key,
stamp,
value0, value1, value2, value3);
}
static inline void
@ -234,8 +240,9 @@ gsk_ngl_program_set_uniform_color (GskNglProgram *self,
{
gsk_ngl_uniform_state_set_color (self->uniforms,
self->program_info,
gsk_ngl_program_get_uniform_location (self, key),
stamp, color);
key,
stamp,
color);
}
static inline void
@ -252,8 +259,9 @@ gsk_ngl_program_set_uniform_texture (GskNglProgram *self,
texture_id);
gsk_ngl_uniform_state_set_texture (self->uniforms,
self->program_info,
gsk_ngl_program_get_uniform_location (self, key),
stamp, texture_slot);
key,
stamp,
texture_slot);
}
static inline void
@ -264,8 +272,9 @@ gsk_ngl_program_set_uniform_matrix (GskNglProgram *self,
{
gsk_ngl_uniform_state_set_matrix (self->uniforms,
self->program_info,
gsk_ngl_program_get_uniform_location (self, key),
stamp, matrix);
key,
stamp,
matrix);
}
G_END_DECLS

View File

@ -1003,41 +1003,36 @@ gsk_ngl_render_job_begin_draw (GskNglRenderJob *job,
job->viewport.size.width,
job->viewport.size.height);
if (program->uniform_locations[UNIFORM_SHARED_VIEWPORT] > -1)
gsk_ngl_uniform_state_set4fv (program->uniforms,
program->program_info,
program->uniform_locations[UNIFORM_SHARED_VIEWPORT],
job->driver->stamps[UNIFORM_SHARED_VIEWPORT],
1,
(const float *)&job->viewport);
gsk_ngl_uniform_state_set4fv (program->uniforms,
program->program_info,
UNIFORM_SHARED_VIEWPORT,
job->driver->stamps[UNIFORM_SHARED_VIEWPORT],
1,
(const float *)&job->viewport);
if (program->uniform_locations[UNIFORM_SHARED_MODELVIEW] > -1)
gsk_ngl_uniform_state_set_matrix (program->uniforms,
program->program_info,
program->uniform_locations[UNIFORM_SHARED_MODELVIEW],
job->driver->stamps[UNIFORM_SHARED_MODELVIEW],
&job->current_modelview->matrix);
gsk_ngl_uniform_state_set_matrix (program->uniforms,
program->program_info,
UNIFORM_SHARED_MODELVIEW,
job->driver->stamps[UNIFORM_SHARED_MODELVIEW],
&job->current_modelview->matrix);
if (program->uniform_locations[UNIFORM_SHARED_PROJECTION] > -1)
gsk_ngl_uniform_state_set_matrix (program->uniforms,
program->program_info,
program->uniform_locations[UNIFORM_SHARED_PROJECTION],
job->driver->stamps[UNIFORM_SHARED_PROJECTION],
&job->projection);
gsk_ngl_uniform_state_set_matrix (program->uniforms,
program->program_info,
UNIFORM_SHARED_PROJECTION,
job->driver->stamps[UNIFORM_SHARED_PROJECTION],
&job->projection);
if (program->uniform_locations[UNIFORM_SHARED_CLIP_RECT] > -1)
gsk_ngl_uniform_state_set_rounded_rect (program->uniforms,
program->program_info,
program->uniform_locations[UNIFORM_SHARED_CLIP_RECT],
job->driver->stamps[UNIFORM_SHARED_CLIP_RECT],
&job->current_clip->rect);
gsk_ngl_uniform_state_set_rounded_rect (program->uniforms,
program->program_info,
UNIFORM_SHARED_CLIP_RECT,
job->driver->stamps[UNIFORM_SHARED_CLIP_RECT],
&job->current_clip->rect);
if (program->uniform_locations[UNIFORM_SHARED_ALPHA] > -1)
gsk_ngl_uniform_state_set1f (program->uniforms,
program->program_info,
program->uniform_locations[UNIFORM_SHARED_ALPHA],
job->driver->stamps[UNIFORM_SHARED_ALPHA],
job->alpha);
gsk_ngl_uniform_state_set1f (program->uniforms,
program->program_info,
UNIFORM_SHARED_ALPHA,
job->driver->stamps[UNIFORM_SHARED_ALPHA],
job->alpha);
}
#define CHOOSE_PROGRAM(job,name) \
@ -3086,10 +3081,6 @@ gsk_ngl_render_job_visit_gl_shader_node (GskNglRenderJob *job,
const GskGLUniform *u = &uniforms[i];
const guint8 *data = base + u->offset;
/* Ignore unused uniforms */
if (program->args_locations[i] == -1)
continue;
switch (u->type)
{
default:
@ -3098,38 +3089,38 @@ gsk_ngl_render_job_visit_gl_shader_node (GskNglRenderJob *job,
case GSK_GL_UNIFORM_TYPE_FLOAT:
gsk_ngl_uniform_state_set1fv (job->command_queue->uniforms,
program->program_info,
program->args_locations[i],
UNIFORM_CUSTOM_ARG0 + i,
0, 1, (const float *)data);
break;
case GSK_GL_UNIFORM_TYPE_INT:
gsk_ngl_uniform_state_set1i (job->command_queue->uniforms,
program->program_info,
program->args_locations[i],
UNIFORM_CUSTOM_ARG0 + i,
0, *(const gint32 *)data);
break;
case GSK_GL_UNIFORM_TYPE_UINT:
case GSK_GL_UNIFORM_TYPE_BOOL:
gsk_ngl_uniform_state_set1ui (job->command_queue->uniforms,
program->program_info,
program->args_locations[i],
UNIFORM_CUSTOM_ARG0 + i,
0, *(const guint32 *)data);
break;
case GSK_GL_UNIFORM_TYPE_VEC2:
gsk_ngl_uniform_state_set2fv (job->command_queue->uniforms,
program->program_info,
program->args_locations[i],
UNIFORM_CUSTOM_ARG0 + i,
0, 1, (const float *)data);
break;
case GSK_GL_UNIFORM_TYPE_VEC3:
gsk_ngl_uniform_state_set3fv (job->command_queue->uniforms,
program->program_info,
program->args_locations[i],
UNIFORM_CUSTOM_ARG0 + i,
0, 1, (const float *)data);
break;
case GSK_GL_UNIFORM_TYPE_VEC4:
gsk_ngl_uniform_state_set4fv (job->command_queue->uniforms,
program->program_info,
program->args_locations[i],
UNIFORM_CUSTOM_ARG0 + i,
0, 1, (const float *)data);
break;
}

View File

@ -92,14 +92,14 @@ gsk_ngl_uniform_state_unref (GskNglUniformState *state)
}
gpointer
gsk_ngl_uniform_state_init_value (GskNglUniformState *state,
GskNglUniformProgram *program,
GskNglUniformFormat format,
guint array_count,
guint location,
GskNglUniformInfoElement **infoptr)
gsk_ngl_uniform_state_init_value (GskNglUniformState *state,
GskNglUniformProgram *program,
GskNglUniformFormat format,
guint array_count,
guint key,
GskNglUniformMapping **infoptr)
{
GskNglUniformInfoElement *info;
GskNglUniformMapping *mapping;
guint offset;
g_assert (state != NULL);
@ -107,23 +107,22 @@ gsk_ngl_uniform_state_init_value (GskNglUniformState *state,
g_assert ((int)format >= 0 && format < GSK_NGL_UNIFORM_FORMAT_LAST);
g_assert (format > 0);
g_assert (program != NULL);
g_assert (program->sparse != NULL);
g_assert (program->n_sparse <= program->n_uniforms);
g_assert (location < GL_MAX_UNIFORM_LOCATIONS || location == (guint)-1);
g_assert (location < program->n_uniforms);
g_assert (key < program->n_mappings);
/* Handle unused uniforms gracefully */
if G_UNLIKELY (location == (guint)-1)
return NULL;
mapping = &program->mappings[key];
info = &program->uniforms[location];
if G_LIKELY (format == info->info.format)
if (mapping->location == -1)
{
if G_LIKELY (array_count <= info->info.array_count)
*infoptr = NULL;
return NULL;
}
if G_LIKELY (format == mapping->info.format)
{
if G_LIKELY (array_count <= mapping->info.array_count)
{
*infoptr = info;
return GSK_NGL_UNIFORM_VALUE (state->values_buf, info->info.offset);
*infoptr = mapping;
return GSK_NGL_UNIFORM_VALUE (state->values_buf, mapping->info.offset);
}
/* We found the uniform, but there is not enough space for the
@ -136,7 +135,7 @@ gsk_ngl_uniform_state_init_value (GskNglUniformState *state,
*/
goto setup_info;
}
else if (info->info.format == 0)
else if (mapping->info.format == 0)
{
goto setup_info;
}
@ -145,8 +144,8 @@ gsk_ngl_uniform_state_init_value (GskNglUniformState *state,
g_critical ("Attempt to access uniform with different type of value "
"than it was initialized with. Program %u Location %u. "
"Was %d now %d (array length %d now %d).",
program->program_id, location, info->info.format, format,
info->info.array_count, array_count);
program->program_id, key, mapping->info.format, format,
mapping->info.array_count, array_count);
*infoptr = NULL;
return NULL;
}
@ -160,22 +159,15 @@ setup_info:
/* we have 21 bits for offset */
g_assert (offset < (1 << GSK_NGL_UNIFORM_OFFSET_BITS));
/* We could once again be setting up this info if the array size grew.
* So make sure that we have space in our space array for the value.
*/
g_assert (info->info.format != 0 || program->n_sparse < program->n_uniforms);
if (info->info.format == 0)
program->sparse[program->n_sparse++] = location;
mapping->info.format = format;
mapping->info.offset = offset;
mapping->info.array_count = array_count;
mapping->info.initial = TRUE;
mapping->stamp = 0;
info->info.format = format;
info->info.offset = offset;
info->info.array_count = array_count;
info->info.initial = TRUE;
info->stamp = 0;
*infoptr = mapping;
*infoptr = info;
return GSK_NGL_UNIFORM_VALUE (state->values_buf, info->info.offset);
return GSK_NGL_UNIFORM_VALUE (state->values_buf, mapping->info.offset);
}
void
@ -196,24 +188,25 @@ gsk_ngl_uniform_state_end_frame (GskNglUniformState *state)
g_hash_table_iter_init (&iter, state->programs);
while (g_hash_table_iter_next (&iter, NULL, (gpointer *)&program))
{
for (guint j = 0; j < program->n_sparse; j++)
for (guint j = 0; j < program->n_mappings; j++)
{
guint location = program->sparse[j];
GskNglUniformInfoElement *info = &program->uniforms[location];
GskNglUniformMapping *mapping = &program->mappings[j];
guint size;
g_assert (info->info.format > 0);
/* Skip unused uniform mappings */
if (mapping->info.format == 0 || mapping->location == -1)
continue;
/* Calculate how much size is needed for the uniform, including arrays */
size = uniform_sizes[info->info.format] * MAX (1, info->info.array_count);
size = uniform_sizes[mapping->info.format] * MAX (1, mapping->info.array_count);
/* Adjust alignment for value */
allocator += gsk_ngl_uniform_state_align (allocator, size);
/* Offset is in slots of 4 bytes */
info->info.offset = allocator / 4;
info->info.initial = TRUE;
info->stamp = 0;
mapping->info.offset = allocator / 4;
mapping->info.initial = TRUE;
mapping->stamp = 0;
/* Now advance for this items data */
allocator += size;
@ -237,35 +230,27 @@ gsk_ngl_uniform_format_size (GskNglUniformFormat format)
}
GskNglUniformProgram *
gsk_ngl_uniform_state_get_program (GskNglUniformState *state,
guint program,
guint n_uniforms)
gsk_ngl_uniform_state_get_program (GskNglUniformState *state,
guint program,
const GskNglUniformMapping *mappings,
guint n_mappings)
{
GskNglUniformProgram *ret;
g_return_val_if_fail (state != NULL, NULL);
g_return_val_if_fail (program > 0, NULL);
g_return_val_if_fail (program < G_MAXUINT, NULL);
g_return_val_if_fail (n_mappings <= G_N_ELEMENTS (ret->mappings), NULL);
ret = g_hash_table_lookup (state->programs, GUINT_TO_POINTER (program));
if (ret == NULL)
{
gsize uniform_size = n_uniforms * sizeof (GskNglUniformInfoElement);
gsize sparse_size = n_uniforms * sizeof (guint);
gsize size = sizeof (GskNglUniformProgram) + uniform_size + sparse_size;
/* Must be multiple of 4 for space pointer to align */
G_STATIC_ASSERT (sizeof (GskNglUniformInfoElement) == 8);
ret = g_malloc0 (size);
ret = g_new0 (GskNglUniformProgram, 1);
ret->program_id = program;
ret->n_uniforms = n_uniforms;
ret->n_sparse = 0;
ret->sparse = (guint *)&ret->uniforms[n_uniforms];
ret->n_mappings = n_mappings;
for (guint i = 0; i < n_uniforms; i++)
ret->uniforms[i].info.initial = TRUE;
memcpy (ret->mappings, mappings, n_mappings * sizeof *mappings);
g_hash_table_insert (state->programs, GUINT_TO_POINTER (program), ret);
}

View File

@ -51,30 +51,21 @@ typedef struct _GskNglUniformInfo
G_STATIC_ASSERT (sizeof (GskNglUniformInfo) == 4);
typedef struct _GskNglUniformInfoElement
typedef struct _GskNglUniformMapping
{
const char *name;
GskNglUniformInfo info;
guint stamp;
} GskNglUniformInfoElement;
G_STATIC_ASSERT (sizeof (GskNglUniformInfoElement) == 8);
int location;
} GskNglUniformMapping;
typedef struct _GskNglUniformProgram
{
guint program_id;
guint n_uniforms : 12;
guint has_attachments : 1;
/* To avoid walking our 1:1 array of location->uniform slots, we have
* a sparse index that allows us to skip the empty zones.
*/
guint *sparse;
guint n_sparse;
/* Uniforms are provided inline at the end of structure to avoid
* an extra dereference.
*/
GskNglUniformInfoElement uniforms[0];
guint n_mappings;
GskNglUniformMapping mappings[32];
} GskNglUniformProgram;
typedef struct _GskNglUniformState
@ -86,20 +77,6 @@ typedef struct _GskNglUniformState
GskNglUniformInfo apply_hash[512];
} GskNglUniformState;
/**
* GskNglUniformStateCallback:
* @info: a pointer to the information about the uniform
* @location: the location of the uniform within the GPU program.
* @user_data: closure data for the callback
*
* This callback can be used to snapshot state of a program which
* is useful when batching commands so that the state may be compared
* with future evocations of the program.
*/
typedef void (*GskNglUniformStateCallback) (const GskNglUniformInfo *info,
guint location,
gpointer user_data);
typedef enum _GskNglUniformKind
{
GSK_NGL_UNIFORM_FORMAT_1F = 1,
@ -131,49 +108,42 @@ typedef enum _GskNglUniformKind
G_STATIC_ASSERT (GSK_NGL_UNIFORM_FORMAT_LAST < (1 << GSK_NGL_UNIFORM_FORMAT_BITS));
GskNglUniformState *gsk_ngl_uniform_state_new (void);
GskNglUniformState *gsk_ngl_uniform_state_ref (GskNglUniformState *state);
void gsk_ngl_uniform_state_unref (GskNglUniformState *state);
GskNglUniformProgram *gsk_ngl_uniform_state_get_program (GskNglUniformState *state,
guint program,
guint n_uniforms);
void gsk_ngl_uniform_state_end_frame (GskNglUniformState *state);
gsize gsk_ngl_uniform_format_size (GskNglUniformFormat format);
gpointer gsk_ngl_uniform_state_init_value (GskNglUniformState *state,
GskNglUniformProgram *program,
GskNglUniformFormat format,
guint array_count,
guint location,
GskNglUniformInfoElement **infoptr);
GskNglUniformState *gsk_ngl_uniform_state_ref (GskNglUniformState *state);
void gsk_ngl_uniform_state_unref (GskNglUniformState *state);
GskNglUniformProgram *gsk_ngl_uniform_state_get_program (GskNglUniformState *state,
guint program,
const GskNglUniformMapping *mappings,
guint n_mappings);
void gsk_ngl_uniform_state_end_frame (GskNglUniformState *state);
gsize gsk_ngl_uniform_format_size (GskNglUniformFormat format);
gpointer gsk_ngl_uniform_state_init_value (GskNglUniformState *state,
GskNglUniformProgram *program,
GskNglUniformFormat format,
guint array_count,
guint key,
GskNglUniformMapping **out_mapping);
#define GSK_NGL_UNIFORM_VALUE(base, offset) ((gpointer)((base) + ((offset) * 4)))
#define gsk_ngl_uniform_state_get_uniform_data(state,offset) GSK_NGL_UNIFORM_VALUE((state)->values_buf, offset)
#define gsk_ngl_uniform_state_snapshot(state, program_info, callback, user_data) \
G_STMT_START { \
for (guint z = 0; z < program_info->n_sparse; z++) \
{ \
guint location = program_info->sparse[z]; \
GskNglUniformInfoElement *info = &program_info->uniforms[location]; \
\
g_assert (location < GL_MAX_UNIFORM_LOCATIONS); \
g_assert (location < program_info->n_uniforms); \
\
if (info->info.format > 0) \
callback (&info->info, location, user_data); \
} \
} G_STMT_END
static inline gpointer
gsk_ngl_uniform_state_get_value (GskNglUniformState *state,
GskNglUniformProgram *program,
GskNglUniformFormat format,
guint array_count,
guint location,
guint stamp,
GskNglUniformInfoElement **infoptr)
gsk_ngl_uniform_state_get_value (GskNglUniformState *state,
GskNglUniformProgram *program,
GskNglUniformFormat format,
guint array_count,
guint key,
guint stamp,
GskNglUniformMapping **out_mapping)
{
GskNglUniformInfoElement *info;
GskNglUniformMapping *mapping;
if (location == (guint)-1)
g_assert (key < G_N_ELEMENTS (program->mappings));
g_assert (key < program->n_mappings);
mapping = &program->mappings[key];
/* Short-circuit if the program optimized the uniform out */
if (mapping->location == -1)
return NULL;
/* If the stamp is the same, then we can ignore the request
@ -185,17 +155,16 @@ gsk_ngl_uniform_state_get_value (GskNglUniformState *state,
* modelview, clip, etc to avoid so many comparisons which cost
* considerable CPU.
*/
info = &program->uniforms[location];
if (stamp != 0 && stamp == info->stamp)
if (stamp != 0 && stamp == mapping->stamp)
return NULL;
if G_LIKELY (format == info->info.format && array_count <= info->info.array_count)
if G_LIKELY (format == mapping->info.format && array_count <= mapping->info.array_count)
{
*infoptr = info;
return GSK_NGL_UNIFORM_VALUE (state->values_buf, info->info.offset);
*out_mapping = mapping;
return GSK_NGL_UNIFORM_VALUE (state->values_buf, mapping->info.offset);
}
return gsk_ngl_uniform_state_init_value (state, program, format, array_count, location, infoptr);
return gsk_ngl_uniform_state_init_value (state, program, format, array_count, key, out_mapping);
}
static inline guint
@ -251,8 +220,7 @@ gsk_ngl_uniform_state_realloc (GskNglUniformState *state,
} G_STMT_END
static inline void
gsk_ngl_uniform_info_changed (GskNglUniformInfoElement *info,
guint location,
gsk_ngl_uniform_info_changed (GskNglUniformMapping *info,
guint stamp)
{
info->stamp = stamp;
@ -262,23 +230,23 @@ gsk_ngl_uniform_info_changed (GskNglUniformInfoElement *info,
static inline void
gsk_ngl_uniform_state_set1f (GskNglUniformState *state,
GskNglUniformProgram *program,
guint location,
guint key,
guint stamp,
float value0)
{
Uniform1f *u;
GskNglUniformInfoElement *info;
GskNglUniformMapping *info;
g_assert (state != NULL);
g_assert (program != 0);
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_1F, 1, location, stamp, &info)))
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_1F, 1, key, stamp, &info)))
{
if (info->info.initial || u->v0 != value0)
{
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform1f , 1);
u->v0 = value0;
gsk_ngl_uniform_info_changed (info, location, stamp);
gsk_ngl_uniform_info_changed (info, stamp);
}
}
}
@ -286,25 +254,25 @@ gsk_ngl_uniform_state_set1f (GskNglUniformState *state,
static inline void
gsk_ngl_uniform_state_set2f (GskNglUniformState *state,
GskNglUniformProgram *program,
guint location,
guint key,
guint stamp,
float value0,
float value1)
{
Uniform2f *u;
GskNglUniformInfoElement *info;
GskNglUniformMapping *info;
g_assert (state != NULL);
g_assert (program != NULL);
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_2F, 1, location, stamp, &info)))
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_2F, 1, key, stamp, &info)))
{
if (info->info.initial || u->v0 != value0 || u->v1 != value1)
{
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform2f, 1);
u->v0 = value0;
u->v1 = value1;
gsk_ngl_uniform_info_changed (info, location, stamp);
gsk_ngl_uniform_info_changed (info, stamp);
}
}
}
@ -312,19 +280,19 @@ gsk_ngl_uniform_state_set2f (GskNglUniformState *state,
static inline void
gsk_ngl_uniform_state_set3f (GskNglUniformState *state,
GskNglUniformProgram *program,
guint location,
guint key,
guint stamp,
float value0,
float value1,
float value2)
{
Uniform3f *u;
GskNglUniformInfoElement *info;
GskNglUniformMapping *info;
g_assert (state != NULL);
g_assert (program != NULL);
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_3F, 1, location, stamp, &info)))
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_3F, 1, key, stamp, &info)))
{
if (info->info.initial || u->v0 != value0 || u->v1 != value1 || u->v2 != value2)
{
@ -332,7 +300,7 @@ gsk_ngl_uniform_state_set3f (GskNglUniformState *state,
u->v0 = value0;
u->v1 = value1;
u->v2 = value2;
gsk_ngl_uniform_info_changed (info, location, stamp);
gsk_ngl_uniform_info_changed (info, stamp);
}
}
}
@ -340,7 +308,7 @@ gsk_ngl_uniform_state_set3f (GskNglUniformState *state,
static inline void
gsk_ngl_uniform_state_set4f (GskNglUniformState *state,
GskNglUniformProgram *program,
guint location,
guint key,
guint stamp,
float value0,
float value1,
@ -348,12 +316,12 @@ gsk_ngl_uniform_state_set4f (GskNglUniformState *state,
float value3)
{
Uniform4f *u;
GskNglUniformInfoElement *info;
GskNglUniformMapping *info;
g_assert (state != NULL);
g_assert (program != NULL);
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_4F, 1, location, stamp, &info)))
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_4F, 1, key, stamp, &info)))
{
if (info->info.initial || u->v0 != value0 || u->v1 != value1 || u->v2 != value2 || u->v3 != value3)
{
@ -362,7 +330,7 @@ gsk_ngl_uniform_state_set4f (GskNglUniformState *state,
u->v1 = value1;
u->v2 = value2;
u->v3 = value3;
gsk_ngl_uniform_info_changed (info, location, stamp);
gsk_ngl_uniform_info_changed (info, stamp);
}
}
}
@ -370,23 +338,23 @@ gsk_ngl_uniform_state_set4f (GskNglUniformState *state,
static inline void
gsk_ngl_uniform_state_set1ui (GskNglUniformState *state,
GskNglUniformProgram *program,
guint location,
guint key,
guint stamp,
guint value0)
{
Uniform1ui *u;
GskNglUniformInfoElement *info;
GskNglUniformMapping *info;
g_assert (state != NULL);
g_assert (program != NULL);
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_1UI, 1, location, stamp, &info)))
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_1UI, 1, key, stamp, &info)))
{
if (info->info.initial || u->v0 != value0)
{
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform1ui, 1);
u->v0 = value0;
gsk_ngl_uniform_info_changed (info, location, stamp);
gsk_ngl_uniform_info_changed (info, stamp);
}
}
}
@ -394,23 +362,23 @@ gsk_ngl_uniform_state_set1ui (GskNglUniformState *state,
static inline void
gsk_ngl_uniform_state_set1i (GskNglUniformState *state,
GskNglUniformProgram *program,
guint location,
guint key,
guint stamp,
int value0)
{
Uniform1i *u;
GskNglUniformInfoElement *info;
GskNglUniformMapping *info;
g_assert (state != NULL);
g_assert (program != NULL);
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_1I, 1, location, stamp, &info)))
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_1I, 1, key, stamp, &info)))
{
if (info->info.initial || u->v0 != value0)
{
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform1i, 1);
u->v0 = value0;
gsk_ngl_uniform_info_changed (info, location, stamp);
gsk_ngl_uniform_info_changed (info, stamp);
}
}
}
@ -418,25 +386,25 @@ gsk_ngl_uniform_state_set1i (GskNglUniformState *state,
static inline void
gsk_ngl_uniform_state_set2i (GskNglUniformState *state,
GskNglUniformProgram *program,
guint location,
guint key,
guint stamp,
int value0,
int value1)
{
Uniform2i *u;
GskNglUniformInfoElement *info;
GskNglUniformMapping *info;
g_assert (state != NULL);
g_assert (program != NULL);
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_2I, 1, location, stamp, &info)))
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_2I, 1, key, stamp, &info)))
{
if (info->info.initial || u->v0 != value0 || u->v1 != value1)
{
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform2i, 1);
u->v0 = value0;
u->v1 = value1;
gsk_ngl_uniform_info_changed (info, location, stamp);
gsk_ngl_uniform_info_changed (info, stamp);
}
}
}
@ -444,19 +412,19 @@ gsk_ngl_uniform_state_set2i (GskNglUniformState *state,
static inline void
gsk_ngl_uniform_state_set3i (GskNglUniformState *state,
GskNglUniformProgram *program,
guint location,
guint key,
guint stamp,
int value0,
int value1,
int value2)
{
Uniform3i *u;
GskNglUniformInfoElement *info;
GskNglUniformMapping *info;
g_assert (state != NULL);
g_assert (program != NULL);
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_3I, 1, location, stamp, &info)))
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_3I, 1, key, stamp, &info)))
{
if (info->info.initial || u->v0 != value0 || u->v1 != value1 || u->v2 != value2)
{
@ -464,7 +432,7 @@ gsk_ngl_uniform_state_set3i (GskNglUniformState *state,
u->v0 = value0;
u->v1 = value1;
u->v2 = value2;
gsk_ngl_uniform_info_changed (info, location, stamp);
gsk_ngl_uniform_info_changed (info, stamp);
}
}
}
@ -472,7 +440,7 @@ gsk_ngl_uniform_state_set3i (GskNglUniformState *state,
static inline void
gsk_ngl_uniform_state_set4i (GskNglUniformState *state,
GskNglUniformProgram *program,
guint location,
guint key,
guint stamp,
int value0,
int value1,
@ -480,12 +448,12 @@ gsk_ngl_uniform_state_set4i (GskNglUniformState *state,
int value3)
{
Uniform4i *u;
GskNglUniformInfoElement *info;
GskNglUniformMapping *info;
g_assert (state != NULL);
g_assert (program != NULL);
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_4I, 1, location, stamp, &info)))
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_4I, 1, key, stamp, &info)))
{
if (info->info.initial || u->v0 != value0 || u->v1 != value1 || u->v2 != value2 || u->v3 != value3)
{
@ -494,7 +462,7 @@ gsk_ngl_uniform_state_set4i (GskNglUniformState *state,
u->v1 = value1;
u->v2 = value2;
u->v3 = value3;
gsk_ngl_uniform_info_changed (info, location, stamp);
gsk_ngl_uniform_info_changed (info, stamp);
}
}
}
@ -502,24 +470,24 @@ gsk_ngl_uniform_state_set4i (GskNglUniformState *state,
static inline void
gsk_ngl_uniform_state_set_rounded_rect (GskNglUniformState *state,
GskNglUniformProgram *program,
guint location,
guint key,
guint stamp,
const GskRoundedRect *rounded_rect)
{
GskRoundedRect *u;
GskNglUniformInfoElement *info;
GskNglUniformMapping *info;
g_assert (state != NULL);
g_assert (program != NULL);
g_assert (rounded_rect != NULL);
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_ROUNDED_RECT, 1, location, stamp, &info)))
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_ROUNDED_RECT, 1, key, stamp, &info)))
{
if (info->info.initial || memcmp (u, rounded_rect, sizeof *u) != 0)
{
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, GskRoundedRect, 1);
memcpy (u, rounded_rect, sizeof *rounded_rect);
gsk_ngl_uniform_info_changed (info, location, stamp);
gsk_ngl_uniform_info_changed (info, stamp);
}
}
}
@ -527,24 +495,24 @@ gsk_ngl_uniform_state_set_rounded_rect (GskNglUniformState *state,
static inline void
gsk_ngl_uniform_state_set_matrix (GskNglUniformState *state,
GskNglUniformProgram *program,
guint location,
guint key,
guint stamp,
const graphene_matrix_t *matrix)
{
graphene_matrix_t *u;
GskNglUniformInfoElement *info;
GskNglUniformMapping *info;
g_assert (state != NULL);
g_assert (program != NULL);
g_assert (matrix != NULL);
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_MATRIX, 1, location, stamp, &info)))
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_MATRIX, 1, key, stamp, &info)))
{
if (info->info.initial || memcmp (u, matrix, sizeof *u) != 0)
{
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, graphene_matrix_t, 1);
memcpy (u, matrix, sizeof *matrix);
gsk_ngl_uniform_info_changed (info, location, stamp);
gsk_ngl_uniform_info_changed (info, stamp);
}
}
}
@ -566,11 +534,11 @@ gsk_ngl_uniform_state_set_matrix (GskNglUniformState *state,
static inline void
gsk_ngl_uniform_state_set_texture (GskNglUniformState *state,
GskNglUniformProgram *program,
guint location,
guint key,
guint stamp,
guint texture_slot)
{
GskNglUniformInfoElement *info;
GskNglUniformMapping *info;
guint *u;
g_assert (texture_slot >= GL_TEXTURE0);
@ -578,13 +546,13 @@ gsk_ngl_uniform_state_set_texture (GskNglUniformState *state,
texture_slot -= GL_TEXTURE0;
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_TEXTURE, 1, location, stamp, &info)))
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_TEXTURE, 1, key, stamp, &info)))
{
if (info->info.initial || *u != texture_slot)
{
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, guint, 1);
*u = texture_slot;
gsk_ngl_uniform_info_changed (info, location, stamp);
gsk_ngl_uniform_info_changed (info, stamp);
}
}
}
@ -603,18 +571,18 @@ gsk_ngl_uniform_state_set_texture (GskNglUniformState *state,
static inline void
gsk_ngl_uniform_state_set_color (GskNglUniformState *state,
GskNglUniformProgram *program,
guint location,
guint key,
guint stamp,
const GdkRGBA *color)
{
static const GdkRGBA transparent = {0};
GskNglUniformInfoElement *info;
GskNglUniformMapping *info;
GdkRGBA *u;
g_assert (state != NULL);
g_assert (program != NULL);
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_COLOR, 1, location, stamp, &info)))
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_COLOR, 1, key, stamp, &info)))
{
if (color == NULL)
color = &transparent;
@ -623,7 +591,7 @@ gsk_ngl_uniform_state_set_color (GskNglUniformState *state,
{
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, GdkRGBA, 1);
memcpy (u, color, sizeof *color);
gsk_ngl_uniform_info_changed (info, location, stamp);
gsk_ngl_uniform_info_changed (info, stamp);
}
}
}
@ -631,25 +599,25 @@ gsk_ngl_uniform_state_set_color (GskNglUniformState *state,
static inline void
gsk_ngl_uniform_state_set1fv (GskNglUniformState *state,
GskNglUniformProgram *program,
guint location,
guint key,
guint stamp,
guint count,
const float *value)
{
Uniform1f *u;
GskNglUniformInfoElement *info;
GskNglUniformMapping *info;
g_assert (state != NULL);
g_assert (program != NULL);
g_assert (count > 0);
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_1FV, count, location, stamp, &info)))
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_1FV, count, key, stamp, &info)))
{
if (info->info.initial || count != info->info.array_count || memcmp (u, value, sizeof *u * count) != 0)
{
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform1f, count);
memcpy (u, value, sizeof (Uniform1f) * count);
gsk_ngl_uniform_info_changed (info, location, stamp);
gsk_ngl_uniform_info_changed (info, stamp);
}
}
}
@ -657,25 +625,25 @@ gsk_ngl_uniform_state_set1fv (GskNglUniformState *state,
static inline void
gsk_ngl_uniform_state_set2fv (GskNglUniformState *state,
GskNglUniformProgram *program,
guint location,
guint key,
guint stamp,
guint count,
const float *value)
{
Uniform2f *u;
GskNglUniformInfoElement *info;
GskNglUniformMapping *info;
g_assert (state != NULL);
g_assert (program != NULL);
g_assert (count > 0);
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_2FV, count, location, stamp, &info)))
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_2FV, count, key, stamp, &info)))
{
if (info->info.initial || count != info->info.array_count || memcmp (u, value, sizeof *u * count) != 0)
{
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform2f, count);
memcpy (u, value, sizeof (Uniform2f) * count);
gsk_ngl_uniform_info_changed (info, location, stamp);
gsk_ngl_uniform_info_changed (info, stamp);
}
}
}
@ -683,25 +651,25 @@ gsk_ngl_uniform_state_set2fv (GskNglUniformState *state,
static inline void
gsk_ngl_uniform_state_set3fv (GskNglUniformState *state,
GskNglUniformProgram *program,
guint location,
guint key,
guint stamp,
guint count,
const float *value)
{
Uniform3f *u;
GskNglUniformInfoElement *info;
GskNglUniformMapping *info;
g_assert (state != NULL);
g_assert (program != NULL);
g_assert (count > 0);
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_3FV, count, location, stamp, &info)))
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_3FV, count, key, stamp, &info)))
{
if (info->info.initial || count != info->info.array_count || memcmp (u, value, sizeof *u * count) != 0)
{
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform3f, count);
memcpy (u, value, sizeof (Uniform3f) * count);
gsk_ngl_uniform_info_changed (info, location, stamp);
gsk_ngl_uniform_info_changed (info, stamp);
}
}
}
@ -709,25 +677,25 @@ gsk_ngl_uniform_state_set3fv (GskNglUniformState *state,
static inline void
gsk_ngl_uniform_state_set4fv (GskNglUniformState *state,
GskNglUniformProgram *program,
guint location,
guint key,
guint stamp,
guint count,
const float *value)
{
Uniform4f *u;
GskNglUniformInfoElement *info;
GskNglUniformMapping *info;
g_assert (state != NULL);
g_assert (program != NULL);
g_assert (count > 0);
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_4FV, count, location, stamp, &info)))
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_4FV, count, key, stamp, &info)))
{
if (info->info.initial || count != info->info.array_count || memcmp (u, value, sizeof *u * count) != 0)
{
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform4f, count);
memcpy (u, value, sizeof (Uniform4f) * count);
gsk_ngl_uniform_info_changed (info, location, stamp);
gsk_ngl_uniform_info_changed (info, stamp);
}
}
}