summaryrefslogtreecommitdiffstats
path: root/video/out/opengl/utils.c
diff options
context:
space:
mode:
authorNiklas Haas <git@haasn.xyz>2017-07-17 21:39:06 +0200
committerNiklas Haas <git@haasn.xyz>2017-07-24 17:19:31 +0200
commitb196cadf9f9f6ea210db9236c2b26523a9a2719f (patch)
tree7faa5a77c65d84e45c074eb248fe0b54a62288ad /video/out/opengl/utils.c
parentaad6ba018a17eded2b3f4af2212e0123cfb29b79 (diff)
downloadmpv-b196cadf9f9f6ea210db9236c2b26523a9a2719f.tar.bz2
mpv-b196cadf9f9f6ea210db9236c2b26523a9a2719f.tar.xz
vo_opengl: support HDR peak detection
This is done via compute shaders. As a consequence, the tone mapping algorithms had to be rewritten to compute their known constants in GLSL (ahead of time), instead of doing it once. Didn't affect performance. Using shmem/SSBO atomics in this way is extremely fast on nvidia, but it might be slow on other platforms. Needs testing. Unfortunately, setting up the SSBO still requires OpenGL calls, which means I can't have it in video_shaders.c, where it belongs. But I'll defer worrying about that until the backend refactor, since then I'll be breaking up the video/video_shaders structure anyway.
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);