Lines 34-39
Link Here
|
34 |
#include <stdio.h> |
34 |
#include <stdio.h> |
35 |
#include <xf86drm.h> |
35 |
#include <xf86drm.h> |
36 |
#include <unistd.h> |
36 |
#include <unistd.h> |
|
|
37 |
#include <xcb/dri2.h> |
37 |
|
38 |
|
38 |
#include "loader.h" |
39 |
#include "loader.h" |
39 |
#include "target-helpers/drm_helper_public.h" |
40 |
#include "target-helpers/drm_helper_public.h" |
Lines 151-156
Link Here
|
151 |
}; |
152 |
}; |
152 |
#endif |
153 |
#endif |
153 |
|
154 |
|
|
|
155 |
static void |
156 |
pipe_loader_drm_x_auth(int fd) |
157 |
{ |
158 |
/* Try authenticate with the X server to give us access to devices that X |
159 |
* is running on. */ |
160 |
xcb_connection_t *xcb_conn; |
161 |
const xcb_setup_t *xcb_setup; |
162 |
xcb_screen_iterator_t s; |
163 |
xcb_dri2_connect_cookie_t connect_cookie; |
164 |
xcb_dri2_connect_reply_t *connect; |
165 |
drm_magic_t magic; |
166 |
xcb_dri2_authenticate_cookie_t authenticate_cookie; |
167 |
xcb_dri2_authenticate_reply_t *authenticate; |
168 |
|
169 |
xcb_conn = xcb_connect(NULL, NULL); |
170 |
|
171 |
if(!xcb_conn) |
172 |
return; |
173 |
|
174 |
xcb_setup = xcb_get_setup(xcb_conn); |
175 |
|
176 |
if (!xcb_setup) |
177 |
goto disconnect; |
178 |
|
179 |
s = xcb_setup_roots_iterator(xcb_setup); |
180 |
connect_cookie = xcb_dri2_connect_unchecked(xcb_conn, s.data->root, |
181 |
XCB_DRI2_DRIVER_TYPE_DRI); |
182 |
connect = xcb_dri2_connect_reply(xcb_conn, connect_cookie, NULL); |
183 |
|
184 |
if (!connect || connect->driver_name_length |
185 |
+ connect->device_name_length == 0) { |
186 |
|
187 |
goto disconnect; |
188 |
} |
189 |
|
190 |
if (drmGetMagic(fd, &magic)) |
191 |
goto disconnect; |
192 |
|
193 |
authenticate_cookie = xcb_dri2_authenticate_unchecked(xcb_conn, |
194 |
s.data->root, |
195 |
magic); |
196 |
authenticate = xcb_dri2_authenticate_reply(xcb_conn, |
197 |
authenticate_cookie, |
198 |
NULL); |
199 |
FREE(authenticate); |
200 |
|
201 |
disconnect: |
202 |
xcb_disconnect(xcb_conn); |
203 |
} |
204 |
|
154 |
bool |
205 |
bool |
155 |
pipe_loader_drm_probe_fd(struct pipe_loader_device **dev, int fd) |
206 |
pipe_loader_drm_probe_fd(struct pipe_loader_device **dev, int fd) |
156 |
{ |
207 |
{ |
Lines 159-164
Link Here
|
159 |
|
210 |
|
160 |
if (!ddev) |
211 |
if (!ddev) |
161 |
return false; |
212 |
return false; |
|
|
213 |
pipe_loader_drm_x_auth(fd); |
162 |
|
214 |
|
163 |
if (loader_get_pci_id_for_fd(fd, &vendor_id, &chip_id)) { |
215 |
if (loader_get_pci_id_for_fd(fd, &vendor_id, &chip_id)) { |
164 |
ddev->base.type = PIPE_LOADER_DEVICE_PCI; |
216 |
ddev->base.type = PIPE_LOADER_DEVICE_PCI; |
Lines 209-214
Link Here
|
209 |
} |
261 |
} |
210 |
|
262 |
|
211 |
static int |
263 |
static int |
|
|
264 |
open_drm_minor(int minor) |
265 |
{ |
266 |
char path[PATH_MAX]; |
267 |
snprintf(path, sizeof(path), DRM_DEV_NAME, DRM_DIR_NAME, minor); |
268 |
return open(path, O_RDWR, 0); |
269 |
} |
270 |
|
271 |
static int |
212 |
open_drm_render_node_minor(int minor) |
272 |
open_drm_render_node_minor(int minor) |
213 |
{ |
273 |
{ |
214 |
char path[PATH_MAX]; |
274 |
char path[PATH_MAX]; |
Lines 220-227
Link Here
|
220 |
int |
280 |
int |
221 |
pipe_loader_drm_probe(struct pipe_loader_device **devs, int ndev) |
281 |
pipe_loader_drm_probe(struct pipe_loader_device **devs, int ndev) |
222 |
{ |
282 |
{ |
223 |
int i, j, fd; |
283 |
int i, k, fd, num_render_node_devs; |
|
|
284 |
int j = 0; |
224 |
|
285 |
|
|
|
286 |
struct { |
287 |
unsigned vendor_id; |
288 |
unsigned chip_id; |
289 |
} render_node_devs[DRM_RENDER_NODE_MAX_NODES]; |
290 |
|
291 |
/* Look for render nodes first */ |
225 |
for (i = DRM_RENDER_NODE_MIN_MINOR, j = 0; |
292 |
for (i = DRM_RENDER_NODE_MIN_MINOR, j = 0; |
226 |
i <= DRM_RENDER_NODE_MAX_MINOR; i++) { |
293 |
i <= DRM_RENDER_NODE_MAX_MINOR; i++) { |
227 |
struct pipe_loader_device *dev; |
294 |
struct pipe_loader_device *dev; |
Lines 235-240
Link Here
|
235 |
continue; |
302 |
continue; |
236 |
} |
303 |
} |
237 |
|
304 |
|
|
|
305 |
render_node_devs[j].vendor_id = dev->u.pci.vendor_id; |
306 |
render_node_devs[j].chip_id = dev->u.pci.chip_id; |
307 |
|
238 |
if (j < ndev) { |
308 |
if (j < ndev) { |
239 |
devs[j] = dev; |
309 |
devs[j] = dev; |
240 |
} else { |
310 |
} else { |
Lines 244-249
Link Here
|
244 |
j++; |
314 |
j++; |
245 |
} |
315 |
} |
246 |
|
316 |
|
|
|
317 |
num_render_node_devs = j; |
318 |
|
319 |
/* Next look for drm devices. */ |
320 |
for (i = 0; i < DRM_MAX_MINOR; i++) { |
321 |
struct pipe_loader_device *dev; |
322 |
boolean duplicate = FALSE; |
323 |
fd = open_drm_minor(i); |
324 |
if (fd < 0) |
325 |
continue; |
326 |
|
327 |
if (!pipe_loader_drm_probe_fd(&dev, fd)) { |
328 |
close(fd); |
329 |
continue; |
330 |
} |
331 |
|
332 |
/* Check to make sure we aren't already accessing this device via |
333 |
* render nodes. |
334 |
*/ |
335 |
for (k = 0; k < num_render_node_devs; k++) { |
336 |
if (dev->u.pci.vendor_id == render_node_devs[k].vendor_id && |
337 |
dev->u.pci.chip_id == render_node_devs[k].chip_id) { |
338 |
close(fd); |
339 |
dev->ops->release(&dev); |
340 |
duplicate = TRUE; |
341 |
break; |
342 |
} |
343 |
} |
344 |
|
345 |
if (duplicate) |
346 |
continue; |
347 |
|
348 |
if (j < ndev) { |
349 |
devs[j] = dev; |
350 |
} else { |
351 |
dev->ops->release(&dev); |
352 |
} |
353 |
|
354 |
j++; |
355 |
} |
356 |
|
247 |
return j; |
357 |
return j; |
248 |
} |
358 |
} |
249 |
|
359 |
|