nouveau: Fix serious compiler warnings
[mesa.git] / src / gallium / drivers / nouveau / nouveau_screen.c
1 #include "pipe/p_defines.h"
2 #include "pipe/p_screen.h"
3 #include "pipe/p_state.h"
4
5 #include "util/u_memory.h"
6 #include "util/u_inlines.h"
7 #include "util/u_format.h"
8 #include "util/u_format_s3tc.h"
9 #include "util/u_string.h"
10
11 #include <stdio.h>
12 #include <errno.h>
13
14 #include "nouveau/nouveau_bo.h"
15 #include "nouveau/nouveau_mm.h"
16 #include "nouveau_winsys.h"
17 #include "nouveau_screen.h"
18 #include "nouveau_fence.h"
19
20 /* XXX this should go away */
21 #include "state_tracker/drm_driver.h"
22 #include "util/u_simple_screen.h"
23
24 static const char *
25 nouveau_screen_get_name(struct pipe_screen *pscreen)
26 {
27 struct nouveau_device *dev = nouveau_screen(pscreen)->device;
28 static char buffer[128];
29
30 util_snprintf(buffer, sizeof(buffer), "NV%02X", dev->chipset);
31 return buffer;
32 }
33
34 static const char *
35 nouveau_screen_get_vendor(struct pipe_screen *pscreen)
36 {
37 return "nouveau";
38 }
39
40
41
42 struct nouveau_bo *
43 nouveau_screen_bo_new(struct pipe_screen *pscreen, unsigned alignment,
44 unsigned usage, unsigned bind, unsigned size)
45 {
46 struct nouveau_device *dev = nouveau_screen(pscreen)->device;
47 struct nouveau_bo *bo = NULL;
48 uint32_t flags = NOUVEAU_BO_MAP, tile_mode = 0, tile_flags = 0;
49 int ret;
50
51 if (bind & PIPE_BIND_VERTEX_BUFFER)
52 flags |= nouveau_screen(pscreen)->vertex_buffer_flags;
53 else if (bind & PIPE_BIND_INDEX_BUFFER)
54 flags |= nouveau_screen(pscreen)->index_buffer_flags;
55
56 if (bind & (PIPE_BIND_RENDER_TARGET |
57 PIPE_BIND_DEPTH_STENCIL |
58 PIPE_BIND_SCANOUT |
59 PIPE_BIND_DISPLAY_TARGET |
60 PIPE_BIND_SAMPLER_VIEW))
61 {
62 /* TODO: this may be incorrect or suboptimal */
63 if (!(bind & PIPE_BIND_SCANOUT))
64 flags |= NOUVEAU_BO_GART;
65 if (usage != PIPE_USAGE_DYNAMIC)
66 flags |= NOUVEAU_BO_VRAM;
67
68 if (dev->chipset == 0x50 || dev->chipset >= 0x80) {
69 if (bind & PIPE_BIND_DEPTH_STENCIL)
70 tile_flags = 0x2800;
71 else
72 tile_flags = 0x7000;
73 }
74 }
75
76 ret = nouveau_bo_new_tile(dev, flags, alignment, size,
77 tile_mode, tile_flags, &bo);
78 if (ret)
79 return NULL;
80
81 return bo;
82 }
83
84 struct nouveau_bo *
85 nouveau_screen_bo_user(struct pipe_screen *pscreen, void *ptr, unsigned bytes)
86 {
87 struct nouveau_device *dev = nouveau_screen(pscreen)->device;
88 struct nouveau_bo *bo = NULL;
89 int ret;
90
91 ret = nouveau_bo_user(dev, ptr, bytes, &bo);
92 if (ret)
93 return NULL;
94
95 return bo;
96 }
97
98 void *
99 nouveau_screen_bo_map(struct pipe_screen *pscreen,
100 struct nouveau_bo *bo,
101 unsigned map_flags)
102 {
103 int ret;
104
105 ret = nouveau_bo_map(bo, map_flags);
106 if (ret) {
107 debug_printf("map failed: %d\n", ret);
108 return NULL;
109 }
110
111 return bo->map;
112 }
113
114 void *
115 nouveau_screen_bo_map_range(struct pipe_screen *pscreen, struct nouveau_bo *bo,
116 unsigned offset, unsigned length, unsigned flags)
117 {
118 int ret;
119
120 ret = nouveau_bo_map_range(bo, offset, length, flags);
121 if (ret) {
122 nouveau_bo_unmap(bo);
123 if (!(flags & NOUVEAU_BO_NOWAIT) || ret != -EBUSY)
124 debug_printf("map_range failed: %d\n", ret);
125 return NULL;
126 }
127
128 return (char *)bo->map - offset; /* why gallium? why? */
129 }
130
131 void
132 nouveau_screen_bo_map_flush_range(struct pipe_screen *pscreen, struct nouveau_bo *bo,
133 unsigned offset, unsigned length)
134 {
135 nouveau_bo_map_flush(bo, offset, length);
136 }
137
138 void
139 nouveau_screen_bo_unmap(struct pipe_screen *pscreen, struct nouveau_bo *bo)
140 {
141 nouveau_bo_unmap(bo);
142 }
143
144 void
145 nouveau_screen_bo_release(struct pipe_screen *pscreen, struct nouveau_bo *bo)
146 {
147 nouveau_bo_ref(NULL, &bo);
148 }
149
150 static void
151 nouveau_screen_fence_ref(struct pipe_screen *pscreen,
152 struct pipe_fence_handle **ptr,
153 struct pipe_fence_handle *pfence)
154 {
155 nouveau_fence_ref(nouveau_fence(pfence), (struct nouveau_fence **)ptr);
156 }
157
158 static boolean
159 nouveau_screen_fence_signalled(struct pipe_screen *screen,
160 struct pipe_fence_handle *pfence)
161 {
162 return nouveau_fence_signalled(nouveau_fence(pfence));
163 }
164
165 static boolean
166 nouveau_screen_fence_finish(struct pipe_screen *screen,
167 struct pipe_fence_handle *pfence,
168 uint64_t timeout)
169 {
170 return nouveau_fence_wait(nouveau_fence(pfence));
171 }
172
173
174 struct nouveau_bo *
175 nouveau_screen_bo_from_handle(struct pipe_screen *pscreen,
176 struct winsys_handle *whandle,
177 unsigned *out_stride)
178 {
179 struct nouveau_device *dev = nouveau_screen(pscreen)->device;
180 struct nouveau_bo *bo = 0;
181 int ret;
182
183 ret = nouveau_bo_handle_ref(dev, whandle->handle, &bo);
184 if (ret) {
185 debug_printf("%s: ref name 0x%08x failed with %d\n",
186 __FUNCTION__, whandle->handle, ret);
187 return NULL;
188 }
189
190 *out_stride = whandle->stride;
191 return bo;
192 }
193
194
195 boolean
196 nouveau_screen_bo_get_handle(struct pipe_screen *pscreen,
197 struct nouveau_bo *bo,
198 unsigned stride,
199 struct winsys_handle *whandle)
200 {
201 whandle->stride = stride;
202
203 if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
204 return nouveau_bo_handle_get(bo, &whandle->handle) == 0;
205 } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
206 whandle->handle = bo->handle;
207 return TRUE;
208 } else {
209 return FALSE;
210 }
211 }
212
213 int
214 nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
215 {
216 struct pipe_screen *pscreen = &screen->base;
217 int ret;
218
219 ret = nouveau_channel_alloc(dev, 0xbeef0201, 0xbeef0202,
220 512*1024, &screen->channel);
221 if (ret)
222 return ret;
223 screen->device = dev;
224
225 pscreen->get_name = nouveau_screen_get_name;
226 pscreen->get_vendor = nouveau_screen_get_vendor;
227
228 pscreen->fence_reference = nouveau_screen_fence_ref;
229 pscreen->fence_signalled = nouveau_screen_fence_signalled;
230 pscreen->fence_finish = nouveau_screen_fence_finish;
231
232 util_format_s3tc_init();
233
234 screen->mm_GART = nouveau_mm_create(dev,
235 NOUVEAU_BO_GART | NOUVEAU_BO_MAP,
236 0x000);
237 screen->mm_VRAM = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, 0x000);
238 return 0;
239 }
240
241 void
242 nouveau_screen_fini(struct nouveau_screen *screen)
243 {
244 struct pipe_winsys *ws = screen->base.winsys;
245
246 nouveau_mm_destroy(screen->mm_GART);
247 nouveau_mm_destroy(screen->mm_VRAM);
248
249 nouveau_channel_free(&screen->channel);
250
251 if (ws)
252 ws->destroy(ws);
253 }
254