1 #include "pipe/p_winsys.h"
2 #include "pipe/p_defines.h"
3 #include "pipe/p_inlines.h"
5 #include "util/u_memory.h"
7 #include "nouveau_context.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_buffer
*
30 nouveau_pipe_bo_create(struct pipe_winsys
*pws
, unsigned alignment
,
31 unsigned usage
, unsigned size
)
33 struct nouveau_pipe_winsys
*nvpws
= (struct nouveau_pipe_winsys
*)pws
;
34 struct nouveau_context
*nv
= nvpws
->nv
;
35 struct nouveau_device
*dev
= nv
->nv_screen
->device
;
36 struct nouveau_pipe_buffer
*nvbuf
;
39 nvbuf
= calloc(1, sizeof(*nvbuf
));
42 nvbuf
->base
.refcount
= 1;
43 nvbuf
->base
.alignment
= alignment
;
44 nvbuf
->base
.usage
= usage
;
45 nvbuf
->base
.size
= size
;
47 flags
= NOUVEAU_BO_LOCAL
;
49 if (usage
& PIPE_BUFFER_USAGE_PIXEL
) {
50 if (usage
& NOUVEAU_BUFFER_USAGE_TEXTURE
)
51 flags
|= NOUVEAU_BO_GART
;
52 flags
|= NOUVEAU_BO_VRAM
;
54 switch (dev
->chipset
& 0xf0) {
58 flags
|= NOUVEAU_BO_TILED
;
59 if (usage
& NOUVEAU_BUFFER_USAGE_ZETA
)
60 flags
|= NOUVEAU_BO_ZTILE
;
67 if (usage
& PIPE_BUFFER_USAGE_VERTEX
) {
68 if (nv
->cap
.hw_vertex_buffer
)
69 flags
|= NOUVEAU_BO_GART
;
72 if (usage
& PIPE_BUFFER_USAGE_INDEX
) {
73 if (nv
->cap
.hw_index_buffer
)
74 flags
|= NOUVEAU_BO_GART
;
77 if (nouveau_bo_new(dev
, flags
, alignment
, size
, &nvbuf
->bo
)) {
85 static struct pipe_buffer
*
86 nouveau_pipe_bo_user_create(struct pipe_winsys
*pws
, void *ptr
, unsigned bytes
)
88 struct nouveau_pipe_winsys
*nvpws
= (struct nouveau_pipe_winsys
*)pws
;
89 struct nouveau_device
*dev
= nvpws
->nv
->nv_screen
->device
;
90 struct nouveau_pipe_buffer
*nvbuf
;
92 nvbuf
= calloc(1, sizeof(*nvbuf
));
95 nvbuf
->base
.refcount
= 1;
96 nvbuf
->base
.size
= bytes
;
98 if (nouveau_bo_user(dev
, ptr
, bytes
, &nvbuf
->bo
)) {
107 nouveau_pipe_bo_del(struct pipe_winsys
*ws
, struct pipe_buffer
*buf
)
109 struct nouveau_pipe_buffer
*nvbuf
= nouveau_buffer(buf
);
111 nouveau_bo_del(&nvbuf
->bo
);
116 nouveau_pipe_bo_map(struct pipe_winsys
*pws
, struct pipe_buffer
*buf
,
119 struct nouveau_pipe_buffer
*nvbuf
= nouveau_buffer(buf
);
120 uint32_t map_flags
= 0;
122 if (flags
& PIPE_BUFFER_USAGE_CPU_READ
)
123 map_flags
|= NOUVEAU_BO_RD
;
124 if (flags
& PIPE_BUFFER_USAGE_CPU_WRITE
)
125 map_flags
|= NOUVEAU_BO_WR
;
127 if (nouveau_bo_map(nvbuf
->bo
, map_flags
))
129 return nvbuf
->bo
->map
;
133 nouveau_pipe_bo_unmap(struct pipe_winsys
*pws
, struct pipe_buffer
*buf
)
135 struct nouveau_pipe_buffer
*nvbuf
= nouveau_buffer(buf
);
137 nouveau_bo_unmap(nvbuf
->bo
);
140 static INLINE
struct nouveau_fence
*
141 nouveau_pipe_fence(struct pipe_fence_handle
*pfence
)
143 return (struct nouveau_fence
*)pfence
;
147 nouveau_pipe_fence_reference(struct pipe_winsys
*ws
,
148 struct pipe_fence_handle
**ptr
,
149 struct pipe_fence_handle
*pfence
)
151 nouveau_fence_ref((void *)pfence
, (void *)ptr
);
155 nouveau_pipe_fence_signalled(struct pipe_winsys
*ws
,
156 struct pipe_fence_handle
*pfence
, unsigned flag
)
158 struct nouveau_pipe_winsys
*nvpws
= (struct nouveau_pipe_winsys
*)ws
;
159 struct nouveau_fence
*fence
= nouveau_pipe_fence(pfence
);
161 if (nouveau_fence(fence
)->signalled
== 0)
162 nouveau_fence_flush(nvpws
->nv
->nvc
->channel
);
164 return !nouveau_fence(fence
)->signalled
;
168 nouveau_pipe_fence_finish(struct pipe_winsys
*ws
,
169 struct pipe_fence_handle
*pfence
, unsigned flag
)
171 struct nouveau_fence
*fence
= nouveau_pipe_fence(pfence
);
172 struct nouveau_fence
*ref
= NULL
;
174 nouveau_fence_ref(fence
, &ref
);
175 return nouveau_fence_wait(&ref
);
179 nouveau_create_pipe_winsys(struct nouveau_context
*nv
)
181 struct nouveau_pipe_winsys
*nvpws
;
182 struct pipe_winsys
*pws
;
184 nvpws
= CALLOC_STRUCT(nouveau_pipe_winsys
);
190 pws
->flush_frontbuffer
= nouveau_flush_frontbuffer
;
192 pws
->buffer_create
= nouveau_pipe_bo_create
;
193 pws
->buffer_destroy
= nouveau_pipe_bo_del
;
194 pws
->user_buffer_create
= nouveau_pipe_bo_user_create
;
195 pws
->buffer_map
= nouveau_pipe_bo_map
;
196 pws
->buffer_unmap
= nouveau_pipe_bo_unmap
;
198 pws
->fence_reference
= nouveau_pipe_fence_reference
;
199 pws
->fence_signalled
= nouveau_pipe_fence_signalled
;
200 pws
->fence_finish
= nouveau_pipe_fence_finish
;
202 pws
->get_name
= nouveau_get_name
;