diff options
author | wm4 <wm4@mplayer2.org> | 2011-11-08 20:21:00 +0100 |
---|---|---|
committer | Uoti Urpala <uau@mplayer2.org> | 2011-11-25 23:59:49 +0200 |
commit | 046692d90b3282ae99c9470aec711158eb2f1c40 (patch) | |
tree | ac84c653d187d008237880947e0a791d3a2ed268 /libvo/gl_common.c | |
parent | b65ee1f5ac0b8634b6b79c81deeea86ef39c4069 (diff) | |
download | mpv-046692d90b3282ae99c9470aec711158eb2f1c40.tar.bz2 mpv-046692d90b3282ae99c9470aec711158eb2f1c40.tar.xz |
vo_gl: fix 10 bit with Mesa drivers (Intel/Nouveau on Linux)
The GL_LUMINANCE16 texture format had only 8 bit precision on Mesa
based drivers. This caused heavy degradation of the image when playing
formats with more than 8 bits per pixel, such as 10 bit h264. Use
GL_R16 instead, which at least Mesa and Nvidia drivers actually
implement as 16 bit textures. Since sampling from this texture format
doesn't return anything meaningful in the other color components
(unlike luminance textures), the shader code has to be slightly
changed.
GL_R16 requires the GL_ARB_texture_rg extension. Check for it, and fall
back to the old texture format if it's not available.
The low precision of the GL_LUMINANCE16 format has just been fixed in
upstream Mesa, but it'll take a while before that fix is available in
distros.
Diffstat (limited to 'libvo/gl_common.c')
-rw-r--r-- | libvo/gl_common.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/libvo/gl_common.c b/libvo/gl_common.c index 47b0429ccf..626f7e4643 100644 --- a/libvo/gl_common.c +++ b/libvo/gl_common.c @@ -88,6 +88,7 @@ static const struct gl_name_map_struct gl_name_map[] = { MAP(GL_RGB10), MAP(GL_RGB12), MAP(GL_RGB16), MAP(GL_RGBA2), MAP(GL_RGBA4), MAP(GL_RGB5_A1), MAP(GL_RGBA8), MAP(GL_RGB10_A2), MAP(GL_RGBA12), MAP(GL_RGBA16), MAP(GL_LUMINANCE8), MAP(GL_LUMINANCE16), + MAP(GL_R16), // format MAP(GL_RGB), MAP(GL_RGBA), MAP(GL_RED), MAP(GL_GREEN), MAP(GL_BLUE), @@ -146,7 +147,7 @@ const char *glValName(GLint value) * \return 1 if format is supported by OpenGL, 0 if not. * \ingroup gltexture */ -int glFindFormat(uint32_t fmt, int *bpp, GLint *gl_texfmt, +int glFindFormat(uint32_t fmt, int have_texture_rg, int *bpp, GLint *gl_texfmt, GLenum *gl_format, GLenum *gl_type) { int supported = 1; @@ -190,9 +191,9 @@ int glFindFormat(uint32_t fmt, int *bpp, GLint *gl_texfmt, break; case IMGFMT_420P16: supported = 0; // no native YUV support - *gl_texfmt = GL_LUMINANCE16; + *gl_texfmt = have_texture_rg ? GL_R16 : GL_LUMINANCE16; *bpp = 16; - *gl_format = GL_LUMINANCE; + *gl_format = have_texture_rg ? GL_RED : GL_LUMINANCE; *gl_type = GL_UNSIGNED_SHORT; break; case IMGFMT_YV12: @@ -592,6 +593,8 @@ int glFmt2bpp(GLenum format, GLenum type) case GL_RGBA: case GL_BGRA: return 4 * component_size; + case GL_RED: + return component_size; } return 0; // unknown } @@ -853,7 +856,8 @@ static void gen_spline_lookup_tex(GL *gl, GLenum unit) } #define SAMPLE(dest, coord, texture) \ - "TEX dest, " coord ", " texture ", $tex_type;\n" + "TEX textemp, " coord ", " texture ", $tex_type;\n" \ + "MOV " dest ", textemp.r;\n" static const char *bilin_filt_template = SAMPLE("yuv.$out_comp","fragment.texcoord[$in_tex]","texture[$in_tex]"); |