remove INTEL_FIREVERTICES
[mesa.git] / src / mesa / drivers / dri / intel_winsys / intel_winsys_pipe.c
1 /**************************************************************************
2 *
3 * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
18 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 * USE OR OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
24 * of the Software.
25 *
26 *
27 **************************************************************************/
28 /*
29 * Authors: Keith Whitwell <keithw-at-tungstengraphics-dot-com>
30 */
31
32 #include <stdlib.h>
33 #include <xf86drm.h>
34 #include "dri_bufpool.h"
35 #include "dri_bufmgr.h"
36
37 #include "intel_context.h"
38 #include "intel_winsys.h"
39 #include "intel_swapbuffers.h"
40 #include "intel_batchbuffer.h"
41
42 #include "pipe/p_winsys.h"
43 #include "pipe/p_defines.h"
44 #include "pipe/p_state.h"
45 #include "pipe/p_util.h"
46
47
48
49 struct intel_pipe_winsys {
50 struct pipe_winsys winsys;
51 struct intel_context *intel;
52 };
53
54
55
56 /* Turn a pipe winsys into an intel/pipe winsys:
57 */
58 static inline struct intel_pipe_winsys *
59 intel_pipe_winsys( struct pipe_winsys *sws )
60 {
61 return (struct intel_pipe_winsys *)sws;
62 }
63
64
65 /* Most callbacks map direcly onto dri_bufmgr operations:
66 */
67 static void *intel_buffer_map(struct pipe_winsys *sws,
68 struct pipe_buffer_handle *buf,
69 unsigned flags )
70 {
71 unsigned drm_flags = 0;
72
73 if (flags & PIPE_BUFFER_FLAG_WRITE)
74 drm_flags |= DRM_BO_FLAG_WRITE;
75
76 if (flags & PIPE_BUFFER_FLAG_READ)
77 drm_flags |= DRM_BO_FLAG_READ;
78
79 return driBOMap( dri_bo(buf), drm_flags, 0 );
80 }
81
82 static void intel_buffer_unmap(struct pipe_winsys *sws,
83 struct pipe_buffer_handle *buf)
84 {
85 driBOUnmap( dri_bo(buf) );
86 }
87
88
89 static void
90 intel_buffer_reference(struct pipe_winsys *sws,
91 struct pipe_buffer_handle **ptr,
92 struct pipe_buffer_handle *buf)
93 {
94 if (*ptr) {
95 driBOUnReference( dri_bo(*ptr) );
96 *ptr = NULL;
97 }
98
99 if (buf) {
100 driBOReference( dri_bo(buf) );
101 *ptr = buf;
102 }
103 }
104
105
106 /* Grabs the hardware lock!
107 */
108 static void intel_buffer_data(struct pipe_winsys *sws,
109 struct pipe_buffer_handle *buf,
110 unsigned size, const void *data )
111 {
112 struct intel_context *intel = intel_pipe_winsys(sws)->intel;
113
114 LOCK_HARDWARE( intel );
115 driBOData( dri_bo(buf), size, data, 0 );
116 UNLOCK_HARDWARE( intel );
117 }
118
119 static void intel_buffer_subdata(struct pipe_winsys *sws,
120 struct pipe_buffer_handle *buf,
121 unsigned long offset,
122 unsigned long size,
123 const void *data)
124 {
125 driBOSubData( dri_bo(buf), offset, size, data );
126 }
127
128 static void intel_buffer_get_subdata(struct pipe_winsys *sws,
129 struct pipe_buffer_handle *buf,
130 unsigned long offset,
131 unsigned long size,
132 void *data)
133 {
134 driBOGetSubData( dri_bo(buf), offset, size, data );
135 }
136
137 /* Pipe has no concept of pools. We choose the tex/region pool
138 * for all buffers.
139 */
140 static struct pipe_buffer_handle *
141 intel_buffer_create(struct pipe_winsys *sws,
142 unsigned alignment)
143 {
144 struct intel_context *intel = intel_pipe_winsys(sws)->intel;
145 struct _DriBufferObject *buffer;
146
147 LOCK_HARDWARE( intel );
148 driGenBuffers( intel->intelScreen->regionPool,
149 "pipe buffer", 1, &buffer, alignment, 0, 0 );
150 UNLOCK_HARDWARE( intel );
151
152 return pipe_bo(buffer);
153 }
154
155
156 static struct pipe_buffer_handle *
157 intel_user_buffer_create(struct pipe_winsys *sws, void *ptr, unsigned bytes)
158 {
159 struct intel_context *intel = intel_pipe_winsys(sws)->intel;
160 struct _DriBufferObject *buffer;
161
162 LOCK_HARDWARE( intel );
163 driGenUserBuffer( intel->intelScreen->regionPool,
164 "pipe user buffer", &buffer, ptr, bytes);
165 UNLOCK_HARDWARE( intel );
166
167 return pipe_bo(buffer);
168 }
169
170
171 static void intel_wait_idle( struct pipe_winsys *sws )
172 {
173 struct intel_context *intel = intel_pipe_winsys(sws)->intel;
174
175 if (intel->batch->last_fence) {
176 driFenceFinish(intel->batch->last_fence,
177 DRM_FENCE_TYPE_EXE | DRM_I915_FENCE_TYPE_RW, GL_FALSE);
178 driFenceUnReference(intel->batch->last_fence);
179 intel->batch->last_fence = NULL;
180 }
181 }
182
183
184 /* The state tracker (should!) keep track of whether the fake
185 * frontbuffer has been touched by any rendering since the last time
186 * we copied its contents to the real frontbuffer. Our task is easy:
187 */
188 static void
189 intel_flush_frontbuffer( struct pipe_winsys *sws,
190 struct pipe_surface *surf )
191 {
192 struct intel_context *intel = intel_pipe_winsys(sws)->intel;
193 __DRIdrawablePrivate *dPriv = intel->driDrawable;
194
195 intelDisplaySurface(dPriv, surf, NULL);
196 }
197
198
199 static struct pipe_region *
200 intel_i915_region_alloc(struct pipe_winsys *winsys,
201 unsigned cpp, unsigned width,
202 unsigned height, unsigned flags)
203 {
204 struct pipe_region *region = calloc(sizeof(*region), 1);
205 const unsigned alignment = 64;
206
207 /* Choose a pitch to match hardware requirements - requires 64 byte
208 * alignment of render targets.
209 *
210 * XXX: is this ok for textures??
211 * clearly want to be able to render to textures under some
212 * circumstances, but maybe not always a requirement.
213 */
214 unsigned pitch;
215
216 /* XXX is the pitch different for textures vs. drawables? */
217 if (flags & PIPE_SURFACE_FLAG_TEXTURE) /* or PIPE_SURFACE_FLAG_RENDER? */
218 pitch = ((cpp * width + 63) & ~63) / cpp;
219 else
220 pitch = ((cpp * width + 63) & ~63) / cpp;
221
222 region->cpp = cpp;
223 region->pitch = pitch;
224 region->height = height; /* needed? */
225 region->refcount = 1;
226
227 region->buffer = winsys->buffer_create( winsys, alignment );
228
229 winsys->buffer_data( winsys,
230 region->buffer,
231 pitch * cpp * height,
232 NULL );
233
234 return region;
235 }
236
237 static void
238 intel_i915_region_release(struct pipe_winsys *winsys,
239 struct pipe_region **region)
240 {
241 if (!*region)
242 return;
243
244 assert((*region)->refcount > 0);
245 (*region)->refcount--;
246
247 if ((*region)->refcount == 0) {
248 assert((*region)->map_refcount == 0);
249
250 winsys->buffer_reference( winsys,
251 &((*region)->buffer), NULL );
252 free(*region);
253 }
254 *region = NULL;
255 }
256
257
258 static struct pipe_surface *
259 intel_i915_surface_alloc(struct pipe_winsys *winsys, unsigned format)
260 {
261 struct pipe_surface *surf = CALLOC_STRUCT(pipe_surface);
262 if (surf) {
263 surf->format = format;
264 surf->refcount = 1;
265 }
266 return surf;
267 }
268
269
270 static void
271 intel_printf( struct pipe_winsys *sws, const char *fmtString, ... )
272 {
273 va_list args;
274 va_start( args, fmtString );
275 vfprintf(stderr, fmtString, args);
276 va_end( args );
277 }
278
279 static const char *
280 intel_get_name( struct pipe_winsys *sws )
281 {
282 return "Intel/DRI/ttm";
283 }
284
285
286 struct pipe_winsys *
287 intel_create_pipe_winsys( struct intel_context *intel )
288 {
289 struct intel_pipe_winsys *iws = CALLOC_STRUCT( intel_pipe_winsys );
290
291 /* Fill in this struct with callbacks that pipe will need to
292 * communicate with the window system, buffer manager, etc.
293 *
294 * Pipe would be happy with a malloc based memory manager, but
295 * the SwapBuffers implementation in this winsys driver requires
296 * that rendering be done to an appropriate _DriBufferObject.
297 */
298 iws->winsys.buffer_create = intel_buffer_create;
299 iws->winsys.user_buffer_create = intel_user_buffer_create;
300 iws->winsys.buffer_map = intel_buffer_map;
301 iws->winsys.buffer_unmap = intel_buffer_unmap;
302 iws->winsys.buffer_reference = intel_buffer_reference;
303 iws->winsys.buffer_data = intel_buffer_data;
304 iws->winsys.buffer_subdata = intel_buffer_subdata;
305 iws->winsys.buffer_get_subdata = intel_buffer_get_subdata;
306 iws->winsys.flush_frontbuffer = intel_flush_frontbuffer;
307 iws->winsys.wait_idle = intel_wait_idle;
308 iws->winsys.printf = intel_printf;
309 iws->winsys.get_name = intel_get_name;
310 iws->intel = intel;
311
312 iws->winsys.region_alloc = intel_i915_region_alloc;
313 iws->winsys.region_release = intel_i915_region_release;
314
315 iws->winsys.surface_alloc = intel_i915_surface_alloc;
316
317 return &iws->winsys;
318 }