dri_util.c revision 1b8ef9416bf3a4d2d47fcf9935063af57da2975d
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
53680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
54f968f67e6214416f04b8875ce59a94a02f464c81Kristian Høgsberg * This is just a token extension used to signal that the driver
55f968f67e6214416f04b8875ce59a94a02f464c81Kristian Høgsberg * supports setting a read drawable.
56f968f67e6214416f04b8875ce59a94a02f464c81Kristian Høgsberg */
57f968f67e6214416f04b8875ce59a94a02f464c81Kristian Høgsbergconst __DRIextension driReadDrawableExtension = {
58ccff0cb26378ce370fc8697a2a2ada138d2e119eKristian Høgsberg    __DRI_READ_DRAWABLE, __DRI_READ_DRAWABLE_VERSION
59f968f67e6214416f04b8875ce59a94a02f464c81Kristian Høgsberg};
60f968f67e6214416f04b8875ce59a94a02f464c81Kristian Høgsberg
61c95e66120be049ee51ff84868b1da3379b312fabGeorge SapountzisGLint
62c95e66120be049ee51ff84868b1da3379b312fabGeorge SapountzisdriIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 )
63c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis{
64c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis   if (rect2.x1 > rect1.x1) rect1.x1 = rect2.x1;
65c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis   if (rect2.x2 < rect1.x2) rect1.x2 = rect2.x2;
66c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis   if (rect2.y1 > rect1.y1) rect1.y1 = rect2.y1;
67c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis   if (rect2.y2 < rect1.y2) rect1.y2 = rect2.y2;
68c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis
69c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis   if (rect1.x1 > rect1.x2 || rect1.y1 > rect1.y2) return 0;
70c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis
71c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis   return (rect1.x2 - rect1.x1) * (rect1.y2 - rect1.y1);
72c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis}
73680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
74680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
75680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name Context (un)binding functions                          */
76680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
77680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/
78680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
79680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
80680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Unbind context.
81680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
82aceccda56b08338e217991e54607f1c9f18fc3e6Kristian Høgsberg * \param scrn the screen.
83680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param gc context.
84680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
85680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \return \c GL_TRUE on success, or \c GL_FALSE on failure.
86680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
87680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \internal
88680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function calls __DriverAPIRec::UnbindContext, and then decrements
89d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian Høgsberg * __DRIdrawableRec::refcount which must be non-zero for a successful
90680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * return.
91680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
92680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * While casting the opaque private pointers associated with the parameters
93680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * into their respective real types it also assures they are not \c NULL.
94680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
95e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic int driUnbindContext(__DRIcontext *pcp)
96680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
97e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    __DRIscreen *psp;
98418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    __DRIdrawable *pdp;
99418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    __DRIdrawable *prp;
100680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
101680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /*
102680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    ** Assume error checking is done properly in glXMakeCurrent before
103c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick    ** calling driUnbindContext.
104680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    */
105680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
106e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    if (pcp == NULL)
107aceccda56b08338e217991e54607f1c9f18fc3e6Kristian Høgsberg        return GL_FALSE;
108680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
109e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    psp = pcp->driScreenPriv;
110418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    pdp = pcp->driDrawablePriv;
111418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    prp = pcp->driReadablePriv;
112680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
113418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    /* already unbound */
114418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    if (!pdp && !prp)
115418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen      return GL_TRUE;
116418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    /* Let driver unbind drawable from context */
117680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    (*psp->DriverAPI.UnbindContext)(pcp);
118680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
119cab77711b3e8d398393677bcefcd413f50503a64Vinson Lee    assert(pdp);
120418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    if (pdp->refcount == 0) {
121418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen	/* ERROR!!! */
122418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen	return GL_FALSE;
123418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    }
124418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen
125418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    dri_put_drawable(pdp);
126418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen
127418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    if (prp != pdp) {
128418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen        if (prp->refcount == 0) {
129418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen	    /* ERROR!!! */
130418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen	    return GL_FALSE;
131418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen	}
132418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen
133418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    	dri_put_drawable(prp);
134418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    }
135418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen
136418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen
137418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    /* XXX this is disabled so that if we call SwapBuffers on an unbound
138418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen     * window we can determine the last context bound to the window and
139418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen     * use that context's lock. (BrianP, 2-Dec-2000)
140418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen     */
141418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    pcp->driDrawablePriv = pcp->driReadablePriv = NULL;
142418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen
143680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    return GL_TRUE;
144680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
145680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
146680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
147680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function takes both a read buffer and a draw buffer.  This is needed
148680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent
149680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * function.
150680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
151e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic int driBindContext(__DRIcontext *pcp,
152e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg			  __DRIdrawable *pdp,
153e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg			  __DRIdrawable *prp)
154680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
155d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian Høgsberg    __DRIscreen *psp = NULL;
156680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
15764fa717b18272bda2551a6dc2e1a40725b031097Jakob Bornecrantz    /*
15864fa717b18272bda2551a6dc2e1a40725b031097Jakob Bornecrantz    ** Assume error checking is done properly in glXMakeCurrent before
15964fa717b18272bda2551a6dc2e1a40725b031097Jakob Bornecrantz    ** calling driUnbindContext.
16064fa717b18272bda2551a6dc2e1a40725b031097Jakob Bornecrantz    */
1618e753d04045a82062ac34d3b2622eb9dba8af374Thomas Hellstrom
16264fa717b18272bda2551a6dc2e1a40725b031097Jakob Bornecrantz    if (!pcp)
16364fa717b18272bda2551a6dc2e1a40725b031097Jakob Bornecrantz	return GL_FALSE;
16464fa717b18272bda2551a6dc2e1a40725b031097Jakob Bornecrantz
16564fa717b18272bda2551a6dc2e1a40725b031097Jakob Bornecrantz    /* Bind the drawable to the context */
16664fa717b18272bda2551a6dc2e1a40725b031097Jakob Bornecrantz    psp = pcp->driScreenPriv;
16764fa717b18272bda2551a6dc2e1a40725b031097Jakob Bornecrantz    pcp->driDrawablePriv = pdp;
16864fa717b18272bda2551a6dc2e1a40725b031097Jakob Bornecrantz    pcp->driReadablePriv = prp;
16964fa717b18272bda2551a6dc2e1a40725b031097Jakob Bornecrantz    if (pdp) {
17064fa717b18272bda2551a6dc2e1a40725b031097Jakob Bornecrantz	pdp->driContextPriv = pcp;
17164fa717b18272bda2551a6dc2e1a40725b031097Jakob Bornecrantz	dri_get_drawable(pdp);
17264fa717b18272bda2551a6dc2e1a40725b031097Jakob Bornecrantz    }
17364fa717b18272bda2551a6dc2e1a40725b031097Jakob Bornecrantz    if (prp && pdp != prp) {
17464fa717b18272bda2551a6dc2e1a40725b031097Jakob Bornecrantz	dri_get_drawable(prp);
175418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    }
176680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
177680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /*
178680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    ** Now that we have a context associated with this drawable, we can
179680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    ** initialize the drawable information if has not been done before.
180680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    */
181680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
182f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    if (!psp->dri2.enabled) {
1838e753d04045a82062ac34d3b2622eb9dba8af374Thomas Hellstrom	if (pdp && !pdp->pStamp) {
1847da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	    DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
1857da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	    __driUtilUpdateDrawableInfo(pdp);
1867da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	    DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
1877da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	}
1888e753d04045a82062ac34d3b2622eb9dba8af374Thomas Hellstrom	if (prp && pdp != prp && !prp->pStamp) {
1897da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	    DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
1907da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	    __driUtilUpdateDrawableInfo(prp);
1917da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	    DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
1928e753d04045a82062ac34d3b2622eb9dba8af374Thomas Hellstrom        }
1937b1ff326071658d5bd6e7feb2ad78d0e0209211dIan Romanick    }
1947b1ff326071658d5bd6e7feb2ad78d0e0209211dIan Romanick
195680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /* Call device-specific MakeCurrent */
196c952b3e907ab31cd5f95157c18ce2f81626aafe4Thomas Hellstrom    return (*psp->DriverAPI.MakeCurrent)(pcp, pdp, prp);
197680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
198680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
199680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@}*/
200680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
201680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
202680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
203680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name Drawable handling functions                            */
204680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
205680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/
206680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
207680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
208680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Update private drawable information.
209680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
210680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param pdp pointer to the private drawable information to update.
211680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
212d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian Høgsberg * This function basically updates the __DRIdrawable struct's
2135f1ba3e21b62cee1a4f900a2e6964728f3eeea9bIan Romanick * cliprect information by calling \c __DRIinterfaceMethods::getDrawableInfo.
2145f1ba3e21b62cee1a4f900a2e6964728f3eeea9bIan Romanick * This is usually called by the DRI_VALIDATE_DRAWABLE_INFO macro which
215680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * compares the __DRIdrwablePrivate pStamp and lastStamp values.  If
216680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * the values are different that means we have to update the clipping
217680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * info.
218680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
219680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellvoid
220d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian Høgsberg__driUtilUpdateDrawableInfo(__DRIdrawable *pdp)
221680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
222d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian Høgsberg    __DRIscreen *psp = pdp->driScreenPriv;
223d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian Høgsberg    __DRIcontext *pcp = pdp->driContextPriv;
224680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
2257b1ff326071658d5bd6e7feb2ad78d0e0209211dIan Romanick    if (!pcp
2267b1ff326071658d5bd6e7feb2ad78d0e0209211dIan Romanick	|| ((pdp != pcp->driDrawablePriv) && (pdp != pcp->driReadablePriv))) {
227682393944c72ecfabe8df674af0b48975e90b98cThomas Hellström	/* ERROR!!!
228682393944c72ecfabe8df674af0b48975e90b98cThomas Hellström	 * ...but we must ignore it. There can be many contexts bound to a
229682393944c72ecfabe8df674af0b48975e90b98cThomas Hellström	 * drawable.
230682393944c72ecfabe8df674af0b48975e90b98cThomas Hellström	 */
231680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
232680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
233680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (pdp->pClipRects) {
23432f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg	free(pdp->pClipRects);
235a903749b246fce26038c66d06fe7eb77daf815abMichel Dänzer	pdp->pClipRects = NULL;
236680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
237680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
238680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (pdp->pBackClipRects) {
23932f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg	free(pdp->pBackClipRects);
240a903749b246fce26038c66d06fe7eb77daf815abMichel Dänzer	pdp->pBackClipRects = NULL;
241680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
242680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
243680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
244680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
245e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    if (! (*psp->getDrawableInfo->getDrawableInfo)(pdp,
246680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			  &pdp->index, &pdp->lastStamp,
247680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			  &pdp->x, &pdp->y, &pdp->w, &pdp->h,
248680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			  &pdp->numClipRects, &pdp->pClipRects,
249680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			  &pdp->backX,
250680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			  &pdp->backY,
251680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			  &pdp->numBackClipRects,
252e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg			  &pdp->pBackClipRects,
253e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg			  pdp->loaderPrivate)) {
254680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	/* Error -- eg the window may have been destroyed.  Keep going
255680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	 * with no cliprects.
256680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	 */
257680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        pdp->pStamp = &pdp->lastStamp; /* prevent endless loop */
258680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	pdp->numClipRects = 0;
259680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	pdp->pClipRects = NULL;
260680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	pdp->numBackClipRects = 0;
261680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	pdp->pBackClipRects = NULL;
262680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
263680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    else
264680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       pdp->pStamp = &(psp->pSAREA->drawableTable[pdp->index].stamp);
265680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
266680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
267680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
268680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
269680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@}*/
270680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
271680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
272680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name GLX callbacks                                          */
273680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
274680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/
275680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
276e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic void driReportDamage(__DRIdrawable *pdp,
277e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg			    struct drm_clip_rect *pClipRects, int numClipRects)
278e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg{
279e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    __DRIscreen *psp = pdp->driScreenPriv;
280e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
281e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    /* Check that we actually have the new damage report method */
282f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    if (psp->damage) {
283e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg	/* Report the damage.  Currently, all our drivers draw
284e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg	 * directly to the front buffer, so we report the damage there
285e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg	 * rather than to the backing storein (if any).
286e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg	 */
287e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg	(*psp->damage->reportDamage)(pdp,
288e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg				     pdp->x, pdp->y,
289e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg				     pClipRects, numClipRects,
290e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg				     GL_TRUE, pdp->loaderPrivate);
291e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    }
292e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg}
293e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
294e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
295680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
296680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Swap buffers.
297680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
298680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param drawablePrivate opaque pointer to the per-drawable private info.
299680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
300680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \internal
301d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian Høgsberg * This function calls __DRIdrawable::swapBuffers.
302680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
303680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Is called directly from glXSwapBuffers().
304680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
305e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic void driSwapBuffers(__DRIdrawable *dPriv)
306680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
307e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    __DRIscreen *psp = dPriv->driScreenPriv;
3087627c7f5dfa3b1bc7be9d1670668a81a70d9f64aXiang, Haihao    drm_clip_rect_t *rects;
3097627c7f5dfa3b1bc7be9d1670668a81a70d9f64aXiang, Haihao    int i;
3102407e48f2805e27e76e2e1d7083926c4077d9032Xiang, Haihao
311e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    psp->DriverAPI.SwapBuffers(dPriv);
312c2b185cff82a6cdb723cda4e05ffe1a213a9de3eEric Anholt
31343c7ffaea635f949fd4803c4f594cf53e4b98f24Younes Manton    if (!dPriv->numClipRects)
31443c7ffaea635f949fd4803c4f594cf53e4b98f24Younes Manton        return;
31543c7ffaea635f949fd4803c4f594cf53e4b98f24Younes Manton
31632f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg    rects = malloc(sizeof(*rects) * dPriv->numClipRects);
3177627c7f5dfa3b1bc7be9d1670668a81a70d9f64aXiang, Haihao
3187627c7f5dfa3b1bc7be9d1670668a81a70d9f64aXiang, Haihao    if (!rects)
3197627c7f5dfa3b1bc7be9d1670668a81a70d9f64aXiang, Haihao        return;
3207627c7f5dfa3b1bc7be9d1670668a81a70d9f64aXiang, Haihao
3217627c7f5dfa3b1bc7be9d1670668a81a70d9f64aXiang, Haihao    for (i = 0; i < dPriv->numClipRects; i++) {
3227627c7f5dfa3b1bc7be9d1670668a81a70d9f64aXiang, Haihao        rects[i].x1 = dPriv->pClipRects[i].x1 - dPriv->x;
3237627c7f5dfa3b1bc7be9d1670668a81a70d9f64aXiang, Haihao        rects[i].y1 = dPriv->pClipRects[i].y1 - dPriv->y;
3247627c7f5dfa3b1bc7be9d1670668a81a70d9f64aXiang, Haihao        rects[i].x2 = dPriv->pClipRects[i].x2 - dPriv->x;
3257627c7f5dfa3b1bc7be9d1670668a81a70d9f64aXiang, Haihao        rects[i].y2 = dPriv->pClipRects[i].y2 - dPriv->y;
3267627c7f5dfa3b1bc7be9d1670668a81a70d9f64aXiang, Haihao    }
3277627c7f5dfa3b1bc7be9d1670668a81a70d9f64aXiang, Haihao
3287627c7f5dfa3b1bc7be9d1670668a81a70d9f64aXiang, Haihao    driReportDamage(dPriv, rects, dPriv->numClipRects);
32932f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg    free(rects);
330680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
331680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
332e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic int driDrawableGetMSC( __DRIscreen *sPriv, __DRIdrawable *dPriv,
33338fdb47d26055e19d50cd407266b56ed4317ae0aJesse Barnes			      int64_t *msc )
33438fdb47d26055e19d50cd407266b56ed4317ae0aJesse Barnes{
3356e8d21d72f35767e07081a8bee4323aaaf5e2aaeKristian Høgsberg    return sPriv->DriverAPI.GetDrawableMSC(sPriv, dPriv, msc);
336680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
337680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
3383f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul
339e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic int driWaitForMSC(__DRIdrawable *dPriv, int64_t target_msc,
3405987a03f994af2bb413d1cf984ab01aa095c0943Kristian Høgsberg			 int64_t divisor, int64_t remainder,
3415987a03f994af2bb413d1cf984ab01aa095c0943Kristian Høgsberg			 int64_t * msc, int64_t * sbc)
342680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
343680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIswapInfo  sInfo;
344680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    int  status;
345680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
346680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    status = dPriv->driScreenPriv->DriverAPI.WaitForMSC( dPriv, target_msc,
347680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell                                                         divisor, remainder,
348680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell                                                         msc );
349680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
350680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /* GetSwapInfo() may not be provided by the driver if GLX_SGI_video_sync
351680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell     * is supported but GLX_OML_sync_control is not.  Therefore, don't return
352680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell     * an error value if GetSwapInfo() is not implemented.
353680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    */
354680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if ( status == 0
355680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell         && dPriv->driScreenPriv->DriverAPI.GetSwapInfo ) {
356680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        status = dPriv->driScreenPriv->DriverAPI.GetSwapInfo( dPriv, & sInfo );
357680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        *sbc = sInfo.swap_count;
358680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
359680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
360680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    return status;
361680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
362680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
3633f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul
364106a6f29bbdc71982afd629bdf89369cefd1459eKristian Høgsbergconst __DRImediaStreamCounterExtension driMediaStreamCounterExtension = {
365ccff0cb26378ce370fc8697a2a2ada138d2e119eKristian Høgsberg    { __DRI_MEDIA_STREAM_COUNTER, __DRI_MEDIA_STREAM_COUNTER_VERSION },
366106a6f29bbdc71982afd629bdf89369cefd1459eKristian Høgsberg    driWaitForMSC,
36738fdb47d26055e19d50cd407266b56ed4317ae0aJesse Barnes    driDrawableGetMSC,
368106a6f29bbdc71982afd629bdf89369cefd1459eKristian Høgsberg};
369680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
3703f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul
371e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic void driCopySubBuffer(__DRIdrawable *dPriv,
372f2ad1b60c0da11283b399008f491792790cea294Brian Paul			      int x, int y, int w, int h)
373f2ad1b60c0da11283b399008f491792790cea294Brian Paul{
374e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    drm_clip_rect_t rect;
375e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
376e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    rect.x1 = x;
377377016d728ace47c9eeb3ac2f01191608ab060f6Dennis Kasprzyk    rect.y1 = dPriv->h - y - h;
378e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    rect.x2 = x + w;
379377016d728ace47c9eeb3ac2f01191608ab060f6Dennis Kasprzyk    rect.y2 = rect.y1 + h;
380e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driReportDamage(dPriv, &rect, 1);
3813a94b25538c647df965a93cd7734b841257ef203Peter Hutterer
3823a94b25538c647df965a93cd7734b841257ef203Peter Hutterer    dPriv->driScreenPriv->DriverAPI.CopySubBuffer(dPriv, x, y, w, h);
383f2ad1b60c0da11283b399008f491792790cea294Brian Paul}
384680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
385ac3e838fa748c8c8a6ffc04d1ab13da71f75f103Kristian Høgsbergconst __DRIcopySubBufferExtension driCopySubBufferExtension = {
386ccff0cb26378ce370fc8697a2a2ada138d2e119eKristian Høgsberg    { __DRI_COPY_SUB_BUFFER, __DRI_COPY_SUB_BUFFER_VERSION },
387ccff0cb26378ce370fc8697a2a2ada138d2e119eKristian Høgsberg    driCopySubBuffer
388ac3e838fa748c8c8a6ffc04d1ab13da71f75f103Kristian Høgsberg};
389ac3e838fa748c8c8a6ffc04d1ab13da71f75f103Kristian Høgsberg
390e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic void driSetSwapInterval(__DRIdrawable *dPriv, unsigned int interval)
391efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg{
392e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    dPriv->swap_interval = interval;
393efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg}
394efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg
395e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic unsigned int driGetSwapInterval(__DRIdrawable *dPriv)
396efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg{
397e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    return dPriv->swap_interval;
398efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg}
399efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg
400efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsbergconst __DRIswapControlExtension driSwapControlExtension = {
401ccff0cb26378ce370fc8697a2a2ada138d2e119eKristian Høgsberg    { __DRI_SWAP_CONTROL, __DRI_SWAP_CONTROL_VERSION },
402efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg    driSetSwapInterval,
403efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg    driGetSwapInterval
404efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg};
405efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg
406efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg
407680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
408680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This is called via __DRIscreenRec's createNewDrawable pointer.
409680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
410e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic __DRIdrawable *
411e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian HøgsbergdriCreateNewDrawable(__DRIscreen *psp, const __DRIconfig *config,
412e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		     drm_drawable_t hwDrawable, int renderType,
413e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		     const int *attrs, void *data)
414680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
415e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    __DRIdrawable *pdp;
4161960182ece3f1eca06d2e439f64dd61be8a03ff5Ian Romanick
417680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /* Since pbuffers are not yet supported, no drawable attributes are
418680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell     * supported either.
419680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell     */
420680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    (void) attrs;
421680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
42232f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg    pdp = malloc(sizeof *pdp);
423680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (!pdp) {
424680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return NULL;
425680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
426680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
42747de9adece49f78c6e4065bedc69ce13272bc120Dave Airlie    pdp->driContextPriv = NULL;
428e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    pdp->loaderPrivate = data;
4294ff95e78e19e5902352ea3759d32d9f013255f42Kristian Høgsberg    pdp->hHWDrawable = hwDrawable;
4303264352c577ce1d6681e70abd76624ede906df71Dave Airlie    pdp->refcount = 1;
431680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->pStamp = NULL;
432680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->lastStamp = 0;
433680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->index = 0;
434680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->x = 0;
435680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->y = 0;
436680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->w = 0;
437680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->h = 0;
438680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->numClipRects = 0;
439680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->numBackClipRects = 0;
440680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->pClipRects = NULL;
441680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->pBackClipRects = NULL;
44238fdb47d26055e19d50cd407266b56ed4317ae0aJesse Barnes    pdp->vblSeq = 0;
44338fdb47d26055e19d50cd407266b56ed4317ae0aJesse Barnes    pdp->vblFlags = 0;
444680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
445680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->driScreenPriv = psp;
446680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
447705e142dda047f24b563fc2bea0f922173e91d1bKristian Høgsberg    if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, &config->modes, 0)) {
44832f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg       free(pdp);
449680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       return NULL;
450680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
451680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
45238fdb47d26055e19d50cd407266b56ed4317ae0aJesse Barnes    pdp->msc_base = 0;
453680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
454c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick    /* This special default value is replaced with the configured
455c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick     * default value when the drawable is first bound to a direct
456c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick     * rendering context.
457c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick     */
458efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg    pdp->swap_interval = (unsigned)-1;
459680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
460e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    return pdp;
461e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg}
462680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
4633f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul
464e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic __DRIdrawable *
465f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsbergdri2CreateNewDrawable(__DRIscreen *screen,
466f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg		      const __DRIconfig *config,
467f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg		      void *loaderPrivate)
468e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg{
469e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    __DRIdrawable *pdraw;
4707da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg
471f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    pdraw = driCreateNewDrawable(screen, config, 0, 0, NULL, loaderPrivate);
4725cf69fe511a67a7bcf6787974becf6a143abb507Alan Hourihane    if (!pdraw)
4735cf69fe511a67a7bcf6787974becf6a143abb507Alan Hourihane    	return NULL;
474e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
475925b901ba313a3ddd7567eca088951be39414430Kristian Høgsberg    pdraw->pClipRects = &pdraw->dri2.clipRect;
476925b901ba313a3ddd7567eca088951be39414430Kristian Høgsberg    pdraw->pBackClipRects = &pdraw->dri2.clipRect;
477e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
47861d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez    pdraw->pStamp = &pdraw->dri2.stamp;
47961d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez    *pdraw->pStamp = pdraw->lastStamp + 1;
48061d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez
481e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    return pdraw;
482680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
483680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
4841b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzkestatic __DRIbuffer *
4851b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzkedri2AllocateBuffer(__DRIscreen *screen,
4861b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke		   unsigned int attachment, unsigned int format,
4871b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke		   int width, int height)
4881b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke{
4891b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke    return (*screen->DriverAPI.AllocateBuffer)(screen, attachment, format,
4901b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke					       width, height);
4911b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke}
4921b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke
4931b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzkestatic void
4941b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzkedri2ReleaseBuffer(__DRIscreen *screen, __DRIbuffer *buffer)
4951b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke{
4961b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke   (*screen->DriverAPI.ReleaseBuffer)(screen, buffer);
4971b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke}
4981b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke
4991b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke
500234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnesstatic int
501234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnesdri2ConfigQueryb(__DRIscreen *screen, const char *var, GLboolean *val)
502234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes{
503234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes   if (!driCheckOption(&screen->optionCache, var, DRI_BOOL))
504234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes      return -1;
505234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
506234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes   *val = driQueryOptionb(&screen->optionCache, var);
507234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
508234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes   return 0;
509234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes}
510234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
511234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnesstatic int
512234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnesdri2ConfigQueryi(__DRIscreen *screen, const char *var, GLint *val)
513234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes{
514234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes   if (!driCheckOption(&screen->optionCache, var, DRI_INT) &&
515234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes       !driCheckOption(&screen->optionCache, var, DRI_ENUM))
516234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes      return -1;
517234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
518234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes    *val = driQueryOptioni(&screen->optionCache, var);
519234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
520234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes    return 0;
521234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes}
522234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
523234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnesstatic int
524234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnesdri2ConfigQueryf(__DRIscreen *screen, const char *var, GLfloat *val)
525234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes{
526234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes   if (!driCheckOption(&screen->optionCache, var, DRI_FLOAT))
527234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes      return -1;
528234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
529234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes    *val = driQueryOptionf(&screen->optionCache, var);
530234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
531234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes    return 0;
532234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes}
533234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
534234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
5353264352c577ce1d6681e70abd76624ede906df71Dave Airliestatic void dri_get_drawable(__DRIdrawable *pdp)
5363264352c577ce1d6681e70abd76624ede906df71Dave Airlie{
5373264352c577ce1d6681e70abd76624ede906df71Dave Airlie    pdp->refcount++;
5383264352c577ce1d6681e70abd76624ede906df71Dave Airlie}
5393264352c577ce1d6681e70abd76624ede906df71Dave Airlie
5403264352c577ce1d6681e70abd76624ede906df71Dave Airliestatic void dri_put_drawable(__DRIdrawable *pdp)
541680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
542d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian Høgsberg    __DRIscreen *psp;
543680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
544680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (pdp) {
545f622b649fb0c55b1640997f9d32ea327743519a1Vinson Lee	pdp->refcount--;
546f622b649fb0c55b1640997f9d32ea327743519a1Vinson Lee	if (pdp->refcount)
547f622b649fb0c55b1640997f9d32ea327743519a1Vinson Lee	    return;
548f622b649fb0c55b1640997f9d32ea327743519a1Vinson Lee
549eab896cc213157758d74a2f39b5e3b1e748c071fDave Airlie	psp = pdp->driScreenPriv;
550680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        (*psp->DriverAPI.DestroyBuffer)(pdp);
551925b901ba313a3ddd7567eca088951be39414430Kristian Høgsberg	if (pdp->pClipRects && pdp->pClipRects != &pdp->dri2.clipRect) {
55232f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg	    free(pdp->pClipRects);
553680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    pdp->pClipRects = NULL;
554680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	}
555925b901ba313a3ddd7567eca088951be39414430Kristian Høgsberg	if (pdp->pBackClipRects && pdp->pClipRects != &pdp->dri2.clipRect) {
55632f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg	    free(pdp->pBackClipRects);
557680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    pdp->pBackClipRects = NULL;
558680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	}
55932f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg	free(pdp);
560680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
561680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
562680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
5633264352c577ce1d6681e70abd76624ede906df71Dave Airliestatic void
5643264352c577ce1d6681e70abd76624ede906df71Dave AirliedriDestroyDrawable(__DRIdrawable *pdp)
5653264352c577ce1d6681e70abd76624ede906df71Dave Airlie{
5663264352c577ce1d6681e70abd76624ede906df71Dave Airlie    dri_put_drawable(pdp);
5673264352c577ce1d6681e70abd76624ede906df71Dave Airlie}
5683264352c577ce1d6681e70abd76624ede906df71Dave Airlie
569680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@}*/
570680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
571680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
572680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
573680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name Context handling functions                             */
574680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
575680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/
576680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
577680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
578680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Destroy the per-context private information.
579680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
580680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \internal
581680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function calls __DriverAPIRec::DestroyContext on \p contextPrivate, calls
582680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * drmDestroyContext(), and finally frees \p contextPrivate.
583680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
584b4b040f7d83f5f4917c48bf5833394d550e30421Brian Paulstatic void
585e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian HøgsbergdriDestroyContext(__DRIcontext *pcp)
586680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
587680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (pcp) {
588680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	(*pcp->driScreenPriv->DriverAPI.DestroyContext)(pcp);
58932f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg	free(pcp);
590680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
591680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
592680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
593680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
594680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
595680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Create the per-drawable private driver information.
596680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
597680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param render_type   Type of rendering target.  \c GLX_RGBA is the only
598680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *                      type likely to ever be supported for direct-rendering.
5993f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul * \param shared        Context with which to share textures, etc. or NULL
600680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
601680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \returns An opaque pointer to the per-context private information on
602680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *          success, or \c NULL on failure.
603680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
604680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \internal
605d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian Høgsberg * This function allocates and fills a __DRIcontextRec structure.  It
606680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * performs some device independent initialization and passes all the
607680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * relevent information to __DriverAPIRec::CreateContext to create the
608680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * context.
609680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
610680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
611e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic __DRIcontext *
612e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian HøgsbergdriCreateNewContext(__DRIscreen *psp, const __DRIconfig *config,
613ecdb45cb29e3209287cc297081596126e955ff2bKristian Høgsberg		    int render_type, __DRIcontext *shared,
614e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		    drm_context_t hwContext, void *data)
615680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
616e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    __DRIcontext *pcp;
617e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    void * const shareCtx = (shared != NULL) ? shared->driverPrivate : NULL;
618680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
61932f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg    pcp = malloc(sizeof *pcp);
620e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    if (!pcp)
621680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return NULL;
622680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
623680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pcp->driScreenPriv = psp;
624680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pcp->driDrawablePriv = NULL;
62593931d9e684cd5a5659c3f28f8da7294ac174542Kristian Høgsberg    pcp->loaderPrivate = data;
62693931d9e684cd5a5659c3f28f8da7294ac174542Kristian Høgsberg
627d449627829e1a4a3250a1a723af2f4e3cd5fd194Kristian Høgsberg    pcp->dri2.draw_stamp = 0;
628d449627829e1a4a3250a1a723af2f4e3cd5fd194Kristian Høgsberg    pcp->dri2.read_stamp = 0;
629680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
630e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    pcp->hHWContext = hwContext;
63174d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell
632a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    if ( !(*psp->DriverAPI.CreateContext)(API_OPENGL,
633a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg					  &config->modes, pcp, shareCtx) ) {
63432f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg        free(pcp);
635680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        return NULL;
636680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
637680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
638680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    return pcp;
639680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
640ac3e838fa748c8c8a6ffc04d1ab13da71f75f103Kristian Høgsberg
641a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsbergstatic unsigned int
642a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsbergdri2GetAPIMask(__DRIscreen *screen)
643a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg{
644a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    return screen->api_mask;
645a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg}
646a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg
647a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsbergstatic __DRIcontext *
648a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsbergdri2CreateNewContextForAPI(__DRIscreen *screen, int api,
649a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg			   const __DRIconfig *config,
650a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg			   __DRIcontext *shared, void *data)
651a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg{
652a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    __DRIcontext *context;
653d3491e775fb07f891463b2185d74bbad62f3ed24Kristian Høgsberg    const struct gl_config *modes = (config != NULL) ? &config->modes : NULL;
654a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    void *shareCtx = (shared != NULL) ? shared->driverPrivate : NULL;
655a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    gl_api mesa_api;
656a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg
657a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    if (!(screen->api_mask & (1 << api)))
658a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg	return NULL;
659a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg
660a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    switch (api) {
661a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    case __DRI_API_OPENGL:
662a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg	    mesa_api = API_OPENGL;
663a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg	    break;
664a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    case __DRI_API_GLES:
665a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg	    mesa_api = API_OPENGLES;
666a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg	    break;
667a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    case __DRI_API_GLES2:
668a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg	    mesa_api = API_OPENGLES2;
669a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg	    break;
6701b8c9fef1128cfeee5e5ba75ba7d645522cc76c2nobled    default:
6711b8c9fef1128cfeee5e5ba75ba7d645522cc76c2nobled	    return NULL;
672a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    }
673a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg
674a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    context = malloc(sizeof *context);
675a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    if (!context)
676a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg	return NULL;
677a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg
678a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    context->driScreenPriv = screen;
679a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    context->driDrawablePriv = NULL;
680a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    context->loaderPrivate = data;
681a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg
6826561a64a69c0f5005d03ea297f9a309f48449731nobled    if (!(*screen->DriverAPI.CreateContext)(mesa_api, modes,
683a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg					    context, shareCtx) ) {
684a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg        free(context);
685a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg        return NULL;
686a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    }
687a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg
688a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    return context;
689a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg}
690a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg
6913f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul
692e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic __DRIcontext *
693e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergdri2CreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
694e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		      __DRIcontext *shared, void *data)
695f616a263a25eda135800bea7d3a863c569b93e30Kristian Høgsberg{
696a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg   return dri2CreateNewContextForAPI(screen, __DRI_API_OPENGL,
697a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg				     config, shared, data);
698f616a263a25eda135800bea7d3a863c569b93e30Kristian Høgsberg}
699680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
700e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic int
701e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian HøgsbergdriCopyContext(__DRIcontext *dest, __DRIcontext *src, unsigned long mask)
702e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg{
703e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    return GL_FALSE;
704e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg}
705e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
706e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg/*@}*/
707e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
708e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
709680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
710680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name Screen handling functions                              */
711680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
712680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/
713680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
714680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
715680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Destroy the per-screen private information.
716680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
717680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \internal
718680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function calls __DriverAPIRec::DestroyScreen on \p screenPrivate, calls
719680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * drmClose(), and finally frees \p screenPrivate.
720680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
721e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic void driDestroyScreen(__DRIscreen *psp)
722680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
723680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (psp) {
724680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	/* No interaction with the X-server is possible at this point.  This
725680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	 * routine is called after XCloseDisplay, so there is no protocol
726680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	 * stream open to the X-server anymore.
727680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	 */
728680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
729b83846475bac76268d75f53632faf8aad8cad02cEric Anholt       _mesa_destroy_shader_compiler();
730b83846475bac76268d75f53632faf8aad8cad02cEric Anholt
731680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	if (psp->DriverAPI.DestroyScreen)
732680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    (*psp->DriverAPI.DestroyScreen)(psp);
733680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
734f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg	if (!psp->dri2.enabled) {
7357da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	   (void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX);
7367da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	   (void)drmUnmap((drmAddress)psp->pFB, psp->fbSize);
7377da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	   (void)drmCloseOnce(psp->fd);
738a482e033082bb0794fdf56c47dd76d949afde6faEric Anholt	} else {
739a482e033082bb0794fdf56c47dd76d949afde6faEric Anholt	   driDestroyOptionCache(&psp->optionCache);
740a482e033082bb0794fdf56c47dd76d949afde6faEric Anholt	   driDestroyOptionInfo(&psp->optionInfo);
7417da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	}
742e5c28321b2047418ba960c5f9c3aa86cf2514bbbTilman Sauerbeck
74332f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg	free(psp);
744680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
745680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
746680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
7476cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsbergstatic void
748e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian HøgsbergsetupLoaderExtensions(__DRIscreen *psp,
7496cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg		      const __DRIextension **extensions)
7506cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg{
7516cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg    int i;
7526cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg
7536cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg    for (i = 0; extensions[i]; i++) {
7546cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg	if (strcmp(extensions[i]->name, __DRI_GET_DRAWABLE_INFO) == 0)
7556cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg	    psp->getDrawableInfo = (__DRIgetDrawableInfoExtension *) extensions[i];
7566cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg	if (strcmp(extensions[i]->name, __DRI_DAMAGE) == 0)
7576cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg	    psp->damage = (__DRIdamageExtension *) extensions[i];
7586cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg	if (strcmp(extensions[i]->name, __DRI_SYSTEM_TIME) == 0)
7596cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg	    psp->systemTime = (__DRIsystemTimeExtension *) extensions[i];
760f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg	if (strcmp(extensions[i]->name, __DRI_DRI2_LOADER) == 0)
761f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg	    psp->dri2.loader = (__DRIdri2LoaderExtension *) extensions[i];
762c26247100bfd453a7ec013f630abe366c12fbd8bKristian Høgsberg	if (strcmp(extensions[i]->name, __DRI_IMAGE_LOOKUP) == 0)
763c26247100bfd453a7ec013f630abe366c12fbd8bKristian Høgsberg	    psp->dri2.image = (__DRIimageLookupExtension *) extensions[i];
764db2993faa0211b60efd46016de5d07110cb9777aKristian Høgsberg	if (strcmp(extensions[i]->name, __DRI_USE_INVALIDATE) == 0)
765db2993faa0211b60efd46016de5d07110cb9777aKristian Høgsberg	    psp->dri2.useInvalidate = (__DRIuseInvalidateExtension *) extensions[i];
7666cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg    }
7676cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg}
7686cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg
769680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
77064106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg * This is the bootstrap function for the driver.  libGL supplies all of the
77164106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg * requisite information about the system, and the driver initializes itself.
77264106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg * This routine also fills in the linked list pointed to by \c driver_modes
773d3491e775fb07f891463b2185d74bbad62f3ed24Kristian Høgsberg * with the \c struct gl_config that the driver can support for windows or
77464106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg * pbuffers.
7753f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul *
7763f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul * For legacy DRI.
777680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
778680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param scrn  Index of the screen
779680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param ddx_version Version of the 2D DDX.  This may not be meaningful for
780680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *                    all drivers.
781680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param dri_version Version of the "server-side" DRI.
782680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param drm_version Version of the kernel DRM.
783680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param frame_buffer Data describing the location and layout of the
784680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *                     framebuffer.
785fab1f07d6ad01463897ae792f4b33738afb07369Jeff Smith * \param pSAREA       Pointer to the SAREA.
786680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param fd           Device handle for the DRM.
7873f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul * \param extensions   ??
7883f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul * \param driver_modes  Returns modes suppoted by the driver
7893f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul * \param loaderPrivate  ??
790c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick *
79164106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg * \note There is no need to check the minimum API version in this
79264106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg * function.  Since the name of this function is versioned, it is
79364106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg * impossible for a loader that is too old to even load this driver.
794680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
795e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic __DRIscreen *
796e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian HøgsbergdriCreateNewScreen(int scrn,
797e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		   const __DRIversion *ddx_version,
798e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		   const __DRIversion *dri_version,
799e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		   const __DRIversion *drm_version,
800e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		   const __DRIframebuffer *frame_buffer,
801e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		   drmAddress pSAREA, int fd,
802e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		   const __DRIextension **extensions,
803e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		   const __DRIconfig ***driver_modes,
804e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		   void *loaderPrivate)
805680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
806efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg    static const __DRIextension *emptyExtensionList[] = { NULL };
807e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    __DRIscreen *psp;
808680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
809dad914f6b2e5862a5174133f11276e975867be04Paulo Zanoni    if (driDriverAPI.InitScreen == NULL)
810dad914f6b2e5862a5174133f11276e975867be04Paulo Zanoni	return NULL;
811dad914f6b2e5862a5174133f11276e975867be04Paulo Zanoni
81232f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg    psp = calloc(1, sizeof *psp);
81364106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg    if (!psp)
814680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return NULL;
815680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
8166cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg    setupLoaderExtensions(psp, extensions);
8176cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg
818680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /*
819680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    ** NOT_DONE: This is used by the X server to detect when the client
820680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    ** has died while holding the drawable lock.  The client sets the
821680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    ** drawable lock to this value.
822680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    */
823680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->drawLockID = 1;
824680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
825efd03a278ae55b454509e9659c42899133983ebdKristian Høgsberg    psp->drm_version = *drm_version;
826efd03a278ae55b454509e9659c42899133983ebdKristian Høgsberg    psp->ddx_version = *ddx_version;
827efd03a278ae55b454509e9659c42899133983ebdKristian Høgsberg    psp->dri_version = *dri_version;
828680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
829680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->pSAREA = pSAREA;
8307da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    psp->lock = (drmLock *) &psp->pSAREA->lock;
831680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
832680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->pFB = frame_buffer->base;
833680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->fbSize = frame_buffer->size;
834680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->fbStride = frame_buffer->stride;
835680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->fbWidth = frame_buffer->width;
836680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->fbHeight = frame_buffer->height;
837680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->devPrivSize = frame_buffer->dev_priv_size;
838680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->pDevPriv = frame_buffer->dev_priv;
839fd4f7064e24654c89248be6d76f39c7baf22fce4Jon Smirl    psp->fbBPP = psp->fbStride * 8 / frame_buffer->width;
840680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
841ac3e838fa748c8c8a6ffc04d1ab13da71f75f103Kristian Høgsberg    psp->extensions = emptyExtensionList;
842680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->fd = fd;
84364106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg    psp->myNum = scrn;
8447da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    psp->dri2.enabled = GL_FALSE;
845680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
846e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    psp->DriverAPI = driDriverAPI;
847a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    psp->api_mask = (1 << __DRI_API_OPENGL);
848680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
849e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    *driver_modes = driDriverAPI.InitScreen(psp);
85064106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg    if (*driver_modes == NULL) {
85132f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg	free(psp);
852680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return NULL;
853680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
854680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
855680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    return psp;
856680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
857680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
8583f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul/**
8593f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul * DRI2
8603f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul */
861e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic __DRIscreen *
862f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsbergdri2CreateNewScreen(int scrn, int fd,
863e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		    const __DRIextension **extensions,
864e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		    const __DRIconfig ***driver_configs, void *data)
8657da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg{
8667da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    static const __DRIextension *emptyExtensionList[] = { NULL };
867e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    __DRIscreen *psp;
86816242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg    drmVersionPtr version;
869129b9ad16f95421d12f77c1bd3eca915d8768b78Kristian Høgsberg
870e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    if (driDriverAPI.InitScreen2 == NULL)
871129b9ad16f95421d12f77c1bd3eca915d8768b78Kristian Høgsberg        return NULL;
8727da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg
87332f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg    psp = calloc(1, sizeof(*psp));
8747da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    if (!psp)
8757da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	return NULL;
8767da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg
8776cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg    setupLoaderExtensions(psp, extensions);
8786cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg
87916242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg    version = drmGetVersion(fd);
88016242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg    if (version) {
88116242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg	psp->drm_version.major = version->version_major;
88216242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg	psp->drm_version.minor = version->version_minor;
88316242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg	psp->drm_version.patch = version->version_patchlevel;
88416242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg	drmFreeVersion(version);
88516242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg    }
88616242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg
8877da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    psp->extensions = emptyExtensionList;
8887da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    psp->fd = fd;
8897da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    psp->myNum = scrn;
8907da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    psp->dri2.enabled = GL_TRUE;
8917da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg
892e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    psp->DriverAPI = driDriverAPI;
893a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    psp->api_mask = (1 << __DRI_API_OPENGL);
894e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    *driver_configs = driDriverAPI.InitScreen2(psp);
895e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    if (*driver_configs == NULL) {
89632f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg	free(psp);
8977da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	return NULL;
8987da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    }
8997da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg
900e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    psp->DriverAPI = driDriverAPI;
90117eace581d25a626a7d75d9d1205d012cbb14a6eKristian Høgsberg    psp->loaderPrivate = data;
902e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
903a482e033082bb0794fdf56c47dd76d949afde6faEric Anholt    driParseOptionInfo(&psp->optionInfo, __dri2ConfigOptions,
904a482e033082bb0794fdf56c47dd76d949afde6faEric Anholt		       __dri2NConfigOptions);
905a482e033082bb0794fdf56c47dd76d949afde6faEric Anholt    driParseConfigFiles(&psp->optionCache, &psp->optionInfo, psp->myNum,
906a482e033082bb0794fdf56c47dd76d949afde6faEric Anholt			"dri2");
907234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
9087da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    return psp;
9097da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg}
9107da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg
911e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic const __DRIextension **driGetExtensions(__DRIscreen *psp)
912e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg{
913e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    return psp->extensions;
914e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg}
915e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
916f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg/** Core interface */
917e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergconst __DRIcoreExtension driCoreExtension = {
918e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    { __DRI_CORE, __DRI_CORE_VERSION },
919f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    NULL,
920e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driDestroyScreen,
921e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driGetExtensions,
922e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driGetConfigAttrib,
923e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driIndexConfigAttrib,
924f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    NULL,
925e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driDestroyDrawable,
926e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driSwapBuffers,
927f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    NULL,
928e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driCopyContext,
929e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driDestroyContext,
930e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driBindContext,
931e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driUnbindContext
932e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg};
933e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
934f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg/** Legacy DRI interface */
935f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsbergconst __DRIlegacyExtension driLegacyExtension = {
936f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    { __DRI_LEGACY, __DRI_LEGACY_VERSION },
937f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    driCreateNewScreen,
938f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    driCreateNewDrawable,
939f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    driCreateNewContext,
940f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg};
941f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg
94239a0e4e7de379a182c1544fa24d5cb2a7687ec72Kristian Høgsberg/** DRI2 interface */
943f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsbergconst __DRIdri2Extension driDRI2Extension = {
944f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    { __DRI_DRI2, __DRI_DRI2_VERSION },
945f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    dri2CreateNewScreen,
946f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    dri2CreateNewDrawable,
947f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    dri2CreateNewContext,
948a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    dri2GetAPIMask,
9491b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke    dri2CreateNewContextForAPI,
9501b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke    dri2AllocateBuffer,
9511b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke    dri2ReleaseBuffer
952f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg};
953f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg
954234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnesconst __DRI2configQueryExtension dri2ConfigQueryExtension = {
955234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes   { __DRI2_CONFIG_QUERY, __DRI2_CONFIG_QUERY_VERSION },
956234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes   dri2ConfigQueryb,
957234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes   dri2ConfigQueryi,
958234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes   dri2ConfigQueryf,
959234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes};
960234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
961680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
962680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Calculate amount of swap interval used between GLX buffer swaps.
963680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
964680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * The usage value, on the range [0,max], is the fraction of total swap
965680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * interval time used between GLX buffer swaps is calculated.
966680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
967680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *            \f$p = t_d / (i * t_r)\f$
968680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
969680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Where \f$t_d\f$ is the time since the last GLX buffer swap, \f$i\f$ is the
970680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * swap interval (as set by \c glXSwapIntervalSGI), and \f$t_r\f$ time
971680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * required for a single vertical refresh period (as returned by \c
972680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * glXGetMscRateOML).
973680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
974680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * See the documentation for the GLX_MESA_swap_frame_usage extension for more
975680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * details.
976680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
977680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param   dPriv  Pointer to the private drawable structure.
978680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \return  If less than a single swap interval time period was required
979680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *          between GLX buffer swaps, a number greater than 0 and less than
980680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *          1.0 is returned.  If exactly one swap interval time period is
981680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *          required, 1.0 is returned, and if more than one is required then
982680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *          a number greater than 1.0 will be returned.
983680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
984680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \sa glXSwapIntervalSGI glXGetMscRateOML
985680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
986680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \todo Instead of caching the \c glXGetMscRateOML function pointer, would it
987680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *       be possible to cache the sync rate?
988680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
989680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellfloat
990d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian HøgsbergdriCalculateSwapUsage( __DRIdrawable *dPriv, int64_t last_swap_ust,
991680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		       int64_t current_ust )
992680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
993680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   int32_t   n;
994680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   int32_t   d;
995680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   int       interval;
996680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   float     usage = 1.0;
997d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian Høgsberg   __DRIscreen *psp = dPriv->driScreenPriv;
998680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
999e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg   if ( (*psp->systemTime->getMSCRate)(dPriv, &n, &d, dPriv->loaderPrivate) ) {
1000efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg      interval = (dPriv->swap_interval != 0) ? dPriv->swap_interval : 1;
1001680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1002680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1003680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      /* We want to calculate
1004680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * (current_UST - last_swap_UST) / (interval * us_per_refresh).  We get
1005680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * current_UST by calling __glXGetUST.  last_swap_UST is stored in
1006680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * dPriv->swap_ust.  interval has already been calculated.
1007680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       *
1008680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * The only tricky part is us_per_refresh.  us_per_refresh is
1009680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * 1000000 / MSC_rate.  We know the MSC_rate is n / d.  We can flip it
1010680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * around and say us_per_refresh = 1000000 * d / n.  Since this goes in
1011680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * the denominator of the final calculation, we calculate
1012680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * (interval * 1000000 * d) and move n into the numerator.
1013680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       */
1014680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1015680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      usage = (current_ust - last_swap_ust);
1016680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      usage *= n;
1017680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      usage /= (interval * d);
1018680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      usage /= 1000000.0;
1019680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   }
1020680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1021680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   return usage;
1022680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
1023680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
102461d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerezvoid
102561d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerezdri2InvalidateDrawable(__DRIdrawable *drawable)
102661d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez{
102761d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez    drawable->dri2.stamp++;
102861d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez}
102961d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez
1030680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@}*/
1031