1GLX Framebuffer Compatibility investigation
2===========================================
3
4In GLX and EGL, contexts are created with respect to a config that
5describes the type of surfaces they will be used to render to.
6Likewise surfaces are created with respect to a config and for
7a context to be able to render to a surface, both their configs
8must be compatible. Compatibility is losely described in both
9the GLX and EGL specs but the following is clear:
10 * In GLX the config's color buffer must have the same type, including
11RGBA vs. ColorIndex and the buffers must have the same depth, if they
12exist.
13 * In EGL the config's color buffer must have the same type and the
14buffers must have the same depth (not clear if it is only if they exist)
15
16Obviously the EGLconfig we will expose will have a one-to-one
17correspondance with GLXFBConfigs.
18
19Our EGL implementation uses a single OpenGL context to back all
20the EGLcontexts created by the application. Since our GL context
21and GLXContext are the same object but in two APIs, we will make
22the confusion and call the GLX context our backing context.
23
24The problem we have is that the the GLX context is created before
25the application can choose what type of context it wants to use,
26that means we have to expose EGLconfigs whose respective GLXFBConfigs
27are compatible with the GLXFBConfig of our GLX context; we also need
28to choose the GLXFBConfig of our GLX context so that it matches the
29most common needs of application.
30
31Choice of the GLX context GLXFBConfig
32-------------------------------------
33
34We decided that our GLX context's configuration must satisfy the following:
35 * Have a RGBA8 color buffer and D24S8 depth-stencil buffer which is what
36the vast majority of applications use.
37 * It must render in direct colors, i.e. not in a color indexed format.
38 * It must be double-buffered (see later)
39 * It must support rendering to all the types of GLX surfaces so that we can
40use it for all types of EGL surfaces
41 * It must have an associated visual ID so that we can use it with X, it seems
42like this would be strongly tied to it having the ```WINDOW_BIT``` set.
43 * We would like a conformant context.
44
45Study of compatible GLXFBConfigs
46--------------------------------
47
48When using the condition of compatibility defined in the GLX spec and filtering
49out the non-conformant GLXFBConfig we got the following list (see function
50```print_visual_attribs_short``` in [glxinfo's source code](http://cgit.freedesktop.org/mesa/demos/tree/src/xdemos/glxinfo.c)
51to understand how to read the table):
52
53```
54    visual  x   bf lv rg d st  colorbuffer  sr ax dp st accumbuffer  ms  cav
55  id dep cl sp  sz l  ci b ro  r  g  b  a F gb bf th cl  r  g  b  a ns b eat  Result
56----------------------------------------------------------------------------
570x02e 24 tc  0  32  0 r  . .   8  8  8  8 .  s  4  0  0 16 16 16 16  0 0 None Fail
580x0e4 32 tc  0  32  0 r  . .   8  8  8  8 .  s  4  0  0 16 16 16 16  0 0 None BadMatch
590x02c 24 tc  0  32  0 r  y .   8  8  8  8 .  s  4  0  0 16 16 16 16  0 0 None Pass
600x0e2 32 tc  0  32  0 r  y .   8  8  8  8 .  s  4  0  0 16 16 16 16  0 0 None BadMatch
610x089 24 dc  0  32  0 r  . .   8  8  8  8 .  s  4  0  0 16 16 16 16  0 0 None Fail
620x087 24 dc  0  32  0 r  y .   8  8  8  8 .  s  4  0  0 16 16 16 16  0 0 None Pass
630x026 24 tc  0  32  0 r  . .   8  8  8  8 .  s  4 24  8 16 16 16 16  0 0 None Fail
640x0dc 32 tc  0  32  0 r  . .   8  8  8  8 .  s  4 24  8 16 16 16 16  0 0 None BadMatch
650x024 24 tc  0  32  0 r  y .   8  8  8  8 .  s  4 24  8 16 16 16 16  0 0 None Pass
660x0da 32 tc  0  32  0 r  y .   8  8  8  8 .  s  4 24  8 16 16 16 16  0 0 None BadMatch
670x081 24 dc  0  32  0 r  . .   8  8  8  8 .  s  4 24  8 16 16 16 16  0 0 None Fail
680x07f 24 dc  0  32  0 r  y .   8  8  8  8 .  s  4 24  8 16 16 16 16  0 0 None Pass
69```
70
71The last column shows the result of trying to render on a window using the config,
72with a GLX context using config 0x024. The first thing we see is that BadMatch is
73thrown by the X server when creating the subwindow for rendering. This was because
74we didn't set the border pixel of the subwindow *shake fist at X11* (see this [StackOverflow question](http://stackoverflow.com/questions/3645632/how-to-create-a-window-with-a-bit-depth-of-32)).
75The result updated with this fix give:
76
77```
78    visual  x   bf lv rg d st  colorbuffer  sr ax dp st accumbuffer  ms  cav
79  id dep cl sp  sz l  ci b ro  r  g  b  a F gb bf th cl  r  g  b  a ns b eat
80----------------------------------------------------------------------------
810x02e 24 tc  0  32  0 r  . .   8  8  8  8 .  s  4  0  0 16 16 16 16  0 0 None Fail
820x0e4 32 tc  0  32  0 r  . .   8  8  8  8 .  s  4  0  0 16 16 16 16  0 0 None Fail
830x02c 24 tc  0  32  0 r  y .   8  8  8  8 .  s  4  0  0 16 16 16 16  0 0 None Pass
840x0e2 32 tc  0  32  0 r  y .   8  8  8  8 .  s  4  0  0 16 16 16 16  0 0 None Pass
850x089 24 dc  0  32  0 r  . .   8  8  8  8 .  s  4  0  0 16 16 16 16  0 0 None Fail
860x087 24 dc  0  32  0 r  y .   8  8  8  8 .  s  4  0  0 16 16 16 16  0 0 None Pass
870x026 24 tc  0  32  0 r  . .   8  8  8  8 .  s  4 24  8 16 16 16 16  0 0 None Fail
880x0dc 32 tc  0  32  0 r  . .   8  8  8  8 .  s  4 24  8 16 16 16 16  0 0 None Fail
890x024 24 tc  0  32  0 r  y .   8  8  8  8 .  s  4 24  8 16 16 16 16  0 0 None Pass
900x0da 32 tc  0  32  0 r  y .   8  8  8  8 .  s  4 24  8 16 16 16 16  0 0 None Pass
910x081 24 dc  0  32  0 r  . .   8  8  8  8 .  s  4 24  8 16 16 16 16  0 0 None Fail
920x07f 24 dc  0  32  0 r  y .   8  8  8  8 .  s  4 24  8 16 16 16 16  0 0 None Pass
93```
94
95From this we see that our rendering test passed if and only if the config was double
96buffered like 0x024 which is our GLX context config. The compatible configs are then:
97
98```
99    visual  x   bf lv rg d st  colorbuffer  sr ax dp st accumbuffer  ms  cav
100  id dep cl sp  sz l  ci b ro  r  g  b  a F gb bf th cl  r  g  b  a ns b eat
101----------------------------------------------------------------------------
1020x02c 24 tc  0  32  0 r  y .   8  8  8  8 .  s  4  0  0 16 16 16 16  0 0 None
1030x0e2 32 tc  0  32  0 r  y .   8  8  8  8 .  s  4  0  0 16 16 16 16  0 0 None
1040x087 24 dc  0  32  0 r  y .   8  8  8  8 .  s  4  0  0 16 16 16 16  0 0 None
1050x024 24 tc  0  32  0 r  y .   8  8  8  8 .  s  4 24  8 16 16 16 16  0 0 None
1060x0da 32 tc  0  32  0 r  y .   8  8  8  8 .  s  4 24  8 16 16 16 16  0 0 None
1070x07f 24 dc  0  32  0 r  y .   8  8  8  8 .  s  4 24  8 16 16 16 16  0 0 None
108```
109
110We can see two dimensions, with our without a depth-stencil buffer and with TrueColor
111or DirectColor. The depth-stencil will be useful to expose to application.
112
113More on double buffering
114------------------------
115The tests above show that double-buffered contexts are not compatible with single-
116buffered surfaces; however other tests show that single-buffered contexts are
117compatible with both single and double-buffered surfaces. The problem is that in
118that case, we can see some flickering even with double-buffered surfaces. If we
119can find a trick to avoid that flicker, then we would be able to expose single
120and double-buffered surfaces at the EGL level. Not exposing them isn't too much
121of a problem though as the vast majority of application want double-buffering.
122
123AMD and extra buffers
124---------------------
125As can be seen above, NVIDIA does not expose conformant context with multisampled
126buffers or non RGBA16 accumulation buffers. The behavior is different on AMD that
127exposes them as conformant, which gives the following list after filtering as
128explained above:
129
130```
131    visual  x   bf lv rg d st  colorbuffer  sr ax dp st accumbuffer  ms  cav
132  id dep cl sp  sz l  ci b ro  r  g  b  a F gb bf th cl  r  g  b  a ns b eat
133----------------------------------------------------------------------------
1340x023 24 tc  0  32  0 r  y .   8  8  8  8 .  .  0 24  8 16 16 16 16  0 0 None
1350x027 24 tc  0  32  0 r  y .   8  8  8  8 .  .  0 24  8  0  0  0  0  0 0 None
1360x02b 24 tc  0  32  0 r  y .   8  8  8  8 .  .  0 24  8  0  0  0  0  2 1 None
1370x02f 24 tc  0  32  0 r  y .   8  8  8  8 .  .  0 24  8  0  0  0  0  4 1 None
1380x03b 24 dc  0  32  0 r  y .   8  8  8  8 .  .  0 24  8 16 16 16 16  0 0 None
1390x03f 24 dc  0  32  0 r  y .   8  8  8  8 .  .  0 24  8  0  0  0  0  0 0 None
1400x043 24 dc  0  32  0 r  y .   8  8  8  8 .  .  0 24  8  0  0  0  0  2 1 None
1410x047 24 dc  0  32  0 r  y .   8  8  8  8 .  .  0 24  8  0  0  0  0  4 1 None
142```
143
144ANGLE's context is created using 0x027 and experimentation shows it is only compatible
145with 0x03f which is the only other config lacking both an accumulation buffer and a
146multisample buffer. The GLX spec seems to hint it should still work ("should have the
147same size, if they exist") but it doesn't work in this case. Filtering the configs to
148have the same multisample and accumulation buffers gives the following:
149
150```
151    visual  x   bf lv rg d st  colorbuffer  sr ax dp st accumbuffer  ms  cav
152  id dep cl sp  sz l  ci b ro  r  g  b  a F gb bf th cl  r  g  b  a ns b eat
153----------------------------------------------------------------------------
1540x027 24 tc  0  32  0 r  y .   8  8  8  8 .  .  0 24  8  0  0  0  0  0 0 None
1550x03f 24 dc  0  32  0 r  y .   8  8  8  8 .  .  0 24  8  0  0  0  0  0 0 None
156```
157
158Mesa Intel driver
159-----------------
160In GLX, a criterium for context and surface compatibility is that buffers
161should have the same depth, if they exist at all in the surface. This means
162that it should be possible to make a context with a D24S8 depth-stencil
163buffer to a surface without a depth-stencil buffer. This doesn't work on the
164Mesa Intel driver. The list before the workaround was the following, with
1650x020 being the fbconfig chosen for the context:
166
167```
168    visual  x   bf lv rg d st  colorbuffer  sr ax dp st accumbuffer  ms  cav
169  id dep cl sp  sz l  ci b ro  r  g  b  a F gb bf th cl  r  g  b  a ns b eat
170----------------------------------------------------------------------------
1710x020 24 tc  0  32  0 r  y .   8  8  8  8 .  .  0 24  8  0  0  0  0  0 0 None
1720x021 24 dc  0  32  0 r  y .   8  8  8  8 .  .  0 24  8  0  0  0  0  0 0 None
1730x08f 32 tc  0  32  0 r  y .   8  8  8  8 .  .  0 24  8  0  0  0  0  0 0 None
1740x0d0 24 tc  0  32  0 r  y .   8  8  8  8 .  .  0  0  0  0  0  0  0  0 0 None
1750x0e2 24 dc  0  32  0 r  y .   8  8  8  8 .  .  0  0  0  0  0  0  0  0 0 None
1760x0e9 24 dc  0  32  0 r  y .   8  8  8  8 .  .  0 24  8  0  0  0  0  0 0 None
177```
178
179After the workaround that list becomes the following:
180
181```
182    visual  x   bf lv rg d st  colorbuffer  sr ax dp st accumbuffer  ms  cav
183  id dep cl sp  sz l  ci b ro  r  g  b  a F gb bf th cl  r  g  b  a ns b eat
184----------------------------------------------------------------------------
1850x020 24 tc  0  32  0 r  y .   8  8  8  8 .  .  0 24  8  0  0  0  0  0 0 None
1860x021 24 dc  0  32  0 r  y .   8  8  8  8 .  .  0 24  8  0  0  0  0  0 0 None
1870x08f 32 tc  0  32  0 r  y .   8  8  8  8 .  .  0 24  8  0  0  0  0  0 0 None
1880x0e9 24 dc  0  32  0 r  y .   8  8  8  8 .  .  0 24  8  0  0  0  0  0 0 None
189```
190
191Future investigation
192--------------------
193All the non-conformant configs have a multisampled buffer, so it could be interesting
194to see if we can use them to expose another EGL extension.
195
196Finally this document is written with respect to a small number of drivers, before
197using the GLX EGL implementation in the wild it would be good to test it on other
198drivers and hardware.
199
200The drivers tested were:
201
202 - the proprietary NVIDIA driver
203 - the proprietary AMD driver
204 - the open source Intel (Broadwell) Mesa driver
205