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_device.h"
8 #include "nouveau_local.h"
9 #include "nouveau_screen.h"
10 #include "nouveau_swapbuffers.h"
11 #include "nouveau_winsys_pipe.h"
14 nouveau_flush_frontbuffer(struct pipe_winsys
*pws
, struct pipe_surface
*surf
,
15 void *context_private
)
17 struct nouveau_context
*nv
= context_private
;
18 __DRIdrawablePrivate
*dPriv
= nv
->dri_drawable
;
20 nouveau_copy_buffer(dPriv
, surf
, NULL
);
24 nouveau_get_name(struct pipe_winsys
*pws
)
29 static struct pipe_surface
*
30 nouveau_surface_alloc(struct pipe_winsys
*ws
)
32 struct pipe_surface
*surf
;
34 surf
= CALLOC_STRUCT(pipe_surface
);
44 nouveau_surface_alloc_storage(struct pipe_winsys
*ws
, struct pipe_surface
*surf
,
45 unsigned width
, unsigned height
,
46 enum pipe_format format
, unsigned flags
)
48 unsigned pitch
= ((width
* pf_get_size(format
)) + 63) & ~63;
50 surf
->format
= format
;
52 surf
->height
= height
;
53 surf
->cpp
= pf_get_size(format
);
54 surf
->pitch
= pitch
/ surf
->cpp
;
56 surf
->buffer
= ws
->buffer_create(ws
, 256, PIPE_BUFFER_USAGE_PIXEL
,
65 nouveau_surface_release(struct pipe_winsys
*ws
, struct pipe_surface
**s
)
67 struct pipe_surface
*surf
= *s
;
70 if (--surf
->refcount
<= 0) {
72 pipe_buffer_reference(ws
, &surf
->buffer
, NULL
);
77 static struct pipe_buffer
*
78 nouveau_pipe_bo_create(struct pipe_winsys
*pws
, unsigned alignment
,
79 unsigned usage
, unsigned size
)
81 struct nouveau_pipe_winsys
*nvpws
= (struct nouveau_pipe_winsys
*)pws
;
82 struct nouveau_context
*nv
= nvpws
->nv
;
83 struct nouveau_device
*dev
= nv
->nv_screen
->device
;
84 struct nouveau_pipe_buffer
*nvbuf
;
87 nvbuf
= calloc(1, sizeof(*nvbuf
));
90 nvbuf
->base
.refcount
= 1;
91 nvbuf
->base
.alignment
= alignment
;
92 nvbuf
->base
.usage
= usage
;
93 nvbuf
->base
.size
= size
;
95 flags
= NOUVEAU_BO_LOCAL
;
97 if (usage
& PIPE_BUFFER_USAGE_PIXEL
) {
98 if (usage
& NOUVEAU_BUFFER_USAGE_TEXTURE
)
99 flags
|= NOUVEAU_BO_GART
;
100 flags
|= NOUVEAU_BO_VRAM
;
103 if (usage
& PIPE_BUFFER_USAGE_VERTEX
) {
104 if (nv
->cap
.hw_vertex_buffer
)
105 flags
|= NOUVEAU_BO_GART
;
108 if (usage
& PIPE_BUFFER_USAGE_INDEX
) {
109 if (nv
->cap
.hw_index_buffer
)
110 flags
|= NOUVEAU_BO_GART
;
113 if (nouveau_bo_new(dev
, flags
, alignment
, size
, &nvbuf
->bo
)) {
121 static struct pipe_buffer
*
122 nouveau_pipe_bo_user_create(struct pipe_winsys
*pws
, void *ptr
, unsigned bytes
)
124 struct nouveau_pipe_winsys
*nvpws
= (struct nouveau_pipe_winsys
*)pws
;
125 struct nouveau_device
*dev
= nvpws
->nv
->nv_screen
->device
;
126 struct nouveau_pipe_buffer
*nvbuf
;
128 nvbuf
= calloc(1, sizeof(*nvbuf
));
131 nvbuf
->base
.refcount
= 1;
132 nvbuf
->base
.size
= bytes
;
134 if (nouveau_bo_user(dev
, ptr
, bytes
, &nvbuf
->bo
)) {
143 nouveau_pipe_bo_del(struct pipe_winsys
*ws
, struct pipe_buffer
*buf
)
145 struct nouveau_pipe_buffer
*nvbuf
= nouveau_buffer(buf
);
147 nouveau_bo_del(&nvbuf
->bo
);
152 nouveau_pipe_bo_map(struct pipe_winsys
*pws
, struct pipe_buffer
*buf
,
155 struct nouveau_pipe_buffer
*nvbuf
= nouveau_buffer(buf
);
156 uint32_t map_flags
= 0;
158 if (flags
& PIPE_BUFFER_USAGE_CPU_READ
)
159 map_flags
|= NOUVEAU_BO_RD
;
160 if (flags
& PIPE_BUFFER_USAGE_CPU_WRITE
)
161 map_flags
|= NOUVEAU_BO_WR
;
163 if (nouveau_bo_map(nvbuf
->bo
, map_flags
))
165 return nvbuf
->bo
->map
;
169 nouveau_pipe_bo_unmap(struct pipe_winsys
*pws
, struct pipe_buffer
*buf
)
171 struct nouveau_pipe_buffer
*nvbuf
= nouveau_buffer(buf
);
173 nouveau_bo_unmap(nvbuf
->bo
);
176 static INLINE
struct nouveau_fence
*
177 nouveau_pipe_fence(struct pipe_fence_handle
*pfence
)
179 return (struct nouveau_fence
*)pfence
;
183 nouveau_pipe_fence_reference(struct pipe_winsys
*ws
,
184 struct pipe_fence_handle
**ptr
,
185 struct pipe_fence_handle
*pfence
)
187 nouveau_fence_ref((void *)pfence
, (void *)ptr
);
191 nouveau_pipe_fence_signalled(struct pipe_winsys
*ws
,
192 struct pipe_fence_handle
*pfence
, unsigned flag
)
194 struct nouveau_pipe_winsys
*nvpws
= (struct nouveau_pipe_winsys
*)ws
;
195 struct nouveau_fence
*fence
= nouveau_pipe_fence(pfence
);
197 if (nouveau_fence(fence
)->signalled
== 0)
198 nouveau_fence_flush(nvpws
->nv
->nvc
->channel
);
200 return !nouveau_fence(fence
)->signalled
;
204 nouveau_pipe_fence_finish(struct pipe_winsys
*ws
,
205 struct pipe_fence_handle
*pfence
, unsigned flag
)
207 struct nouveau_fence
*fence
= nouveau_pipe_fence(pfence
);
208 struct nouveau_fence
*ref
= NULL
;
210 nouveau_fence_ref(fence
, &ref
);
211 return nouveau_fence_wait(&ref
);
215 nouveau_create_pipe_winsys(struct nouveau_context
*nv
)
217 struct nouveau_pipe_winsys
*nvpws
;
218 struct pipe_winsys
*pws
;
220 nvpws
= CALLOC_STRUCT(nouveau_pipe_winsys
);
226 pws
->flush_frontbuffer
= nouveau_flush_frontbuffer
;
228 pws
->surface_alloc
= nouveau_surface_alloc
;
229 pws
->surface_alloc_storage
= nouveau_surface_alloc_storage
;
230 pws
->surface_release
= nouveau_surface_release
;
232 pws
->buffer_create
= nouveau_pipe_bo_create
;
233 pws
->buffer_destroy
= nouveau_pipe_bo_del
;
234 pws
->user_buffer_create
= nouveau_pipe_bo_user_create
;
235 pws
->buffer_map
= nouveau_pipe_bo_map
;
236 pws
->buffer_unmap
= nouveau_pipe_bo_unmap
;
238 pws
->fence_reference
= nouveau_pipe_fence_reference
;
239 pws
->fence_signalled
= nouveau_pipe_fence_signalled
;
240 pws
->fence_finish
= nouveau_pipe_fence_finish
;
242 pws
->get_name
= nouveau_get_name
;