summaryrefslogtreecommitdiffstats
path: root/video/out/opengl/utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'video/out/opengl/utils.c')
-rw-r--r--video/out/opengl/utils.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/video/out/opengl/utils.c b/video/out/opengl/utils.c
index f1e0081b10..afbd6f65af 100644
--- a/video/out/opengl/utils.c
+++ b/video/out/opengl/utils.c
@@ -473,6 +473,13 @@ struct sc_uniform {
GLenum img_iformat;
};
+struct sc_buffer {
+ char *name;
+ char *format;
+ GLuint binding;
+ GLuint ssbo;
+};
+
struct sc_cached_uniform {
GLint loc;
union uniform_val v;
@@ -503,6 +510,7 @@ struct gl_shader_cache {
bstr text;
int next_texture_unit;
int next_image_unit;
+ int next_buffer_binding;
struct gl_vao *vao; // deprecated
struct sc_entry *entries;
@@ -512,6 +520,8 @@ struct gl_shader_cache {
struct sc_uniform *uniforms;
int num_uniforms;
+ struct sc_buffer *buffers;
+ int num_buffers;
const struct gl_vao_entry *vertex_entries;
size_t vertex_size;
@@ -562,6 +572,11 @@ void gl_sc_reset(struct gl_shader_cache *sc)
}
}
gl->ActiveTexture(GL_TEXTURE0);
+
+ for (int n = 0; n < sc->num_buffers; n++) {
+ struct sc_buffer *b = &sc->buffers[n];
+ gl->BindBufferBase(GL_SHADER_STORAGE_BUFFER, b->binding, 0);
+ }
}
sc->prelude_text.len = 0;
@@ -570,8 +585,14 @@ void gl_sc_reset(struct gl_shader_cache *sc)
for (int n = 0; n < sc->num_uniforms; n++)
talloc_free(sc->uniforms[n].name);
sc->num_uniforms = 0;
+ for (int n = 0; n < sc->num_buffers; n++) {
+ talloc_free(sc->buffers[n].name);
+ talloc_free(sc->buffers[n].format);
+ }
+ sc->num_buffers = 0;
sc->next_texture_unit = 1; // not 0, as 0 is "free for use"
sc->next_image_unit = 1;
+ sc->next_buffer_binding = 1;
sc->vertex_entries = NULL;
sc->vertex_size = 0;
sc->current_shader = NULL;
@@ -680,6 +701,21 @@ static struct sc_uniform *find_uniform(struct gl_shader_cache *sc,
return &sc->uniforms[sc->num_uniforms - 1];
}
+static struct sc_buffer *find_buffer(struct gl_shader_cache *sc,
+ const char *name)
+{
+ for (int n = 0; n < sc->num_buffers; n++) {
+ if (strcmp(sc->buffers[n].name, name) == 0)
+ return &sc->buffers[n];
+ }
+ // not found -> add it
+ struct sc_buffer new = {
+ .name = talloc_strdup(NULL, name),
+ };
+ MP_TARRAY_APPEND(sc, sc->buffers, sc->num_buffers, new);
+ return &sc->buffers[sc->num_buffers - 1];
+}
+
const char *mp_sampler_type(GLenum texture_target)
{
switch (texture_target) {
@@ -738,6 +774,20 @@ void gl_sc_uniform_image2D(struct gl_shader_cache *sc, char *name, GLuint textur
u->img_iformat = iformat;
}
+void gl_sc_ssbo(struct gl_shader_cache *sc, char *name, GLuint ssbo,
+ char *format, ...)
+{
+ struct sc_buffer *b = find_buffer(sc, name);
+ b->binding = sc->next_buffer_binding++;
+ b->ssbo = ssbo;
+ b->format = format;
+
+ va_list ap;
+ va_start(ap, format);
+ b->format = ta_vasprintf(sc, format, ap);
+ va_end(ap);
+}
+
void gl_sc_uniform_f(struct gl_shader_cache *sc, char *name, GLfloat f)
{
struct sc_uniform *u = find_uniform(sc, name);
@@ -1217,6 +1267,12 @@ struct mp_pass_perf gl_sc_generate(struct gl_shader_cache *sc, GLenum type)
ADD(comp, "uniform %s %s;\n", u->glsl_type, u->name);
}
+ for (int n = 0; n < sc->num_buffers; n++) {
+ struct sc_buffer *b = &sc->buffers[n];
+ ADD(comp, "layout(std430, binding=%d) buffer %s { %s };\n",
+ b->binding, b->name, b->format);
+ }
+
ADD_BSTR(comp, sc->prelude_text);
ADD_BSTR(comp, sc->header_text);
@@ -1271,6 +1327,10 @@ struct mp_pass_perf gl_sc_generate(struct gl_shader_cache *sc, GLenum type)
for (int n = 0; n < sc->num_uniforms; n++)
update_uniform(gl, entry, &sc->uniforms[n], n);
+ for (int n = 0; n < sc->num_buffers; n++) {
+ struct sc_buffer *b = &sc->buffers[n];
+ gl->BindBufferBase(GL_SHADER_STORAGE_BUFFER, b->binding, b->ssbo);
+ }
gl->ActiveTexture(GL_TEXTURE0);