1 #include "pipe/p_defines.h"
2 #include "pipe/p_screen.h"
3 #include "pipe/p_state.h"
5 #include "util/u_memory.h"
6 #include "util/u_inlines.h"
7 #include "util/format/u_format.h"
8 #include "util/format/u_format_s3tc.h"
9 #include "util/u_string.h"
11 #include "os/os_mman.h"
12 #include "util/os_time.h"
18 #include <nouveau_drm.h>
21 #include "nouveau_winsys.h"
22 #include "nouveau_screen.h"
23 #include "nouveau_context.h"
24 #include "nouveau_fence.h"
25 #include "nouveau_mm.h"
26 #include "nouveau_buffer.h"
28 #include <compiler/glsl_types.h>
30 /* XXX this should go away */
31 #include "frontend/drm_driver.h"
33 /* Even though GPUs might allow addresses with more bits, some engines do not.
34 * Stick with 40 for compatibility.
36 #define NV_GENERIC_VM_LIMIT_SHIFT 39
38 int nouveau_mesa_debug
= 0;
41 nouveau_screen_get_name(struct pipe_screen
*pscreen
)
43 struct nouveau_device
*dev
= nouveau_screen(pscreen
)->device
;
44 static char buffer
[128];
46 snprintf(buffer
, sizeof(buffer
), "NV%02X", dev
->chipset
);
51 nouveau_screen_get_vendor(struct pipe_screen
*pscreen
)
57 nouveau_screen_get_device_vendor(struct pipe_screen
*pscreen
)
63 nouveau_screen_get_timestamp(struct pipe_screen
*pscreen
)
65 int64_t cpu_time
= os_time_get() * 1000;
67 /* getparam of PTIMER_TIME takes about x10 as long (several usecs) */
69 return cpu_time
+ nouveau_screen(pscreen
)->cpu_gpu_time_delta
;
72 static struct disk_cache
*
73 nouveau_screen_get_disk_shader_cache(struct pipe_screen
*pscreen
)
75 return nouveau_screen(pscreen
)->disk_shader_cache
;
79 nouveau_screen_fence_ref(struct pipe_screen
*pscreen
,
80 struct pipe_fence_handle
**ptr
,
81 struct pipe_fence_handle
*pfence
)
83 nouveau_fence_ref(nouveau_fence(pfence
), (struct nouveau_fence
**)ptr
);
87 nouveau_screen_fence_finish(struct pipe_screen
*screen
,
88 struct pipe_context
*ctx
,
89 struct pipe_fence_handle
*pfence
,
93 return nouveau_fence_signalled(nouveau_fence(pfence
));
95 return nouveau_fence_wait(nouveau_fence(pfence
), NULL
);
100 nouveau_screen_bo_from_handle(struct pipe_screen
*pscreen
,
101 struct winsys_handle
*whandle
,
102 unsigned *out_stride
)
104 struct nouveau_device
*dev
= nouveau_screen(pscreen
)->device
;
105 struct nouveau_bo
*bo
= 0;
108 if (whandle
->offset
!= 0) {
109 debug_printf("%s: attempt to import unsupported winsys offset %d\n",
110 __FUNCTION__
, whandle
->offset
);
114 if (whandle
->type
!= WINSYS_HANDLE_TYPE_SHARED
&&
115 whandle
->type
!= WINSYS_HANDLE_TYPE_FD
) {
116 debug_printf("%s: attempt to import unsupported handle type %d\n",
117 __FUNCTION__
, whandle
->type
);
121 if (whandle
->type
== WINSYS_HANDLE_TYPE_SHARED
)
122 ret
= nouveau_bo_name_ref(dev
, whandle
->handle
, &bo
);
124 ret
= nouveau_bo_prime_handle_ref(dev
, whandle
->handle
, &bo
);
127 debug_printf("%s: ref name 0x%08x failed with %d\n",
128 __FUNCTION__
, whandle
->handle
, ret
);
132 *out_stride
= whandle
->stride
;
138 nouveau_screen_bo_get_handle(struct pipe_screen
*pscreen
,
139 struct nouveau_bo
*bo
,
141 struct winsys_handle
*whandle
)
143 whandle
->stride
= stride
;
145 if (whandle
->type
== WINSYS_HANDLE_TYPE_SHARED
) {
146 return nouveau_bo_name_get(bo
, &whandle
->handle
) == 0;
147 } else if (whandle
->type
== WINSYS_HANDLE_TYPE_KMS
) {
148 whandle
->handle
= bo
->handle
;
150 } else if (whandle
->type
== WINSYS_HANDLE_TYPE_FD
) {
151 return nouveau_bo_set_prime(bo
, (int *)&whandle
->handle
) == 0;
158 nouveau_disk_cache_create(struct nouveau_screen
*screen
)
160 struct mesa_sha1 ctx
;
161 unsigned char sha1
[20];
162 char cache_id
[20 * 2 + 1];
163 uint64_t driver_flags
= 0;
165 _mesa_sha1_init(&ctx
);
166 if (!disk_cache_get_function_identifier(nouveau_disk_cache_create
,
170 _mesa_sha1_final(&ctx
, sha1
);
171 disk_cache_format_hex_id(cache_id
, sha1
, 20 * 2);
173 if (screen
->prefer_nir
)
174 driver_flags
|= NOUVEAU_SHADER_CACHE_FLAGS_IR_NIR
;
176 driver_flags
|= NOUVEAU_SHADER_CACHE_FLAGS_IR_TGSI
;
178 screen
->disk_shader_cache
=
179 disk_cache_create(nouveau_screen_get_name(&screen
->base
),
180 cache_id
, driver_flags
);
184 reserve_vma(uintptr_t start
, uint64_t reserved_size
)
186 void *reserved
= os_mmap((void*)start
, reserved_size
, PROT_NONE
,
187 MAP_ANONYMOUS
| MAP_PRIVATE
, -1, 0);
188 if (reserved
== MAP_FAILED
)
194 nouveau_screen_init(struct nouveau_screen
*screen
, struct nouveau_device
*dev
)
196 struct pipe_screen
*pscreen
= &screen
->base
;
197 struct nv04_fifo nv04_data
= { .vram
= 0xbeef0201, .gart
= 0xbeef0202 };
198 struct nvc0_fifo nvc0_data
= { };
202 union nouveau_bo_config mm_config
;
204 char *nv_dbg
= getenv("NOUVEAU_MESA_DEBUG");
206 nouveau_mesa_debug
= atoi(nv_dbg
);
208 if (dev
->chipset
< 0x140)
209 screen
->prefer_nir
= debug_get_bool_option("NV50_PROG_USE_NIR", false);
211 screen
->prefer_nir
= true;
213 screen
->force_enable_cl
= debug_get_bool_option("NOUVEAU_ENABLE_CL", false);
214 if (screen
->force_enable_cl
)
215 glsl_type_singleton_init_or_ref();
217 /* These must be set before any failure is possible, as the cleanup
218 * paths assume they're responsible for deleting them.
220 screen
->drm
= nouveau_drm(&dev
->object
);
221 screen
->device
= dev
;
224 * this is initialized to 1 in nouveau_drm_screen_create after screen
225 * is fully constructed and added to the global screen list.
227 screen
->refcount
= -1;
229 if (dev
->chipset
< 0xc0) {
231 size
= sizeof(nv04_data
);
234 size
= sizeof(nvc0_data
);
237 screen
->has_svm
= false;
238 /* we only care about HMM with OpenCL enabled */
239 if (dev
->chipset
> 0x130 && screen
->force_enable_cl
) {
240 /* Before being able to enable SVM we need to carve out some memory for
241 * driver bo allocations. Let's just base the size on the available VRAM.
243 * 40 bit is the biggest we care about and for 32 bit systems we don't
244 * want to allocate all of the available memory either.
246 * Also we align the size we want to reserve to the next POT to make use
249 const int vram_shift
= util_logbase2_ceil64(dev
->vram_size
);
250 const int limit_bit
=
251 MIN2(sizeof(void*) * 8 - 1, NV_GENERIC_VM_LIMIT_SHIFT
);
252 screen
->svm_cutout_size
=
253 BITFIELD64_BIT(MIN2(sizeof(void*) == 4 ? 26 : NV_GENERIC_VM_LIMIT_SHIFT
, vram_shift
));
255 size_t start
= screen
->svm_cutout_size
;
257 screen
->svm_cutout
= reserve_vma(start
, screen
->svm_cutout_size
);
258 if (!screen
->svm_cutout
) {
259 start
+= screen
->svm_cutout_size
;
263 struct drm_nouveau_svm_init svm_args
= {
264 .unmanaged_addr
= (uint64_t)screen
->svm_cutout
,
265 .unmanaged_size
= screen
->svm_cutout_size
,
268 ret
= drmCommandWrite(screen
->drm
->fd
, DRM_NOUVEAU_SVM_INIT
,
269 &svm_args
, sizeof(svm_args
));
270 screen
->has_svm
= !ret
;
271 if (!screen
->has_svm
)
272 os_munmap(screen
->svm_cutout
, screen
->svm_cutout_size
);
274 } while ((start
+ screen
->svm_cutout_size
) < BITFIELD64_MASK(limit_bit
));
278 * Set default VRAM domain if not overridden
280 if (!screen
->vram_domain
) {
281 if (dev
->vram_size
> 0)
282 screen
->vram_domain
= NOUVEAU_BO_VRAM
;
284 screen
->vram_domain
= NOUVEAU_BO_GART
;
287 ret
= nouveau_object_new(&dev
->object
, 0, NOUVEAU_FIFO_CHANNEL_CLASS
,
288 data
, size
, &screen
->channel
);
292 ret
= nouveau_client_new(screen
->device
, &screen
->client
);
295 ret
= nouveau_pushbuf_new(screen
->client
, screen
->channel
,
301 /* getting CPU time first appears to be more accurate */
302 screen
->cpu_gpu_time_delta
= os_time_get();
304 ret
= nouveau_getparam(dev
, NOUVEAU_GETPARAM_PTIMER_TIME
, &time
);
306 screen
->cpu_gpu_time_delta
= time
- screen
->cpu_gpu_time_delta
* 1000;
308 pscreen
->get_name
= nouveau_screen_get_name
;
309 pscreen
->get_vendor
= nouveau_screen_get_vendor
;
310 pscreen
->get_device_vendor
= nouveau_screen_get_device_vendor
;
311 pscreen
->get_disk_shader_cache
= nouveau_screen_get_disk_shader_cache
;
313 pscreen
->get_timestamp
= nouveau_screen_get_timestamp
;
315 pscreen
->fence_reference
= nouveau_screen_fence_ref
;
316 pscreen
->fence_finish
= nouveau_screen_fence_finish
;
318 nouveau_disk_cache_create(screen
);
320 screen
->transfer_pushbuf_threshold
= 192;
321 screen
->lowmem_bindings
= PIPE_BIND_GLOBAL
; /* gallium limit */
322 screen
->vidmem_bindings
=
323 PIPE_BIND_RENDER_TARGET
| PIPE_BIND_DEPTH_STENCIL
|
324 PIPE_BIND_DISPLAY_TARGET
| PIPE_BIND_SCANOUT
|
326 PIPE_BIND_SAMPLER_VIEW
|
327 PIPE_BIND_SHADER_BUFFER
| PIPE_BIND_SHADER_IMAGE
|
328 PIPE_BIND_COMPUTE_RESOURCE
|
330 screen
->sysmem_bindings
=
331 PIPE_BIND_SAMPLER_VIEW
| PIPE_BIND_STREAM_OUTPUT
|
332 PIPE_BIND_COMMAND_ARGS_BUFFER
;
334 memset(&mm_config
, 0, sizeof(mm_config
));
336 screen
->mm_GART
= nouveau_mm_create(dev
,
337 NOUVEAU_BO_GART
| NOUVEAU_BO_MAP
,
339 screen
->mm_VRAM
= nouveau_mm_create(dev
, NOUVEAU_BO_VRAM
, &mm_config
);
343 if (screen
->svm_cutout
)
344 os_munmap(screen
->svm_cutout
, screen
->svm_cutout_size
);
349 nouveau_screen_fini(struct nouveau_screen
*screen
)
351 int fd
= screen
->drm
->fd
;
353 if (screen
->force_enable_cl
)
354 glsl_type_singleton_decref();
356 os_munmap(screen
->svm_cutout
, screen
->svm_cutout_size
);
358 nouveau_mm_destroy(screen
->mm_GART
);
359 nouveau_mm_destroy(screen
->mm_VRAM
);
361 nouveau_pushbuf_del(&screen
->pushbuf
);
363 nouveau_client_del(&screen
->client
);
364 nouveau_object_del(&screen
->channel
);
366 nouveau_device_del(&screen
->device
);
367 nouveau_drm_del(&screen
->drm
);
370 disk_cache_destroy(screen
->disk_shader_cache
);
374 nouveau_set_debug_callback(struct pipe_context
*pipe
,
375 const struct pipe_debug_callback
*cb
)
377 struct nouveau_context
*context
= nouveau_context(pipe
);
380 context
->debug
= *cb
;
382 memset(&context
->debug
, 0, sizeof(context
->debug
));
386 nouveau_context_init(struct nouveau_context
*context
)
388 context
->pipe
.set_debug_callback
= nouveau_set_debug_callback
;