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/u_format.h"
8 #include "util/u_format_s3tc.h"
9 #include "util/u_string.h"
11 #include "os/os_time.h"
17 #include <nouveau_drm.h>
19 #include "nouveau_winsys.h"
20 #include "nouveau_screen.h"
21 #include "nouveau_context.h"
22 #include "nouveau_fence.h"
23 #include "nouveau_mm.h"
24 #include "nouveau_buffer.h"
26 /* XXX this should go away */
27 #include "state_tracker/drm_driver.h"
29 int nouveau_mesa_debug
= 0;
32 nouveau_screen_get_name(struct pipe_screen
*pscreen
)
34 struct nouveau_device
*dev
= nouveau_screen(pscreen
)->device
;
35 static char buffer
[128];
37 util_snprintf(buffer
, sizeof(buffer
), "NV%02X", dev
->chipset
);
42 nouveau_screen_get_vendor(struct pipe_screen
*pscreen
)
48 nouveau_screen_get_device_vendor(struct pipe_screen
*pscreen
)
54 nouveau_screen_get_timestamp(struct pipe_screen
*pscreen
)
56 int64_t cpu_time
= os_time_get() * 1000;
58 /* getparam of PTIMER_TIME takes about x10 as long (several usecs) */
60 return cpu_time
+ nouveau_screen(pscreen
)->cpu_gpu_time_delta
;
63 static struct disk_cache
*
64 nouveau_screen_get_disk_shader_cache(struct pipe_screen
*pscreen
)
66 return nouveau_screen(pscreen
)->disk_shader_cache
;
70 nouveau_screen_fence_ref(struct pipe_screen
*pscreen
,
71 struct pipe_fence_handle
**ptr
,
72 struct pipe_fence_handle
*pfence
)
74 nouveau_fence_ref(nouveau_fence(pfence
), (struct nouveau_fence
**)ptr
);
78 nouveau_screen_fence_finish(struct pipe_screen
*screen
,
79 struct pipe_context
*ctx
,
80 struct pipe_fence_handle
*pfence
,
84 return nouveau_fence_signalled(nouveau_fence(pfence
));
86 return nouveau_fence_wait(nouveau_fence(pfence
), NULL
);
91 nouveau_screen_bo_from_handle(struct pipe_screen
*pscreen
,
92 struct winsys_handle
*whandle
,
95 struct nouveau_device
*dev
= nouveau_screen(pscreen
)->device
;
96 struct nouveau_bo
*bo
= 0;
99 if (whandle
->offset
!= 0) {
100 debug_printf("%s: attempt to import unsupported winsys offset %d\n",
101 __FUNCTION__
, whandle
->offset
);
105 if (whandle
->type
!= DRM_API_HANDLE_TYPE_SHARED
&&
106 whandle
->type
!= DRM_API_HANDLE_TYPE_FD
) {
107 debug_printf("%s: attempt to import unsupported handle type %d\n",
108 __FUNCTION__
, whandle
->type
);
112 if (whandle
->type
== DRM_API_HANDLE_TYPE_SHARED
)
113 ret
= nouveau_bo_name_ref(dev
, whandle
->handle
, &bo
);
115 ret
= nouveau_bo_prime_handle_ref(dev
, whandle
->handle
, &bo
);
118 debug_printf("%s: ref name 0x%08x failed with %d\n",
119 __FUNCTION__
, whandle
->handle
, ret
);
123 *out_stride
= whandle
->stride
;
129 nouveau_screen_bo_get_handle(struct pipe_screen
*pscreen
,
130 struct nouveau_bo
*bo
,
132 struct winsys_handle
*whandle
)
134 whandle
->stride
= stride
;
136 if (whandle
->type
== DRM_API_HANDLE_TYPE_SHARED
) {
137 return nouveau_bo_name_get(bo
, &whandle
->handle
) == 0;
138 } else if (whandle
->type
== DRM_API_HANDLE_TYPE_KMS
) {
139 whandle
->handle
= bo
->handle
;
141 } else if (whandle
->type
== DRM_API_HANDLE_TYPE_FD
) {
142 return nouveau_bo_set_prime(bo
, (int *)&whandle
->handle
) == 0;
149 nouveau_disk_cache_create(struct nouveau_screen
*screen
)
151 uint32_t mesa_timestamp
;
155 if (disk_cache_get_function_timestamp(nouveau_disk_cache_create
,
157 res
= asprintf(×tamp_str
, "%u", mesa_timestamp
);
159 screen
->disk_shader_cache
=
160 disk_cache_create(nouveau_screen_get_name(&screen
->base
),
168 nouveau_screen_init(struct nouveau_screen
*screen
, struct nouveau_device
*dev
)
170 struct pipe_screen
*pscreen
= &screen
->base
;
171 struct nv04_fifo nv04_data
= { .vram
= 0xbeef0201, .gart
= 0xbeef0202 };
172 struct nvc0_fifo nvc0_data
= { };
176 union nouveau_bo_config mm_config
;
178 char *nv_dbg
= getenv("NOUVEAU_MESA_DEBUG");
180 nouveau_mesa_debug
= atoi(nv_dbg
);
182 /* These must be set before any failure is possible, as the cleanup
183 * paths assume they're responsible for deleting them.
185 screen
->drm
= nouveau_drm(&dev
->object
);
186 screen
->device
= dev
;
189 * this is initialized to 1 in nouveau_drm_screen_create after screen
190 * is fully constructed and added to the global screen list.
192 screen
->refcount
= -1;
194 if (dev
->chipset
< 0xc0) {
196 size
= sizeof(nv04_data
);
199 size
= sizeof(nvc0_data
);
203 * Set default VRAM domain if not overridden
205 if (!screen
->vram_domain
) {
206 if (dev
->vram_size
> 0)
207 screen
->vram_domain
= NOUVEAU_BO_VRAM
;
209 screen
->vram_domain
= NOUVEAU_BO_GART
;
212 ret
= nouveau_object_new(&dev
->object
, 0, NOUVEAU_FIFO_CHANNEL_CLASS
,
213 data
, size
, &screen
->channel
);
217 ret
= nouveau_client_new(screen
->device
, &screen
->client
);
220 ret
= nouveau_pushbuf_new(screen
->client
, screen
->channel
,
226 /* getting CPU time first appears to be more accurate */
227 screen
->cpu_gpu_time_delta
= os_time_get();
229 ret
= nouveau_getparam(dev
, NOUVEAU_GETPARAM_PTIMER_TIME
, &time
);
231 screen
->cpu_gpu_time_delta
= time
- screen
->cpu_gpu_time_delta
* 1000;
233 pscreen
->get_name
= nouveau_screen_get_name
;
234 pscreen
->get_vendor
= nouveau_screen_get_vendor
;
235 pscreen
->get_device_vendor
= nouveau_screen_get_device_vendor
;
236 pscreen
->get_disk_shader_cache
= nouveau_screen_get_disk_shader_cache
;
238 pscreen
->get_timestamp
= nouveau_screen_get_timestamp
;
240 pscreen
->fence_reference
= nouveau_screen_fence_ref
;
241 pscreen
->fence_finish
= nouveau_screen_fence_finish
;
243 nouveau_disk_cache_create(screen
);
245 util_format_s3tc_init();
247 screen
->lowmem_bindings
= PIPE_BIND_GLOBAL
; /* gallium limit */
248 screen
->vidmem_bindings
=
249 PIPE_BIND_RENDER_TARGET
| PIPE_BIND_DEPTH_STENCIL
|
250 PIPE_BIND_DISPLAY_TARGET
| PIPE_BIND_SCANOUT
|
252 PIPE_BIND_SAMPLER_VIEW
|
253 PIPE_BIND_SHADER_BUFFER
| PIPE_BIND_SHADER_IMAGE
|
254 PIPE_BIND_COMPUTE_RESOURCE
|
256 screen
->sysmem_bindings
=
257 PIPE_BIND_SAMPLER_VIEW
| PIPE_BIND_STREAM_OUTPUT
|
258 PIPE_BIND_COMMAND_ARGS_BUFFER
;
260 memset(&mm_config
, 0, sizeof(mm_config
));
262 screen
->mm_GART
= nouveau_mm_create(dev
,
263 NOUVEAU_BO_GART
| NOUVEAU_BO_MAP
,
265 screen
->mm_VRAM
= nouveau_mm_create(dev
, NOUVEAU_BO_VRAM
, &mm_config
);
270 nouveau_screen_fini(struct nouveau_screen
*screen
)
272 int fd
= screen
->drm
->fd
;
274 nouveau_mm_destroy(screen
->mm_GART
);
275 nouveau_mm_destroy(screen
->mm_VRAM
);
277 nouveau_pushbuf_del(&screen
->pushbuf
);
279 nouveau_client_del(&screen
->client
);
280 nouveau_object_del(&screen
->channel
);
282 nouveau_device_del(&screen
->device
);
283 nouveau_drm_del(&screen
->drm
);
286 disk_cache_destroy(screen
->disk_shader_cache
);
290 nouveau_set_debug_callback(struct pipe_context
*pipe
,
291 const struct pipe_debug_callback
*cb
)
293 struct nouveau_context
*context
= nouveau_context(pipe
);
296 context
->debug
= *cb
;
298 memset(&context
->debug
, 0, sizeof(context
->debug
));
302 nouveau_context_init(struct nouveau_context
*context
)
304 context
->pipe
.set_debug_callback
= nouveau_set_debug_callback
;