dri_util.c revision 6260618b29983fd961718fd6e3961bdd32163cb5
1680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
2680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \file dri_util.c
3680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * DRI utility functions.
4680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
5680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This module acts as glue between GLX and the actual hardware driver.  A DRI
6680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * driver doesn't really \e have to use any of this - it's optional.  But, some
7680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * useful stuff is done here that otherwise would have to be duplicated in most
8680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * drivers.
9680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
10680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Basically, these utility functions take care of some of the dirty details of
11680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * screen initialization, context creation, context binding, DRM setup, etc.
12680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
13680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * These functions are compiled into each DRI driver so libGL.so knows nothing
14680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * about them.
15680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
16680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
17680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
18680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#include <assert.h>
19680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#include <stdarg.h>
20680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#include <unistd.h>
21680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#include <sys/mman.h>
22680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#include <stdio.h>
237c46033130b1b4d6098647d85c2710367572e079Ian Romanick
2438b317d508a2a3a4cc6d700ebca80c3b06c913e2Alan Hourihane#ifndef MAP_FAILED
2538b317d508a2a3a4cc6d700ebca80c3b06c913e2Alan Hourihane#define MAP_FAILED ((void *)-1)
2638b317d508a2a3a4cc6d700ebca80c3b06c913e2Alan Hourihane#endif
2738b317d508a2a3a4cc6d700ebca80c3b06c913e2Alan Hourihane
28ecadb51bbcb972a79f3ed79e65a7986b9396e757Brian Paul#include "main/imports.h"
29c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick#define None 0
307c46033130b1b4d6098647d85c2710367572e079Ian Romanick
317c46033130b1b4d6098647d85c2710367572e079Ian Romanick#include "dri_util.h"
32ffb36d57a5f6359b5b91b73af60482a0016dd431Jon Smirl#include "drm_sarea.h"
33c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis#include "utils.h"
3445e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes#include "xmlpool.h"
35ae6e112c69cf42fb81ef4ed5bdeb3b280647f141Eric Anholt#include "../glsl/glsl_parser_extras.h"
3645e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes
3745e2b51c853471b79004a954ce3092a253b20b77Jesse BarnesPUBLIC const char __dri2ConfigOptions[] =
3845e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes   DRI_CONF_BEGIN
3945e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes      DRI_CONF_SECTION_PERFORMANCE
4045e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes         DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_1)
4145e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes      DRI_CONF_SECTION_END
4245e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes   DRI_CONF_END;
4345e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes
4445e2b51c853471b79004a954ce3092a253b20b77Jesse Barnesstatic const uint __dri2NConfigOptions = 1;
45680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
46c604e457d1ebe9a884b0a1fb08af38a0ce486699Ian Romanick#ifndef GLX_OML_sync_control
47aceccda56b08338e217991e54607f1c9f18fc3e6Kristian Høgsbergtypedef GLboolean ( * PFNGLXGETMSCRATEOMLPROC) (__DRIdrawable *drawable, int32_t *numerator, int32_t *denominator);
488cdccc82d7948daee256e092a5253d49e277ef75Ian Romanick#endif
498cdccc82d7948daee256e092a5253d49e277ef75Ian Romanick
503264352c577ce1d6681e70abd76624ede906df71Dave Airliestatic void dri_get_drawable(__DRIdrawable *pdp);
513264352c577ce1d6681e70abd76624ede906df71Dave Airliestatic void dri_put_drawable(__DRIdrawable *pdp);
523264352c577ce1d6681e70abd76624ede906df71Dave Airlie
53c95e66120be049ee51ff84868b1da3379b312fabGeorge SapountzisGLint
54c95e66120be049ee51ff84868b1da3379b312fabGeorge SapountzisdriIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 )
55c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis{
56c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis   if (rect2.x1 > rect1.x1) rect1.x1 = rect2.x1;
57c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis   if (rect2.x2 < rect1.x2) rect1.x2 = rect2.x2;
58c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis   if (rect2.y1 > rect1.y1) rect1.y1 = rect2.y1;
59c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis   if (rect2.y2 < rect1.y2) rect1.y2 = rect2.y2;
60c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis
61c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis   if (rect1.x1 > rect1.x2 || rect1.y1 > rect1.y2) return 0;
62c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis
63c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis   return (rect1.x2 - rect1.x1) * (rect1.y2 - rect1.y1);
64c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis}
65680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
66680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
67680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name Context (un)binding functions                          */
68680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
69680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/
70680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
71680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
72680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Unbind context.
73680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
74aceccda56b08338e217991e54607f1c9f18fc3e6Kristian Høgsberg * \param scrn the screen.
75680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param gc context.
76680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
77680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \return \c GL_TRUE on success, or \c GL_FALSE on failure.
78680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
79680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \internal
80680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function calls __DriverAPIRec::UnbindContext, and then decrements
81d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian Høgsberg * __DRIdrawableRec::refcount which must be non-zero for a successful
82680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * return.
83680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
84680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * While casting the opaque private pointers associated with the parameters
85680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * into their respective real types it also assures they are not \c NULL.
86680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
87e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic int driUnbindContext(__DRIcontext *pcp)
88680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
89e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    __DRIscreen *psp;
90418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    __DRIdrawable *pdp;
91418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    __DRIdrawable *prp;
92680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
93680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /*
94680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    ** Assume error checking is done properly in glXMakeCurrent before
95c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick    ** calling driUnbindContext.
96680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    */
97680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
98e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    if (pcp == NULL)
99aceccda56b08338e217991e54607f1c9f18fc3e6Kristian Høgsberg        return GL_FALSE;
100680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
101e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    psp = pcp->driScreenPriv;
102418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    pdp = pcp->driDrawablePriv;
103418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    prp = pcp->driReadablePriv;
104680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
105418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    /* already unbound */
106418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    if (!pdp && !prp)
107418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen      return GL_TRUE;
108418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    /* Let driver unbind drawable from context */
109680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    (*psp->DriverAPI.UnbindContext)(pcp);
110680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
111cab77711b3e8d398393677bcefcd413f50503a64Vinson Lee    assert(pdp);
112418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    if (pdp->refcount == 0) {
113418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen	/* ERROR!!! */
114418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen	return GL_FALSE;
115418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    }
116418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen
117418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    dri_put_drawable(pdp);
118418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen
119418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    if (prp != pdp) {
120418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen        if (prp->refcount == 0) {
121418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen	    /* ERROR!!! */
122418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen	    return GL_FALSE;
123418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen	}
124418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen
125418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    	dri_put_drawable(prp);
126418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    }
127418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen
128418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen
129418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    /* XXX this is disabled so that if we call SwapBuffers on an unbound
130418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen     * window we can determine the last context bound to the window and
131418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen     * use that context's lock. (BrianP, 2-Dec-2000)
132418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen     */
133418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    pcp->driDrawablePriv = pcp->driReadablePriv = NULL;
134418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen
135680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    return GL_TRUE;
136680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
137680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
138680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
139680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function takes both a read buffer and a draw buffer.  This is needed
140680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent
141680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * function.
142680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
143e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic int driBindContext(__DRIcontext *pcp,
144e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg			  __DRIdrawable *pdp,
145e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg			  __DRIdrawable *prp)
146680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
147d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian Høgsberg    __DRIscreen *psp = NULL;
148680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
14964fa717b18272bda2551a6dc2e1a40725b031097Jakob Bornecrantz    /*
15064fa717b18272bda2551a6dc2e1a40725b031097Jakob Bornecrantz    ** Assume error checking is done properly in glXMakeCurrent before
15164fa717b18272bda2551a6dc2e1a40725b031097Jakob Bornecrantz    ** calling driUnbindContext.
15264fa717b18272bda2551a6dc2e1a40725b031097Jakob Bornecrantz    */
1538e753d04045a82062ac34d3b2622eb9dba8af374Thomas Hellstrom
15464fa717b18272bda2551a6dc2e1a40725b031097Jakob Bornecrantz    if (!pcp)
15564fa717b18272bda2551a6dc2e1a40725b031097Jakob Bornecrantz	return GL_FALSE;
15664fa717b18272bda2551a6dc2e1a40725b031097Jakob Bornecrantz
15764fa717b18272bda2551a6dc2e1a40725b031097Jakob Bornecrantz    /* Bind the drawable to the context */
15864fa717b18272bda2551a6dc2e1a40725b031097Jakob Bornecrantz    psp = pcp->driScreenPriv;
15964fa717b18272bda2551a6dc2e1a40725b031097Jakob Bornecrantz    pcp->driDrawablePriv = pdp;
16064fa717b18272bda2551a6dc2e1a40725b031097Jakob Bornecrantz    pcp->driReadablePriv = prp;
16164fa717b18272bda2551a6dc2e1a40725b031097Jakob Bornecrantz    if (pdp) {
16264fa717b18272bda2551a6dc2e1a40725b031097Jakob Bornecrantz	pdp->driContextPriv = pcp;
16364fa717b18272bda2551a6dc2e1a40725b031097Jakob Bornecrantz	dri_get_drawable(pdp);
16464fa717b18272bda2551a6dc2e1a40725b031097Jakob Bornecrantz    }
16564fa717b18272bda2551a6dc2e1a40725b031097Jakob Bornecrantz    if (prp && pdp != prp) {
16664fa717b18272bda2551a6dc2e1a40725b031097Jakob Bornecrantz	dri_get_drawable(prp);
167418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    }
168680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
169680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /*
170680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    ** Now that we have a context associated with this drawable, we can
171680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    ** initialize the drawable information if has not been done before.
172680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    */
173680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
174f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    if (!psp->dri2.enabled) {
1758e753d04045a82062ac34d3b2622eb9dba8af374Thomas Hellstrom	if (pdp && !pdp->pStamp) {
1767da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	    DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
1777da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	    __driUtilUpdateDrawableInfo(pdp);
1787da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	    DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
1797da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	}
1808e753d04045a82062ac34d3b2622eb9dba8af374Thomas Hellstrom	if (prp && pdp != prp && !prp->pStamp) {
1817da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	    DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
1827da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	    __driUtilUpdateDrawableInfo(prp);
1837da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	    DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
1848e753d04045a82062ac34d3b2622eb9dba8af374Thomas Hellstrom        }
1857b1ff326071658d5bd6e7feb2ad78d0e0209211dIan Romanick    }
1867b1ff326071658d5bd6e7feb2ad78d0e0209211dIan Romanick
187680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /* Call device-specific MakeCurrent */
188c952b3e907ab31cd5f95157c18ce2f81626aafe4Thomas Hellstrom    return (*psp->DriverAPI.MakeCurrent)(pcp, pdp, prp);
189680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
190680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
191680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@}*/
192680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
193680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
194680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
195680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name Drawable handling functions                            */
196680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
197680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/
198680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
199680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
200680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Update private drawable information.
201680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
202680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param pdp pointer to the private drawable information to update.
203680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
204d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian Høgsberg * This function basically updates the __DRIdrawable struct's
2055f1ba3e21b62cee1a4f900a2e6964728f3eeea9bIan Romanick * cliprect information by calling \c __DRIinterfaceMethods::getDrawableInfo.
2065f1ba3e21b62cee1a4f900a2e6964728f3eeea9bIan Romanick * This is usually called by the DRI_VALIDATE_DRAWABLE_INFO macro which
207680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * compares the __DRIdrwablePrivate pStamp and lastStamp values.  If
208680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * the values are different that means we have to update the clipping
209680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * info.
210680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
211680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellvoid
212d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian Høgsberg__driUtilUpdateDrawableInfo(__DRIdrawable *pdp)
213680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
214d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian Høgsberg    __DRIscreen *psp = pdp->driScreenPriv;
215d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian Høgsberg    __DRIcontext *pcp = pdp->driContextPriv;
216680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
2177b1ff326071658d5bd6e7feb2ad78d0e0209211dIan Romanick    if (!pcp
2187b1ff326071658d5bd6e7feb2ad78d0e0209211dIan Romanick	|| ((pdp != pcp->driDrawablePriv) && (pdp != pcp->driReadablePriv))) {
219682393944c72ecfabe8df674af0b48975e90b98cThomas Hellström	/* ERROR!!!
220682393944c72ecfabe8df674af0b48975e90b98cThomas Hellström	 * ...but we must ignore it. There can be many contexts bound to a
221682393944c72ecfabe8df674af0b48975e90b98cThomas Hellström	 * drawable.
222682393944c72ecfabe8df674af0b48975e90b98cThomas Hellström	 */
223680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
224680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
225680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (pdp->pClipRects) {
22632f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg	free(pdp->pClipRects);
227a903749b246fce26038c66d06fe7eb77daf815abMichel Dänzer	pdp->pClipRects = NULL;
228680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
229680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
230680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (pdp->pBackClipRects) {
23132f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg	free(pdp->pBackClipRects);
232a903749b246fce26038c66d06fe7eb77daf815abMichel Dänzer	pdp->pBackClipRects = NULL;
233680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
234680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
235680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
236680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
237e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    if (! (*psp->getDrawableInfo->getDrawableInfo)(pdp,
238680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			  &pdp->index, &pdp->lastStamp,
239680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			  &pdp->x, &pdp->y, &pdp->w, &pdp->h,
240680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			  &pdp->numClipRects, &pdp->pClipRects,
241680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			  &pdp->backX,
242680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			  &pdp->backY,
243680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			  &pdp->numBackClipRects,
244e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg			  &pdp->pBackClipRects,
245e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg			  pdp->loaderPrivate)) {
246680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	/* Error -- eg the window may have been destroyed.  Keep going
247680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	 * with no cliprects.
248680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	 */
249680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        pdp->pStamp = &pdp->lastStamp; /* prevent endless loop */
250680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	pdp->numClipRects = 0;
251680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	pdp->pClipRects = NULL;
252680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	pdp->numBackClipRects = 0;
253680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	pdp->pBackClipRects = NULL;
254680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
255680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    else
256680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       pdp->pStamp = &(psp->pSAREA->drawableTable[pdp->index].stamp);
257680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
258680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
259680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
260680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
261e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic __DRIdrawable *
262f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsbergdri2CreateNewDrawable(__DRIscreen *screen,
263f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg		      const __DRIconfig *config,
264f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg		      void *loaderPrivate)
265680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
266f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    __DRIdrawable *pdraw;
267680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
268f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    pdraw = malloc(sizeof *pdraw);
269f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    if (!pdraw)
270680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return NULL;
271680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
272f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    pdraw->driContextPriv = NULL;
273f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    pdraw->loaderPrivate = loaderPrivate;
274f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    pdraw->hHWDrawable = 0;
275f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    pdraw->refcount = 1;
276f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    pdraw->pStamp = NULL;
277f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    pdraw->lastStamp = 0;
278f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    pdraw->index = 0;
279f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    pdraw->x = 0;
280f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    pdraw->y = 0;
281f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    pdraw->w = 0;
282f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    pdraw->h = 0;
283f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    pdraw->numClipRects = 0;
284f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    pdraw->numBackClipRects = 0;
285f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    pdraw->pClipRects = NULL;
286f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    pdraw->pBackClipRects = NULL;
287f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    pdraw->vblSeq = 0;
288f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    pdraw->vblFlags = 0;
289f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg
290f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    pdraw->driScreenPriv = screen;
291f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg
292f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    if (!(*screen->DriverAPI.CreateBuffer)(screen, pdraw, &config->modes, 0)) {
293f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg       free(pdraw);
294680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       return NULL;
295680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
296680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
297f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    pdraw->msc_base = 0;
298680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
299c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick    /* This special default value is replaced with the configured
300c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick     * default value when the drawable is first bound to a direct
301c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick     * rendering context.
302c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick     */
303f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    pdraw->swap_interval = (unsigned)-1;
304e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
305925b901ba313a3ddd7567eca088951be39414430Kristian Høgsberg    pdraw->pClipRects = &pdraw->dri2.clipRect;
306925b901ba313a3ddd7567eca088951be39414430Kristian Høgsberg    pdraw->pBackClipRects = &pdraw->dri2.clipRect;
307e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
30861d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez    pdraw->pStamp = &pdraw->dri2.stamp;
30961d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez    *pdraw->pStamp = pdraw->lastStamp + 1;
31061d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez
311e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    return pdraw;
312680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
313680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
3141b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzkestatic __DRIbuffer *
3151b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzkedri2AllocateBuffer(__DRIscreen *screen,
3161b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke		   unsigned int attachment, unsigned int format,
3171b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke		   int width, int height)
3181b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke{
3191b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke    return (*screen->DriverAPI.AllocateBuffer)(screen, attachment, format,
3201b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke					       width, height);
3211b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke}
3221b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke
3231b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzkestatic void
3241b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzkedri2ReleaseBuffer(__DRIscreen *screen, __DRIbuffer *buffer)
3251b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke{
3261b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke   (*screen->DriverAPI.ReleaseBuffer)(screen, buffer);
3271b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke}
3281b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke
3291b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke
330234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnesstatic int
331234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnesdri2ConfigQueryb(__DRIscreen *screen, const char *var, GLboolean *val)
332234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes{
333234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes   if (!driCheckOption(&screen->optionCache, var, DRI_BOOL))
334234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes      return -1;
335234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
336234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes   *val = driQueryOptionb(&screen->optionCache, var);
337234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
338234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes   return 0;
339234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes}
340234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
341234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnesstatic int
342234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnesdri2ConfigQueryi(__DRIscreen *screen, const char *var, GLint *val)
343234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes{
344234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes   if (!driCheckOption(&screen->optionCache, var, DRI_INT) &&
345234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes       !driCheckOption(&screen->optionCache, var, DRI_ENUM))
346234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes      return -1;
347234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
348234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes    *val = driQueryOptioni(&screen->optionCache, var);
349234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
350234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes    return 0;
351234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes}
352234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
353234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnesstatic int
354234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnesdri2ConfigQueryf(__DRIscreen *screen, const char *var, GLfloat *val)
355234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes{
356234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes   if (!driCheckOption(&screen->optionCache, var, DRI_FLOAT))
357234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes      return -1;
358234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
359234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes    *val = driQueryOptionf(&screen->optionCache, var);
360234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
361234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes    return 0;
362234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes}
363234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
364234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
3653264352c577ce1d6681e70abd76624ede906df71Dave Airliestatic void dri_get_drawable(__DRIdrawable *pdp)
3663264352c577ce1d6681e70abd76624ede906df71Dave Airlie{
3673264352c577ce1d6681e70abd76624ede906df71Dave Airlie    pdp->refcount++;
3683264352c577ce1d6681e70abd76624ede906df71Dave Airlie}
3693264352c577ce1d6681e70abd76624ede906df71Dave Airlie
3703264352c577ce1d6681e70abd76624ede906df71Dave Airliestatic void dri_put_drawable(__DRIdrawable *pdp)
371680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
372d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian Høgsberg    __DRIscreen *psp;
373680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
374680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (pdp) {
375f622b649fb0c55b1640997f9d32ea327743519a1Vinson Lee	pdp->refcount--;
376f622b649fb0c55b1640997f9d32ea327743519a1Vinson Lee	if (pdp->refcount)
377f622b649fb0c55b1640997f9d32ea327743519a1Vinson Lee	    return;
378f622b649fb0c55b1640997f9d32ea327743519a1Vinson Lee
379eab896cc213157758d74a2f39b5e3b1e748c071fDave Airlie	psp = pdp->driScreenPriv;
380680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        (*psp->DriverAPI.DestroyBuffer)(pdp);
381925b901ba313a3ddd7567eca088951be39414430Kristian Høgsberg	if (pdp->pClipRects && pdp->pClipRects != &pdp->dri2.clipRect) {
38232f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg	    free(pdp->pClipRects);
383680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    pdp->pClipRects = NULL;
384680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	}
385925b901ba313a3ddd7567eca088951be39414430Kristian Høgsberg	if (pdp->pBackClipRects && pdp->pClipRects != &pdp->dri2.clipRect) {
38632f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg	    free(pdp->pBackClipRects);
387680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    pdp->pBackClipRects = NULL;
388680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	}
38932f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg	free(pdp);
390680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
391680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
392680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
3933264352c577ce1d6681e70abd76624ede906df71Dave Airliestatic void
3943264352c577ce1d6681e70abd76624ede906df71Dave AirliedriDestroyDrawable(__DRIdrawable *pdp)
3953264352c577ce1d6681e70abd76624ede906df71Dave Airlie{
3963264352c577ce1d6681e70abd76624ede906df71Dave Airlie    dri_put_drawable(pdp);
3973264352c577ce1d6681e70abd76624ede906df71Dave Airlie}
3983264352c577ce1d6681e70abd76624ede906df71Dave Airlie
399680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@}*/
400680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
401680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
402680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
403680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name Context handling functions                             */
404680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
405680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/
406680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
407680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
408680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Destroy the per-context private information.
409680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
410680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \internal
411680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function calls __DriverAPIRec::DestroyContext on \p contextPrivate, calls
412680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * drmDestroyContext(), and finally frees \p contextPrivate.
413680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
414b4b040f7d83f5f4917c48bf5833394d550e30421Brian Paulstatic void
415e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian HøgsbergdriDestroyContext(__DRIcontext *pcp)
416680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
417680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (pcp) {
418680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	(*pcp->driScreenPriv->DriverAPI.DestroyContext)(pcp);
41932f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg	free(pcp);
420680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
421680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
422680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
423a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsbergstatic unsigned int
424a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsbergdri2GetAPIMask(__DRIscreen *screen)
425a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg{
426a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    return screen->api_mask;
427a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg}
428a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg
429a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsbergstatic __DRIcontext *
430a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsbergdri2CreateNewContextForAPI(__DRIscreen *screen, int api,
431a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg			   const __DRIconfig *config,
432a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg			   __DRIcontext *shared, void *data)
433a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg{
434a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    __DRIcontext *context;
435d3491e775fb07f891463b2185d74bbad62f3ed24Kristian Høgsberg    const struct gl_config *modes = (config != NULL) ? &config->modes : NULL;
436a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    void *shareCtx = (shared != NULL) ? shared->driverPrivate : NULL;
437a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    gl_api mesa_api;
438a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg
439a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    if (!(screen->api_mask & (1 << api)))
440a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg	return NULL;
441a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg
442a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    switch (api) {
443a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    case __DRI_API_OPENGL:
444a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg	    mesa_api = API_OPENGL;
445a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg	    break;
446a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    case __DRI_API_GLES:
447a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg	    mesa_api = API_OPENGLES;
448a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg	    break;
449a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    case __DRI_API_GLES2:
450a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg	    mesa_api = API_OPENGLES2;
451a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg	    break;
4521b8c9fef1128cfeee5e5ba75ba7d645522cc76c2nobled    default:
4531b8c9fef1128cfeee5e5ba75ba7d645522cc76c2nobled	    return NULL;
454a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    }
455a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg
456a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    context = malloc(sizeof *context);
457a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    if (!context)
458a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg	return NULL;
459a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg
460a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    context->driScreenPriv = screen;
461a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    context->driDrawablePriv = NULL;
462a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    context->loaderPrivate = data;
463a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg
4646561a64a69c0f5005d03ea297f9a309f48449731nobled    if (!(*screen->DriverAPI.CreateContext)(mesa_api, modes,
465a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg					    context, shareCtx) ) {
466a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg        free(context);
467a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg        return NULL;
468a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    }
469a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg
470a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    return context;
471a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg}
472a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg
4733f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul
474e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic __DRIcontext *
475e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergdri2CreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
476e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		      __DRIcontext *shared, void *data)
477f616a263a25eda135800bea7d3a863c569b93e30Kristian Høgsberg{
478a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg   return dri2CreateNewContextForAPI(screen, __DRI_API_OPENGL,
479a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg				     config, shared, data);
480f616a263a25eda135800bea7d3a863c569b93e30Kristian Høgsberg}
481680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
482e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic int
483e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian HøgsbergdriCopyContext(__DRIcontext *dest, __DRIcontext *src, unsigned long mask)
484e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg{
48517d898d5b96809227d940768dc54cfe86070b8d0Ian Romanick    (void) dest;
48617d898d5b96809227d940768dc54cfe86070b8d0Ian Romanick    (void) src;
48717d898d5b96809227d940768dc54cfe86070b8d0Ian Romanick    (void) mask;
488e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    return GL_FALSE;
489e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg}
490e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
491e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg/*@}*/
492e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
493e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
494680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
495680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name Screen handling functions                              */
496680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
497680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/
498680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
499680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
500680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Destroy the per-screen private information.
501680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
502680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \internal
503680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function calls __DriverAPIRec::DestroyScreen on \p screenPrivate, calls
504680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * drmClose(), and finally frees \p screenPrivate.
505680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
506e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic void driDestroyScreen(__DRIscreen *psp)
507680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
508680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (psp) {
509680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	/* No interaction with the X-server is possible at this point.  This
510680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	 * routine is called after XCloseDisplay, so there is no protocol
511680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	 * stream open to the X-server anymore.
512680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	 */
513680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
514b83846475bac76268d75f53632faf8aad8cad02cEric Anholt       _mesa_destroy_shader_compiler();
515b83846475bac76268d75f53632faf8aad8cad02cEric Anholt
516680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	if (psp->DriverAPI.DestroyScreen)
517680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    (*psp->DriverAPI.DestroyScreen)(psp);
518680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
519f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg	if (!psp->dri2.enabled) {
5207da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	   (void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX);
5217da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	   (void)drmUnmap((drmAddress)psp->pFB, psp->fbSize);
5227da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	   (void)drmCloseOnce(psp->fd);
523a482e033082bb0794fdf56c47dd76d949afde6faEric Anholt	} else {
524a482e033082bb0794fdf56c47dd76d949afde6faEric Anholt	   driDestroyOptionCache(&psp->optionCache);
525a482e033082bb0794fdf56c47dd76d949afde6faEric Anholt	   driDestroyOptionInfo(&psp->optionInfo);
5267da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	}
527e5c28321b2047418ba960c5f9c3aa86cf2514bbbTilman Sauerbeck
52832f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg	free(psp);
529680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
530680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
531680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
5326cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsbergstatic void
533e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian HøgsbergsetupLoaderExtensions(__DRIscreen *psp,
5346cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg		      const __DRIextension **extensions)
5356cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg{
5366cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg    int i;
5376cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg
5386cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg    for (i = 0; extensions[i]; i++) {
5396cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg	if (strcmp(extensions[i]->name, __DRI_GET_DRAWABLE_INFO) == 0)
5406cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg	    psp->getDrawableInfo = (__DRIgetDrawableInfoExtension *) extensions[i];
5416cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg	if (strcmp(extensions[i]->name, __DRI_DAMAGE) == 0)
5426cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg	    psp->damage = (__DRIdamageExtension *) extensions[i];
5436cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg	if (strcmp(extensions[i]->name, __DRI_SYSTEM_TIME) == 0)
5446cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg	    psp->systemTime = (__DRIsystemTimeExtension *) extensions[i];
545f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg	if (strcmp(extensions[i]->name, __DRI_DRI2_LOADER) == 0)
546f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg	    psp->dri2.loader = (__DRIdri2LoaderExtension *) extensions[i];
547c26247100bfd453a7ec013f630abe366c12fbd8bKristian Høgsberg	if (strcmp(extensions[i]->name, __DRI_IMAGE_LOOKUP) == 0)
548c26247100bfd453a7ec013f630abe366c12fbd8bKristian Høgsberg	    psp->dri2.image = (__DRIimageLookupExtension *) extensions[i];
549db2993faa0211b60efd46016de5d07110cb9777aKristian Høgsberg	if (strcmp(extensions[i]->name, __DRI_USE_INVALIDATE) == 0)
550db2993faa0211b60efd46016de5d07110cb9777aKristian Høgsberg	    psp->dri2.useInvalidate = (__DRIuseInvalidateExtension *) extensions[i];
5516cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg    }
5526cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg}
5536cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg
554680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
5553f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul * DRI2
5563f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul */
557e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic __DRIscreen *
558f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsbergdri2CreateNewScreen(int scrn, int fd,
559e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		    const __DRIextension **extensions,
560e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		    const __DRIconfig ***driver_configs, void *data)
5617da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg{
5627da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    static const __DRIextension *emptyExtensionList[] = { NULL };
563e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    __DRIscreen *psp;
56416242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg    drmVersionPtr version;
565129b9ad16f95421d12f77c1bd3eca915d8768b78Kristian Høgsberg
566e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    if (driDriverAPI.InitScreen2 == NULL)
567129b9ad16f95421d12f77c1bd3eca915d8768b78Kristian Høgsberg        return NULL;
5687da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg
56932f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg    psp = calloc(1, sizeof(*psp));
5707da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    if (!psp)
5717da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	return NULL;
5727da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg
5736cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg    setupLoaderExtensions(psp, extensions);
5746cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg
57516242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg    version = drmGetVersion(fd);
57616242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg    if (version) {
57716242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg	psp->drm_version.major = version->version_major;
57816242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg	psp->drm_version.minor = version->version_minor;
57916242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg	psp->drm_version.patch = version->version_patchlevel;
58016242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg	drmFreeVersion(version);
58116242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg    }
58216242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg
5837da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    psp->extensions = emptyExtensionList;
5847da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    psp->fd = fd;
5857da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    psp->myNum = scrn;
5867da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    psp->dri2.enabled = GL_TRUE;
5877da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg
588e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    psp->DriverAPI = driDriverAPI;
589a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    psp->api_mask = (1 << __DRI_API_OPENGL);
590e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    *driver_configs = driDriverAPI.InitScreen2(psp);
591e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    if (*driver_configs == NULL) {
59232f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg	free(psp);
5937da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	return NULL;
5947da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    }
5957da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg
596e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    psp->DriverAPI = driDriverAPI;
59717eace581d25a626a7d75d9d1205d012cbb14a6eKristian Høgsberg    psp->loaderPrivate = data;
598e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
599a482e033082bb0794fdf56c47dd76d949afde6faEric Anholt    driParseOptionInfo(&psp->optionInfo, __dri2ConfigOptions,
600a482e033082bb0794fdf56c47dd76d949afde6faEric Anholt		       __dri2NConfigOptions);
601a482e033082bb0794fdf56c47dd76d949afde6faEric Anholt    driParseConfigFiles(&psp->optionCache, &psp->optionInfo, psp->myNum,
602a482e033082bb0794fdf56c47dd76d949afde6faEric Anholt			"dri2");
603234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
6047da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    return psp;
6057da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg}
6067da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg
607e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic const __DRIextension **driGetExtensions(__DRIscreen *psp)
608e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg{
609e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    return psp->extensions;
610e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg}
611e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
612f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg/** Core interface */
613e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergconst __DRIcoreExtension driCoreExtension = {
614e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    { __DRI_CORE, __DRI_CORE_VERSION },
615f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    NULL,
616e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driDestroyScreen,
617e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driGetExtensions,
618e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driGetConfigAttrib,
619e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driIndexConfigAttrib,
620f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    NULL,
621e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driDestroyDrawable,
6226260618b29983fd961718fd6e3961bdd32163cb5Kristian Høgsberg    NULL,
623f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    NULL,
624e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driCopyContext,
625e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driDestroyContext,
626e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driBindContext,
627e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driUnbindContext
628e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg};
629e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
63039a0e4e7de379a182c1544fa24d5cb2a7687ec72Kristian Høgsberg/** DRI2 interface */
631f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsbergconst __DRIdri2Extension driDRI2Extension = {
632f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    { __DRI_DRI2, __DRI_DRI2_VERSION },
633f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    dri2CreateNewScreen,
634f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    dri2CreateNewDrawable,
635f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    dri2CreateNewContext,
636a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    dri2GetAPIMask,
6371b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke    dri2CreateNewContextForAPI,
6381b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke    dri2AllocateBuffer,
6391b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke    dri2ReleaseBuffer
640f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg};
641f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg
642234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnesconst __DRI2configQueryExtension dri2ConfigQueryExtension = {
643234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes   { __DRI2_CONFIG_QUERY, __DRI2_CONFIG_QUERY_VERSION },
644234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes   dri2ConfigQueryb,
645234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes   dri2ConfigQueryi,
646234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes   dri2ConfigQueryf,
647234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes};
648234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
649680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
650680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Calculate amount of swap interval used between GLX buffer swaps.
651680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
652680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * The usage value, on the range [0,max], is the fraction of total swap
653680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * interval time used between GLX buffer swaps is calculated.
654680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
655680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *            \f$p = t_d / (i * t_r)\f$
656680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
657680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Where \f$t_d\f$ is the time since the last GLX buffer swap, \f$i\f$ is the
658680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * swap interval (as set by \c glXSwapIntervalSGI), and \f$t_r\f$ time
659680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * required for a single vertical refresh period (as returned by \c
660680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * glXGetMscRateOML).
661680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
662680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * See the documentation for the GLX_MESA_swap_frame_usage extension for more
663680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * details.
664680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
665680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param   dPriv  Pointer to the private drawable structure.
666680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \return  If less than a single swap interval time period was required
667680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *          between GLX buffer swaps, a number greater than 0 and less than
668680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *          1.0 is returned.  If exactly one swap interval time period is
669680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *          required, 1.0 is returned, and if more than one is required then
670680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *          a number greater than 1.0 will be returned.
671680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
672680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \sa glXSwapIntervalSGI glXGetMscRateOML
673680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
674680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \todo Instead of caching the \c glXGetMscRateOML function pointer, would it
675680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *       be possible to cache the sync rate?
676680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
677680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellfloat
678d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian HøgsbergdriCalculateSwapUsage( __DRIdrawable *dPriv, int64_t last_swap_ust,
679680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		       int64_t current_ust )
680680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
681680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   int32_t   n;
682680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   int32_t   d;
683680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   int       interval;
684680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   float     usage = 1.0;
685d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian Høgsberg   __DRIscreen *psp = dPriv->driScreenPriv;
686680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
687e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg   if ( (*psp->systemTime->getMSCRate)(dPriv, &n, &d, dPriv->loaderPrivate) ) {
688efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg      interval = (dPriv->swap_interval != 0) ? dPriv->swap_interval : 1;
689680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
690680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
691680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      /* We want to calculate
692680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * (current_UST - last_swap_UST) / (interval * us_per_refresh).  We get
693680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * current_UST by calling __glXGetUST.  last_swap_UST is stored in
694680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * dPriv->swap_ust.  interval has already been calculated.
695680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       *
696680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * The only tricky part is us_per_refresh.  us_per_refresh is
697680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * 1000000 / MSC_rate.  We know the MSC_rate is n / d.  We can flip it
698680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * around and say us_per_refresh = 1000000 * d / n.  Since this goes in
699680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * the denominator of the final calculation, we calculate
700680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * (interval * 1000000 * d) and move n into the numerator.
701680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       */
702680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
703680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      usage = (current_ust - last_swap_ust);
704680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      usage *= n;
705680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      usage /= (interval * d);
706680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      usage /= 1000000.0;
707680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   }
708680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
709680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   return usage;
710680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
711680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
71261d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerezvoid
71361d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerezdri2InvalidateDrawable(__DRIdrawable *drawable)
71461d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez{
71561d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez    drawable->dri2.stamp++;
71661d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez}
71761d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez
718680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@}*/
719