util: don't include p_defines.h and u_pointer.h from gallium
[mesa.git] / src / gallium / winsys / etnaviv / drm / etnaviv_drm_winsys.c
1 /*
2 * Copyright (c) 2015 Etnaviv Project
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sub license,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the
12 * next paragraph) shall be included in all copies or substantial portions
13 * of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 *
23 * Authors:
24 * Christian Gmeiner <christian.gmeiner@gmail.com>
25 */
26
27 #include <sys/stat.h>
28
29 #include "util/u_hash_table.h"
30 #include "util/u_memory.h"
31 #include "util/u_pointer.h"
32
33 #include "etnaviv/etnaviv_screen.h"
34 #include "etnaviv/hw/common.xml.h"
35 #include "etnaviv_drm_public.h"
36
37 #include <stdio.h>
38
39 static struct pipe_screen *
40 screen_create(struct renderonly *ro)
41 {
42 struct etna_device *dev;
43 struct etna_gpu *gpu;
44 uint64_t val;
45 int i;
46
47 dev = etna_device_new_dup(ro->gpu_fd);
48 if (!dev) {
49 fprintf(stderr, "Error creating device\n");
50 return NULL;
51 }
52
53 for (i = 0;; i++) {
54 gpu = etna_gpu_new(dev, i);
55 if (!gpu) {
56 fprintf(stderr, "Error creating gpu\n");
57 return NULL;
58 }
59
60 /* Look for a 3D capable GPU */
61 int ret = etna_gpu_get_param(gpu, ETNA_GPU_FEATURES_0, &val);
62 if (ret == 0 && (val & chipFeatures_PIPE_3D))
63 break;
64
65 etna_gpu_del(gpu);
66 }
67
68 return etna_screen_create(dev, gpu, ro);
69 }
70
71 static struct hash_table *etna_tab = NULL;
72
73 static mtx_t etna_screen_mutex = _MTX_INITIALIZER_NP;
74
75 static void
76 etna_drm_screen_destroy(struct pipe_screen *pscreen)
77 {
78 struct etna_screen *screen = etna_screen(pscreen);
79 boolean destroy;
80
81 mtx_lock(&etna_screen_mutex);
82 destroy = --screen->refcnt == 0;
83 if (destroy) {
84 int fd = etna_device_fd(screen->dev);
85 _mesa_hash_table_remove_key(etna_tab, intptr_to_pointer(fd));
86 }
87 mtx_unlock(&etna_screen_mutex);
88
89 if (destroy) {
90 pscreen->destroy = screen->winsys_priv;
91 pscreen->destroy(pscreen);
92 }
93 }
94
95 struct pipe_screen *
96 etna_drm_screen_create_renderonly(struct renderonly *ro)
97 {
98 struct pipe_screen *pscreen = NULL;
99
100 mtx_lock(&etna_screen_mutex);
101 if (!etna_tab) {
102 etna_tab = util_hash_table_create_fd_keys();
103 if (!etna_tab)
104 goto unlock;
105 }
106
107 pscreen = util_hash_table_get(etna_tab, intptr_to_pointer(ro->gpu_fd));
108 if (pscreen) {
109 etna_screen(pscreen)->refcnt++;
110 } else {
111 pscreen = screen_create(ro);
112 if (pscreen) {
113 int fd = etna_device_fd(etna_screen(pscreen)->dev);
114 _mesa_hash_table_insert(etna_tab, intptr_to_pointer(fd), pscreen);
115
116 /* Bit of a hack, to avoid circular linkage dependency,
117 * ie. pipe driver having to call in to winsys, we
118 * override the pipe drivers screen->destroy() */
119 etna_screen(pscreen)->winsys_priv = pscreen->destroy;
120 pscreen->destroy = etna_drm_screen_destroy;
121 }
122 }
123
124 unlock:
125 mtx_unlock(&etna_screen_mutex);
126 return pscreen;
127 }
128
129 struct pipe_screen *
130 etna_drm_screen_create(int fd)
131 {
132 struct renderonly ro = {
133 .create_for_resource = renderonly_create_gpu_import_for_resource,
134 .kms_fd = -1,
135 .gpu_fd = fd
136 };
137
138 return etna_drm_screen_create_renderonly(&ro);
139 }