1 #include "pipe/internal/p_winsys_screen.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
& NOUVEAU_BUFFER_USAGE_TRANSFER
)
23 flags
|= NOUVEAU_BO_GART
;
25 if (usage
& PIPE_BUFFER_USAGE_PIXEL
) {
26 if (usage
& NOUVEAU_BUFFER_USAGE_TEXTURE
)
27 flags
|= NOUVEAU_BO_GART
;
28 if (!(usage
& PIPE_BUFFER_USAGE_CPU_READ_WRITE
))
29 flags
|= NOUVEAU_BO_VRAM
;
31 switch (dev
->chipset
& 0xf0) {
35 flags
|= NOUVEAU_BO_TILED
;
36 if (usage
& NOUVEAU_BUFFER_USAGE_ZETA
)
37 flags
|= NOUVEAU_BO_ZTILE
;
44 if (usage
& PIPE_BUFFER_USAGE_VERTEX
) {
45 if (nv
->cap
.hw_vertex_buffer
)
46 flags
|= NOUVEAU_BO_GART
;
49 if (usage
& PIPE_BUFFER_USAGE_INDEX
) {
50 if (nv
->cap
.hw_index_buffer
)
51 flags
|= NOUVEAU_BO_GART
;
57 static struct pipe_buffer
*
58 nouveau_pipe_bo_create(struct pipe_winsys
*pws
, unsigned alignment
,
59 unsigned usage
, unsigned size
)
61 struct nouveau_pipe_winsys
*nvpws
= (struct nouveau_pipe_winsys
*)pws
;
62 struct nouveau_context
*nv
= nvpws
->nv
;
63 struct nouveau_device
*dev
= nv
->nv_screen
->device
;
64 struct nouveau_pipe_buffer
*nvbuf
;
67 nvbuf
= CALLOC_STRUCT(nouveau_pipe_buffer
);
70 nvbuf
->base
.refcount
= 1;
71 nvbuf
->base
.alignment
= alignment
;
72 nvbuf
->base
.usage
= usage
;
73 nvbuf
->base
.size
= size
;
75 flags
= nouveau_flags_from_usage(nv
, usage
);
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_STRUCT(nouveau_pipe_buffer
);
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_pipe_buffer(buf
);
111 nouveau_bo_ref(NULL
, &nvbuf
->bo
);
116 nouveau_pipe_bo_map(struct pipe_winsys
*pws
, struct pipe_buffer
*buf
,
119 struct nouveau_pipe_buffer
*nvbuf
= nouveau_pipe_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
;
128 if (flags
& PIPE_BUFFER_USAGE_DISCARD
&&
129 !(flags
& PIPE_BUFFER_USAGE_CPU_READ
) &&
130 nouveau_bo_busy(nvbuf
->bo
, map_flags
)) {
131 struct nouveau_pipe_winsys
*nvpws
= (struct nouveau_pipe_winsys
*)pws
;
132 struct nouveau_context
*nv
= nvpws
->nv
;
133 struct nouveau_device
*dev
= nv
->nv_screen
->device
;
134 struct nouveau_bo
*rename
;
135 uint32_t flags
= nouveau_flags_from_usage(nv
, buf
->usage
);
137 if (!nouveau_bo_new(dev
, flags
, buf
->alignment
, buf
->size
, &rename
)) {
138 nouveau_bo_ref(NULL
, &nvbuf
->bo
);
144 if (nouveau_bo_map(nvbuf
->bo
, map_flags
))
146 return nvbuf
->bo
->map
;
150 nouveau_pipe_bo_unmap(struct pipe_winsys
*pws
, struct pipe_buffer
*buf
)
152 struct nouveau_pipe_buffer
*nvbuf
= nouveau_pipe_buffer(buf
);
154 nouveau_bo_unmap(nvbuf
->bo
);
158 nouveau_pipe_fence_reference(struct pipe_winsys
*ws
,
159 struct pipe_fence_handle
**ptr
,
160 struct pipe_fence_handle
*pfence
)
166 nouveau_pipe_fence_signalled(struct pipe_winsys
*ws
,
167 struct pipe_fence_handle
*pfence
, unsigned flag
)
173 nouveau_pipe_fence_finish(struct pipe_winsys
*ws
,
174 struct pipe_fence_handle
*pfence
, unsigned flag
)
179 struct pipe_surface
*
180 nouveau_surface_buffer_ref(struct nouveau_context
*nv
, struct pipe_buffer
*pb
,
181 enum pipe_format format
, int w
, int h
,
182 unsigned pitch
, struct pipe_texture
**ppt
)
184 struct pipe_screen
*pscreen
= nv
->nvc
->pscreen
;
185 struct pipe_texture tmpl
, *pt
;
186 struct pipe_surface
*ps
;
188 memset(&tmpl
, 0, sizeof(tmpl
));
189 tmpl
.tex_usage
= PIPE_TEXTURE_USAGE_DISPLAY_TARGET
|
190 NOUVEAU_TEXTURE_USAGE_LINEAR
;
191 tmpl
.target
= PIPE_TEXTURE_2D
;
195 tmpl
.format
= format
;
196 pf_get_block(tmpl
.format
, &tmpl
.block
);
197 tmpl
.nblocksx
[0] = pf_get_nblocksx(&tmpl
.block
, w
);
198 tmpl
.nblocksy
[0] = pf_get_nblocksy(&tmpl
.block
, h
);
200 pt
= pscreen
->texture_blanket(pscreen
, &tmpl
, &pitch
, pb
);
204 ps
= pscreen
->get_tex_surface(pscreen
, pt
, 0, 0, 0,
205 PIPE_BUFFER_USAGE_GPU_WRITE
);
212 nouveau_destroy(struct pipe_winsys
*pws
)
218 nouveau_create_pipe_winsys(struct nouveau_context
*nv
)
220 struct nouveau_pipe_winsys
*nvpws
;
221 struct pipe_winsys
*pws
;
223 nvpws
= CALLOC_STRUCT(nouveau_pipe_winsys
);
229 pws
->flush_frontbuffer
= nouveau_flush_frontbuffer
;
231 pws
->buffer_create
= nouveau_pipe_bo_create
;
232 pws
->buffer_destroy
= nouveau_pipe_bo_del
;
233 pws
->user_buffer_create
= nouveau_pipe_bo_user_create
;
234 pws
->buffer_map
= nouveau_pipe_bo_map
;
235 pws
->buffer_unmap
= nouveau_pipe_bo_unmap
;
237 pws
->fence_reference
= nouveau_pipe_fence_reference
;
238 pws
->fence_signalled
= nouveau_pipe_fence_signalled
;
239 pws
->fence_finish
= nouveau_pipe_fence_finish
;
241 pws
->get_name
= nouveau_get_name
;
242 pws
->destroy
= nouveau_destroy
;