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"
11 #include "nouveau/nouveau_bo.h"
12 #include "nouveau_winsys.h"
13 #include "nouveau_screen.h"
16 nouveau_screen_get_name(struct pipe_screen
*pscreen
)
18 struct nouveau_device
*dev
= nouveau_screen(pscreen
)->device
;
19 static char buffer
[128];
21 snprintf(buffer
, sizeof(buffer
), "NV%02X", dev
->chipset
);
26 nouveau_screen_get_vendor(struct pipe_screen
*pscreen
)
31 static struct pipe_buffer
*
32 nouveau_screen_bo_skel(struct pipe_screen
*pscreen
, struct nouveau_bo
*bo
,
33 unsigned alignment
, unsigned usage
, unsigned size
)
35 struct pipe_buffer
*pb
;
37 pb
= CALLOC(1, sizeof(struct pipe_buffer
)+sizeof(struct nouveau_bo
*));
39 nouveau_bo_ref(NULL
, &bo
);
43 pipe_reference_init(&pb
->reference
, 1);
45 pb
->alignment
= alignment
;
48 *(struct nouveau_bo
**)(pb
+ 1) = bo
;
52 static struct pipe_buffer
*
53 nouveau_screen_bo_new(struct pipe_screen
*pscreen
, unsigned alignment
,
54 unsigned usage
, unsigned size
)
56 struct nouveau_device
*dev
= nouveau_screen(pscreen
)->device
;
57 struct nouveau_bo
*bo
= NULL
;
58 uint32_t flags
= NOUVEAU_BO_MAP
, tile_mode
= 0, tile_flags
= 0;
61 if (usage
& NOUVEAU_BUFFER_USAGE_TRANSFER
)
62 flags
|= NOUVEAU_BO_GART
;
64 if (usage
& PIPE_BUFFER_USAGE_VERTEX
) {
65 if (pscreen
->get_param(pscreen
, NOUVEAU_CAP_HW_VTXBUF
))
66 flags
|= NOUVEAU_BO_GART
;
68 if (usage
& PIPE_BUFFER_USAGE_INDEX
) {
69 if (pscreen
->get_param(pscreen
, NOUVEAU_CAP_HW_IDXBUF
))
70 flags
|= NOUVEAU_BO_GART
;
73 if (usage
& PIPE_BUFFER_USAGE_PIXEL
) {
74 if (usage
& NOUVEAU_BUFFER_USAGE_TEXTURE
)
75 flags
|= NOUVEAU_BO_GART
;
76 if (!(usage
& PIPE_BUFFER_USAGE_CPU_READ_WRITE
))
77 flags
|= NOUVEAU_BO_VRAM
;
79 if (dev
->chipset
== 0x50 || dev
->chipset
>= 0x80) {
80 if (usage
& NOUVEAU_BUFFER_USAGE_ZETA
)
87 ret
= nouveau_bo_new_tile(dev
, flags
, alignment
, size
,
88 tile_mode
, tile_flags
, &bo
);
92 return nouveau_screen_bo_skel(pscreen
, bo
, alignment
, usage
, size
);
95 static struct pipe_buffer
*
96 nouveau_screen_bo_user(struct pipe_screen
*pscreen
, void *ptr
, unsigned bytes
)
98 struct nouveau_device
*dev
= nouveau_screen(pscreen
)->device
;
99 struct nouveau_bo
*bo
= NULL
;
102 ret
= nouveau_bo_user(dev
, ptr
, bytes
, &bo
);
106 return nouveau_screen_bo_skel(pscreen
, bo
, 0, 0, bytes
);
109 static inline uint32_t
110 nouveau_screen_map_flags(unsigned pipe
)
114 if (pipe
& PIPE_BUFFER_USAGE_CPU_READ
)
115 flags
|= NOUVEAU_BO_RD
;
116 if (pipe
& PIPE_BUFFER_USAGE_CPU_WRITE
)
117 flags
|= NOUVEAU_BO_WR
;
118 if (pipe
& PIPE_BUFFER_USAGE_DISCARD
)
119 flags
|= NOUVEAU_BO_INVAL
;
120 if (pipe
& PIPE_BUFFER_USAGE_DONTBLOCK
)
121 flags
|= NOUVEAU_BO_NOWAIT
;
123 if (pipe
& 0 /*PIPE_BUFFER_USAGE_UNSYNCHRONIZED*/)
124 flags
|= NOUVEAU_BO_NOSYNC
;
130 nouveau_screen_bo_map(struct pipe_screen
*pscreen
, struct pipe_buffer
*pb
,
133 struct nouveau_bo
*bo
= nouveau_bo(pb
);
134 struct nouveau_screen
*nscreen
= nouveau_screen(pscreen
);
137 if (nscreen
->pre_pipebuffer_map_callback
) {
138 ret
= nscreen
->pre_pipebuffer_map_callback(pscreen
, pb
, usage
);
140 debug_printf("pre_pipebuffer_map_callback failed %d\n",
146 ret
= nouveau_bo_map(bo
, nouveau_screen_map_flags(usage
));
148 debug_printf("map failed: %d\n", ret
);
156 nouveau_screen_bo_map_range(struct pipe_screen
*pscreen
, struct pipe_buffer
*pb
,
157 unsigned offset
, unsigned length
, unsigned usage
)
159 struct nouveau_bo
*bo
= nouveau_bo(pb
);
160 struct nouveau_screen
*nscreen
= nouveau_screen(pscreen
);
161 uint32_t flags
= nouveau_screen_map_flags(usage
);
164 if (nscreen
->pre_pipebuffer_map_callback
) {
165 ret
= nscreen
->pre_pipebuffer_map_callback(pscreen
, pb
, usage
);
167 debug_printf("pre_pipebuffer_map_callback failed %d\n",
173 ret
= nouveau_bo_map_range(bo
, offset
, length
, flags
);
175 nouveau_bo_unmap(bo
);
176 if (!(flags
& NOUVEAU_BO_NOWAIT
) || ret
!= -EBUSY
)
177 debug_printf("map_range failed: %d\n", ret
);
181 return (char *)bo
->map
- offset
; /* why gallium? why? */
185 nouveau_screen_bo_map_flush(struct pipe_screen
*pscreen
, struct pipe_buffer
*pb
,
186 unsigned offset
, unsigned length
)
188 struct nouveau_bo
*bo
= nouveau_bo(pb
);
190 nouveau_bo_map_flush(bo
, offset
, length
);
194 nouveau_screen_bo_unmap(struct pipe_screen
*pscreen
, struct pipe_buffer
*pb
)
196 struct nouveau_bo
*bo
= nouveau_bo(pb
);
198 nouveau_bo_unmap(bo
);
202 nouveau_screen_bo_del(struct pipe_buffer
*pb
)
204 struct nouveau_bo
*bo
= nouveau_bo(pb
);
206 nouveau_bo_ref(NULL
, &bo
);
211 nouveau_screen_fence_ref(struct pipe_screen
*pscreen
,
212 struct pipe_fence_handle
**ptr
,
213 struct pipe_fence_handle
*pfence
)
219 nouveau_screen_fence_signalled(struct pipe_screen
*screen
,
220 struct pipe_fence_handle
*pfence
,
227 nouveau_screen_fence_finish(struct pipe_screen
*screen
,
228 struct pipe_fence_handle
*pfence
,
235 nouveau_screen_init(struct nouveau_screen
*screen
, struct nouveau_device
*dev
)
237 struct pipe_screen
*pscreen
= &screen
->base
;
240 ret
= nouveau_channel_alloc(dev
, 0xbeef0201, 0xbeef0202,
244 screen
->device
= dev
;
246 pscreen
->get_name
= nouveau_screen_get_name
;
247 pscreen
->get_vendor
= nouveau_screen_get_vendor
;
249 pscreen
->buffer_create
= nouveau_screen_bo_new
;
250 pscreen
->user_buffer_create
= nouveau_screen_bo_user
;
251 pscreen
->buffer_map
= nouveau_screen_bo_map
;
252 pscreen
->buffer_map_range
= nouveau_screen_bo_map_range
;
253 pscreen
->buffer_flush_mapped_range
= nouveau_screen_bo_map_flush
;
254 pscreen
->buffer_unmap
= nouveau_screen_bo_unmap
;
255 pscreen
->buffer_destroy
= nouveau_screen_bo_del
;
257 pscreen
->fence_reference
= nouveau_screen_fence_ref
;
258 pscreen
->fence_signalled
= nouveau_screen_fence_signalled
;
259 pscreen
->fence_finish
= nouveau_screen_fence_finish
;
265 nouveau_screen_fini(struct nouveau_screen
*screen
)
267 struct pipe_winsys
*ws
= screen
->base
.winsys
;
268 nouveau_channel_free(&screen
->channel
);