summaryrefslogtreecommitdiffstats
path: root/video/out
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-12-16 18:55:02 +0100
committerwm4 <wm4@nowhere>2014-12-16 18:55:20 +0100
commit0e8fbdbdb1ea212128ae6a193d198ed90f5ca4ac (patch)
tree62da75feb37ada97b833b7e0c80d4c0e763fbd87 /video/out
parent446e759f64c8a9cf23cf5ba1aa66e02d569786ff (diff)
downloadmpv-0e8fbdbdb1ea212128ae6a193d198ed90f5ca4ac.tar.bz2
mpv-0e8fbdbdb1ea212128ae6a193d198ed90f5ca4ac.tar.xz
vo_opengl: remove requirement for RG textures
Features not supported are disabled (although with a misleading error message).
Diffstat (limited to 'video/out')
-rw-r--r--video/out/gl_osd.c3
-rw-r--r--video/out/gl_video.c93
-rw-r--r--video/out/gl_video_shaders.glsl34
-rw-r--r--video/out/vo_opengl.c2
-rw-r--r--video/out/vo_opengl_cb.c2
5 files changed, 92 insertions, 42 deletions
diff --git a/video/out/gl_osd.c b/video/out/gl_osd.c
index 67944186a1..6b97ef77cf 100644
--- a/video/out/gl_osd.c
+++ b/video/out/gl_osd.c
@@ -61,6 +61,9 @@ struct mpgl_osd *mpgl_osd_init(GL *gl, struct mp_log *log, struct osd_state *osd
.scratch = talloc_zero_size(ctx, 1),
};
+ if (!(gl->mpgl_caps & MPGL_CAP_TEX_RG))
+ ctx->fmt_table = osd_to_gl_legacy_formats;
+
for (int n = 0; n < MAX_OSD_PARTS; n++) {
struct mpgl_osd_part *p = talloc_ptrtype(ctx, p);
*p = (struct mpgl_osd_part) {
diff --git a/video/out/gl_video.c b/video/out/gl_video.c
index c74e387f01..f37c715356 100644
--- a/video/out/gl_video.c
+++ b/video/out/gl_video.c
@@ -231,6 +231,21 @@ static const struct fmt_entry gl_byte_formats[] = {
{0, GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT}, // 4 x 16
};
+static const struct fmt_entry gl_byte_formats_legacy[] = {
+ {0, GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE}, // 1 x 8
+ {0, GL_LUMINANCE_ALPHA,
+ GL_LUMINANCE_ALPHA,
+ GL_UNSIGNED_BYTE}, // 2 x 8
+ {0, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE}, // 3 x 8
+ {0, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE}, // 4 x 8
+ {0, GL_ALPHA16, GL_ALPHA, GL_UNSIGNED_SHORT}, // 1 x 16
+ {0, GL_LUMINANCE16_ALPHA16,
+ GL_LUMINANCE_ALPHA,
+ GL_UNSIGNED_SHORT}, // 2 x 16
+ {0, GL_RGB16, GL_RGB, GL_UNSIGNED_SHORT}, // 3 x 16
+ {0, GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT}, // 4 x 16
+};
+
static const struct fmt_entry gl_float16_formats[] = {
{0, GL_R16F, GL_RED, GL_FLOAT}, // 1 x f
{0, GL_RG16F, GL_RG, GL_FLOAT}, // 2 x f
@@ -369,6 +384,15 @@ static void delete_shaders(struct gl_video *p);
static void check_gl_features(struct gl_video *p);
static bool init_format(int fmt, struct gl_video *init);
+static const struct fmt_entry *find_tex_format(GL *gl, int bytes_per_comp,
+ int n_channels)
+{
+ assert(bytes_per_comp == 1 || bytes_per_comp == 2);
+ assert(n_channels >= 1 && n_channels <= 4);
+ const struct fmt_entry *fmts = (gl->mpgl_caps & MPGL_CAP_TEX_RG)
+ ? gl_byte_formats : gl_byte_formats_legacy;
+ return &fmts[n_channels - 1 + (bytes_per_comp - 1) * 4];
+}
static void default_tex_params(struct GL *gl, GLenum target, GLint filter)
{
@@ -887,8 +911,12 @@ static void compile_shaders(struct gl_video *p)
char *shader_prelude = get_section(tmp, src, "prelude");
char *s_video = get_section(tmp, src, "frag_video");
- char *header = talloc_asprintf(tmp, "#version %d\n%s%s", gl->glsl_version,
- shader_prelude, PRELUDE_END);
+ int rg = !!(gl->mpgl_caps & MPGL_CAP_TEX_RG);
+ char *header =
+ talloc_asprintf(tmp, "#version %d\n"
+ "#define HAVE_RG %d\n"
+ "%s%s",
+ gl->glsl_version, rg, shader_prelude, PRELUDE_END);
bool use_cms = p->opts.srgb || p->use_lut_3d;
@@ -1233,6 +1261,7 @@ static void init_dither(struct gl_video *p)
GLint tex_iformat;
GLenum tex_type;
unsigned char temp[256];
+ GLint tex_format = find_tex_format(gl, 1, 1)->format;
if (p->opts.dither_algo == 0) {
int sizeb = p->opts.dither_size;
@@ -1246,7 +1275,7 @@ static void init_dither(struct gl_video *p)
}
tex_size = size;
- tex_iformat = GL_R16;
+ tex_iformat = find_tex_format(gl, 2, 1)->internal_format;
tex_type = GL_FLOAT;
tex_data = p->last_dither_matrix;
} else {
@@ -1254,7 +1283,7 @@ static void init_dither(struct gl_video *p)
mp_make_ordered_dither_matrix(temp, 8);
tex_size = 8;
- tex_iformat = GL_RED;
+ tex_iformat = tex_format;
tex_type = GL_UNSIGNED_BYTE;
tex_data = temp;
}
@@ -1272,8 +1301,8 @@ static void init_dither(struct gl_video *p)
gl->BindTexture(GL_TEXTURE_2D, p->dither_texture);
gl->PixelStorei(GL_UNPACK_ALIGNMENT, 1);
gl->PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- gl->TexImage2D(GL_TEXTURE_2D, 0, tex_iformat, tex_size, tex_size, 0, GL_RED,
- tex_type, tex_data);
+ gl->TexImage2D(GL_TEXTURE_2D, 0, tex_iformat, tex_size, tex_size, 0,
+ tex_format, tex_type, tex_data);
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
@@ -2022,9 +2051,10 @@ static bool test_fbo(struct gl_video *p, GLenum format)
for (int i = 0; i < 4; i++) {
float pixel = -1;
float val = vals[i];
- gl->ClearColor(val, 0.0f, 0.0f, 1.0f);
+ gl->ClearColor(val, val, val, val);
gl->Clear(GL_COLOR_BUFFER_BIT);
- gl->ReadPixels(0, 0, 1, 1, GL_RED, GL_FLOAT, &pixel);
+ GLint one_byte = find_tex_format(gl, 1, 1)->format;
+ gl->ReadPixels(0, 0, 1, 1, one_byte, GL_FLOAT, &pixel);
MP_VERBOSE(p, " %s: %a\n", val_names[i], val - pixel);
}
gl->BindFramebuffer(GL_FRAMEBUFFER, 0);
@@ -2044,6 +2074,7 @@ static void check_gl_features(struct gl_video *p)
bool have_float_tex = gl->mpgl_caps & MPGL_CAP_FLOAT_TEX;
bool have_fbo = gl->mpgl_caps & MPGL_CAP_FB;
bool have_srgb = gl->mpgl_caps & MPGL_CAP_SRGB_TEX;
+ bool have_rg = gl->mpgl_caps & MPGL_CAP_TEX_RG;
bool have_mix = gl->glsl_version >= 130;
char *disabled[10];
@@ -2068,7 +2099,8 @@ static void check_gl_features(struct gl_video *p)
// Normally, we want to disable them by default if FBOs are unavailable,
// because they will be slow (not critically slow, but still slower).
// Without FP textures, we must always disable them.
- if (!have_float_tex || (!have_fbo && p->opts.scale_sep)) {
+ // I don't know if luminance alpha float textures exist, so disregard them.
+ if (!have_float_tex || !have_rg || (!have_fbo && p->opts.scale_sep)) {
for (int n = 0; n < 2; n++) {
if (mp_find_filter_kernel(p->opts.scalers[n])) {
p->opts.scalers[n] = "bilinear";
@@ -2110,8 +2142,7 @@ static void check_gl_features(struct gl_video *p)
}
if (n_disabled) {
- MP_ERR(p, "Some OpenGL extensions not detected, "
- "disabling: ");
+ MP_ERR(p, "Some OpenGL extensions not detected, disabling: ");
for (int n = 0; n < n_disabled; n++) {
if (n)
MP_ERR(p, ", ");
@@ -2208,22 +2239,26 @@ void gl_video_unset_gl_state(struct gl_video *p)
}
// dest = src.<w> (always using 4 components)
-static void packed_fmt_swizzle(char w[5], const struct packed_fmt_entry *fmt)
+static void packed_fmt_swizzle(char w[5], const struct fmt_entry *texfmt,
+ const struct packed_fmt_entry *fmt)
{
+ const char *comp = "rgba";
+
+ // Normally, we work with GL_RED and GL_RG
+ if (texfmt && texfmt->internal_format == GL_LUMINANCE_ALPHA)
+ comp = "ragb";
+ if (texfmt && texfmt->internal_format == GL_ALPHA)
+ comp = "argb";
+
for (int c = 0; c < 4; c++)
- w[c] = "rgba"[MPMAX(fmt->components[c] - 1, 0)];
+ w[c] = comp[MPMAX(fmt->components[c] - 1, 0)];
w[4] = '\0';
}
-static const struct fmt_entry *find_tex_format(int bytes_per_comp, int n_channels)
-{
- assert(bytes_per_comp == 1 || bytes_per_comp == 2);
- assert(n_channels >= 1 && n_channels <= 4);
- return &gl_byte_formats[n_channels - 1 + (bytes_per_comp - 1) * 4];
-}
-
static bool init_format(int fmt, struct gl_video *init)
{
+ struct GL *gl = init->gl;
+
init->hwdec_active = false;
if (init->hwdec && init->hwdec->driver->imgfmt == fmt) {
fmt = init->hwdec->converted_imgfmt;
@@ -2250,17 +2285,21 @@ static bool init_format(int fmt, struct gl_video *init)
if ((desc.flags & MP_IMGFLAG_NE) && bits >= 8 && bits <= 16) {
init->plane_bits = bits;
init->has_alpha = desc.num_planes > 3;
- plane_format[0] = find_tex_format((bits + 7) / 8, 1);
+ plane_format[0] = find_tex_format(gl, (bits + 7) / 8, 1);
for (int p = 1; p < desc.num_planes; p++)
plane_format[p] = plane_format[0];
+ if (!(init->gl->mpgl_caps & MPGL_CAP_TEX_RG) && desc.num_planes < 2)
+ snprintf(init->color_swizzle, sizeof(init->color_swizzle), "argb");
goto supported;
}
}
// YUV/half-packed
if (fmt == IMGFMT_NV12 || fmt == IMGFMT_NV21) {
- plane_format[0] = find_tex_format(1, 1);
- plane_format[1] = find_tex_format(1, 2);
+ if (!(init->gl->mpgl_caps & MPGL_CAP_TEX_RG))
+ return false;
+ plane_format[0] = find_tex_format(gl, 1, 1);
+ plane_format[1] = find_tex_format(gl, 1, 2);
if (fmt == IMGFMT_NV21)
snprintf(init->color_swizzle, sizeof(init->color_swizzle), "rbga");
goto supported;
@@ -2269,7 +2308,7 @@ static bool init_format(int fmt, struct gl_video *init)
// RGB/planar
if (fmt == IMGFMT_GBRP) {
snprintf(init->color_swizzle, sizeof(init->color_swizzle), "brga");
- plane_format[0] = find_tex_format(1, 1);
+ plane_format[0] = find_tex_format(gl, 1, 1);
for (int p = 1; p < desc.num_planes; p++)
plane_format[p] = plane_format[0];
goto supported;
@@ -2277,7 +2316,7 @@ static bool init_format(int fmt, struct gl_video *init)
// XYZ (same organization as RGB packed, but requires conversion matrix)
if (fmt == IMGFMT_XYZ12) {
- plane_format[0] = find_tex_format(2, 3);
+ plane_format[0] = find_tex_format(gl, 2, 3);
goto supported;
}
@@ -2293,8 +2332,8 @@ static bool init_format(int fmt, struct gl_video *init)
for (const struct packed_fmt_entry *e = mp_packed_formats; e->fmt; e++) {
if (e->fmt == fmt) {
int n_comp = desc.bytes[0] / e->component_size;
- plane_format[0] = find_tex_format(e->component_size, n_comp);
- packed_fmt_swizzle(init->color_swizzle, e);
+ plane_format[0] = find_tex_format(gl, e->component_size, n_comp);
+ packed_fmt_swizzle(init->color_swizzle, plane_format[0], e);
init->has_alpha = e->components[3] != 0;
goto supported;
}
diff --git a/video/out/gl_video_shaders.glsl b/video/out/gl_video_shaders.glsl
index 4c32f77c3a..eb24d6ab75 100644
--- a/video/out/gl_video_shaders.glsl
+++ b/video/out/gl_video_shaders.glsl
@@ -41,6 +41,14 @@
# define in varying
#endif
+#if HAVE_RG
+#define R r
+#define RG rg
+#else
+#define R a
+#define RG ra
+#endif
+
// Earlier GLSL doesn't support mix() with bvec
#if __VERSION__ >= 130
vec3 srgb_expand(vec3 v)
@@ -133,7 +141,7 @@ in vec4 color;
DECLARE_FRAGPARMS
void main() {
- out_color = vec4(color.rgb, color.a * texture(texture0, texcoord).r);
+ out_color = vec4(color.rgb, color.a * texture(texture0, texcoord).R);
}
#!section frag_osd_rgba
@@ -205,8 +213,8 @@ vec4 sample_bicubic_fast(VIDEO_SAMPLER tex, vec2 texsize, vec2 texcoord, float p
vec4 parmx = calcweights(fcoord.x);
vec4 parmy = calcweights(fcoord.y);
vec4 cdelta;
- cdelta.xz = parmx.rg * vec2(-pt.x, pt.x);
- cdelta.yw = parmy.rg * vec2(-pt.y, pt.y);
+ cdelta.xz = parmx.RG * vec2(-pt.x, pt.x);
+ cdelta.yw = parmy.RG * vec2(-pt.y, pt.y);
// first y-interpolation
vec4 ar = texture(tex, texcoord + cdelta.xy);
vec4 ag = texture(tex, texcoord + cdelta.xw);
@@ -220,7 +228,7 @@ vec4 sample_bicubic_fast(VIDEO_SAMPLER tex, vec2 texsize, vec2 texcoord, float p
}
float[2] weights2(sampler2D lookup, float f) {
- vec4 c = texture(lookup, vec2(0.5, f));
+ vec2 c = texture(lookup, vec2(0.5, f)).RG;
return float[2](c.r, c.g);
}
@@ -326,23 +334,23 @@ void main() {
#define USE_CONV 0
#endif
#if USE_CONV == CONV_PLANAR
- vec4 acolor = vec4(SAMPLE_L(texture0, textures_size[0], texcoord).r,
- SAMPLE_C(texture1, textures_size[1], chr_texcoord).r,
- SAMPLE_C(texture2, textures_size[2], chr_texcoord).r,
+ vec4 acolor = vec4(SAMPLE_L(texture0, textures_size[0], texcoord).R,
+ SAMPLE_C(texture1, textures_size[1], chr_texcoord).R,
+ SAMPLE_C(texture2, textures_size[2], chr_texcoord).R,
1.0);
#elif USE_CONV == CONV_NV12
- vec4 acolor = vec4(SAMPLE_L(texture0, textures_size[0], texcoord).r,
- SAMPLE_C(texture1, textures_size[1], chr_texcoord).rg,
+ vec4 acolor = vec4(SAMPLE_L(texture0, textures_size[0], texcoord).R,
+ SAMPLE_C(texture1, textures_size[1], chr_texcoord).RG,
1.0);
#else
vec4 acolor = SAMPLE_L(texture0, textures_size[0], texcoord);
#endif
-#ifdef USE_ALPHA_PLANE
- acolor.a = SAMPLE_L(texture3, textures_size[3], texcoord).r;
-#endif
#ifdef USE_COLOR_SWIZZLE
acolor = acolor. USE_COLOR_SWIZZLE ;
#endif
+#ifdef USE_ALPHA_PLANE
+ acolor.a = SAMPLE_L(texture3, textures_size[3], texcoord).R;
+#endif
vec3 color = acolor.rgb;
float alpha = acolor.a;
#ifdef USE_YGRAY
@@ -452,7 +460,7 @@ void main() {
#ifdef USE_TEMPORAL_DITHER
dither_pos = dither_trafo * dither_pos;
#endif
- float dither_value = texture(dither, dither_pos).r;
+ float dither_value = texture(dither, dither_pos).R;
color = floor(color * dither_quantization + dither_value + dither_center) /
dither_quantization;
#endif
diff --git a/video/out/vo_opengl.c b/video/out/vo_opengl.c
index 0728223415..65f5d4c434 100644
--- a/video/out/vo_opengl.c
+++ b/video/out/vo_opengl.c
@@ -410,7 +410,7 @@ static int preinit(struct vo *vo)
if (p->use_gl_debug)
vo_flags |= VOFLAG_GL_DEBUG;
- int mpgl_caps = MPGL_CAP_GL21 | MPGL_CAP_TEX_RG;
+ int mpgl_caps = MPGL_CAP_GL21;
if (!p->allow_sw)
mpgl_caps |= MPGL_CAP_NO_SW;
diff --git a/video/out/vo_opengl_cb.c b/video/out/vo_opengl_cb.c
index 97c50ba489..a6731c6a51 100644
--- a/video/out/vo_opengl_cb.c
+++ b/video/out/vo_opengl_cb.c
@@ -135,7 +135,7 @@ int mpv_opengl_cb_init_gl(struct mpv_opengl_cb_context *ctx, const char *exts,
mpgl_load_functions2(ctx->gl, get_proc_address, get_proc_address_ctx,
exts, ctx->log);
- int caps = MPGL_CAP_GL21 | MPGL_CAP_TEX_RG;
+ int caps = MPGL_CAP_GL21;
if ((ctx->gl->mpgl_caps & caps) != caps) {
MP_FATAL(ctx, "Missing OpenGL features.\n");
return MPV_ERROR_UNSUPPORTED;