July 16 progess for David Shao GSoC 2010
[ikiwiki.git] / docs / developer / GEMdrmKMS / index.mdwn
1 # Port of GEM and KMS
2
3 A [Google Summer of Code 2010](http://socghop.appspot.com/gsoc/program/list_projects/google/gsoc2010) project.
4
5 Student: David Shao
6
7 Mentor: Matthew Dillon
8
9 ## Introduction
10
11 We port to the BSDs modern graphics card drivers that have already or are in the process of being written for Linux.  Fortunately for the BSDs the source code that is the basis of these drivers, userland hosted in git repositories accessible from [freedesktop.org](http://cgit.freedesktop.org/), and even the part that is now residing in the Linux kernel, is mostly licensed under terms compatible with the [MIT X License](http://www.opensource.org/licenses/mit-license.php), and therefore can be directly ported to the BSDs
12 without licensing issues.
13
14 When we refer to DRM, we are referring to the [Direct Render Manager](http://dri.freedesktop.org/wiki/DRM) that is a kernel module arbitrating requests for various graphics related services.  Because of this acronym, the source code for DragonFly's DRM module can be found in directory **sys/dev/drm**, while the source code for Linux'd DRM module has been split into **include/drm** hosting common header files and **drivers/gpu/drm**.  Furthermore the Linux files have had vendor specific code split off into their own separate directories, a change the BSDs should consider since having all files in one directory is becoming rather unwieldy.
15
16 We feel the fastest path to porting is through the DragonFly BSD project, but we intend for our code to be the basis for
17 ports to all the BSDs.
18
19 ## Acknowledgment to the FreeBSD Project
20
21 We must acknowledge the hard work that previous porters of DRM such as Robert Noland of the FreeBSD project have already
22 accomplished in translating much of earlier DRM to BSD kernel semantics.  Simply take a diff of the FreeBSD and DragonFlyBSD
23 versions of DRM and one can readily see that the hard work of translating the semantics of the locking for the Linux drivers
24 has mostly been done, and better still can be done almost automatically.  Furthermore the FreeBSD port has translated calls
25 to manipulating hardware devices such as for AGP.
26
27 ## Goal
28
29 We intend to write a portability layer that will allow the BSDs to use as much of the Linux drm code as possible.
30 The developers of X.org / freedesktop.org related graphics drivers have their current efforts focused on Linux
31 because they have to get something working anywhere as fast as possible.  It is the BSDs responsibility to keep
32 up with these efforts and to contribute back to these developers to justify the developers continuing
33 to generously license their drm code under terms compatible with those of the BSD licenses.
34
35 It is especially vital for Linux drm GEM, TTM, KMS code to be ported immediately to the BSDs because developers
36 are in the process of removing userland modesetting code from current graphics drivers.  To paraphrase what
37 we have been told by freedesktop.org developers, if we do not port this code, very shortly the BSDs will be
38 left only using the simplest VESA driver at 1024 x 768 resolution with no hardware acceleration.
39
40 We believe that limiting divergence from Linux's drm code is the clearest path for the BSDs to be able
41 to follow the latest drm developments.
42
43 ## Disclaimer
44
45 Code that is uploaded to the experimental git branches has been verified to work for at most
46 two graphics cards only, both Radeon-compatible cards.  It is highly likely that systems exist
47 where replacing kernel code using the experimental git branches will leave one's system unable
48 to use software based on X.org.  In particular nothing is known about systems with graphics
49 hardware from other vendors such as Intel or Nvidia.
50
51 We have experienced from ill-fated experiments forced rebooting with corruption of a ufs2 root filesystem;
52 therefore, the same could well happen to you.  Only use this code on a system with no valuable or
53 irreplaceable data.  We disclaim any warranty or fitness of code.
54
55 ## Test Machines
56
57 Our test machines both use Radeon-compatible graphics hardware: an
58 older Radeon 9200-compatible card (r200) on an Asus P4B266 32-bit i386
59 machine and a Radeon HD 4550 (r600) on a Shuttle SG45H7 64-bit x86_64 machine.
60
61 We develop on the x86_64 machine then push our changes to the git experimental branch
62 **gsocdrmalpha** at
63
64 git://leaf.dragonflybsd.org/~davshao/dragonfly.git
65
66 We then pull the changes to the i386 machine to test build and compatibility.
67
68
69 ### Sample **dmesg* output
70
71 The software used for graphics whether the kernel or userland Mesa is surprisingly resilient.  As long as it compiles it will try and find a way with dealing with other mismatched components by falling back on default behavior.  Working on a fast x86_64 machine, it is easy to be lulled into a false sense that things are working properly unless one checks the logs.
72
73 Here the proper kernel module appears to be loaded for the x86_64 machine.  We have on previous occasions not realized an error that led to the kernel module not being loaded at all that appeared from the messages to be a device non-existence problem.
74
75     drm0: <ATI Radeon HD 4550> on vgapci0
76     vgapci0: child drm0 requested pci_enable_busmaster
77     info: [drm] Initialized radeon 1.31.0 20080613
78     info: [drm] Setting GART location based on new memory map
79     info: [drm] Loading RV710 Microcode
80     info: [drm] Resetting GPU
81     info: [drm] writeback test succeeded in 1 usecs
82
83 Similarly for the Radeon 9200-compatible i386 machine:
84
85     drm0: <ATI Radeon If RV250 9000> on vgapci0
86     vgapci0: child drm0 requested pci_enable_busmaster
87     info::[drm] AGP at 0xf8000000 64MB
88     info::[drm] Initialized radeon 1.31.0 20080613
89     info::[drm] Setting GART location based on new memory map
90     info::[drm] Loading R200 Microcode
91     info::[drm] writeback test succeeded in 1 usecs
92
93 ### **var/log/Xorg.0.log** output
94
95 Somewhere on one's system are the logs of the latest startup of the X server and the modules it finds.  There can be an alternate place if one installs a second X.org, say at */opt/xtest*, in which case instead of **/var/log/Xorg.0.log** one will look in **/opt/xtest/var/log/Xorg.0.log**.
96
97 Here's a case of a failure on the fast x86_64 machine where things appeared to be fine: we were composing this wiki from within Firefox 3.6.3 on a system where the proper module failed to load and yet where because of the machine's speed there was no discernible problem for this application.
98
99     drmOpenDevice: node name is /dev/dri/card0
100     drmOpenDevice: open result is 10, (OK)
101     drmOpenByBusid: Searching for BusID pci:0000:01:00.0
102     drmOpenDevice: node name is /dev/dri/card0
103     drmOpenDevice: open result is 10, (OK)
104     drmOpenByBusid: drmOpenMinor returns 10
105     drmOpenByBusid: drmGetBusid reports pci:0000:01:00.0
106     (EE) AIGLX error: dlopen of /usr/pkg/lib/dri/r600_dri.so failed (Cannot open "/usr/pkg/lib/dri/r600_dri.so")
107     (EE) AIGLX: reverting to software rendering
108     (II) AIGLX: Loaded and initialized /usr/pkg/lib/dri/swrast_dri.so
109
110 The Mesa 7.4.x series simply does not *have* a r600_drv.so driver so of course it can't be found.  Mesa happily falls back to using software rendering and nothing seems greatly wrong.
111
112 Now here is an example using latest Mesa and everything else from git on the x86_64 machine where the driver is found on the x86_64 machine:
113
114     [    95.404] drmOpenDevice: node name is /dev/dri/card0
115     [    95.405] drmOpenDevice: open result is 11, (OK)
116     [    95.405] drmOpenByBusid: Searching for BusID pci:0000:01:00.0
117     [    95.405] drmOpenDevice: node name is /dev/dri/card0
118     [    95.405] drmOpenDevice: open result is 11, (OK)
119     [    95.405] drmOpenByBusid: drmOpenMinor returns 11
120     [    95.405] drmOpenByBusid: drmGetBusid reports pci:0000:01:00.0
121     [    95.507] (II) AIGLX: enabled GLX_MESA_copy_sub_buffer
122     [    95.507] (II) AIGLX: enabled GLX_SGI_make_current_read
123     [    95.507] (II) AIGLX: enabled GLX_texture_from_pixmap with driver support
124     [    95.507] (II) AIGLX: Loaded and initialized /opt/xtest/lib/dri/r600_dri.so
125     [    95.507] (II) GLX: Initialized DRI GL provider for screen 0
126     [    95.508] (II) RADEON(0): Setting screen physical size to 508 x 285
127
128 Pkgsrc on the i386 r200 machine does have a supporting driver; therefore, we obtain from its log:
129
130     drmOpenDevice: node name is /dev/dri/card0
131     drmOpenDevice: open result is 10, (OK)
132     drmOpenByBusid: Searching for BusID pci:0000:01:00.0
133     drmOpenDevice: node name is /dev/dri/card0
134     drmOpenDevice: open result is 10, (OK)
135     drmOpenByBusid: drmOpenMinor returns 10
136     drmOpenByBusid: drmGetBusid reports pci:0000:01:00.0
137     (II) AIGLX: enabled GLX_MESA_copy_sub_buffer
138     (II) AIGLX: enabled GLX_SGI_make_current_read
139     (II) AIGLX: enabled GLX_SGI_swap_control and GLX_MESA_swap_control
140     (II) AIGLX: enabled GLX_texture_from_pixmap with driver support
141     (II) AIGLX: Loaded and initialized /usr/pkg/lib/dri/r200_dri.so
142     (II) GLX: Initialized DRI GL provider for screen 0
143     (II) RADEON(0): Setting screen physical size to 510 x 290
144
145 Ironically we knew we were on the right track porting the latest git versions of the X.org stack when we succeeded in locking up hard our machine.  That meant a real hardware acceleration module was being loaded that the previous kernel could not handle, which was why the latest drm from FreeBSD had to be imported.
146
147
148 ## Status
149
150 The latest drm code from FreeBSD 9.x current has been successfully ported to DragonFly BSD, [patch](http://leaf.dragonflybsd.org/~davshao/r600fbsd.diff) and git branch **r600fbsd** git://leaf.dragonflybsd.org/~davshao/dragonfly.git, and tested with a Radeon HD 4550 on an x86_64 machine (Shuttle SG45H7).  However it must be remembered that testing has only been done with this one graphics card and it is completely unknown whether say an Intel machine will lock up solid.  Also nothing was done to port the extensive Via drivers FreeBSD has already ported.
151
152 ## Current Progress for Google Summer of Code 2010
153
154 Current work on porting the Linux drm to DragonFly BSD can be found in
155 git branch **gsocdrmalpha** git://leaf.dragonflybsd.org/~davshao/dragonfly.git
156
157 As of Friday, July 16, 2010, weeks of work have brought us to where many good things are on the cusp of happening.
158
159 ### Data structures for minors and masters ported
160
161 Linux drm has data structures for representing different devices, say */dev/dri/card0*, which are analogous to device minors,
162 and for representing a current master process that has authentication for using such a device.  These data structures
163 have now been ported to the latest DragonFly BSD port of drm.  The minors allow the possibility of eventually using
164 dual-headed cards, and also there is a concept of a legacy minor and a control minor.  However, Linux has code for
165 what it calls the VGA arbiter for which the BSDs may not have an equivalent.
166
167 ### Locking porting almost done
168
169 The legacy BSD code was using an equivalent of one global lock for a drm device and the Linux code had
170 moved on to use many more locks, as well as using a different global lock for a drm device.  The bulk of
171 porting time has been spent carefully changing locking to fit the Linux model while having all machines
172 continue to function, a process of locking up a test machine and then figuring how to fix the lockup.
173 As of July 16, we are very close to basically using the Linux drm locks, translated in DragonFly BSD terms
174 simply using *lockmgr*.  We are well aware that on DragonFly BSD in particular there are much better
175 alternatives, but we are for now using a lowest common denominator just to get things working in some
176 fashion.
177
178 The combination of porting the minor/master data structures and the Linux drm locking means that 
179 DragonFly BSD is very close to speaking the same language as Linux drm.
180
181 ## Next steps
182
183 ### Equivalent of *struct page*
184
185 Every operating system will have an abstraction for virtual memory pages that can have a variety of
186 mappings, but Linux's appears to have a concept allowing mapping more than the virtual memory space allocated
187 in the upper half of virtual memory on 32-bit machines, about 1 GB.  We are investigating what will be
188 the best translation to DragonFly BSD--if worse comes to worse perhaps only cards of lower graphics memory
189 capacity can be supported.
190
191 ### i2c support for user modesetting
192
193 Thanks to fellow DragonFly BSD developers the i2c bus API has been updated to reflect later work from
194 FreeBSD.  We anticipate being able to map the Linux drm i2c callbacks directly to this API.
195  
196