From bbc865a4da72349682db666713e88e19300d0b6a Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 30 May 2013 15:37:13 +0200 Subject: gl_video: add some debug code for testing texture depth This probes and prints the depth of some texture formats with the help of a FBO. By default it tests the format used for scaling, as well as the format used for dithering and the 3D LUT (if any of these are enabled). The output is visible only with -v. Some representative values are probed, and the difference of input and output value is printed as hex- float. Hex-floats are used because they make the implied precision more obvious. Originally I wanted to do some more sophisticated guessing of the implied depth/precision for more user-friendly reporting, but then I decided that printing raw data is better for debugging, especially if things go wrong. This does not try to disable any functionality and does not print any warnings if the depth is lower than what it should be. --- video/out/gl_video.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 60 insertions(+), 7 deletions(-) (limited to 'video') 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 -- cgit v1.2.3