1 #include "git_sha1.h"
2
3 #include "pipe/p_defines.h"
4 #include "pipe/p_screen.h"
5 #include "pipe/p_state.h"
6
7 #include "util/u_memory.h"
8 #include "util/u_inlines.h"
9 #include "util/format/u_format.h"
10 #include "util/format/u_format_s3tc.h"
11 #include "util/u_string.h"
12 #include "util/hex.h"
13
14 #include "util/os_mman.h"
15 #include "util/os_time.h"
16
17 #include <stdio.h>
18 #include <errno.h>
19 #include <stdlib.h>
20
21 #include "drm-uapi/nouveau_drm.h"
22 #include <xf86drm.h>
23 #include "nvif/class.h"
24 #include "nvif/cl0080.h"
25
26 #include "nouveau_winsys.h"
27 #include "nouveau_screen.h"
28 #include "nouveau_context.h"
29 #include "nouveau_fence.h"
30 #include "nouveau_mm.h"
31 #include "nouveau_buffer.h"
32
33 #include <compiler/glsl_types.h>
34
35 /* XXX this should go away */
36 #include "frontend/drm_driver.h"
37
38 /* Even though GPUs might allow addresses with more bits, some engines do not.
39 * Stick with 40 for compatibility.
40 */
41 #define NV_GENERIC_VM_LIMIT_SHIFT 39
42
43 int nouveau_mesa_debug = 0;
44
45 static const char *
nouveau_screen_get_name(struct pipe_screen * pscreen)46 nouveau_screen_get_name(struct pipe_screen *pscreen)
47 {
48 struct nouveau_screen *screen = nouveau_screen(pscreen);
49 return screen->chipset_name;
50 }
51
52 static const char *
nouveau_screen_get_vendor(struct pipe_screen * pscreen)53 nouveau_screen_get_vendor(struct pipe_screen *pscreen)
54 {
55 return "Mesa";
56 }
57
58 static const char *
nouveau_screen_get_device_vendor(struct pipe_screen * pscreen)59 nouveau_screen_get_device_vendor(struct pipe_screen *pscreen)
60 {
61 return "NVIDIA";
62 }
63
64 static uint64_t
nouveau_screen_get_timestamp(struct pipe_screen * pscreen)65 nouveau_screen_get_timestamp(struct pipe_screen *pscreen)
66 {
67 int64_t cpu_time = os_time_get_nano();
68
69 /* getparam of PTIMER_TIME takes about x10 as long (several usecs) */
70
71 return cpu_time + nouveau_screen(pscreen)->cpu_gpu_time_delta;
72 }
73
74 static struct disk_cache *
nouveau_screen_get_disk_shader_cache(struct pipe_screen * pscreen)75 nouveau_screen_get_disk_shader_cache(struct pipe_screen *pscreen)
76 {
77 return nouveau_screen(pscreen)->disk_shader_cache;
78 }
79
80 static void
nouveau_screen_fence_ref(struct pipe_screen * pscreen,struct pipe_fence_handle ** ptr,struct pipe_fence_handle * pfence)81 nouveau_screen_fence_ref(struct pipe_screen *pscreen,
82 struct pipe_fence_handle **ptr,
83 struct pipe_fence_handle *pfence)
84 {
85 nouveau_fence_ref((pfence ? nouveau_fence(pfence) : NULL),
86 (ptr ? (struct nouveau_fence **)ptr : NULL));
87 }
88
89 static bool
nouveau_screen_fence_finish(struct pipe_screen * screen,struct pipe_context * ctx,struct pipe_fence_handle * pfence,uint64_t timeout)90 nouveau_screen_fence_finish(struct pipe_screen *screen,
91 struct pipe_context *ctx,
92 struct pipe_fence_handle *pfence,
93 uint64_t timeout)
94 {
95 if (!timeout)
96 return nouveau_fence_signalled(nouveau_fence(pfence));
97
98 return nouveau_fence_wait(nouveau_fence(pfence), NULL);
99 }
100
101
102 struct nouveau_bo *
nouveau_screen_bo_from_handle(struct pipe_screen * pscreen,struct winsys_handle * whandle,unsigned * out_stride)103 nouveau_screen_bo_from_handle(struct pipe_screen *pscreen,
104 struct winsys_handle *whandle,
105 unsigned *out_stride)
106 {
107 struct nouveau_device *dev = nouveau_screen(pscreen)->device;
108 struct nouveau_bo *bo = NULL;
109 int ret;
110
111 if (whandle->offset != 0) {
112 debug_printf("%s: attempt to import unsupported winsys offset %d\n",
113 __func__, whandle->offset);
114 return NULL;
115 }
116
117 if (whandle->type != WINSYS_HANDLE_TYPE_SHARED &&
118 whandle->type != WINSYS_HANDLE_TYPE_FD) {
119 debug_printf("%s: attempt to import unsupported handle type %d\n",
120 __func__, whandle->type);
121 return NULL;
122 }
123
124 if (whandle->type == WINSYS_HANDLE_TYPE_SHARED)
125 ret = nouveau_bo_name_ref(dev, whandle->handle, &bo);
126 else
127 ret = nouveau_bo_prime_handle_ref(dev, whandle->handle, &bo);
128
129 if (ret) {
130 debug_printf("%s: ref name 0x%08x failed with %d\n",
131 __func__, whandle->handle, ret);
132 return NULL;
133 }
134
135 *out_stride = whandle->stride;
136 return bo;
137 }
138
139
140 bool
nouveau_screen_bo_get_handle(struct pipe_screen * pscreen,struct nouveau_bo * bo,unsigned stride,struct winsys_handle * whandle)141 nouveau_screen_bo_get_handle(struct pipe_screen *pscreen,
142 struct nouveau_bo *bo,
143 unsigned stride,
144 struct winsys_handle *whandle)
145 {
146 whandle->stride = stride;
147
148 if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) {
149 return nouveau_bo_name_get(bo, &whandle->handle) == 0;
150 } else if (whandle->type == WINSYS_HANDLE_TYPE_KMS) {
151 int fd;
152 int ret;
153
154 /* The handle is exported in this case, but the global list of
155 * handles is in libdrm and there is no libdrm API to add
156 * handles to the list without additional side effects. The
157 * closest API available also gets a fd for the handle, which
158 * is not necessary in this case. Call it and close the fd.
159 */
160 ret = nouveau_bo_set_prime(bo, &fd);
161 if (ret != 0)
162 return false;
163
164 close(fd);
165
166 whandle->handle = bo->handle;
167 return true;
168 } else if (whandle->type == WINSYS_HANDLE_TYPE_FD) {
169 return nouveau_bo_set_prime(bo, (int *)&whandle->handle) == 0;
170 } else {
171 return false;
172 }
173 }
174
175 static void
nouveau_disk_cache_create(struct nouveau_screen * screen)176 nouveau_disk_cache_create(struct nouveau_screen *screen)
177 {
178 struct mesa_sha1 ctx;
179 unsigned char sha1[20];
180 char cache_id[20 * 2 + 1];
181 uint64_t driver_flags = 0;
182
183 _mesa_sha1_init(&ctx);
184 if (!disk_cache_get_function_identifier(nouveau_disk_cache_create,
185 &ctx))
186 return;
187
188 _mesa_sha1_final(&ctx, sha1);
189 mesa_bytes_to_hex(cache_id, sha1, 20);
190
191 driver_flags |= NOUVEAU_SHADER_CACHE_FLAGS_IR_NIR;
192
193 screen->disk_shader_cache =
194 disk_cache_create(nouveau_screen_get_name(&screen->base),
195 cache_id, driver_flags);
196 }
197
198 static void*
reserve_vma(uintptr_t start,uint64_t reserved_size)199 reserve_vma(uintptr_t start, uint64_t reserved_size)
200 {
201 void *reserved = os_mmap((void*)start, reserved_size, PROT_NONE,
202 MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
203 if (reserved == MAP_FAILED)
204 return NULL;
205 return reserved;
206 }
207
208 static void
nouveau_query_memory_info(struct pipe_screen * pscreen,struct pipe_memory_info * info)209 nouveau_query_memory_info(struct pipe_screen *pscreen,
210 struct pipe_memory_info *info)
211 {
212 const struct nouveau_screen *screen = nouveau_screen(pscreen);
213 struct nouveau_device *dev = screen->device;
214
215 info->total_device_memory = dev->vram_size / 1024;
216 info->total_staging_memory = dev->gart_size / 1024;
217
218 info->avail_device_memory = dev->vram_limit / 1024;
219 info->avail_staging_memory = dev->gart_limit / 1024;
220 }
221
222 static void
nouveau_pushbuf_cb(struct nouveau_pushbuf * push)223 nouveau_pushbuf_cb(struct nouveau_pushbuf *push)
224 {
225 struct nouveau_pushbuf_priv *p = (struct nouveau_pushbuf_priv *)push->user_priv;
226
227 if (p->context)
228 p->context->kick_notify(p->context);
229 else
230 _nouveau_fence_update(p->screen, true);
231
232 NOUVEAU_DRV_STAT(p->screen, pushbuf_count, 1);
233 }
234
235 int
nouveau_pushbuf_create(struct nouveau_screen * screen,struct nouveau_context * context,struct nouveau_client * client,struct nouveau_object * chan,int nr,uint32_t size,struct nouveau_pushbuf ** push)236 nouveau_pushbuf_create(struct nouveau_screen *screen, struct nouveau_context *context,
237 struct nouveau_client *client, struct nouveau_object *chan, int nr,
238 uint32_t size, struct nouveau_pushbuf **push)
239 {
240 int ret;
241 ret = nouveau_pushbuf_new(client, chan, nr, size, push);
242 if (ret)
243 return ret;
244
245 struct nouveau_pushbuf_priv *p = MALLOC_STRUCT(nouveau_pushbuf_priv);
246 if (!p) {
247 nouveau_pushbuf_del(push);
248 return -ENOMEM;
249 }
250 p->screen = screen;
251 p->context = context;
252 (*push)->kick_notify = nouveau_pushbuf_cb;
253 (*push)->user_priv = p;
254 return 0;
255 }
256
257 void
nouveau_pushbuf_destroy(struct nouveau_pushbuf ** push)258 nouveau_pushbuf_destroy(struct nouveau_pushbuf **push)
259 {
260 if (!*push)
261 return;
262 FREE((*push)->user_priv);
263 nouveau_pushbuf_del(push);
264 }
265
266 static int
nouveau_screen_get_fd(struct pipe_screen * pscreen)267 nouveau_screen_get_fd(struct pipe_screen *pscreen)
268 {
269 const struct nouveau_screen *screen = nouveau_screen(pscreen);
270
271 return screen->drm->fd;
272 }
273
274 static void
nouveau_driver_uuid(struct pipe_screen * screen,char * uuid)275 nouveau_driver_uuid(struct pipe_screen *screen, char *uuid)
276 {
277 const char* driver = PACKAGE_VERSION MESA_GIT_SHA1;
278 struct mesa_sha1 sha1_ctx;
279 uint8_t sha1[20];
280
281 _mesa_sha1_init(&sha1_ctx);
282 _mesa_sha1_update(&sha1_ctx, driver, strlen(driver));
283 _mesa_sha1_final(&sha1_ctx, sha1);
284 memcpy(uuid, sha1, PIPE_UUID_SIZE);
285 }
286
287 static void
nouveau_device_uuid(struct pipe_screen * pscreen,char * uuid)288 nouveau_device_uuid(struct pipe_screen *pscreen, char *uuid)
289 {
290 const struct nouveau_screen *screen = nouveau_screen(pscreen);
291 nv_device_uuid(&screen->device->info, (void *)uuid, PIPE_UUID_SIZE, false);
292 }
293
294 int
nouveau_screen_init(struct nouveau_screen * screen,struct nouveau_device * dev)295 nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
296 {
297 struct pipe_screen *pscreen = &screen->base;
298 struct nv04_fifo nv04_data = { .vram = 0xbeef0201, .gart = 0xbeef0202 };
299 struct nvc0_fifo nvc0_data = { };
300 struct nve0_fifo nve0_data = { .engine = NOUVEAU_FIFO_ENGINE_GR };
301 uint64_t time;
302 int size, ret;
303 void *data;
304 union nouveau_bo_config mm_config;
305
306 glsl_type_singleton_init_or_ref();
307
308 char *nv_dbg = getenv("NOUVEAU_MESA_DEBUG");
309 if (nv_dbg)
310 nouveau_mesa_debug = atoi(nv_dbg);
311
312 screen->force_enable_cl = debug_get_bool_option("NOUVEAU_ENABLE_CL", false);
313 screen->disable_fences = debug_get_bool_option("NOUVEAU_DISABLE_FENCES", false);
314
315 /* These must be set before any failure is possible, as the cleanup
316 * paths assume they're responsible for deleting them.
317 */
318 screen->drm = nouveau_drm(&dev->object);
319 screen->device = dev;
320
321 /*
322 * this is initialized to 1 in nouveau_drm_screen_create after screen
323 * is fully constructed and added to the global screen list.
324 */
325 screen->refcount = -1;
326
327 if (dev->chipset < 0xc0) {
328 data = &nv04_data;
329 size = sizeof(nv04_data);
330 } else if (dev->chipset < 0xe0) {
331 data = &nvc0_data;
332 size = sizeof(nvc0_data);
333 } else {
334 data = &nve0_data;
335 size = sizeof(nve0_data);
336 }
337
338 bool enable_svm = debug_get_bool_option("NOUVEAU_SVM", false);
339 screen->has_svm = false;
340 /* we only care about HMM with OpenCL enabled */
341 if (dev->chipset > 0x130 && enable_svm) {
342 /* Before being able to enable SVM we need to carve out some memory for
343 * driver bo allocations. Let's just base the size on the available VRAM.
344 *
345 * 40 bit is the biggest we care about and for 32 bit systems we don't
346 * want to allocate all of the available memory either.
347 *
348 * Also we align the size we want to reserve to the next POT to make use
349 * of hugepages.
350 */
351 const int vram_shift = util_logbase2_ceil64(dev->vram_size);
352 const int limit_bit =
353 MIN2(sizeof(void*) * 8 - 1, NV_GENERIC_VM_LIMIT_SHIFT);
354 screen->svm_cutout_size =
355 BITFIELD64_BIT(MIN2(sizeof(void*) == 4 ? 26 : NV_GENERIC_VM_LIMIT_SHIFT, vram_shift));
356
357 size_t start = screen->svm_cutout_size;
358 do {
359 screen->svm_cutout = reserve_vma(start, screen->svm_cutout_size);
360 if (!screen->svm_cutout) {
361 start += screen->svm_cutout_size;
362 continue;
363 }
364
365 struct drm_nouveau_svm_init svm_args = {
366 .unmanaged_addr = (uintptr_t)screen->svm_cutout,
367 .unmanaged_size = screen->svm_cutout_size,
368 };
369
370 ret = drmCommandWrite(screen->drm->fd, DRM_NOUVEAU_SVM_INIT,
371 &svm_args, sizeof(svm_args));
372 screen->has_svm = !ret;
373 if (!screen->has_svm)
374 os_munmap(screen->svm_cutout, screen->svm_cutout_size);
375 break;
376 } while ((start + screen->svm_cutout_size) < BITFIELD64_MASK(limit_bit));
377 }
378
379 switch (dev->chipset) {
380 case 0x0ea: /* TK1, GK20A */
381 case 0x12b: /* TX1, GM20B */
382 case 0x13b: /* TX2, GP10B */
383 screen->tegra_sector_layout = true;
384 break;
385 default:
386 /* Xavier's GPU and everything else */
387 screen->tegra_sector_layout = false;
388 break;
389 }
390
391 /*
392 * Set default VRAM domain if not overridden
393 */
394 if (!screen->vram_domain) {
395 if (dev->vram_size > 0)
396 screen->vram_domain = NOUVEAU_BO_VRAM;
397 else
398 screen->vram_domain = NOUVEAU_BO_GART;
399 }
400
401 ret = nouveau_object_new(&dev->object, 0, NOUVEAU_FIFO_CHANNEL_CLASS,
402 data, size, &screen->channel);
403 if (ret)
404 goto err;
405
406 ret = nouveau_client_new(screen->device, &screen->client);
407 if (ret)
408 goto err;
409 ret = nouveau_pushbuf_create(screen, NULL, screen->client, screen->channel,
410 4, 512 * 1024, &screen->pushbuf);
411 if (ret)
412 goto err;
413
414 /* getting CPU time first appears to be more accurate */
415 screen->cpu_gpu_time_delta = os_time_get();
416
417 ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_PTIMER_TIME, &time);
418 if (!ret)
419 screen->cpu_gpu_time_delta = time - screen->cpu_gpu_time_delta * 1000;
420
421 snprintf(screen->chipset_name, sizeof(screen->chipset_name), "NV%02X", dev->chipset);
422 pscreen->get_name = nouveau_screen_get_name;
423 pscreen->get_screen_fd = nouveau_screen_get_fd;
424 pscreen->get_vendor = nouveau_screen_get_vendor;
425 pscreen->get_device_vendor = nouveau_screen_get_device_vendor;
426 pscreen->get_disk_shader_cache = nouveau_screen_get_disk_shader_cache;
427
428 pscreen->get_timestamp = nouveau_screen_get_timestamp;
429
430 pscreen->fence_reference = nouveau_screen_fence_ref;
431 pscreen->fence_finish = nouveau_screen_fence_finish;
432
433 pscreen->query_memory_info = nouveau_query_memory_info;
434 pscreen->get_driver_uuid = nouveau_driver_uuid;
435 pscreen->get_device_uuid = nouveau_device_uuid;
436
437 nouveau_disk_cache_create(screen);
438
439 screen->transfer_pushbuf_threshold = 192;
440 screen->lowmem_bindings = PIPE_BIND_GLOBAL; /* gallium limit */
441 screen->vidmem_bindings =
442 PIPE_BIND_RENDER_TARGET | PIPE_BIND_DEPTH_STENCIL |
443 PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT |
444 PIPE_BIND_CURSOR |
445 PIPE_BIND_SAMPLER_VIEW |
446 PIPE_BIND_SHADER_BUFFER | PIPE_BIND_SHADER_IMAGE |
447 PIPE_BIND_COMPUTE_RESOURCE |
448 PIPE_BIND_GLOBAL;
449 screen->sysmem_bindings =
450 PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_STREAM_OUTPUT |
451 PIPE_BIND_COMMAND_ARGS_BUFFER;
452
453 screen->is_uma = dev->info.type != NV_DEVICE_TYPE_DIS;
454
455 memset(&mm_config, 0, sizeof(mm_config));
456 nouveau_fence_list_init(&screen->fence);
457
458 screen->mm_GART = nouveau_mm_create(dev,
459 NOUVEAU_BO_GART | NOUVEAU_BO_MAP,
460 &mm_config);
461 screen->mm_VRAM = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, &mm_config);
462
463 return 0;
464
465 err:
466 if (screen->svm_cutout)
467 os_munmap(screen->svm_cutout, screen->svm_cutout_size);
468 return ret;
469 }
470
471 void
nouveau_screen_fini(struct nouveau_screen * screen)472 nouveau_screen_fini(struct nouveau_screen *screen)
473 {
474 int fd = screen->drm->fd;
475
476 glsl_type_singleton_decref();
477 if (screen->has_svm)
478 os_munmap(screen->svm_cutout, screen->svm_cutout_size);
479
480 nouveau_mm_destroy(screen->mm_GART);
481 nouveau_mm_destroy(screen->mm_VRAM);
482
483 nouveau_pushbuf_destroy(&screen->pushbuf);
484
485 nouveau_client_del(&screen->client);
486 nouveau_object_del(&screen->channel);
487
488 nouveau_device_del(&screen->device);
489 nouveau_drm_del(&screen->drm);
490 close(fd);
491
492 disk_cache_destroy(screen->disk_shader_cache);
493 nouveau_fence_list_destroy(&screen->fence);
494 }
495
496 static void
nouveau_set_debug_callback(struct pipe_context * pipe,const struct util_debug_callback * cb)497 nouveau_set_debug_callback(struct pipe_context *pipe,
498 const struct util_debug_callback *cb)
499 {
500 struct nouveau_context *context = nouveau_context(pipe);
501
502 if (cb)
503 context->debug = *cb;
504 else
505 memset(&context->debug, 0, sizeof(context->debug));
506 }
507
508 int
nouveau_context_init(struct nouveau_context * context,struct nouveau_screen * screen)509 nouveau_context_init(struct nouveau_context *context, struct nouveau_screen *screen)
510 {
511 int ret;
512
513 context->pipe.set_debug_callback = nouveau_set_debug_callback;
514 context->screen = screen;
515
516 ret = nouveau_client_new(screen->device, &context->client);
517 if (ret)
518 return ret;
519
520 ret = nouveau_pushbuf_create(screen, context, context->client, screen->channel,
521 4, 512 * 1024, &context->pushbuf);
522 if (ret)
523 return ret;
524
525 return 0;
526 }
527