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"
15 #include "nouveau/nouveau_bo.h"
16 #include "nouveau/nouveau_mm.h"
17 #include "nouveau_winsys.h"
18 #include "nouveau_screen.h"
19 #include "nouveau_fence.h"
21 /* XXX this should go away */
22 #include "state_tracker/drm_driver.h"
24 #include "nouveau_drmif.h"
26 int nouveau_mesa_debug
= 0;
29 nouveau_screen_get_name(struct pipe_screen
*pscreen
)
31 struct nouveau_device
*dev
= nouveau_screen(pscreen
)->device
;
32 static char buffer
[128];
34 util_snprintf(buffer
, sizeof(buffer
), "NV%02X", dev
->chipset
);
39 nouveau_screen_get_vendor(struct pipe_screen
*pscreen
)
47 nouveau_screen_bo_new(struct pipe_screen
*pscreen
, unsigned alignment
,
48 unsigned usage
, unsigned bind
, unsigned size
)
50 struct nouveau_device
*dev
= nouveau_screen(pscreen
)->device
;
51 struct nouveau_bo
*bo
= NULL
;
52 uint32_t flags
= NOUVEAU_BO_MAP
, tile_mode
= 0, tile_flags
= 0;
55 if (bind
& PIPE_BIND_VERTEX_BUFFER
)
56 flags
|= nouveau_screen(pscreen
)->vertex_buffer_flags
;
57 else if (bind
& PIPE_BIND_INDEX_BUFFER
)
58 flags
|= nouveau_screen(pscreen
)->index_buffer_flags
;
60 if (bind
& (PIPE_BIND_RENDER_TARGET
|
61 PIPE_BIND_DEPTH_STENCIL
|
63 PIPE_BIND_DISPLAY_TARGET
|
64 PIPE_BIND_SAMPLER_VIEW
))
66 /* TODO: this may be incorrect or suboptimal */
67 if (!(bind
& PIPE_BIND_SCANOUT
))
68 flags
|= NOUVEAU_BO_GART
;
69 if (usage
!= PIPE_USAGE_DYNAMIC
)
70 flags
|= NOUVEAU_BO_VRAM
;
72 if (dev
->chipset
== 0x50 || dev
->chipset
>= 0x80) {
73 if (bind
& PIPE_BIND_DEPTH_STENCIL
)
80 ret
= nouveau_bo_new_tile(dev
, flags
, alignment
, size
,
81 tile_mode
, tile_flags
, &bo
);
89 nouveau_screen_bo_map(struct pipe_screen
*pscreen
,
90 struct nouveau_bo
*bo
,
95 ret
= nouveau_bo_map(bo
, map_flags
);
97 debug_printf("map failed: %d\n", ret
);
105 nouveau_screen_bo_map_range(struct pipe_screen
*pscreen
, struct nouveau_bo
*bo
,
106 unsigned offset
, unsigned length
, unsigned flags
)
110 ret
= nouveau_bo_map_range(bo
, offset
, length
, flags
);
112 nouveau_bo_unmap(bo
);
113 if (!(flags
& NOUVEAU_BO_NOWAIT
) || ret
!= -EBUSY
)
114 debug_printf("map_range failed: %d\n", ret
);
118 return (char *)bo
->map
- offset
; /* why gallium? why? */
122 nouveau_screen_bo_map_flush_range(struct pipe_screen
*pscreen
, struct nouveau_bo
*bo
,
123 unsigned offset
, unsigned length
)
125 nouveau_bo_map_flush(bo
, offset
, length
);
129 nouveau_screen_bo_unmap(struct pipe_screen
*pscreen
, struct nouveau_bo
*bo
)
131 nouveau_bo_unmap(bo
);
135 nouveau_screen_bo_release(struct pipe_screen
*pscreen
, struct nouveau_bo
*bo
)
137 nouveau_bo_ref(NULL
, &bo
);
141 nouveau_screen_fence_ref(struct pipe_screen
*pscreen
,
142 struct pipe_fence_handle
**ptr
,
143 struct pipe_fence_handle
*pfence
)
145 nouveau_fence_ref(nouveau_fence(pfence
), (struct nouveau_fence
**)ptr
);
149 nouveau_screen_fence_signalled(struct pipe_screen
*screen
,
150 struct pipe_fence_handle
*pfence
)
152 return nouveau_fence_signalled(nouveau_fence(pfence
));
156 nouveau_screen_fence_finish(struct pipe_screen
*screen
,
157 struct pipe_fence_handle
*pfence
,
160 return nouveau_fence_wait(nouveau_fence(pfence
));
165 nouveau_screen_bo_from_handle(struct pipe_screen
*pscreen
,
166 struct winsys_handle
*whandle
,
167 unsigned *out_stride
)
169 struct nouveau_device
*dev
= nouveau_screen(pscreen
)->device
;
170 struct nouveau_bo
*bo
= 0;
173 ret
= nouveau_bo_handle_ref(dev
, whandle
->handle
, &bo
);
175 debug_printf("%s: ref name 0x%08x failed with %d\n",
176 __FUNCTION__
, whandle
->handle
, ret
);
180 *out_stride
= whandle
->stride
;
186 nouveau_screen_bo_get_handle(struct pipe_screen
*pscreen
,
187 struct nouveau_bo
*bo
,
189 struct winsys_handle
*whandle
)
191 whandle
->stride
= stride
;
193 if (whandle
->type
== DRM_API_HANDLE_TYPE_SHARED
) {
194 return nouveau_bo_handle_get(bo
, &whandle
->handle
) == 0;
195 } else if (whandle
->type
== DRM_API_HANDLE_TYPE_KMS
) {
196 whandle
->handle
= bo
->handle
;
204 nouveau_screen_init(struct nouveau_screen
*screen
, struct nouveau_device
*dev
)
206 struct pipe_screen
*pscreen
= &screen
->base
;
209 char *nv_dbg
= getenv("NOUVEAU_MESA_DEBUG");
211 nouveau_mesa_debug
= atoi(nv_dbg
);
213 ret
= nouveau_channel_alloc(dev
, 0xbeef0201, 0xbeef0202,
214 512*1024, &screen
->channel
);
217 screen
->device
= dev
;
219 pscreen
->get_name
= nouveau_screen_get_name
;
220 pscreen
->get_vendor
= nouveau_screen_get_vendor
;
222 pscreen
->fence_reference
= nouveau_screen_fence_ref
;
223 pscreen
->fence_signalled
= nouveau_screen_fence_signalled
;
224 pscreen
->fence_finish
= nouveau_screen_fence_finish
;
226 util_format_s3tc_init();
228 screen
->mm_GART
= nouveau_mm_create(dev
,
229 NOUVEAU_BO_GART
| NOUVEAU_BO_MAP
,
231 screen
->mm_VRAM
= nouveau_mm_create(dev
, NOUVEAU_BO_VRAM
, 0x000);
236 nouveau_screen_fini(struct nouveau_screen
*screen
)
238 nouveau_mm_destroy(screen
->mm_GART
);
239 nouveau_mm_destroy(screen
->mm_VRAM
);
241 nouveau_channel_free(&screen
->channel
);
243 nouveau_device_close(&screen
->device
);