1
mirror of https://github.com/mpv-player/mpv synced 2024-11-14 22:48:35 +01:00

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.
This commit is contained in:
wm4 2013-05-30 15:37:13 +02:00
parent 5d0c4b6ac3
commit bbc865a4da

View File

@ -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