1 #include "pipe/p_winsys.h"
2 #include "pipe/p_defines.h"
3 #include "pipe/p_util.h"
4 #include "pipe/p_inlines.h"
6 #include "nouveau_context.h"
7 #include "nouveau_local.h"
8 #include "nouveau_screen.h"
9 #include "nouveau_swapbuffers.h"
10 #include "nouveau_winsys_pipe.h"
13 nouveau_flush_frontbuffer(struct pipe_winsys
*pws
, struct pipe_surface
*surf
,
14 void *context_private
)
16 struct nouveau_context
*nv
= context_private
;
17 dri_drawable_t
*dri_drawable
= nv
->dri_drawable
;
19 nouveau_copy_buffer(dri_drawable
, surf
, NULL
);
23 nouveau_get_name(struct pipe_winsys
*pws
)
28 static struct pipe_surface
*
29 nouveau_surface_alloc(struct pipe_winsys
*ws
)
31 struct pipe_surface
*surf
;
33 surf
= CALLOC_STRUCT(pipe_surface
);
42 /* Borrowed from Mesa's xm_winsys */
44 round_up(unsigned n
, unsigned multiple
)
46 return (n
+ multiple
- 1) & ~(multiple
- 1);
50 nouveau_surface_alloc_storage
52 struct pipe_winsys
*pws
,
53 struct pipe_surface
*surface
,
56 enum pipe_format format
,
61 const unsigned int ALIGNMENT
= 256;
66 surface
->width
= width
;
67 surface
->height
= height
;
68 surface
->format
= format
;
69 pf_get_block(format
, &surface
->block
);
70 surface
->nblocksx
= pf_get_nblocksx(&surface
->block
, width
);
71 surface
->nblocksy
= pf_get_nblocksy(&surface
->block
, height
);
72 surface
->stride
= round_up(surface
->nblocksx
* surface
->block
.size
, ALIGNMENT
);
73 surface
->usage
= flags
;
74 surface
->buffer
= pws
->buffer_create(pws
, ALIGNMENT
, PIPE_BUFFER_USAGE_PIXEL
, surface
->stride
* surface
->nblocksy
);
80 nouveau_surface_release(struct pipe_winsys
*ws
, struct pipe_surface
**s
)
82 struct pipe_surface
*surf
= *s
;
85 if (--surf
->refcount
<= 0) {
87 pipe_buffer_reference(ws
, &surf
->buffer
, NULL
);
92 static struct pipe_buffer
*
93 nouveau_pipe_bo_create(struct pipe_winsys
*pws
, unsigned alignment
,
94 unsigned usage
, unsigned size
)
96 struct nouveau_pipe_winsys
*nvpws
= (struct nouveau_pipe_winsys
*)pws
;
97 struct nouveau_context
*nv
= nvpws
->nv
;
98 struct nouveau_device
*dev
= nv
->nv_screen
->device
;
99 struct nouveau_pipe_buffer
*nvbuf
;
102 nvbuf
= calloc(1, sizeof(*nvbuf
));
105 nvbuf
->base
.refcount
= 1;
106 nvbuf
->base
.alignment
= alignment
;
107 nvbuf
->base
.usage
= usage
;
108 nvbuf
->base
.size
= size
;
110 flags
= NOUVEAU_BO_LOCAL
;
112 if (usage
& PIPE_BUFFER_USAGE_PIXEL
) {
113 if (usage
& NOUVEAU_BUFFER_USAGE_TEXTURE
)
114 flags
|= NOUVEAU_BO_GART
;
115 flags
|= NOUVEAU_BO_VRAM
;
118 if (usage
& PIPE_BUFFER_USAGE_VERTEX
) {
119 if (nv
->cap
.hw_vertex_buffer
)
120 flags
|= NOUVEAU_BO_GART
;
123 if (usage
& PIPE_BUFFER_USAGE_INDEX
) {
124 if (nv
->cap
.hw_index_buffer
)
125 flags
|= NOUVEAU_BO_GART
;
128 if (nouveau_bo_new(dev
, flags
, alignment
, size
, &nvbuf
->bo
)) {
136 static struct pipe_buffer
*
137 nouveau_pipe_bo_user_create(struct pipe_winsys
*pws
, void *ptr
, unsigned bytes
)
139 struct nouveau_pipe_winsys
*nvpws
= (struct nouveau_pipe_winsys
*)pws
;
140 struct nouveau_device
*dev
= nvpws
->nv
->nv_screen
->device
;
141 struct nouveau_pipe_buffer
*nvbuf
;
143 nvbuf
= calloc(1, sizeof(*nvbuf
));
146 nvbuf
->base
.refcount
= 1;
147 nvbuf
->base
.size
= bytes
;
149 if (nouveau_bo_user(dev
, ptr
, bytes
, &nvbuf
->bo
)) {
158 nouveau_pipe_bo_del(struct pipe_winsys
*ws
, struct pipe_buffer
*buf
)
160 struct nouveau_pipe_buffer
*nvbuf
= nouveau_buffer(buf
);
162 nouveau_bo_del(&nvbuf
->bo
);
167 nouveau_pipe_bo_map(struct pipe_winsys
*pws
, struct pipe_buffer
*buf
,
170 struct nouveau_pipe_buffer
*nvbuf
= nouveau_buffer(buf
);
171 uint32_t map_flags
= 0;
173 if (flags
& PIPE_BUFFER_USAGE_CPU_READ
)
174 map_flags
|= NOUVEAU_BO_RD
;
175 if (flags
& PIPE_BUFFER_USAGE_CPU_WRITE
)
176 map_flags
|= NOUVEAU_BO_WR
;
178 if (nouveau_bo_map(nvbuf
->bo
, map_flags
))
180 return nvbuf
->bo
->map
;
184 nouveau_pipe_bo_unmap(struct pipe_winsys
*pws
, struct pipe_buffer
*buf
)
186 struct nouveau_pipe_buffer
*nvbuf
= nouveau_buffer(buf
);
188 nouveau_bo_unmap(nvbuf
->bo
);
191 static INLINE
struct nouveau_fence
*
192 nouveau_pipe_fence(struct pipe_fence_handle
*pfence
)
194 return (struct nouveau_fence
*)pfence
;
198 nouveau_pipe_fence_reference(struct pipe_winsys
*ws
,
199 struct pipe_fence_handle
**ptr
,
200 struct pipe_fence_handle
*pfence
)
202 nouveau_fence_ref((void *)pfence
, (void *)ptr
);
206 nouveau_pipe_fence_signalled(struct pipe_winsys
*ws
,
207 struct pipe_fence_handle
*pfence
, unsigned flag
)
209 struct nouveau_pipe_winsys
*nvpws
= (struct nouveau_pipe_winsys
*)ws
;
210 struct nouveau_fence
*fence
= nouveau_pipe_fence(pfence
);
212 if (nouveau_fence(fence
)->signalled
== 0)
213 nouveau_fence_flush(nvpws
->nv
->nvc
->channel
);
215 return !nouveau_fence(fence
)->signalled
;
219 nouveau_pipe_fence_finish(struct pipe_winsys
*ws
,
220 struct pipe_fence_handle
*pfence
, unsigned flag
)
222 struct nouveau_fence
*fence
= nouveau_pipe_fence(pfence
);
223 struct nouveau_fence
*ref
= NULL
;
225 nouveau_fence_ref(fence
, &ref
);
226 return nouveau_fence_wait(&ref
);
230 nouveau_create_pipe_winsys(struct nouveau_context
*nv
)
232 struct nouveau_pipe_winsys
*nvpws
;
233 struct pipe_winsys
*pws
;
235 nvpws
= CALLOC_STRUCT(nouveau_pipe_winsys
);
241 pws
->flush_frontbuffer
= nouveau_flush_frontbuffer
;
243 pws
->surface_alloc
= nouveau_surface_alloc
;
244 pws
->surface_alloc_storage
= nouveau_surface_alloc_storage
;
245 pws
->surface_release
= nouveau_surface_release
;
247 pws
->buffer_create
= nouveau_pipe_bo_create
;
248 pws
->buffer_destroy
= nouveau_pipe_bo_del
;
249 pws
->user_buffer_create
= nouveau_pipe_bo_user_create
;
250 pws
->buffer_map
= nouveau_pipe_bo_map
;
251 pws
->buffer_unmap
= nouveau_pipe_bo_unmap
;
253 pws
->fence_reference
= nouveau_pipe_fence_reference
;
254 pws
->fence_signalled
= nouveau_pipe_fence_signalled
;
255 pws
->fence_finish
= nouveau_pipe_fence_finish
;
257 pws
->get_name
= nouveau_get_name
;