2 #include "pipe/p_context.h"
3 #include "pipe/p_state.h"
4 #include "util/u_format.h"
5 #include "util/u_memory.h"
6 #include "util/u_inlines.h"
7 #include "util/u_hash_table.h"
8 #include "os/os_thread.h"
10 #include "nouveau_drm_public.h"
12 #include "nouveau/nouveau_winsys.h"
13 #include "nouveau/nouveau_screen.h"
15 static struct util_hash_table
*fd_tab
= NULL
;
17 pipe_static_mutex(nouveau_screen_mutex
);
19 boolean
nouveau_drm_screen_unref(struct nouveau_screen
*screen
)
22 if (screen
->refcount
== -1)
25 pipe_mutex_lock(nouveau_screen_mutex
);
26 ret
= --screen
->refcount
;
29 util_hash_table_remove(fd_tab
, intptr_to_pointer(screen
->device
->fd
));
30 pipe_mutex_unlock(nouveau_screen_mutex
);
34 static unsigned hash_fd(void *key
)
36 int fd
= pointer_to_intptr(key
);
40 return stat
.st_dev
^ stat
.st_ino
^ stat
.st_rdev
;
43 static int compare_fd(void *key1
, void *key2
)
45 int fd1
= pointer_to_intptr(key1
);
46 int fd2
= pointer_to_intptr(key2
);
47 struct stat stat1
, stat2
;
51 return stat1
.st_dev
!= stat2
.st_dev
||
52 stat1
.st_ino
!= stat2
.st_ino
||
53 stat1
.st_rdev
!= stat2
.st_rdev
;
56 PUBLIC
struct pipe_screen
*
57 nouveau_drm_screen_create(int fd
)
59 struct nouveau_device
*dev
= NULL
;
60 struct pipe_screen
*(*init
)(struct nouveau_device
*);
61 struct nouveau_screen
*screen
;
64 pipe_mutex_lock(nouveau_screen_mutex
);
66 fd_tab
= util_hash_table_create(hash_fd
, compare_fd
);
71 screen
= util_hash_table_get(fd_tab
, intptr_to_pointer(fd
));
74 pipe_mutex_unlock(nouveau_screen_mutex
);
78 ret
= nouveau_device_wrap(fd
, 0, &dev
);
82 switch (dev
->chipset
& ~0xf) {
86 init
= nv30_screen_create
;
92 init
= nv50_screen_create
;
100 init
= nvc0_screen_create
;
103 debug_printf("%s: unknown chipset nv%02x\n", __func__
,
108 screen
= (struct nouveau_screen
*)init(dev
);
112 util_hash_table_set(fd_tab
, intptr_to_pointer(fd
), screen
);
113 screen
->refcount
= 1;
114 pipe_mutex_unlock(nouveau_screen_mutex
);
115 return &screen
->base
;
118 pipe_mutex_unlock(nouveau_screen_mutex
);