diff options
Diffstat (limited to 'video/out')
-rw-r--r-- | video/out/gl_video.c | 67 |
1 files changed, 60 insertions, 7 deletions
diff --git a/video/out/gl_video.c b/video/out/gl_video.c index 58c3bdf761..f24163d13f 100644 --- a/video/out/gl_video.c +++ b/video/out/gl_video.c @@ -387,7 +387,8 @@ static void write_quad(struct vertex *va, #undef COLOR_INIT } -static bool fbotex_init(struct gl_video *p, struct fbotex *fbo, int w, int h) +static bool fbotex_init(struct gl_video *p, struct fbotex *fbo, int w, int h, + GLenum iformat) { GL *gl = p->gl; bool res = true; @@ -406,7 +407,7 @@ static bool fbotex_init(struct gl_video *p, struct fbotex *fbo, int w, int h) gl->GenFramebuffers(1, &fbo->fbo); gl->GenTextures(1, &fbo->texture); gl->BindTexture(GL_TEXTURE_2D, fbo->texture); - gl->TexImage2D(GL_TEXTURE_2D, 0, p->opts.fbo_format, + gl->TexImage2D(GL_TEXTURE_2D, 0, iformat, fbo->tex_w, fbo->tex_h, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); default_tex_params(gl, GL_TEXTURE_2D, GL_LINEAR); @@ -1051,7 +1052,8 @@ static void reinit_rendering(struct gl_video *p) update_all_uniforms(p); if (p->indirect_program && !p->indirect_fbo.fbo) - fbotex_init(p, &p->indirect_fbo, p->texture_w, p->texture_h); + fbotex_init(p, &p->indirect_fbo, p->texture_w, p->texture_h, + p->opts.fbo_format); recreate_osd(p); } @@ -1336,7 +1338,8 @@ static void update_window_sized_objects(struct gl_video *p) // Round up to an arbitrary alignment to make window resizing or // panscan controls smoother (less texture reallocations). int height = FFALIGN(h, 256); - fbotex_init(p, &p->scale_sep_fbo, p->image_w, height); + fbotex_init(p, &p->scale_sep_fbo, p->image_w, height, + p->opts.fbo_format); } p->scale_sep_fbo.vp_w = p->image_w; p->scale_sep_fbo.vp_h = h; @@ -1555,6 +1558,48 @@ void gl_video_draw_osd(struct gl_video *p, struct osd_state *osd) gl->Flush(); } +static bool test_fbo(struct gl_video *p, GLenum format) +{ + static const float vals[] = { + 127 / 255.0f, // full 8 bit integer + 32767 / 65535.0f, // full 16 bit integer + 0xFFFFFF / (float)(1 << 25), // float mantissa + 2, // out of range value + }; + static const char *val_names[] = { + "8-bit precision", + "16-bit precision", + "full float", + "out of range value (2)", + }; + + GL *gl = p->gl; + bool success = false; + struct fbotex fbo = {0}; + gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + gl->PixelStorei(GL_PACK_ALIGNMENT, 1); + gl->PixelStorei(GL_PACK_ROW_LENGTH, 0); + if (fbotex_init(p, &fbo, 16, 16, format)) { + gl->BindFramebuffer(GL_FRAMEBUFFER, fbo.fbo); + gl->ReadBuffer(GL_COLOR_ATTACHMENT0); + for (int i = 0; i < 4; i++) { + float p = -1; + float val = vals[i]; + gl->ClearColor(val, 0.0f, 0.0f, 1.0f); + gl->Clear(GL_COLOR_BUFFER_BIT); + gl->ReadPixels(0, 0, 1, 1, GL_RED, GL_FLOAT, &p); + mp_msg(MSGT_VO, MSGL_V, " %s: %a\n", val_names[i], val - p); + } + gl->BindFramebuffer(GL_FRAMEBUFFER, 0); + glCheckError(gl, "after FBO read"); + success = true; + } + fbotex_uninit(p, &fbo); + glCheckError(gl, "FBO test"); + gl->ClearColor(0.0f, 0.0f, 0.0f, 1.0f); + return success; +} + // Disable features that are not supported with the current OpenGL version. static void check_gl_features(struct gl_video *p) { @@ -1571,9 +1616,17 @@ static void check_gl_features(struct gl_video *p) int n_disabled = 0; if (have_fbo) { - struct fbotex fbo = {0}; - have_fbo = fbotex_init(p, &fbo, 16, 16); - fbotex_uninit(p, &fbo); + mp_msg(MSGT_VO, MSGL_V, "Testing user-set FBO format\n"); + have_fbo = test_fbo(p, p->opts.fbo_format); + } + + // fruit dithering mode and the 3D lut use this texture format + if ((p->opts.dither_depth >= 0 && p->opts.dither_algo == 0) || + p->use_lut_3d) + { + // doesn't disalbe anything; it's just for the log + mp_msg(MSGT_VO, MSGL_V, "Testing GL_R16 FBO (dithering/LUT)\n"); + test_fbo(p, GL_R16); } // Disable these only if the user didn't disable scale-sep on the command |