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
& 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_pipe_buffer(buf
);
108 nouveau_bo_ref(NULL
, &nvbuf
->bo
);
113 nouveau_pipe_bo_map(struct pipe_winsys
*pws
, struct pipe_buffer
*buf
,
116 struct nouveau_pipe_buffer
*nvbuf
= nouveau_pipe_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
;
125 if (flags
& PIPE_BUFFER_USAGE_DISCARD
&&
126 !(flags
& PIPE_BUFFER_USAGE_CPU_READ
) &&
127 nouveau_bo_busy(nvbuf
->bo
, map_flags
)) {
128 struct nouveau_pipe_winsys
*nvpws
= (struct nouveau_pipe_winsys
*)pws
;
129 struct nouveau_context
*nv
= nvpws
->nv
;
130 struct nouveau_device
*dev
= nv
->nv_screen
->device
;
131 struct nouveau_bo
*rename
;
132 uint32_t flags
= nouveau_flags_from_usage(nv
, buf
->usage
);
134 if (!nouveau_bo_new(dev
, flags
, buf
->alignment
, buf
->size
, &rename
)) {
135 nouveau_bo_ref(NULL
, &nvbuf
->bo
);
141 if (nouveau_bo_map(nvbuf
->bo
, map_flags
))
143 return nvbuf
->bo
->map
;
147 nouveau_pipe_bo_unmap(struct pipe_winsys
*pws
, struct pipe_buffer
*buf
)
149 struct nouveau_pipe_buffer
*nvbuf
= nouveau_pipe_buffer(buf
);
151 nouveau_bo_unmap(nvbuf
->bo
);
155 nouveau_pipe_fence_reference(struct pipe_winsys
*ws
,
156 struct pipe_fence_handle
**ptr
,
157 struct pipe_fence_handle
*pfence
)
163 nouveau_pipe_fence_signalled(struct pipe_winsys
*ws
,
164 struct pipe_fence_handle
*pfence
, unsigned flag
)
170 nouveau_pipe_fence_finish(struct pipe_winsys
*ws
,
171 struct pipe_fence_handle
*pfence
, unsigned flag
)
176 struct pipe_surface
*
177 nouveau_surface_buffer_ref(struct nouveau_context
*nv
, struct pipe_buffer
*pb
,
178 enum pipe_format format
, int w
, int h
,
179 unsigned pitch
, struct pipe_texture
**ppt
)
181 struct pipe_screen
*pscreen
= nv
->nvc
->pscreen
;
182 struct pipe_texture tmpl
, *pt
;
183 struct pipe_surface
*ps
;
185 memset(&tmpl
, 0, sizeof(tmpl
));
186 tmpl
.tex_usage
= PIPE_TEXTURE_USAGE_DISPLAY_TARGET
|
187 NOUVEAU_TEXTURE_USAGE_LINEAR
;
188 tmpl
.target
= PIPE_TEXTURE_2D
;
192 tmpl
.format
= format
;
193 pf_get_block(tmpl
.format
, &tmpl
.block
);
194 tmpl
.nblocksx
[0] = pf_get_nblocksx(&tmpl
.block
, w
);
195 tmpl
.nblocksy
[0] = pf_get_nblocksy(&tmpl
.block
, h
);
197 pt
= pscreen
->texture_blanket(pscreen
, &tmpl
, &pitch
, pb
);
201 ps
= pscreen
->get_tex_surface(pscreen
, pt
, 0, 0, 0,
202 PIPE_BUFFER_USAGE_GPU_WRITE
);
209 nouveau_destroy(struct pipe_winsys
*pws
)
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
->buffer_create
= nouveau_pipe_bo_create
;
229 pws
->buffer_destroy
= nouveau_pipe_bo_del
;
230 pws
->user_buffer_create
= nouveau_pipe_bo_user_create
;
231 pws
->buffer_map
= nouveau_pipe_bo_map
;
232 pws
->buffer_unmap
= nouveau_pipe_bo_unmap
;
234 pws
->fence_reference
= nouveau_pipe_fence_reference
;
235 pws
->fence_signalled
= nouveau_pipe_fence_signalled
;
236 pws
->fence_finish
= nouveau_pipe_fence_finish
;
238 pws
->get_name
= nouveau_get_name
;
239 pws
->destroy
= nouveau_destroy
;