Merge lp:~compiz-team/compiz/compiz.fix_1016364 into lp:compiz/0.9.8

Proposed by Sam Spilsbury
Status: Rejected
Rejected by: Sam Spilsbury
Proposed branch: lp:~compiz-team/compiz/compiz.fix_1016364
Merge into: lp:compiz/0.9.8
Diff against target: 170 lines (+47/-26)
5 files modified
plugins/opengl/include/opengl/opengl.h (+1/-1)
plugins/opengl/include/opengl/texture.h (+5/-0)
plugins/opengl/src/privatetexture.h (+1/-0)
plugins/opengl/src/screen.cpp (+7/-9)
plugins/opengl/src/texture.cpp (+33/-16)
To merge this branch: bzr merge lp:~compiz-team/compiz/compiz.fix_1016364
Reviewer Review Type Date Requested Status
Sam Spilsbury Needs Resubmitting
Daniel van Vugt Needs Fixing
Review via email: mp+111539@code.launchpad.net

Commit message

Fix broken mipmap support. Mipmap support was broken in the following ways:

1. glGenerateMipmapEXT is called multiple times for tfp textures
2. glGenerateMipmapEXT is called after glTexParameteri with GL_LINEAR_MIPMAP_LINEAR as the filter mode, and sometimes not called at all, which is undefined
3. We check for GL::fbo support before actually setting it from the extension lookup after glXCreateContext is called. As such, when we lookup an optimal pixmap fbconfig, we never find one that supports mipmaps, and it is merely "luck of the draw" as to whether or not we actually get one that does
4. We generate mipmaps for tfp textures even though mipmaps aren't actually supported on the config target, because we don't check priv->mipmapSupport

This generally results in white windows when mipmapping is enabled. See (LP: #1016364)

As such the following measures were implemented:
1. Virtual method to generate a mipmap, different for tfp textures as
   mipmap generation has to happen on damage there
2. Always generate mipmaps before setting texture filter
3. Do not check for GL::fbo support when checking fbconfigs for mimap support
4. Use GLTexture::mipmap () to determine if we actually can do mipmaps - this
   checks if the fbconfig supports mipmaps, that the texture is not
   an NV_TEXTURE_RECTANGLE_EXT, checks for fbo support and NPOT texture
   support

Description of the change

== Problem ==

1. glGenerateMipmapEXT is called multiple times for tfp textures
2. glGenerateMipmapEXT is called after glTexParameteri with GL_LINEAR_MIPMAP_LINEAR as the filter mode, and sometimes not called at all, which is undefined
3. We check for GL::fbo support before actually setting it from the extension lookup after glXCreateContext is called. As such, when we lookup an optimal pixmap fbconfig, we never find one that supports mipmaps, and it is merely "luck of the draw" as to whether or not we actually get one that does
4. We generate mipmaps for tfp textures even though mipmaps aren't actually supported on the config target, because we don't check priv->mipmapSupport

This generally results in white windows when mipmapping is enabled. See (LP: #1016364)

== Solution ==

1. Virtual method to generate a mipmap, different for tfp textures as
   mipmap generation has to happen on damage there
2. Always generate mipmaps before setting texture filter
3. Do not check for GL::fbo support when checking fbconfigs for mimap support
4. Use GLTexture::mipmap () to determine if we actually can do mipmaps - this
   checks if the fbconfig supports mipmaps, that the texture is not
   an NV_TEXTURE_RECTANGLE_EXT, checks for fbo support and NPOT texture
   support

== Test ==

None yet, will add autotests when appropriate to do so (eg, after this fix lands or shortly after, since its a higher priority than normal).

Can be verified at least by turning on mipmap support and observing that scaled down windows don't go white.

To post a comment you must log in.
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Corrected bug IDs.

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Mipmaps don't work at all any more!

Try switcher (Alt+Tab) or enable mipmaps in expo. In both cases, mipmaps don't work at all any more using this branch. They do however work using trunk. Tested with intel.

review: Needs Fixing
Revision history for this message
Sam Spilsbury (smspillaz) wrote :

That's suprising, it works fine here (nouveau + nvidia).

I don't think intel ever supported mipmapping on tfp textures. You can check by reading the value of config->mipmap in GLTexture::bindPixmapToTexture.

What might be different is that it maybe doesn't fall back to bilinear filtering when mipmaps are not available. Can you check that in GLTexture::enable ? (I don't have any intel hardware to test on, and won't for another month)

Revision history for this message
Sam Spilsbury (smspillaz) wrote :

Oh weird, it isn't working for me anymore either!

That's very strange, I'll need to give it a closer look, since I know they were working for sure when I wrote this.

Revision history for this message
Sam Spilsbury (smspillaz) wrote :
Download full text (3.3 KiB)

Did some more investigation into this.

It seems like at least on nouveau, mipmap support is not to be found in any of the available fbconfigs:

found fbconfig with mipmap: 0
found fbconfig with mipmap: 0
found fbconfig with mipmap: 0
found fbconfig with mipmap: 0
found fbconfig with mipmap: 0
found fbconfig with mipmap: 0
found fbconfig with mipmap: 0
found fbconfig with mipmap: 0
found fbconfig with mipmap: 0
found fbconfig with mipmap: 0
found fbconfig with mipmap: 0
found fbconfig with mipmap: 0
found fbconfig with mipmap: 0
found fbconfig with mipmap: 0
found fbconfig with mipmap: 0
found fbconfig with mipmap: 0
found fbconfig with mipmap: 0
found fbconfig with mipmap: 0
found fbconfig with mipmap: 0
found fbconfig with mipmap: 0
found fbconfig with mipmap: 0
found fbconfig with mipmap: 0
found fbconfig with mipmap: 0
found fbconfig with mipmap: 0
found fbconfig with mipmap: 0
found fbconfig with mipmap: 0
found fbconfig with mipmap: 0
found fbconfig with mipmap: 0
found fbconfig with mipmap: 0
found fbconfig with mipmap: 0
found fbconfig with mipmap: 0
found fbconfig with mipmap: 0
found fbconfig with mipmap: 0

Here is an inline patch to get a similar kind of output.

=== modified file 'plugins/opengl/src/screen.cpp'
--- plugins/opengl/src/screen.cpp 2012-06-22 04:32:12 +0000
+++ plugins/opengl/src/screen.cpp 2012-06-26 12:09:05 +0000
@@ -523,6 +523,8 @@

      mipmap = value;

+ printf ("found fbconfig with mipmap: %i\n", mipmap);
+
      (*GL::getFBConfigAttrib) (dpy, fbConfigs[j],
           GLX_Y_INVERTED_EXT, &value);

=== modified file 'plugins/opengl/src/texture.cpp'
--- plugins/opengl/src/texture.cpp 2012-06-22 04:32:12 +0000
+++ plugins/opengl/src/texture.cpp 2012-06-26 12:06:09 +0000
@@ -150,6 +150,11 @@
 bool
 GLTexture::mipmap () const
 {
+ printf ("mipmap: %i support: %i npot %i fb %i\n", priv->mipmap,
+ priv->mipmapSupport,
+ GL::textureNonPowerOfTwo,
+ GL::fbo);
+
     return priv->mipmap &&
     priv->mipmapSupport &&
     GL::textureNonPowerOfTwo &&
@@ -202,6 +207,7 @@
  {
      if (mipmap ())
      {
+ printf ("use mipmaps\n");
   generateMipmap ();
   glTexParameteri (priv->target,
      GL_TEXTURE_MIN_FILTER,
@@ -327,6 +333,8 @@
  mipmap = false;
     }

+ printf ("bind regular texture: mipmap support: %i\n", mipmap);
+
     t->setData (target, matrix, mipmap);
     t->setGeometry (0, 0, width, height);

@@ -571,6 +579,8 @@
      return GLTexture::List ();
     }

+ printf ("bind tfp texture: mipmap support: %i fbconfig: %i\n", mipmap, config->mipmap);
+
     tex = new TfpTexture ();
     tex->setData (texTarget, matrix, mipmap);
     tex->setGeometry (0, 0, width, height);

If it also gives you a similar output, then the driver is lying about its support for mipmaps, saying they aren't supported when they are, in which case we will have to add a workaround to the workarounds plugin to force mipmaps even if the driver says it doesn't support them on the glxPixmap fbconfigs.

I don't have time to try it on nvidia right now (the sun is rising :( ), but I am pretty certain it worked there. In any case, we should always check the driver to see if it supports mipmaps, drivers have probably b...

Read more...

Revision history for this message
Sam Spilsbury (smspillaz) wrote :

fbconfigm: 1
fbconfigm: 1
fbconfigm: 1
fbconfigm: 1
fbconfigm: 1
fbconfigm: 1
fbconfigm: 1
fbconfigm: 1
fbconfigm: 1
fbconfigm: 1
fbconfigm: 1
fbconfigm: 1
fbconfigm: 1

Yeah, nvidia says it supports mipmapped glx pixmaps bound to textures.

I call driver bug in mesa. Should we add a workaround, or just leave it disabled where its not supposed to be supported.

Revision history for this message
Sam Spilsbury (smspillaz) wrote :

First is with mipmapping, second is without (nvidia):

http://imgur.com/abbZQ,LS9wu

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Sorry, still broken.

Using trunk I get nice bilinear-filtered mipmaps. Using this branch, I get no mipmaps (and hence no bilinear filtering).

review: Needs Fixing
Revision history for this message
Sam Spilsbury (smspillaz) wrote :

> Sorry, still broken.
>
> Using trunk I get nice bilinear-filtered mipmaps. Using this branch, I get no
> mipmaps (and hence no bilinear filtering).

You actually still get bilinear filtering (or at least should ... I can double check). Note that you don't actually need mipmapping support to get bilinear filtering, you only need it for /trilinear/ filtering (eg GL_LINEAR_MIPMAP_LINEAR).

Like I just explained, there's a driver bug at work here (spoke to RAOF about it yesterday). That leaves us with three options, and I'd like some guidance as to which one to take.

a) Fix mesa to correctly report whether it supports mipmapping on glx pixmap configs (should take me 2-3 days)
b) Add a workaround to force mipmapping even if the driver doesn't say it supports it
c) "revert" the code that detects whether mipmapping is supported correctly and truly break other drivers where mipmapping really isn't supported.
c)

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Add a workaround, methinks.

Revision history for this message
Sam Spilsbury (smspillaz) wrote :

I am moving this to WIP for now. There are several things which we will need to do independently for this to work correctly because of the driver bug in mesa:

1) We need to add a framework to the workarounds plugin to detect which driver you are running and apply workarounds based on that
2) We need to re-use the fbconfig choosing logic to override the core fbconfigs, which means that we need to abstract that code and get it under test
3) As part of 2), we've resolved to move to glXChooseFBConfig to simplify the code, that's another big chunk of work.

review: Needs Resubmitting
Revision history for this message
Sam Spilsbury (smspillaz) wrote :

Resubmit, because its WIP and after our call today, we have far more pressing things.

review: Needs Resubmitting
Revision history for this message
MC Return (mc-return) wrote :

Is this still a valid fix ?

Unmerged revisions

3257. By Sam Spilsbury

Fix broken mipmap support. Mipmap support was broken in the following ways:

1. glGenerateMipmapEXT is called multiple times for tfp textures
2. glGenerateMipmapEXT is called after glTexParameteri with GL_LINEAR_MIPMAP_LINEAR as the filter mode, and sometimes not called at all, which is undefined
3. We check for GL::fbo support before actually setting it from the extension lookup after glXCreateContext is called. As such, when we lookup an optimal pixmap fbconfig, we never find one that supports mipmaps, and it is merely "luck of the draw" as to whether or not we actually get one that does
4. We generate mipmaps for tfp textures even though mipmaps aren't actually supported on the config target, because we don't check priv->mipmapSupport

This generally results in white windows when mipmapping is enabled. See (LP: #1006216)

As such the following measures were implemented:
1. Virtual method to generate a mipmap, different for tfp textures as
   mipmap generation has to happen on damage there
2. Always generate mipmaps before setting texture filter
3. Do not check for GL::fbo support when checking fbconfigs for mimap support
4. Use GLTexture::mipmap () to determine if we actually can do mipmaps - this
   checks if the fbconfig supports mipmaps, that the texture is not
   an NV_TEXTURE_RECTANGLE_EXT, checks for fbo support and NPOT texture
   support

(LP: #1016364)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/opengl/include/opengl/opengl.h'
2--- plugins/opengl/include/opengl/opengl.h 2012-01-20 09:05:56 +0000
3+++ plugins/opengl/include/opengl/opengl.h 2012-06-22 05:27:21 +0000
4@@ -35,7 +35,7 @@
5 #include <opengl/texture.h>
6 #include <opengl/fragment.h>
7
8-#define COMPIZ_OPENGL_ABI 4
9+#define COMPIZ_OPENGL_ABI 5
10
11 #include <core/pluginclasshandler.h>
12
13
14=== modified file 'plugins/opengl/include/opengl/texture.h'
15--- plugins/opengl/include/opengl/texture.h 2012-01-18 16:26:45 +0000
16+++ plugins/opengl/include/opengl/texture.h 2012-06-22 05:27:21 +0000
17@@ -141,6 +141,11 @@
18 virtual void disable ();
19
20 /**
21+ * Generates mipmap levels
22+ */
23+ virtual bool generateMipmap ();
24+
25+ /**
26 * Returns true if this texture is MipMapped
27 */
28 bool mipmap () const;
29
30=== modified file 'plugins/opengl/src/privatetexture.h'
31--- plugins/opengl/src/privatetexture.h 2012-01-18 16:26:45 +0000
32+++ plugins/opengl/src/privatetexture.h 2012-06-22 05:27:21 +0000
33@@ -68,6 +68,7 @@
34 ~TfpTexture ();
35
36 void enable (Filter filter);
37+ bool generateMipmap ();
38
39 static List bindPixmapToTexture (Pixmap pixmap,
40 int width,
41
42=== modified file 'plugins/opengl/src/screen.cpp'
43--- plugins/opengl/src/screen.cpp 2012-04-20 07:35:20 +0000
44+++ plugins/opengl/src/screen.cpp 2012-06-22 05:27:21 +0000
45@@ -515,16 +515,13 @@
46
47 depth = value;
48
49- if (GL::fbo)
50- {
51- (*GL::getFBConfigAttrib) (dpy, fbConfigs[j],
52- GLX_BIND_TO_MIPMAP_TEXTURE_EXT,
53- &value);
54- if (value < mipmap)
55- continue;
56+ (*GL::getFBConfigAttrib) (dpy, fbConfigs[j],
57+ GLX_BIND_TO_MIPMAP_TEXTURE_EXT,
58+ &value);
59+ if (value < mipmap)
60+ continue;
61
62- mipmap = value;
63- }
64+ mipmap = value;
65
66 (*GL::getFBConfigAttrib) (dpy, fbConfigs[j],
67 GLX_Y_INVERTED_EXT, &value);
68@@ -551,6 +548,7 @@
69 "this isn't going to work.");
70 screen->handleCompizEvent ("opengl", "fatal_fallback", o);
71 setFailed ();
72+ return;
73 }
74
75 if (!glInitContext (visinfo))
76
77=== modified file 'plugins/opengl/src/texture.cpp'
78--- plugins/opengl/src/texture.cpp 2012-06-05 09:31:34 +0000
79+++ plugins/opengl/src/texture.cpp 2012-06-22 05:27:21 +0000
80@@ -150,7 +150,10 @@
81 bool
82 GLTexture::mipmap () const
83 {
84- return priv->mipmap & priv->mipmapSupport;
85+ return priv->mipmap &&
86+ priv->mipmapSupport &&
87+ GL::textureNonPowerOfTwo &&
88+ GL::fbo;
89 }
90
91 GLenum
92@@ -159,6 +162,19 @@
93 return priv->filter;
94 }
95
96+bool
97+GLTexture::generateMipmap ()
98+{
99+ if (priv->initial)
100+ {
101+ (*GL::generateMipmap) (priv->target);
102+ priv->initial = false;
103+ return true;
104+ }
105+
106+ return false;
107+}
108+
109 void
110 GLTexture::enable (GLTexture::Filter filter)
111 {
112@@ -184,8 +200,9 @@
113 {
114 if (gs->textureFilter () == GL_LINEAR_MIPMAP_LINEAR)
115 {
116- if (GL::textureNonPowerOfTwo && GL::fbo && priv->mipmap)
117+ if (mipmap ())
118 {
119+ generateMipmap ();
120 glTexParameteri (priv->target,
121 GL_TEXTURE_MIN_FILTER,
122 GL_LINEAR_MIPMAP_LINEAR);
123@@ -221,15 +238,6 @@
124 priv->filter = gs->textureFilter ();
125 }
126 }
127-
128- if (priv->filter == GL_LINEAR_MIPMAP_LINEAR)
129- {
130- if (priv->initial)
131- {
132- (*GL::generateMipmap) (priv->target);
133- priv->initial = false;
134- }
135- }
136 }
137
138 void
139@@ -587,6 +595,20 @@
140 return rv;
141 }
142
143+bool
144+TfpTexture::generateMipmap ()
145+{
146+ if (updateMipMap)
147+ {
148+ (*GL::generateMipmap) (target ());
149+ updateMipMap = false;
150+
151+ return true;
152+ }
153+
154+ return false;
155+}
156+
157 void
158 TfpTexture::enable (GLTexture::Filter filter)
159 {
160@@ -604,10 +626,5 @@
161 if (damaged)
162 updateMipMap = true;
163
164- if (this->filter () == GL_LINEAR_MIPMAP_LINEAR && updateMipMap)
165- {
166- (*GL::generateMipmap) (target ());
167- updateMipMap = false;
168- }
169 damaged = false;
170 }

Subscribers

People subscribed via source and target branches