summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/interface-changes.rst3
-rw-r--r--video/out/opengl/ra.c9
-rw-r--r--video/out/opengl/ra.h8
-rw-r--r--video/out/opengl/ra_gl.c37
-rw-r--r--video/out/opengl/ra_gl.h1
-rw-r--r--video/out/opengl/utils.c118
-rw-r--r--video/out/opengl/utils.h19
-rw-r--r--video/out/opengl/video.c99
-rw-r--r--video/out/opengl/video.h2
9 files changed, 161 insertions, 135 deletions
diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst
index ea4545bdc3..452e30ed73 100644
--- a/DOCS/interface-changes.rst
+++ b/DOCS/interface-changes.rst
@@ -27,6 +27,9 @@ Interface changes
warning)
- drop deprecated --video-aspect-method=hybrid option choice
- rename --hdr-tone-mapping to --tone-mapping (and generalize it)
+ - --opengl-fbo-format changes from a choice to a string. Also, its value
+ will be checked only on renderer initialization, rather than when the
+ option is set.
--- mpv 0.26.0 ---
- remove remaining deprecated audio device options, like --alsa-device
Some of them were removed in earlier releases.
diff --git a/video/out/opengl/ra.c b/video/out/opengl/ra.c
index 73f2915f95..9096a50148 100644
--- a/video/out/opengl/ra.c
+++ b/video/out/opengl/ra.c
@@ -80,6 +80,15 @@ const struct ra_format *ra_find_float16_format(struct ra *ra, int n_components)
return NULL;
}
+const struct ra_format *ra_find_named_format(struct ra *ra, const char *name)
+{
+ for (int n = 0; n < ra->num_formats; n++) {
+ const struct ra_format *fmt = ra->formats[n];
+ if (strcmp(fmt->name, name) == 0)
+ return fmt;
+ }
+ return NULL;
+}
// Like ra_find_unorm_format(), but if no fixed point format is available,
// return an unsigned integer format.
diff --git a/video/out/opengl/ra.h b/video/out/opengl/ra.h
index 866039a828..bd7a904860 100644
--- a/video/out/opengl/ra.h
+++ b/video/out/opengl/ra.h
@@ -76,6 +76,13 @@ struct ra_tex_params {
void *initial_data;
};
+// Conflates the following typical GPU API concepts:
+// - texture itself
+// - sampler state
+// - staging buffers for texture upload
+// - framebuffer objects
+// - wrappers for swapchain framebuffers
+// - synchronization needed for upload/rendering/etc.
struct ra_tex {
// All fields are read-only after creation.
struct ra_tex_params params;
@@ -149,6 +156,7 @@ const struct ra_format *ra_find_uint_format(struct ra *ra,
int bytes_per_component,
int n_components);
const struct ra_format *ra_find_float16_format(struct ra *ra, int n_components);
+const struct ra_format *ra_find_named_format(struct ra *ra, const char *name);
struct ra_imgfmt_desc {
int num_planes;
diff --git a/video/out/opengl/ra_gl.c b/video/out/opengl/ra_gl.c
index 46cbbda987..a52eeec94b 100644
--- a/video/out/opengl/ra_gl.c
+++ b/video/out/opengl/ra_gl.c
@@ -42,7 +42,8 @@ int ra_init_gl(struct ra *ra, GL *gl)
.pixel_size = gl_bytes_per_pixel(gl_fmt->format, gl_fmt->type),
.luminance_alpha = gl_fmt->format == GL_LUMINANCE_ALPHA,
.linear_filter = gl_fmt->flags & F_TF,
- .renderable = gl_fmt->flags & F_CR,
+ .renderable = (gl_fmt->flags & F_CR) &&
+ (gl->mpgl_caps & MPGL_CAP_FB),
};
int csize = gl_component_size(gl_fmt->type) * 8;
@@ -100,6 +101,9 @@ static void gl_tex_destroy(struct ra *ra, struct ra_tex *tex)
struct ra_gl *p = ra->priv;
struct ra_tex_gl *tex_gl = tex->priv;
+ if (tex_gl->fbo)
+ p->gl->DeleteFramebuffers(1, &tex_gl->fbo);
+
p->gl->DeleteTextures(1, &tex_gl->texture);
gl_pbo_upload_uninit(&tex_gl->pbo);
talloc_free(tex_gl);
@@ -167,6 +171,36 @@ static struct ra_tex *gl_tex_create(struct ra *ra,
tex->params.initial_data = NULL;
+ gl_check_error(gl, ra->log, "after creating texture");
+
+ if (tex->params.render_dst) {
+ if (!tex->params.format->renderable) {
+ MP_ERR(ra, "Trying to create renderable texture with unsupported "
+ "format.\n");
+ ra_tex_free(ra, &tex);
+ return NULL;
+ }
+
+ assert(gl->mpgl_caps & MPGL_CAP_FB);
+
+ gl->GenFramebuffers(1, &tex_gl->fbo);
+ gl->BindFramebuffer(GL_FRAMEBUFFER, tex_gl->fbo);
+ gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D, tex_gl->texture, 0);
+ GLenum err = gl->CheckFramebufferStatus(GL_FRAMEBUFFER);
+ gl->BindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ if (err != GL_FRAMEBUFFER_COMPLETE) {
+ MP_ERR(ra, "Error: framebuffer completeness check failed (error=%d).\n",
+ (int)err);
+ ra_tex_free(ra, &tex);
+ return NULL;
+ }
+
+
+ gl_check_error(gl, ra->log, "after creating framebuffer");
+ }
+
return tex;
}
@@ -294,4 +328,3 @@ static struct ra_fns ra_fns_gl = {
.destroy_mapped_buffer = gl_destroy_mapped_buffer,
.poll_mapped_buffer = gl_poll_mapped_buffer,
};
-
diff --git a/video/out/opengl/ra_gl.h b/video/out/opengl/ra_gl.h
index 9d5cb23fb7..d17b576afc 100644
--- a/video/out/opengl/ra_gl.h
+++ b/video/out/opengl/ra_gl.h
@@ -13,6 +13,7 @@ struct ra_gl {
struct ra_tex_gl {
GLenum target;
GLuint texture;
+ GLuint fbo; // 0 if no rendering requested
// These 3 fields can be 0 if unknown.
GLint internal_format;
GLenum format;
diff --git a/video/out/opengl/utils.c b/video/out/opengl/utils.c
index c38b7bbcbc..239009d4ac 100644
--- a/video/out/opengl/utils.c
+++ b/video/out/opengl/utils.c
@@ -254,37 +254,36 @@ static void gl_vao_draw_data(struct gl_vao *vao, GLenum prim, void *ptr, size_t
}
// Create a texture and a FBO using the texture as color attachments.
-// iformat: texture internal format
+// fmt: texture internal format
// Returns success.
-bool fbotex_init(struct fbotex *fbo, GL *gl, struct mp_log *log, int w, int h,
- GLenum iformat)
+bool fbotex_init(struct fbotex *fbo, struct ra *ra, struct mp_log *log,
+ int w, int h, const struct ra_format *fmt)
{
- assert(!fbo->fbo);
- assert(!fbo->texture);
- return fbotex_change(fbo, gl, log, w, h, iformat, 0);
+ assert(!fbo->tex);
+ return fbotex_change(fbo, ra, log, w, h, fmt, 0);
}
// Like fbotex_init(), except it can be called on an already initialized FBO;
// and if the parameters are the same as the previous call, do not touch it.
// flags can be 0, or a combination of FBOTEX_FUZZY_W and FBOTEX_FUZZY_H.
// Enabling FUZZY for W or H means the w or h does not need to be exact.
-bool fbotex_change(struct fbotex *fbo, GL *gl, struct mp_log *log, int w, int h,
- GLenum iformat, int flags)
-{
- bool res = true;
-
- int cw = w, ch = h;
-
- if ((flags & FBOTEX_FUZZY_W) && cw < fbo->rw)
- cw = fbo->rw;
- if ((flags & FBOTEX_FUZZY_H) && ch < fbo->rh)
- ch = fbo->rh;
-
- if (fbo->rw == cw && fbo->rh == ch && fbo->iformat == iformat) {
- fbo->lw = w;
- fbo->lh = h;
- fbotex_invalidate(fbo);
- return true;
+bool fbotex_change(struct fbotex *fbo, struct ra *ra, struct mp_log *log,
+ int w, int h, const struct ra_format *fmt, int flags)
+{
+ if (fbo->tex) {
+ int cw = w, ch = h;
+ int rw = fbo->tex->params.w, rh = fbo->tex->params.h;
+
+ if ((flags & FBOTEX_FUZZY_W) && cw < rw)
+ cw = rw;
+ if ((flags & FBOTEX_FUZZY_H) && ch < rh)
+ ch = rh;
+
+ if (rw == cw && rh == ch && fbo->tex->params.format == fmt) {
+ fbo->lw = w;
+ fbo->lh = h;
+ return true;
+ }
}
int lw = w, lh = h;
@@ -296,80 +295,51 @@ bool fbotex_change(struct fbotex *fbo, GL *gl, struct mp_log *log, int w, int h,
mp_verbose(log, "Create FBO: %dx%d (%dx%d)\n", lw, lh, w, h);
- const struct gl_format *format = gl_find_internal_format(gl, iformat);
- if (!format || (format->flags & F_CF) != F_CF) {
- mp_verbose(log, "Format 0x%x not supported.\n", (unsigned)iformat);
+ if (!fmt || !fmt->renderable || !fmt->linear_filter) {
+ mp_err(log, "Format %s not supported.\n", fmt ? fmt->name : "(unset)");
return false;
}
- assert(gl->mpgl_caps & MPGL_CAP_FB);
fbotex_uninit(fbo);
*fbo = (struct fbotex) {
- .gl = gl,
+ .ra = ra,
.rw = w,
.rh = h,
.lw = lw,
.lh = lh,
- .iformat = iformat,
};
- gl->GenFramebuffers(1, &fbo->fbo);
- gl->GenTextures(1, &fbo->texture);
- gl->BindTexture(GL_TEXTURE_2D, fbo->texture);
- gl->TexImage2D(GL_TEXTURE_2D, 0, format->internal_format, fbo->rw, fbo->rh, 0,
- format->format, format->type, NULL);
- gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- gl->BindTexture(GL_TEXTURE_2D, 0);
-
- gl_check_error(gl, log, "after creating framebuffer texture");
-
- gl->BindFramebuffer(GL_FRAMEBUFFER, fbo->fbo);
- gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
- GL_TEXTURE_2D, fbo->texture, 0);
-
- GLenum err = gl->CheckFramebufferStatus(GL_FRAMEBUFFER);
- if (err != GL_FRAMEBUFFER_COMPLETE) {
- mp_err(log, "Error: framebuffer completeness check failed (error=%d).\n",
- (int)err);
- res = false;
- }
+ struct ra_tex_params params = {
+ .dimensions = 2,
+ .w = w,
+ .h = h,
+ .d = 1,
+ .format = fmt,
+ .src_linear = true,
+ .render_src = true,
+ .render_dst = true,
+ };
- gl->BindFramebuffer(GL_FRAMEBUFFER, 0);
+ fbo->tex = ra_tex_create(fbo->ra, &params);
- gl_check_error(gl, log, "after creating framebuffer");
+ if (!fbo->tex) {
+ mp_err(log, "Error: framebuffer could not be created.\n");
+ fbotex_uninit(fbo);
+ return false;
+ }
- return res;
+ return true;
}
void fbotex_uninit(struct fbotex *fbo)
{
- GL *gl = fbo->gl;
-
- if (gl && (gl->mpgl_caps & MPGL_CAP_FB)) {
- gl->DeleteFramebuffers(1, &fbo->fbo);
- gl->DeleteTextures(1, &fbo->texture);
+ if (fbo->ra) {
+ ra_tex_free(fbo->ra, &fbo->tex);
*fbo = (struct fbotex) {0};
}
}
-// Mark framebuffer contents as unneeded.
-void fbotex_invalidate(struct fbotex *fbo)
-{
- GL *gl = fbo->gl;
-
- if (!fbo->fbo || !gl->InvalidateFramebuffer)
- return;
-
- gl->BindFramebuffer(GL_FRAMEBUFFER, fbo->fbo);
- gl->InvalidateFramebuffer(GL_FRAMEBUFFER, 1,
- (GLenum[]){GL_COLOR_ATTACHMENT0});
- gl->BindFramebuffer(GL_FRAMEBUFFER, 0);
-}
-
// Standard parallel 2D projection, except y1 < y0 means that the coordinate
// system is flipped, not the projection.
void gl_transform_ortho(struct gl_transform *t, float x0, float x1,
diff --git a/video/out/opengl/utils.h b/video/out/opengl/utils.h
index ba36a59316..491c0da209 100644
--- a/video/out/opengl/utils.h
+++ b/video/out/opengl/utils.h
@@ -51,23 +51,20 @@ struct gl_vao_entry {
};
struct fbotex {
- GL *gl;
- GLuint fbo;
- GLuint texture;
- GLenum iformat;
- int rw, rh; // real (texture) size
- int lw, lh; // logical (configured) size
+ struct ra *ra;
+ struct ra_tex *tex;
+ int rw, rh; // real (texture) size, same as tex->params.w/h
+ int lw, lh; // logical (configured) size, <= than texture size
};
-bool fbotex_init(struct fbotex *fbo, GL *gl, struct mp_log *log, int w, int h,
- GLenum iformat);
+bool fbotex_init(struct fbotex *fbo, struct ra *ra, struct mp_log *log,
+ int w, int h, const struct ra_format *fmt);
void fbotex_uninit(struct fbotex *fbo);
-bool fbotex_change(struct fbotex *fbo, GL *gl, struct mp_log *log, int w, int h,
- GLenum iformat, int flags);
+bool fbotex_change(struct fbotex *fbo, struct ra *ra, struct mp_log *log,
+ int w, int h, const struct ra_format *fmt, int flags);
#define FBOTEX_FUZZY_W 1
#define FBOTEX_FUZZY_H 2
#define FBOTEX_FUZZY (FBOTEX_FUZZY_W | FBOTEX_FUZZY_H)
-void fbotex_invalidate(struct fbotex *fbo);
// A 3x2 matrix, with the translation part separate.
struct gl_transform {
diff --git a/video/out/opengl/video.c b/video/out/opengl/video.c
index ecb0cba183..3fa85019df 100644
--- a/video/out/opengl/video.c
+++ b/video/out/opengl/video.c
@@ -227,6 +227,7 @@ struct gl_video {
bool dumb_mode;
bool forced_dumb_mode;
+ const struct ra_format *fbo_format;
struct fbotex merge_fbo[4];
struct fbotex scale_fbo[4];
struct fbotex integer_fbo[4];
@@ -307,7 +308,7 @@ static const struct gl_video_opts gl_video_opts_def = {
.dither_depth = -1,
.dither_size = 6,
.temporal_dither_period = 1,
- .fbo_format = 0,
+ .fbo_format = "auto",
.sigmoid_center = 0.75,
.sigmoid_slope = 6.5,
.scaler = {
@@ -385,19 +386,7 @@ const struct m_sub_options gl_video_conf = {
OPT_FLAG("sigmoid-upscaling", sigmoid_upscaling, 0),
OPT_FLOATRANGE("sigmoid-center", sigmoid_center, 0, 0.0, 1.0),
OPT_FLOATRANGE("sigmoid-slope", sigmoid_slope, 0, 1.0, 20.0),
- OPT_CHOICE("opengl-fbo-format", fbo_format, 0,
- ({"rgb8", GL_RGB8},
- {"rgba8", GL_RGBA8},
- {"rgb10", GL_RGB10},
- {"rgb10_a2", GL_RGB10_A2},
- {"rgb16", GL_RGB16},
- {"rgb16f", GL_RGB16F},
- {"rgb32f", GL_RGB32F},
- {"rgba12", GL_RGBA12},
- {"rgba16", GL_RGBA16},
- {"rgba16f", GL_RGBA16F},
- {"rgba32f", GL_RGBA32F},
- {"auto", 0})),
+ OPT_STRING("opengl-fbo-format", fbo_format, 0),
OPT_CHOICE_OR_INT("dither-depth", dither_depth, 0, -1, 16,
({"no", -1}, {"auto", 0})),
OPT_CHOICE("dither", dither_algo, 0,
@@ -453,6 +442,14 @@ static void gl_video_setup_hooks(struct gl_video *p);
#define GLSLHF(...) gl_sc_haddf(p->sc, __VA_ARGS__)
#define PRELUDE(...) gl_sc_paddf(p->sc, __VA_ARGS__)
+static GLuint get_fbo(struct fbotex *fbo)
+{
+ if (!fbo->tex)
+ return -1;
+ struct ra_tex_gl *tex_gl = fbo->tex->priv;
+ return tex_gl->fbo ? tex_gl->fbo : -1;
+}
+
static struct bstr load_cached_file(struct gl_video *p, const char *path)
{
if (!path || !path[0])
@@ -644,9 +641,10 @@ static struct img_tex img_tex_fbo(struct fbotex *fbo, enum plane_type type,
int components)
{
assert(type != PLANE_NONE);
+ struct ra_tex_gl *tex_gl = fbo->tex->priv;
return (struct img_tex){
.type = type,
- .gl_tex = fbo->texture,
+ .gl_tex = tex_gl->texture,
.gl_target = GL_TEXTURE_2D,
.multiplier = 1.0,
.tex_w = fbo->rw,
@@ -1267,11 +1265,14 @@ static void finish_pass_direct(struct gl_video *p, GLint fbo, int vp_w, int vp_h
static void finish_pass_fbo(struct gl_video *p, struct fbotex *dst_fbo,
int w, int h, int flags)
{
- fbotex_change(dst_fbo, p->gl, p->log, w, h, p->opts.fbo_format, flags);
+ fbotex_change(dst_fbo, p->ra, p->log, w, h, p->fbo_format, flags);
if (p->pass_compute.active) {
- gl_sc_uniform_image2D(p->sc, "out_image", dst_fbo->texture,
- dst_fbo->iformat, GL_WRITE_ONLY);
+ if (!dst_fbo->tex)
+ return;
+ struct ra_tex_gl *tex_gl = dst_fbo->tex->priv;
+ gl_sc_uniform_image2D(p->sc, "out_image", tex_gl->texture,
+ tex_gl->internal_format, GL_WRITE_ONLY);
if (!p->pass_compute.directly_writes)
GLSL(imageStore(out_image, ivec2(gl_GlobalInvocationID), color);)
@@ -1279,7 +1280,7 @@ static void finish_pass_fbo(struct gl_video *p, struct fbotex *dst_fbo,
p->gl->MemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
p->pass_compute = (struct compute_info){0};
} else {
- finish_pass_direct(p, dst_fbo->fbo, dst_fbo->rw, dst_fbo->rh,
+ finish_pass_direct(p, get_fbo(dst_fbo), dst_fbo->rw, dst_fbo->rh,
&(struct mp_rect){0, 0, w, h});
}
}
@@ -2762,7 +2763,7 @@ static bool pass_render_frame(struct gl_video *p, struct mp_image *mpi, uint64_t
};
finish_pass_fbo(p, &p->blend_subs_fbo, rect.w, rect.h, 0);
pass_draw_osd(p, OSD_DRAW_SUB_ONLY, vpts, rect,
- rect.w, rect.h, p->blend_subs_fbo.fbo, false);
+ rect.w, rect.h, get_fbo(&p->blend_subs_fbo), false);
pass_read_fbo(p, &p->blend_subs_fbo);
pass_describe(p, "blend subs video");
}
@@ -2792,7 +2793,8 @@ static bool pass_render_frame(struct gl_video *p, struct mp_image *mpi, uint64_t
}
finish_pass_fbo(p, &p->blend_subs_fbo, p->texture_w, p->texture_h, 0);
pass_draw_osd(p, OSD_DRAW_SUB_ONLY, vpts, rect,
- p->texture_w, p->texture_h, p->blend_subs_fbo.fbo, false);
+ p->texture_w, p->texture_h, get_fbo(&p->blend_subs_fbo),
+ false);
pass_read_fbo(p, &p->blend_subs_fbo);
pass_describe(p, "blend subs");
}
@@ -3134,10 +3136,10 @@ void gl_video_render_frame(struct gl_video *p, struct vo_frame *frame, int fbo)
if (frame->num_vsyncs > 1 && frame->display_synced &&
!p->dumb_mode && gl->BlitFramebuffer)
{
- fbotex_change(&p->output_fbo, p->gl, p->log,
+ fbotex_change(&p->output_fbo, p->ra, p->log,
p->vp_w, abs(p->vp_h),
- p->opts.fbo_format, FBOTEX_FUZZY);
- dest_fbo = p->output_fbo.fbo;
+ p->fbo_format, FBOTEX_FUZZY);
+ dest_fbo = get_fbo(&p->output_fbo);
p->output_fbo_valid = true;
}
pass_draw_to_screen(p, dest_fbo);
@@ -3147,7 +3149,7 @@ void gl_video_render_frame(struct gl_video *p, struct vo_frame *frame, int fbo)
if (p->output_fbo_valid) {
pass_info_reset(p, true);
pass_describe(p, "redraw cached frame");
- gl->BindFramebuffer(GL_READ_FRAMEBUFFER, p->output_fbo.fbo);
+ gl->BindFramebuffer(GL_READ_FRAMEBUFFER, get_fbo(&p->output_fbo));
gl->BindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
struct mp_rect rc = p->dst_rect;
if (p->vp_h < 0) {
@@ -3276,14 +3278,21 @@ static void reinterleave_vdpau(struct gl_video *p, struct gl_hwdec_frame *frame)
GLSLF(" ? texture(texture%d, texcoord%d)\n", ids[0], ids[0]);
GLSLF(" : texture(texture%d, texcoord%d);", ids[1], ids[1]);
- fbotex_change(fbo, p->gl, p->log, w, h * 2, n == 0 ? GL_R8 : GL_RG8, 0);
+ const struct ra_format *fmt =
+ ra_find_unorm_format(p->ra, 1, n == 0 ? 1 : 2);
+ fbotex_change(fbo, p->ra, p->log, w, h * 2, fmt, 0);
pass_describe(p, "vdpau reinterleaving");
- finish_pass_direct(p, fbo->fbo, fbo->rw, fbo->rh,
+ finish_pass_direct(p, get_fbo(fbo), fbo->rw, fbo->rh,
&(struct mp_rect){0, 0, w, h * 2});
+ GLuint tex = 0;
+ if (fbo->tex) {
+ struct ra_tex_gl *tex_gl = fbo->tex->priv;
+ tex = tex_gl->texture;
+ }
res.planes[n] = (struct gl_hwdec_plane){
- .gl_texture = fbo->texture,
+ .gl_texture = tex,
.gl_target = GL_TEXTURE_2D,
.tex_w = w,
.tex_h = h * 2,
@@ -3385,19 +3394,12 @@ error:
return false;
}
-static bool test_fbo(struct gl_video *p, GLint format)
+static bool test_fbo(struct gl_video *p, const struct ra_format *fmt)
{
- GL *gl = p->gl;
- bool success = false;
- MP_VERBOSE(p, "Testing FBO format 0x%x\n", (unsigned)format);
+ MP_VERBOSE(p, "Testing FBO format %s\n", fmt->name);
struct fbotex fbo = {0};
- if (fbotex_init(&fbo, p->gl, p->log, 16, 16, format)) {
- gl->BindFramebuffer(GL_FRAMEBUFFER, fbo.fbo);
- gl->BindFramebuffer(GL_FRAMEBUFFER, 0);
- success = true;
- }
+ bool success = fbotex_init(&fbo, p->ra, p->log, 16, 16, fmt);
fbotex_uninit(&fbo);
- gl_check_error(gl, p->log, "FBO test");
return success;
}
@@ -3443,18 +3445,21 @@ static void check_gl_features(struct gl_video *p)
bool have_compute = gl->mpgl_caps & MPGL_CAP_COMPUTE_SHADER;
bool have_ssbo = gl->mpgl_caps & MPGL_CAP_SSBO;
- const GLint auto_fbo_fmts[] = {GL_RGBA16, GL_RGBA16F, GL_RGB10_A2,
- GL_RGBA8, 0};
- GLint user_fbo_fmts[] = {p->opts.fbo_format, 0};
- const GLint *fbo_fmts = user_fbo_fmts[0] ? user_fbo_fmts : auto_fbo_fmts;
+ const char *auto_fbo_fmts[] = {"rgba16", "rgba16f", "rgb10_a2", "rgba8", 0};
+ const char *user_fbo_fmts[] = {p->opts.fbo_format, 0};
+ const char **fbo_fmts = user_fbo_fmts[0] && strcmp(user_fbo_fmts[0], "auto")
+ ? user_fbo_fmts : auto_fbo_fmts;
bool have_fbo = false;
+ p->fbo_format = NULL;
for (int n = 0; fbo_fmts[n]; n++) {
- GLint fmt = fbo_fmts[n];
- const struct gl_format *f = gl_find_internal_format(gl, fmt);
- if (f && (f->flags & F_CF) == F_CF && test_fbo(p, fmt)) {
- MP_VERBOSE(p, "Using FBO format 0x%x.\n", (unsigned)fmt);
+ const char *fmt = fbo_fmts[n];
+ const struct ra_format *f = ra_find_named_format(p->ra, fmt);
+ if (!f && fbo_fmts == user_fbo_fmts)
+ MP_WARN(p, "FBO format '%s' not found!\n", fmt);
+ if (f && f->renderable && f->linear_filter && test_fbo(p, f)) {
+ MP_VERBOSE(p, "Using FBO format %s.\n", f->name);
have_fbo = true;
- p->opts.fbo_format = fmt;
+ p->fbo_format = f;
break;
}
}
diff --git a/video/out/opengl/video.h b/video/out/opengl/video.h
index d74f3cf576..4f0c535af7 100644
--- a/video/out/opengl/video.h
+++ b/video/out/opengl/video.h
@@ -126,7 +126,7 @@ struct gl_video_opts {
int dither_size;
int temporal_dither;
int temporal_dither_period;
- int fbo_format;
+ char *fbo_format;
int alpha_mode;
int use_rectangle;
struct m_color background;