1 #include <pipe/p_winsys.h>
2 #include <pipe/p_defines.h>
3 #include <pipe/p_inlines.h>
4 #include <util/u_memory.h>
5 #include "nouveau_context.h"
6 #include "nouveau_local.h"
7 #include "nouveau_screen.h"
8 #include "nouveau_winsys_pipe.h"
11 nouveau_get_name(struct pipe_winsys
*pws
)
17 nouveau_flags_from_usage(struct nouveau_context
*nv
, unsigned usage
)
19 struct nouveau_device
*dev
= nv
->nv_screen
->device
;
20 uint32_t flags
= NOUVEAU_BO_LOCAL
;
22 if (usage
& PIPE_BUFFER_USAGE_PIXEL
) {
23 if (usage
& NOUVEAU_BUFFER_USAGE_TEXTURE
)
24 flags
|= NOUVEAU_BO_GART
;
25 if (!(usage
& PIPE_BUFFER_USAGE_CPU_READ_WRITE
))
26 flags
|= NOUVEAU_BO_VRAM
;
28 switch (dev
->chipset
& 0xf0) {
32 flags
|= NOUVEAU_BO_TILED
;
33 if (usage
& NOUVEAU_BUFFER_USAGE_ZETA
)
34 flags
|= NOUVEAU_BO_ZTILE
;
41 if (usage
& PIPE_BUFFER_USAGE_VERTEX
) {
42 if (nv
->cap
.hw_vertex_buffer
)
43 flags
|= NOUVEAU_BO_GART
;
46 if (usage
& PIPE_BUFFER_USAGE_INDEX
) {
47 if (nv
->cap
.hw_index_buffer
)
48 flags
|= NOUVEAU_BO_GART
;
54 static struct pipe_buffer
*
55 nouveau_pipe_bo_create(struct pipe_winsys
*pws
, unsigned alignment
,
56 unsigned usage
, unsigned size
)
58 struct nouveau_pipe_winsys
*nvpws
= (struct nouveau_pipe_winsys
*)pws
;
59 struct nouveau_context
*nv
= nvpws
->nv
;
60 struct nouveau_device
*dev
= nv
->nv_screen
->device
;
61 struct nouveau_pipe_buffer
*nvbuf
;
64 nvbuf
= CALLOC_STRUCT(nouveau_pipe_buffer
);
67 nvbuf
->base
.refcount
= 1;
68 nvbuf
->base
.alignment
= alignment
;
69 nvbuf
->base
.usage
= usage
;
70 nvbuf
->base
.size
= size
;
72 flags
= nouveau_flags_from_usage(nv
, usage
);
74 if (nouveau_bo_new(dev
, flags
, alignment
, size
, &nvbuf
->bo
)) {
82 static struct pipe_buffer
*
83 nouveau_pipe_bo_user_create(struct pipe_winsys
*pws
, void *ptr
, unsigned bytes
)
85 struct nouveau_pipe_winsys
*nvpws
= (struct nouveau_pipe_winsys
*)pws
;
86 struct nouveau_device
*dev
= nvpws
->nv
->nv_screen
->device
;
87 struct nouveau_pipe_buffer
*nvbuf
;
89 nvbuf
= CALLOC_STRUCT(nouveau_pipe_buffer
);
92 nvbuf
->base
.refcount
= 1;
93 nvbuf
->base
.size
= bytes
;
95 if (nouveau_bo_user(dev
, ptr
, bytes
, &nvbuf
->bo
)) {
104 nouveau_pipe_bo_del(struct pipe_winsys
*ws
, struct pipe_buffer
*buf
)
106 struct nouveau_pipe_buffer
*nvbuf
= nouveau_buffer(buf
);
108 nouveau_bo_del(&nvbuf
->bo
);
113 nouveau_pipe_bo_map(struct pipe_winsys
*pws
, struct pipe_buffer
*buf
,
116 struct nouveau_pipe_buffer
*nvbuf
= nouveau_buffer(buf
);
117 uint32_t map_flags
= 0;
119 if (flags
& PIPE_BUFFER_USAGE_CPU_READ
)
120 map_flags
|= NOUVEAU_BO_RD
;
121 if (flags
& PIPE_BUFFER_USAGE_CPU_WRITE
)
122 map_flags
|= NOUVEAU_BO_WR
;
124 if (nouveau_bo_map(nvbuf
->bo
, map_flags
))
126 return nvbuf
->bo
->map
;
130 nouveau_pipe_bo_unmap(struct pipe_winsys
*pws
, struct pipe_buffer
*buf
)
132 struct nouveau_pipe_buffer
*nvbuf
= nouveau_buffer(buf
);
134 nouveau_bo_unmap(nvbuf
->bo
);
137 static INLINE
struct nouveau_fence
*
138 nouveau_pipe_fence(struct pipe_fence_handle
*pfence
)
140 return (struct nouveau_fence
*)pfence
;
144 nouveau_pipe_fence_reference(struct pipe_winsys
*ws
,
145 struct pipe_fence_handle
**ptr
,
146 struct pipe_fence_handle
*pfence
)
148 nouveau_fence_ref((void *)pfence
, (void *)ptr
);
152 nouveau_pipe_fence_signalled(struct pipe_winsys
*ws
,
153 struct pipe_fence_handle
*pfence
, unsigned flag
)
155 struct nouveau_pipe_winsys
*nvpws
= (struct nouveau_pipe_winsys
*)ws
;
156 struct nouveau_fence
*fence
= nouveau_pipe_fence(pfence
);
158 if (nouveau_fence(fence
)->signalled
== 0)
159 nouveau_fence_flush(nvpws
->nv
->nvc
->channel
);
161 return !nouveau_fence(fence
)->signalled
;
165 nouveau_pipe_fence_finish(struct pipe_winsys
*ws
,
166 struct pipe_fence_handle
*pfence
, unsigned flag
)
168 struct nouveau_fence
*fence
= nouveau_pipe_fence(pfence
);
169 struct nouveau_fence
*ref
= NULL
;
171 nouveau_fence_ref(fence
, &ref
);
172 return nouveau_fence_wait(&ref
);
176 nouveau_destroy(struct pipe_winsys
*pws
)
182 nouveau_create_pipe_winsys(struct nouveau_context
*nv
)
184 struct nouveau_pipe_winsys
*nvpws
;
185 struct pipe_winsys
*pws
;
187 nvpws
= CALLOC_STRUCT(nouveau_pipe_winsys
);
193 pws
->flush_frontbuffer
= nouveau_flush_frontbuffer
;
195 pws
->buffer_create
= nouveau_pipe_bo_create
;
196 pws
->buffer_destroy
= nouveau_pipe_bo_del
;
197 pws
->user_buffer_create
= nouveau_pipe_bo_user_create
;
198 pws
->buffer_map
= nouveau_pipe_bo_map
;
199 pws
->buffer_unmap
= nouveau_pipe_bo_unmap
;
201 pws
->fence_reference
= nouveau_pipe_fence_reference
;
202 pws
->fence_signalled
= nouveau_pipe_fence_signalled
;
203 pws
->fence_finish
= nouveau_pipe_fence_finish
;
205 pws
->get_name
= nouveau_get_name
;
206 pws
->destroy
= nouveau_destroy
;