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"
12 #include "nouveau/nouveau_bo.h"
13 #include "nouveau_winsys.h"
14 #include "nouveau_screen.h"
16 /* XXX this should go away */
17 #include "state_tracker/drm_api.h"
18 #include "util/u_simple_screen.h"
21 nouveau_screen_get_name(struct pipe_screen
*pscreen
)
23 struct nouveau_device
*dev
= nouveau_screen(pscreen
)->device
;
24 static char buffer
[128];
26 snprintf(buffer
, sizeof(buffer
), "NV%02X", dev
->chipset
);
31 nouveau_screen_get_vendor(struct pipe_screen
*pscreen
)
39 nouveau_screen_bo_new(struct pipe_screen
*pscreen
, unsigned alignment
,
40 unsigned usage
, unsigned bind
, unsigned size
)
42 struct nouveau_device
*dev
= nouveau_screen(pscreen
)->device
;
43 struct nouveau_bo
*bo
= NULL
;
44 uint32_t flags
= NOUVEAU_BO_MAP
, tile_mode
= 0, tile_flags
= 0;
47 if (bind
& PIPE_BIND_VERTEX_BUFFER
) {
48 if (pscreen
->get_param(pscreen
, NOUVEAU_CAP_HW_VTXBUF
))
49 flags
|= NOUVEAU_BO_GART
;
51 if (usage
& PIPE_BIND_INDEX_BUFFER
) {
52 if (pscreen
->get_param(pscreen
, NOUVEAU_CAP_HW_IDXBUF
))
53 flags
|= NOUVEAU_BO_GART
;
56 if (bind
& (PIPE_BIND_RENDER_TARGET
|
57 PIPE_BIND_DEPTH_STENCIL
|
58 PIPE_BIND_BLIT_SOURCE
|
59 PIPE_BIND_BLIT_DESTINATION
|
61 PIPE_BIND_DISPLAY_TARGET
|
62 PIPE_BIND_SAMPLER_VIEW
))
64 /* TODO: this may be incorrect or suboptimal */
65 if (!(bind
& PIPE_BIND_SCANOUT
))
66 flags
|= NOUVEAU_BO_GART
;
67 if (usage
!= PIPE_USAGE_DYNAMIC
)
68 flags
|= NOUVEAU_BO_VRAM
;
70 if (dev
->chipset
== 0x50 || dev
->chipset
>= 0x80) {
71 if (bind
& PIPE_BIND_DEPTH_STENCIL
)
78 ret
= nouveau_bo_new_tile(dev
, flags
, alignment
, size
,
79 tile_mode
, tile_flags
, &bo
);
87 nouveau_screen_bo_user(struct pipe_screen
*pscreen
, void *ptr
, unsigned bytes
)
89 struct nouveau_device
*dev
= nouveau_screen(pscreen
)->device
;
90 struct nouveau_bo
*bo
= NULL
;
93 ret
= nouveau_bo_user(dev
, ptr
, bytes
, &bo
);
101 nouveau_screen_bo_map(struct pipe_screen
*pscreen
,
102 struct nouveau_bo
*bo
,
107 ret
= nouveau_bo_map(bo
, map_flags
);
109 debug_printf("map failed: %d\n", ret
);
117 nouveau_screen_bo_map_range(struct pipe_screen
*pscreen
, struct nouveau_bo
*bo
,
118 unsigned offset
, unsigned length
, unsigned flags
)
122 ret
= nouveau_bo_map_range(bo
, offset
, length
, flags
);
124 nouveau_bo_unmap(bo
);
125 if (!(flags
& NOUVEAU_BO_NOWAIT
) || ret
!= -EBUSY
)
126 debug_printf("map_range failed: %d\n", ret
);
130 return (char *)bo
->map
- offset
; /* why gallium? why? */
134 nouveau_screen_bo_map_flush_range(struct pipe_screen
*pscreen
, struct nouveau_bo
*bo
,
135 unsigned offset
, unsigned length
)
137 nouveau_bo_map_flush(bo
, offset
, length
);
141 nouveau_screen_bo_unmap(struct pipe_screen
*pscreen
, struct nouveau_bo
*bo
)
143 nouveau_bo_unmap(bo
);
147 nouveau_screen_bo_release(struct pipe_screen
*pscreen
, struct nouveau_bo
*bo
)
149 nouveau_bo_ref(NULL
, &bo
);
153 nouveau_screen_fence_ref(struct pipe_screen
*pscreen
,
154 struct pipe_fence_handle
**ptr
,
155 struct pipe_fence_handle
*pfence
)
161 nouveau_screen_fence_signalled(struct pipe_screen
*screen
,
162 struct pipe_fence_handle
*pfence
,
169 nouveau_screen_fence_finish(struct pipe_screen
*screen
,
170 struct pipe_fence_handle
*pfence
,
178 nouveau_screen_bo_from_handle(struct pipe_screen
*pscreen
,
179 struct winsys_handle
*whandle
,
180 unsigned *out_stride
)
182 struct nouveau_device
*dev
= nouveau_screen(pscreen
)->device
;
183 struct nouveau_bo
*bo
= 0;
186 ret
= nouveau_bo_handle_ref(dev
, whandle
->handle
, &bo
);
188 debug_printf("%s: ref name 0x%08x failed with %d\n",
189 __func__
, whandle
->handle
, ret
);
193 *out_stride
= whandle
->stride
;
199 nouveau_screen_bo_get_handle(struct pipe_screen
*pscreen
,
200 struct nouveau_bo
*bo
,
202 struct winsys_handle
*whandle
)
204 whandle
->stride
= stride
;
206 if (whandle
->type
== DRM_API_HANDLE_TYPE_SHARED
) {
207 return nouveau_bo_handle_get(bo
, &whandle
->handle
) == 0;
208 } else if (whandle
->type
== DRM_API_HANDLE_TYPE_KMS
) {
209 whandle
->handle
= bo
->handle
;
218 nouveau_reference_flags(struct nouveau_bo
*bo
)
223 bo_flags
= nouveau_bo_pending(bo
);
224 if (bo_flags
& NOUVEAU_BO_RD
)
225 flags
|= PIPE_REFERENCED_FOR_READ
;
226 if (bo_flags
& NOUVEAU_BO_WR
)
227 flags
|= PIPE_REFERENCED_FOR_WRITE
;
237 nouveau_screen_init(struct nouveau_screen
*screen
, struct nouveau_device
*dev
)
239 struct pipe_screen
*pscreen
= &screen
->base
;
242 ret
= nouveau_channel_alloc(dev
, 0xbeef0201, 0xbeef0202,
246 screen
->device
= dev
;
248 pscreen
->get_name
= nouveau_screen_get_name
;
249 pscreen
->get_vendor
= nouveau_screen_get_vendor
;
251 pscreen
->fence_reference
= nouveau_screen_fence_ref
;
252 pscreen
->fence_signalled
= nouveau_screen_fence_signalled
;
253 pscreen
->fence_finish
= nouveau_screen_fence_finish
;
259 nouveau_screen_fini(struct nouveau_screen
*screen
)
261 struct pipe_winsys
*ws
= screen
->base
.winsys
;
262 nouveau_channel_free(&screen
->channel
);