dri1: Add a macro to validate two dri drawables in one go.
[mesa.git] / src / mesa / drivers / dri / common / dri_util.h
1 /* $XFree86: xc/lib/GL/dri/dri_util.h,v 1.1 2002/02/22 21:32:52 dawes Exp $ */
2 /**
3 * \file dri_util.h
4 * DRI utility functions definitions.
5 *
6 * This module acts as glue between GLX and the actual hardware driver. A DRI
7 * driver doesn't really \e have to use any of this - it's optional. But, some
8 * useful stuff is done here that otherwise would have to be duplicated in most
9 * drivers.
10 *
11 * Basically, these utility functions take care of some of the dirty details of
12 * screen initialization, context creation, context binding, DRM setup, etc.
13 *
14 * These functions are compiled into each DRI driver so libGL.so knows nothing
15 * about them.
16 *
17 * \sa dri_util.c.
18 *
19 * \author Kevin E. Martin <kevin@precisioninsight.com>
20 * \author Brian Paul <brian@precisioninsight.com>
21 */
22
23 /*
24 * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
25 * All Rights Reserved.
26 *
27 * Permission is hereby granted, free of charge, to any person obtaining a
28 * copy of this software and associated documentation files (the
29 * "Software"), to deal in the Software without restriction, including
30 * without limitation the rights to use, copy, modify, merge, publish,
31 * distribute, sub license, and/or sell copies of the Software, and to
32 * permit persons to whom the Software is furnished to do so, subject to
33 * the following conditions:
34 *
35 * The above copyright notice and this permission notice (including the
36 * next paragraph) shall be included in all copies or substantial portions
37 * of the Software.
38 *
39 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
40 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
41 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
42 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
43 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
44 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
45 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
46 */
47
48
49 #ifndef _DRI_UTIL_H_
50 #define _DRI_UTIL_H_
51
52 #include <GL/gl.h>
53 #include <drm.h>
54 #include <drm_sarea.h>
55 #include <xf86drm.h>
56 #include "main/glheader.h"
57 #include "GL/internal/glcore.h"
58 #include "GL/internal/dri_interface.h"
59
60 #define GLX_BAD_CONTEXT 5
61
62 typedef struct __DRIswapInfoRec __DRIswapInfo;
63
64 /* Typedefs to avoid rewriting the world. */
65 typedef struct __DRIscreenRec __DRIscreenPrivate;
66 typedef struct __DRIdrawableRec __DRIdrawablePrivate;
67 typedef struct __DRIcontextRec __DRIcontextPrivate;
68
69 /**
70 * Extensions.
71 */
72 extern const __DRIlegacyExtension driLegacyExtension;
73 extern const __DRIcoreExtension driCoreExtension;
74 extern const __DRIextension driReadDrawableExtension;
75 extern const __DRIcopySubBufferExtension driCopySubBufferExtension;
76 extern const __DRIswapControlExtension driSwapControlExtension;
77 extern const __DRIframeTrackingExtension driFrameTrackingExtension;
78 extern const __DRImediaStreamCounterExtension driMediaStreamCounterExtension;
79
80 /**
81 * Used by DRI_VALIDATE_DRAWABLE_INFO
82 */
83 #define DRI_VALIDATE_DRAWABLE_INFO_ONCE(pDrawPriv) \
84 do { \
85 if (*(pDrawPriv->pStamp) != pDrawPriv->lastStamp) { \
86 __driUtilUpdateDrawableInfo(pDrawPriv); \
87 } \
88 } while (0)
89
90
91 /**
92 * Utility macro to validate the drawable information.
93 *
94 * See __DRIdrawable::pStamp and __DRIdrawable::lastStamp.
95 */
96 #define DRI_VALIDATE_DRAWABLE_INFO(psp, pdp) \
97 do { \
98 while (*(pdp->pStamp) != pdp->lastStamp) { \
99 register unsigned int hwContext = psp->pSAREA->lock.lock & \
100 ~(DRM_LOCK_HELD | DRM_LOCK_CONT); \
101 DRM_UNLOCK(psp->fd, &psp->pSAREA->lock, hwContext); \
102 \
103 DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); \
104 DRI_VALIDATE_DRAWABLE_INFO_ONCE(pdp); \
105 DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); \
106 \
107 DRM_LIGHT_LOCK(psp->fd, &psp->pSAREA->lock, hwContext); \
108 } \
109 } while (0)
110
111 /**
112 * Same as above, but for two drawables simultaneously.
113 *
114 */
115
116 #define DRI_VALIDATE_TWO_DRAWABLES_INFO(psp, pdp, prp) \
117 do { \
118 while (*((pdp)->pStamp) != (pdp)->lastStamp || \
119 *((prp)->pStamp) != (prp)->lastStamp) { \
120 register unsigned int hwContext = (psp)->pSAREA->lock.lock & \
121 ~(DRM_LOCK_HELD | DRM_LOCK_CONT); \
122 DRM_UNLOCK((psp)->fd, &(psp)->pSAREA->lock, hwContext); \
123 \
124 DRM_SPINLOCK(&(psp)->pSAREA->drawable_lock, (psp)->drawLockID); \
125 DRI_VALIDATE_DRAWABLE_INFO_ONCE(pdp); \
126 DRI_VALIDATE_DRAWABLE_INFO_ONCE(prp); \
127 DRM_SPINUNLOCK(&(psp)->pSAREA->drawable_lock, (psp)->drawLockID); \
128 \
129 DRM_LIGHT_LOCK((psp)->fd, &(psp)->pSAREA->lock, hwContext); \
130 } \
131 } while (0)
132
133
134 /**
135 * Driver callback functions.
136 *
137 * Each DRI driver must have one of these structures with all the pointers set
138 * to appropriate functions within the driver.
139 *
140 * When glXCreateContext() is called, for example, it'll call a helper function
141 * dri_util.c which in turn will jump through the \a CreateContext pointer in
142 * this structure.
143 */
144 struct __DriverAPIRec {
145 const __DRIconfig **(*InitScreen) (__DRIscreen * priv);
146
147 /**
148 * Screen destruction callback
149 */
150 void (*DestroyScreen)(__DRIscreen *driScrnPriv);
151
152 /**
153 * Context creation callback
154 */
155 GLboolean (*CreateContext)(const __GLcontextModes *glVis,
156 __DRIcontext *driContextPriv,
157 void *sharedContextPrivate);
158
159 /**
160 * Context destruction callback
161 */
162 void (*DestroyContext)(__DRIcontext *driContextPriv);
163
164 /**
165 * Buffer (drawable) creation callback
166 */
167 GLboolean (*CreateBuffer)(__DRIscreen *driScrnPriv,
168 __DRIdrawable *driDrawPriv,
169 const __GLcontextModes *glVis,
170 GLboolean pixmapBuffer);
171
172 /**
173 * Buffer (drawable) destruction callback
174 */
175 void (*DestroyBuffer)(__DRIdrawable *driDrawPriv);
176
177 /**
178 * Buffer swapping callback
179 */
180 void (*SwapBuffers)(__DRIdrawable *driDrawPriv);
181
182 /**
183 * Context activation callback
184 */
185 GLboolean (*MakeCurrent)(__DRIcontext *driContextPriv,
186 __DRIdrawable *driDrawPriv,
187 __DRIdrawable *driReadPriv);
188
189 /**
190 * Context unbinding callback
191 */
192 GLboolean (*UnbindContext)(__DRIcontext *driContextPriv);
193
194 /**
195 * Retrieves statistics about buffer swap operations. Required if
196 * GLX_OML_sync_control or GLX_MESA_swap_frame_usage is supported.
197 */
198 int (*GetSwapInfo)( __DRIdrawable *dPriv, __DRIswapInfo * sInfo );
199
200
201 /**
202 * These are required if GLX_OML_sync_control is supported.
203 */
204 /*@{*/
205 int (*WaitForMSC)( __DRIdrawable *priv, int64_t target_msc,
206 int64_t divisor, int64_t remainder,
207 int64_t * msc );
208 int (*WaitForSBC)( __DRIdrawable *priv, int64_t target_sbc,
209 int64_t * msc, int64_t * sbc );
210
211 int64_t (*SwapBuffersMSC)( __DRIdrawable *priv, int64_t target_msc,
212 int64_t divisor, int64_t remainder );
213 /*@}*/
214 void (*CopySubBuffer)(__DRIdrawable *driDrawPriv,
215 int x, int y, int w, int h);
216
217 /**
218 * New version of GetMSC so we can pass drawable data to the low
219 * level DRM driver (e.g. pipe info). Required if
220 * GLX_SGI_video_sync or GLX_OML_sync_control is supported.
221 */
222 int (*GetDrawableMSC) ( __DRIscreen * priv,
223 __DRIdrawable *drawablePrivate,
224 int64_t *count);
225
226
227
228 /* DRI2 Entry point */
229 const __DRIconfig **(*InitScreen2) (__DRIscreen * priv);
230 };
231
232 extern const struct __DriverAPIRec driDriverAPI;
233
234
235 struct __DRIswapInfoRec {
236 /**
237 * Number of swapBuffers operations that have been *completed*.
238 */
239 uint64_t swap_count;
240
241 /**
242 * Unadjusted system time of the last buffer swap. This is the time
243 * when the swap completed, not the time when swapBuffers was called.
244 */
245 int64_t swap_ust;
246
247 /**
248 * Number of swap operations that occurred after the swap deadline. That
249 * is if a swap happens more than swap_interval frames after the previous
250 * swap, it has missed its deadline. If swap_interval is 0, then the
251 * swap deadline is 1 frame after the previous swap.
252 */
253 uint64_t swap_missed_count;
254
255 /**
256 * Amount of time used by the last swap that missed its deadline. This
257 * is calculated as (__glXGetUST() - swap_ust) / (swap_interval *
258 * time_for_single_vrefresh)). If the actual value of swap_interval is
259 * 0, then 1 is used instead. If swap_missed_count is non-zero, this
260 * should be greater-than 1.0.
261 */
262 float swap_missed_usage;
263 };
264
265
266 /**
267 * Per-drawable private DRI driver information.
268 */
269 struct __DRIdrawableRec {
270 /**
271 * Kernel drawable handle
272 */
273 drm_drawable_t hHWDrawable;
274
275 /**
276 * Driver's private drawable information.
277 *
278 * This structure is opaque.
279 */
280 void *driverPrivate;
281
282 /**
283 * Private data from the loader. We just hold on to it and pass
284 * it back when calling into loader provided functions.
285 */
286 void *loaderPrivate;
287
288 /**
289 * Reference count for number of context's currently bound to this
290 * drawable.
291 *
292 * Once it reaches zero, the drawable can be destroyed.
293 *
294 * \note This behavior will change with GLX 1.3.
295 */
296 int refcount;
297
298 /**
299 * Index of this drawable information in the SAREA.
300 */
301 unsigned int index;
302
303 /**
304 * Pointer to the "drawable has changed ID" stamp in the SAREA.
305 */
306 unsigned int *pStamp;
307
308 /**
309 * Last value of the stamp.
310 *
311 * If this differs from the value stored at __DRIdrawable::pStamp,
312 * then the drawable information has been modified by the X server, and the
313 * drawable information (below) should be retrieved from the X server.
314 */
315 unsigned int lastStamp;
316
317 /**
318 * \name Drawable
319 *
320 * Drawable information used in software fallbacks.
321 */
322 /*@{*/
323 int x;
324 int y;
325 int w;
326 int h;
327 int numClipRects;
328 drm_clip_rect_t *pClipRects;
329 /*@}*/
330
331 /**
332 * \name Back and depthbuffer
333 *
334 * Information about the back and depthbuffer where different from above.
335 */
336 /*@{*/
337 int backX;
338 int backY;
339 int backClipRectType;
340 int numBackClipRects;
341 drm_clip_rect_t *pBackClipRects;
342 /*@}*/
343
344 /**
345 * \name Vertical blank tracking information
346 * Used for waiting on vertical blank events.
347 */
348 /*@{*/
349 unsigned int vblSeq;
350 unsigned int vblFlags;
351 /*@}*/
352
353 /**
354 * \name Monotonic MSC tracking
355 *
356 * Low level driver is responsible for updating msc_base and
357 * vblSeq values so that higher level code can calculate
358 * a new msc value or msc target for a WaitMSC call. The new value
359 * will be:
360 * msc = msc_base + get_vblank_count() - vblank_base;
361 *
362 * And for waiting on a value, core code will use:
363 * actual_target = target_msc - msc_base + vblank_base;
364 */
365 /*@{*/
366 int64_t vblank_base;
367 int64_t msc_base;
368 /*@}*/
369
370 /**
371 * Pointer to context to which this drawable is currently bound.
372 */
373 __DRIcontext *driContextPriv;
374
375 /**
376 * Pointer to screen on which this drawable was created.
377 */
378 __DRIscreen *driScreenPriv;
379
380 /**
381 * Controls swap interval as used by GLX_SGI_swap_control and
382 * GLX_MESA_swap_control.
383 */
384 unsigned int swap_interval;
385 };
386
387 /**
388 * Per-context private driver information.
389 */
390 struct __DRIcontextRec {
391 /**
392 * Kernel context handle used to access the device lock.
393 */
394 drm_context_t hHWContext;
395
396 /**
397 * Device driver's private context data. This structure is opaque.
398 */
399 void *driverPrivate;
400
401 /**
402 * Pointer back to the \c __DRIcontext that contains this structure.
403 */
404 __DRIcontext *pctx;
405
406 /**
407 * Pointer to drawable currently bound to this context for drawing.
408 */
409 __DRIdrawable *driDrawablePriv;
410
411 /**
412 * Pointer to drawable currently bound to this context for reading.
413 */
414 __DRIdrawable *driReadablePriv;
415
416 /**
417 * Pointer to screen on which this context was created.
418 */
419 __DRIscreen *driScreenPriv;
420 };
421
422 /**
423 * Per-screen private driver information.
424 */
425 struct __DRIscreenRec {
426 /**
427 * Current screen's number
428 */
429 int myNum;
430
431 /**
432 * Callback functions into the hardware-specific DRI driver code.
433 */
434 struct __DriverAPIRec DriverAPI;
435
436 const __DRIextension **extensions;
437 /**
438 * DDX / 2D driver version information.
439 */
440 __DRIversion ddx_version;
441
442 /**
443 * DRI X extension version information.
444 */
445 __DRIversion dri_version;
446
447 /**
448 * DRM (kernel module) version information.
449 */
450 __DRIversion drm_version;
451
452 /**
453 * ID used when the client sets the drawable lock.
454 *
455 * The X server uses this value to detect if the client has died while
456 * holding the drawable lock.
457 */
458 int drawLockID;
459
460 /**
461 * File descriptor returned when the kernel device driver is opened.
462 *
463 * Used to:
464 * - authenticate client to kernel
465 * - map the frame buffer, SAREA, etc.
466 * - close the kernel device driver
467 */
468 int fd;
469
470 /**
471 * SAREA pointer
472 *
473 * Used to access:
474 * - the device lock
475 * - the device-independent per-drawable and per-context(?) information
476 */
477 drm_sarea_t *pSAREA;
478
479 /**
480 * \name Direct frame buffer access information
481 * Used for software fallbacks.
482 */
483 /*@{*/
484 unsigned char *pFB;
485 int fbSize;
486 int fbOrigin;
487 int fbStride;
488 int fbWidth;
489 int fbHeight;
490 int fbBPP;
491 /*@}*/
492
493 /**
494 * \name Device-dependent private information (stored in the SAREA).
495 *
496 * This data is accessed by the client driver only.
497 */
498 /*@{*/
499 void *pDevPriv;
500 int devPrivSize;
501 /*@}*/
502
503 /**
504 * Dummy context to which drawables are bound when not bound to any
505 * other context.
506 *
507 * A dummy hHWContext is created for this context, and is used by the GL
508 * core when a hardware lock is required but the drawable is not currently
509 * bound (e.g., potentially during a SwapBuffers request). The dummy
510 * context is created when the first "real" context is created on this
511 * screen.
512 */
513 __DRIcontext dummyContextPriv;
514
515 /**
516 * Device-dependent private information (not stored in the SAREA).
517 *
518 * This pointer is never touched by the DRI layer.
519 */
520 void *private;
521
522 /**
523 * Pointer back to the \c __DRIscreen that contains this structure.
524 */
525 __DRIscreen *psc;
526
527 /* Extensions provided by the loader. */
528 const __DRIgetDrawableInfoExtension *getDrawableInfo;
529 const __DRIsystemTimeExtension *systemTime;
530 const __DRIdamageExtension *damage;
531
532 struct {
533 /* Flag to indicate that this is a DRI2 screen. Many of the above
534 * fields will not be valid or initializaed in that case. */
535 int enabled;
536 __DRIdri2LoaderExtension *loader;
537 } dri2;
538
539 /* The lock actually in use, old sarea or DRI2 */
540 drmLock *lock;
541 };
542
543 extern void
544 __driUtilMessage(const char *f, ...);
545
546
547 extern void
548 __driUtilUpdateDrawableInfo(__DRIdrawable *pdp);
549
550 extern float
551 driCalculateSwapUsage( __DRIdrawable *dPriv,
552 int64_t last_swap_ust, int64_t current_ust );
553
554 extern GLint
555 driIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 );
556
557 #endif /* _DRI_UTIL_H_ */