nouveau: match gallium code reorginisation.
[mesa.git] / src / gallium / winsys / dri / nouveau / nouveau_winsys_pipe.c
1 #include "pipe/p_winsys.h"
2 #include "pipe/p_defines.h"
3 #include "pipe/p_util.h"
4 #include "pipe/p_inlines.h"
5
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"
12
13 static void
14 nouveau_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surf,
15 void *context_private)
16 {
17 struct nouveau_context *nv = context_private;
18 __DRIdrawablePrivate *dPriv = nv->dri_drawable;
19
20 nouveau_copy_buffer(dPriv, surf, NULL);
21 }
22
23 static void
24 nouveau_printf(struct pipe_winsys *pws, const char *fmt, ...)
25 {
26 va_list args;
27 va_start(args, fmt);
28 vfprintf(stderr, fmt, args);
29 va_end(args);
30 }
31
32 static const char *
33 nouveau_get_name(struct pipe_winsys *pws)
34 {
35 return "Nouveau/DRI";
36 }
37
38 static struct pipe_surface *
39 nouveau_surface_alloc(struct pipe_winsys *ws)
40 {
41 struct pipe_surface *surf;
42
43 surf = CALLOC_STRUCT(pipe_surface);
44 if (!surf)
45 return NULL;
46
47 surf->refcount = 1;
48 surf->winsys = ws;
49 return surf;
50 }
51
52 static int
53 nouveau_surface_alloc_storage(struct pipe_winsys *ws, struct pipe_surface *surf,
54 unsigned width, unsigned height,
55 enum pipe_format format, unsigned flags)
56 {
57 unsigned pitch = ((width * pf_get_size(format)) + 63) & ~63;
58
59 surf->format = format;
60 surf->width = width;
61 surf->height = height;
62 surf->cpp = pf_get_size(format);
63 surf->pitch = pitch / surf->cpp;
64
65 surf->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL,
66 pitch * height);
67 if (!surf->buffer)
68 return 1;
69
70 return 0;
71 }
72
73 static void
74 nouveau_surface_release(struct pipe_winsys *ws, struct pipe_surface **s)
75 {
76 struct pipe_surface *surf = *s;
77
78 *s = NULL;
79 if (--surf->refcount <= 0) {
80 if (surf->buffer)
81 pipe_buffer_reference(ws, &surf->buffer, NULL);
82 free(surf);
83 }
84 }
85
86 static struct pipe_buffer *
87 nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment,
88 unsigned usage, unsigned size)
89 {
90 struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws;
91 struct nouveau_device *dev = nvpws->nv->nv_screen->device;
92 struct nouveau_pipe_buffer *nvbuf;
93 uint32_t flags = 0;
94
95 nvbuf = calloc(1, sizeof(*nvbuf));
96 if (!nvbuf)
97 return NULL;
98 nvbuf->base.refcount = 1;
99 nvbuf->base.alignment = alignment;
100 nvbuf->base.usage = usage;
101 nvbuf->base.size = size;
102
103 flags = NOUVEAU_BO_LOCAL;
104 if (nouveau_bo_new(dev, flags, alignment, size, &nvbuf->bo)) {
105 free(nvbuf);
106 return NULL;
107 }
108
109 return &nvbuf->base;
110 }
111
112 static struct pipe_buffer *
113 nouveau_pipe_bo_user_create(struct pipe_winsys *pws, void *ptr, unsigned bytes)
114 {
115 struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws;
116 struct nouveau_device *dev = nvpws->nv->nv_screen->device;
117 struct nouveau_pipe_buffer *nvbuf;
118
119 nvbuf = calloc(1, sizeof(*nvbuf));
120 if (!nvbuf)
121 return NULL;
122 nvbuf->base.refcount = 1;
123 nvbuf->base.size = bytes;
124
125 if (nouveau_bo_user(dev, ptr, bytes, &nvbuf->bo)) {
126 free(nvbuf);
127 return NULL;
128 }
129
130 return &nvbuf->base;
131 }
132
133 static void
134 nouveau_pipe_bo_del(struct pipe_winsys *ws, struct pipe_buffer *buf)
135 {
136 struct nouveau_pipe_buffer *nvbuf = nouveau_buffer(buf);
137
138 nouveau_bo_del(&nvbuf->bo);
139 free(nvbuf);
140 }
141
142 static void *
143 nouveau_pipe_bo_map(struct pipe_winsys *pws, struct pipe_buffer *buf,
144 unsigned flags)
145 {
146 struct nouveau_pipe_buffer *nvbuf = nouveau_buffer(buf);
147 uint32_t map_flags = 0;
148
149 if (flags & PIPE_BUFFER_USAGE_CPU_READ)
150 map_flags |= NOUVEAU_BO_RD;
151 if (flags & PIPE_BUFFER_USAGE_CPU_WRITE)
152 map_flags |= NOUVEAU_BO_WR;
153
154 if (nouveau_bo_map(nvbuf->bo, map_flags))
155 return NULL;
156 return nvbuf->bo->map;
157 }
158
159 static void
160 nouveau_pipe_bo_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf)
161 {
162 struct nouveau_pipe_buffer *nvbuf = nouveau_buffer(buf);
163
164 nouveau_bo_unmap(nvbuf->bo);
165 }
166
167 struct pipe_winsys *
168 nouveau_create_pipe_winsys(struct nouveau_context *nv)
169 {
170 struct nouveau_pipe_winsys *nvpws;
171 struct pipe_winsys *pws;
172
173 nvpws = CALLOC_STRUCT(nouveau_pipe_winsys);
174 if (!nvpws)
175 return NULL;
176 nvpws->nv = nv;
177 pws = &nvpws->pws;
178
179 pws->flush_frontbuffer = nouveau_flush_frontbuffer;
180 pws->printf = nouveau_printf;
181
182 pws->surface_alloc = nouveau_surface_alloc;
183 pws->surface_alloc_storage = nouveau_surface_alloc_storage;
184 pws->surface_release = nouveau_surface_release;
185
186 pws->buffer_create = nouveau_pipe_bo_create;
187 pws->buffer_destroy = nouveau_pipe_bo_del;
188 pws->user_buffer_create = nouveau_pipe_bo_user_create;
189 pws->buffer_map = nouveau_pipe_bo_map;
190 pws->buffer_unmap = nouveau_pipe_bo_unmap;
191
192 pws->get_name = nouveau_get_name;
193
194 return &nvpws->pws;
195 }
196