summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2017-08-04 13:48:37 +0200
committerwm4 <wm4@nowhere>2017-08-05 13:09:05 +0200
commita796745fd272701c9ed435337a161f643d34a26a (patch)
tree058da9d1be62c4a65e9881aa751897e19cae2f94
parent90b53fede618772d39ff964b12e6403d71f7f235 (diff)
downloadmpv-a796745fd272701c9ed435337a161f643d34a26a.tar.bz2
mpv-a796745fd272701c9ed435337a161f643d34a26a.tar.xz
vo_opengl: make fbotex helper use ra
Further work removing GL dependencies from the actual video renderer, and moving them into ra backends. Use of glInvalidateFramebuffer() falls away. I'd like to keep this, but it's better to readd it once shader runs are in ra.
-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;