[vlc-commits] [Git][videolan/vlc][master] 10 commits: opengl: make placebo conditional on <libplacebo/opengl.h>
Jean-Baptiste Kempf (@jbk)
gitlab at videolan.org
Sat Oct 15 17:03:40 UTC 2022
Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC
Commits:
1095115e by Niklas Haas at 2022-10-15T16:06:52+00:00
opengl: make placebo conditional on <libplacebo/opengl.h>
I want to start using the pl_opengl integration, so we need to slightly
revise the check to ensure we also have the libplaceo opengl header
available.
It's worth pointing out that these headers eventually become
non-conditional (in libplacebo git master as of writing), but we need to
live with this transitional logic until then.
- - - - -
90d2a076 by Niklas Haas at 2022-10-15T16:06:52+00:00
opengl: don't leak sampler state on error
This code as-written leaks libplacebo-related objects in the event of a
failure here.
- - - - -
808146d7 by Niklas Haas at 2022-10-15T16:06:52+00:00
opengl: add glUniformNfv
We have this for glUniform4fv, add the other types so I can use them.
- - - - -
08abc4d1 by Niklas Haas at 2022-10-15T16:06:52+00:00
opengl: add pl_var.dim_a support
The dithering code can end up using uniform array variables when
plugging pl_gpu information into the shader, so pre-emptively add
support for these.
- - - - -
41f48d78 by Niklas Haas at 2022-10-15T16:06:52+00:00
opengl: persist pl_shader_obj until shader is freed
This code, as written, is technically undefined behavior. It was fine so
far because we didn't end up using the shader objects in any way that
wasn't baked into the resulting pl_shader_res, but it needs to be fixed
to allow shaders to reference GPU resources which may be used later on.
- - - - -
5b7bdebd by Niklas Haas at 2022-10-15T16:06:52+00:00
opengl: change libplacebo var type check to assertion
Simply continuing in this error case without assigning the corresponding
uniform will silently lead to a broken shader / image. Since we rely on
these assumptions, we should assert them so any such bugs are actually
found in a debuggable way.
This is only a theoretical risk since, as the comment points out, we
don't rely on any such variables. But maybe this will unexpectedly
change in the future.
- - - - -
5cc37e20 by Niklas Haas at 2022-10-15T16:06:52+00:00
opengl: wrap OpenGL context to pl_opengl
This creates a pl_gpu suitable for use by shaders. It's worth noting
that this commit does not hook the resulting pl_gpu into the shaders
yet, because doing so would break the resulting shaders until we add
support for mapping descriptors (in the following commit).
- - - - -
94925cdb by Niklas Haas at 2022-10-15T16:06:52+00:00
opengl: add support for libplacebo descriptors
This change will allow us to integrate more advanced libplacebo
features, such as those requiring LUT-based tone-mapping (in recent
versions of libplacebo).
- - - - -
fb3c80f4 by Niklas Haas at 2022-10-15T16:06:52+00:00
opengl: plug pl_gpu into pl_shader
This commit merely activates the functionality supported by the previous
commits, tying it all together.
- - - - -
207369d9 by Niklas Haas at 2022-10-15T16:06:52+00:00
opengl: stop hard-coding small LUT size
Since we no longer rely on embedding hard-coded arrays into the shader,
we can finally free up this size limitation, thus improving the quality
of dithering massively.
- - - - -
4 changed files:
- configure.ac
- modules/video_output/opengl/gl_api.c
- modules/video_output/opengl/gl_common.h
- modules/video_output/opengl/sampler.c
Changes:
=====================================
configure.ac
=====================================
@@ -3143,6 +3143,7 @@ AS_IF([test "$enable_libplacebo" != "no"], [
AC_DEFINE([HAVE_LIBPLACEBO], [1], [Define to 1 if libplacebo is enabled.])
AC_CHECK_HEADER([libplacebo/vulkan.h], [VLC_ADD_PLUGIN([placebo_vk])])
AC_CHECK_HEADER([libplacebo/opengl.h], [
+ AC_DEFINE([HAVE_LIBPLACEBO_GL], [1], [Define to 1 if <libplacebo/opengl.h> is available.])
VLC_ADD_PLUGIN([placebo_gl])
VLC_ADD_PLUGIN([placebo_gles2])
dnl Minimum version that the OpenGL filter pl_scale is compatible with
=====================================
modules/video_output/opengl/gl_api.c
=====================================
@@ -108,6 +108,9 @@ vlc_gl_api_Init(struct vlc_gl_api *api, vlc_gl_t *gl)
GET_PROC_ADDR(UniformMatrix3fv);
GET_PROC_ADDR(UniformMatrix2fv);
GET_PROC_ADDR(Uniform4fv);
+ GET_PROC_ADDR(Uniform3fv);
+ GET_PROC_ADDR(Uniform2fv);
+ GET_PROC_ADDR(Uniform1fv);
GET_PROC_ADDR(Uniform4f);
GET_PROC_ADDR(Uniform3f);
GET_PROC_ADDR(Uniform2f);
=====================================
modules/video_output/opengl/gl_common.h
=====================================
@@ -90,6 +90,9 @@
#ifndef GL_TEXTURE_LUMINANCE_SIZE
# define GL_TEXTURE_LUMINANCE_SIZE 0x8060
#endif
+#ifndef GL_TEXTURE_WRAP_R
+# define GL_TEXTURE_WRAP_R 0x8072
+#endif
#ifndef GL_CLAMP_TO_EDGE
# define GL_CLAMP_TO_EDGE 0x812F
@@ -252,6 +255,9 @@ typedef void (APIENTRY *PFNGLREADPIXELSPROC) (GLint, GLint, GLsizei, GLsizei, GL
# define PFNGLUNIFORMMATRIX3FVPROC typeof(glUniformMatrix3fv)*
# define PFNGLUNIFORMMATRIX2FVPROC typeof(glUniformMatrix2fv)*
# define PFNGLUNIFORM4FVPROC typeof(glUniform4fv)*
+# define PFNGLUNIFORM3FVPROC typeof(glUniform3fv)*
+# define PFNGLUNIFORM2FVPROC typeof(glUniform2fv)*
+# define PFNGLUNIFORM1FVPROC typeof(glUniform1fv)*
# define PFNGLUNIFORM4FPROC typeof(glUniform4f)*
# define PFNGLUNIFORM3FPROC typeof(glUniform3f)*
# define PFNGLUNIFORM2FPROC typeof(glUniform2f)*
@@ -356,6 +362,9 @@ typedef struct {
PFNGLUNIFORMMATRIX3FVPROC UniformMatrix3fv;
PFNGLUNIFORMMATRIX2FVPROC UniformMatrix2fv;
PFNGLUNIFORM4FVPROC Uniform4fv;
+ PFNGLUNIFORM3FVPROC Uniform3fv;
+ PFNGLUNIFORM2FVPROC Uniform2fv;
+ PFNGLUNIFORM1FVPROC Uniform1fv;
PFNGLUNIFORM4FPROC Uniform4f;
PFNGLUNIFORM3FPROC Uniform3f;
PFNGLUNIFORM2FPROC Uniform2f;
=====================================
modules/video_output/opengl/sampler.c
=====================================
@@ -28,7 +28,8 @@
#include <vlc_memstream.h>
#include <vlc_opengl.h>
-#ifdef HAVE_LIBPLACEBO
+#ifdef HAVE_LIBPLACEBO_GL
+#include <libplacebo/opengl.h>
#include <libplacebo/shaders.h>
#include <libplacebo/shaders/colorspace.h>
#include "../libplacebo/utils.h"
@@ -51,16 +52,18 @@ struct vlc_gl_sampler_priv {
GLint Textures[PICTURE_PLANE_MAX];
GLint TexSizes[PICTURE_PLANE_MAX]; /* for GL_TEXTURE_RECTANGLE */
GLint ConvMatrix;
- GLint *pl_vars; /* for pl_sh_res */
+ GLint *pl_vars, *pl_descs; /* for pl_sh_res */
} uloc;
bool yuv_color;
GLfloat conv_matrix[4*4];
-#ifdef HAVE_LIBPLACEBO
+#ifdef HAVE_LIBPLACEBO_GL
/* libplacebo context */
pl_log pl_log;
+ pl_opengl pl_opengl;
pl_shader pl_sh;
+ pl_shader_obj dither_state, tone_map_state;
const struct pl_shader_res *pl_sh_res;
#endif
@@ -276,12 +279,17 @@ sampler_base_fetch_locations(struct vlc_gl_sampler *sampler, GLuint program)
}
}
-#ifdef HAVE_LIBPLACEBO
+#ifdef HAVE_LIBPLACEBO_GL
const struct pl_shader_res *res = priv->pl_sh_res;
for (int i = 0; res && i < res->num_variables; i++) {
struct pl_shader_var sv = res->variables[i];
priv->uloc.pl_vars[i] = vt->GetUniformLocation(program, sv.var.name);
}
+
+ for (int i = 0; res && i < res->num_descriptors; i++) {
+ struct pl_shader_desc sd = res->descriptors[i];
+ priv->uloc.pl_descs[i] = vt->GetUniformLocation(program, sd.desc.name);
+ }
#endif
}
@@ -315,7 +323,7 @@ sampler_base_load(struct vlc_gl_sampler *sampler)
glfmt->tex_heights[i]);
}
-#ifdef HAVE_LIBPLACEBO
+#ifdef HAVE_LIBPLACEBO_GL
const struct pl_shader_res *res = priv->pl_sh_res;
for (int i = 0; res && i < res->num_variables; i++) {
GLint loc = priv->uloc.pl_vars[i];
@@ -325,27 +333,61 @@ sampler_base_load(struct vlc_gl_sampler *sampler)
struct pl_shader_var sv = res->variables[i];
struct pl_var var = sv.var;
// libplacebo doesn't need anything else anyway
- if (var.type != PL_VAR_FLOAT)
- continue;
- if (var.dim_m > 1 && var.dim_m != var.dim_v)
- continue;
+ assert(var.type == PL_VAR_FLOAT);
+ assert(var.dim_m == 1 || var.dim_m == var.dim_v);
const float *f = sv.data;
switch (var.dim_m) {
- case 4: vt->UniformMatrix4fv(loc, 1, GL_FALSE, f); break;
- case 3: vt->UniformMatrix3fv(loc, 1, GL_FALSE, f); break;
- case 2: vt->UniformMatrix2fv(loc, 1, GL_FALSE, f); break;
+ case 4: vt->UniformMatrix4fv(loc, var.dim_a, GL_FALSE, f); break;
+ case 3: vt->UniformMatrix3fv(loc, var.dim_a, GL_FALSE, f); break;
+ case 2: vt->UniformMatrix2fv(loc, var.dim_a, GL_FALSE, f); break;
case 1:
switch (var.dim_v) {
- case 1: vt->Uniform1f(loc, f[0]); break;
- case 2: vt->Uniform2f(loc, f[0], f[1]); break;
- case 3: vt->Uniform3f(loc, f[0], f[1], f[2]); break;
- case 4: vt->Uniform4f(loc, f[0], f[1], f[2], f[3]); break;
+ case 1: vt->Uniform1fv(loc, var.dim_a, f); break;
+ case 2: vt->Uniform2fv(loc, var.dim_a, f); break;
+ case 3: vt->Uniform3fv(loc, var.dim_a, f); break;
+ case 4: vt->Uniform4fv(loc, var.dim_a, f); break;
}
break;
}
}
+
+ for (int i = 0; res && i < res->num_descriptors; i++) {
+ GLint loc = priv->uloc.pl_descs[i];
+ if (loc == -1)
+ continue;
+ struct pl_shader_desc sd = res->descriptors[i];
+ assert(sd.desc.type == PL_DESC_SAMPLED_TEX);
+ pl_tex tex = sd.binding.object;
+ int texid = glfmt->tex_count + i; // first free texture unit
+ unsigned gltex, target;
+ gltex = pl_opengl_unwrap(priv->pl_opengl->gpu, tex, &target, NULL, NULL);
+ vt->Uniform1i(loc, texid);
+ vt->ActiveTexture(GL_TEXTURE0 + texid);
+ vt->BindTexture(target, gltex);
+
+ static const GLint wraps[PL_TEX_ADDRESS_MODE_COUNT] = {
+ [PL_TEX_ADDRESS_CLAMP] = GL_CLAMP_TO_EDGE,
+ [PL_TEX_ADDRESS_REPEAT] = GL_REPEAT,
+ [PL_TEX_ADDRESS_MIRROR] = GL_MIRRORED_REPEAT,
+ };
+
+ static const GLint filters[PL_TEX_SAMPLE_MODE_COUNT] = {
+ [PL_TEX_SAMPLE_NEAREST] = GL_NEAREST,
+ [PL_TEX_SAMPLE_LINEAR] = GL_LINEAR,
+ };
+
+ GLint filter = filters[sd.binding.sample_mode];
+ GLint wrap = wraps[sd.binding.address_mode];
+ vt->TexParameteri(target, GL_TEXTURE_MIN_FILTER, filter);
+ vt->TexParameteri(target, GL_TEXTURE_MAG_FILTER, filter);
+ switch (pl_tex_params_dimension(tex->params)) {
+ case 3: vt->TexParameteri(target, GL_TEXTURE_WRAP_R, wrap); // fall through
+ case 2: vt->TexParameteri(target, GL_TEXTURE_WRAP_T, wrap); // fall through
+ case 1: vt->TexParameteri(target, GL_TEXTURE_WRAP_S, wrap); break;
+ }
+ }
#endif
}
@@ -661,7 +703,7 @@ opengl_fragment_shader_init(struct vlc_gl_sampler *sampler, bool expose_planes)
ADDF("uniform %s Textures[%u];\n", glsl_sampler, tex_count);
-#ifdef HAVE_LIBPLACEBO
+#ifdef HAVE_LIBPLACEBO_GL
if (priv->pl_sh) {
pl_shader sh = priv->pl_sh;
struct pl_color_map_params color_params;
@@ -671,12 +713,10 @@ opengl_fragment_shader_init(struct vlc_gl_sampler *sampler, bool expose_planes)
dst_space.primaries = var_InheritInteger(priv->gl, "target-prim");
dst_space.transfer = var_InheritInteger(priv->gl, "target-trc");
- pl_shader_obj tone_map_state = NULL;
pl_shader_color_map(sh, &color_params,
vlc_placebo_ColorSpace(fmt),
- dst_space, &tone_map_state, false);
+ dst_space, &priv->tone_map_state, false);
- pl_shader_obj dither_state = NULL;
int method = var_InheritInteger(priv->gl, "dither-algo");
if (method >= 0) {
@@ -700,27 +740,39 @@ opengl_fragment_shader_init(struct vlc_gl_sampler *sampler, bool expose_planes)
out_bits = fb_depth;
}
- pl_shader_dither(sh, out_bits, &dither_state, &(struct pl_dither_params) {
+ pl_shader_dither(sh, out_bits, &priv->dither_state, &(struct pl_dither_params) {
.method = method,
- .lut_size = 4, // avoid too large values, since this gets embedded
});
}
const struct pl_shader_res *res = priv->pl_sh_res = pl_shader_finalize(sh);
- pl_shader_obj_destroy(&tone_map_state);
- pl_shader_obj_destroy(&dither_state);
FREENULL(priv->uloc.pl_vars);
priv->uloc.pl_vars = calloc(res->num_variables, sizeof(GLint));
for (int i = 0; i < res->num_variables; i++) {
struct pl_shader_var sv = res->variables[i];
const char *glsl_type_name = pl_var_glsl_type_name(sv.var);
- ADDF("uniform %s %s;\n", glsl_type_name, sv.var.name);
+ ADDF("uniform %s %s", glsl_type_name, sv.var.name);
+ if (sv.var.dim_a > 1) {
+ ADDF("[%d];\n", sv.var.dim_a);
+ } else {
+ ADDF(";\n");
+ }
+ }
+
+ FREENULL(priv->uloc.pl_descs);
+ priv->uloc.pl_descs = calloc(res->num_descriptors, sizeof(GLint));
+ for (int i = 0; i < res->num_descriptors; i++) {
+ struct pl_shader_desc sd = res->descriptors[i];
+ assert(sd.desc.type == PL_DESC_SAMPLED_TEX);
+ pl_tex tex = sd.binding.object;
+ assert(tex->sampler_type == PL_SAMPLER_NORMAL);
+ int dims = pl_tex_params_dimension(tex->params);
+ ADDF("uniform sampler%dD %s;\n", dims, sd.desc.name);
}
// We can't handle these yet, but nothing we use requires them, either
assert(res->num_vertex_attribs == 0);
- assert(res->num_descriptors == 0);
ADD(res->glsl);
}
@@ -775,7 +827,7 @@ opengl_fragment_shader_init(struct vlc_gl_sampler *sampler, bool expose_planes)
}
assert(yuv_space == COLOR_SPACE_UNDEF || color_count == 3);
-#ifdef HAVE_LIBPLACEBO
+#ifdef HAVE_LIBPLACEBO_GL
if (priv->pl_sh_res) {
const struct pl_shader_res *res = priv->pl_sh_res;
if (res->input != PL_SHADER_SIG_NONE) {
@@ -842,11 +894,20 @@ vlc_gl_sampler_New(struct vlc_gl_t *gl, const struct vlc_gl_api *api,
sampler->shader.extensions = NULL;
sampler->shader.body = NULL;
-#ifdef HAVE_LIBPLACEBO
+#ifdef HAVE_LIBPLACEBO_GL
priv->uloc.pl_vars = NULL;
+ priv->uloc.pl_descs = NULL;
priv->pl_sh_res = NULL;
priv->pl_log = vlc_placebo_CreateLog(VLC_OBJECT(gl));
+ priv->pl_opengl = pl_opengl_create(priv->pl_log, NULL);
+ if (!priv->pl_opengl)
+ {
+ vlc_gl_sampler_Delete(sampler);
+ return NULL;
+ }
+
priv->pl_sh = pl_shader_alloc(priv->pl_log, &(struct pl_shader_params) {
+ .gpu = priv->pl_opengl->gpu,
.glsl = {
# ifdef USE_OPENGL_ES2
.version = 100,
@@ -861,7 +922,7 @@ vlc_gl_sampler_New(struct vlc_gl_t *gl, const struct vlc_gl_api *api,
int ret = opengl_fragment_shader_init(sampler, expose_planes);
if (ret != VLC_SUCCESS)
{
- free(sampler);
+ vlc_gl_sampler_Delete(sampler);
return NULL;
}
@@ -873,9 +934,13 @@ vlc_gl_sampler_Delete(struct vlc_gl_sampler *sampler)
{
struct vlc_gl_sampler_priv *priv = PRIV(sampler);
-#ifdef HAVE_LIBPLACEBO
+#ifdef HAVE_LIBPLACEBO_GL
FREENULL(priv->uloc.pl_vars);
+ FREENULL(priv->uloc.pl_descs);
pl_shader_free(&priv->pl_sh);
+ pl_shader_obj_destroy(&priv->tone_map_state);
+ pl_shader_obj_destroy(&priv->dither_state);
+ pl_opengl_destroy(&priv->pl_opengl);
pl_log_destroy(&priv->pl_log);
#endif
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/804f16bc2cc0229064f5719e54e320673060e613...207369d9073a09a6c7fd8ca65b7a605bec364fa2
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/804f16bc2cc0229064f5719e54e320673060e613...207369d9073a09a6c7fd8ca65b7a605bec364fa2
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
More information about the vlc-commits
mailing list