Hi Luca,

This is something I'm very interested but I'm on travel and I'll need
some more time to review it. Just a few quick thoughts.

Python state tracker has the code to call glxGetGalliumScreenMESA and
glxCreateGalliumContextMESA but I never got around to implement these
functions on any glx/dri/etc state tracker, and I'm glad to see you
making progress on that direction.

The reason why I didn't implement the glX*Gallium*Mesa functions is
because the glx* extensions are implemented by libGL, and a driver
driver never has chance to export those extensions. And libGL is used
for non-gallium drivers.

Furthermore, both on WGL and GLX the hardware specific driver is loaded
quite late -- when the first GL context is created --, so the idea of
having GL context independent extensions to create Gallium pipe_screens
and pipe_contexts sounds good in theory but it's not how things work in
practice.

So both things considered, using gl* extensions names instead of
wgl*/glx* would make more sense:
- libGL could remain untouched
- same extensions names for all OSes

Just to be clear -- names is not the big issue here, but keeping
libGL.so Gallium agnostic is an important thing in the current
circumstances -- libGL.so shouldn't be tied to any particular driver
architecture in any way.

Also, if these extensions become more than a hack for debugging gallium
drivers then we need to start writing a spec for them too..

Jose

On Fri, 2009-12-25 at 18:04 -0800, Luca Barbieri wrote:
> This patch adds two extensions, EGL_MESA_gallium and GLX_MESA_gallium,
> which allow an application to directly access the Gallium3D API
> bypassing OpenGL and using EGL or GLX for general setup.
> 
> The python state tracker already uses the GLX_MESA_gallium functions
> (due to a commit by Jose Fonseca), but the functions are not actually
> implemented.
> There is already a WGL extension with wglGetGalliumScreenMESA and
> wglCreateGalliumContextMESA. A wglGetGalliumSurfacesMESA function
> should probably be added to match the EGL/GLX versions in this patch.
> 
> It adds 3 functions:
> (egl|glx)GetGalliumScreenMESA: returns a pipe_screen for an X11
> display/screen or an EGL display
> (egl|glx)CreateGalliumContextMESA: creates a pipe_context for an X11
> display/screen or an EGL display
> (egl|glx)GetGalliumSurfacesMESA: returns all pipe_surface attachments
> for an X11 drawable or EGL surface
> 
> The array returned by GetGalliumSurfacesMESA must be freed by the application.
> 
> They are implemented for egl_glx, and the EGL and GLX DRI loaders and
> drivers. The egl_glx implementation simply wraps the GLX functions.
> 
> The first two functions are trivially implemented, while
> GetGalliumSurfaces is trickier.
> 
> The problem is that the current code assumes that a GL context is
> bound when getting surfaces, so most of the invasive changes in this
> patch remove this assumption.
> 
> Currently, this only works for double buffered DRI surfaces, because
> the flush_framebuffer functions provided by DRI get the surface to
> flush from the current GL context.
> How to fix this is not obvious. An option could be to provide an
> (egl|glx)FlushFrontbuffer function with takes a drawable as input.
> Another option would be to change (egl|glx)SwapBuffers to do
> frontbuffer flushing without a GL context (it currently does that
> indirectly by calling glFlush()).
> Also currently surfaces are extracted from an st_framebuffer, which is
> not ideal as it keeps a dependency on the Mesa state tracker
> 
> The patch assumes that my previous MESA_screen_surface patch has been
> applied. The patches are independent, but they textually conflict on
> the function tables.
> 
> A GL_MESA_gallium extension could be implemented in the future for
> access to the underlying Gallium objects of OpenGL textures, buffers
> and renderbuffers.
> Some way to access the GLSL compiler without OpenGL would also be useful.
> 
> ---
>  include/EGL/eglext.h                          |   20 +++++++
>  include/GL/glxext.h                           |   20 +++++++
>  include/GL/internal/dri_interface.h           |   19 +++++++
>  src/egl/drivers/glx/egl_glx.c                 |   28 ++++++++++
>  src/egl/main/eglapi.c                         |   40 ++++++++++++++-
>  src/egl/main/eglapi.h                         |   11 ++++
>  src/egl/main/egldisplay.h                     |    1 +
>  src/egl/main/eglmisc.c                        |    6 ++-
>  src/gallium/state_trackers/dri/dri_drawable.c |    4 +-
>  src/gallium/state_trackers/dri/dri_screen.c   |   38 ++++++++++++++
>  src/gallium/state_trackers/egl/egl_tracker.c  |   26 +++++++++
>  src/gallium/winsys/egl_xlib/egl_xlib.c        |   54 +++++++++++++++-----
>  src/glx/x11/dri_common.c                      |    7 +++
>  src/glx/x11/glxclient.h                       |    7 +++
>  src/glx/x11/glxcmds.c                         |   69 
> +++++++++++++++++++++----
>  src/glx/x11/glxcurrent.c                      |   13 +++--
>  src/glx/x11/glxextensions.c                   |    1 +
>  src/glx/x11/glxextensions.h                   |    1 +
>  src/mesa/state_tracker/st_cb_fbo.c            |   26 ++++++----
>  src/mesa/state_tracker/st_cb_fbo.h            |    4 ++
>  src/mesa/state_tracker/st_framebuffer.c       |   51 ++++++++++++++++++
>  src/mesa/state_tracker/st_public.h            |    8 +++-
>  22 files changed, 409 insertions(+), 45 deletions(-)
> 
> diff --git a/include/EGL/eglext.h b/include/EGL/eglext.h
> index b65f7f2..1b94784 100644
> --- a/include/EGL/eglext.h
> +++ b/include/EGL/eglext.h
> @@ -179,6 +179,26 @@ typedef EGLBoolean (EGLAPIENTRYP
> PFNEGLCOPYCONTEXTMESA) (EGLDisplay dpy, EGLCont
> 
>  #endif /* EGL_MESA_copy_context */
> 
> +/* EGL_MESA_gallium  >>> PRELIMINARY <<< */
> +#ifndef EGL_MESA_gallium
> +#define EGL_MESA_gallium 1
> +
> +struct pipe_screen;
> +struct pipe_context;
> +struct pipe_surface;
> +
> +#ifdef EGL_EGLEXT_PROTOTYPES
> +EGLAPI struct pipe_screen* EGLAPIENTRY eglGetGalliumScreenMESA(EGLDisplay 
> dpy);
> +EGLAPI struct pipe_context* EGLAPIENTRY
> eglCreateGalliumContextMESA(EGLDisplay dpy);
> +EGLAPI int EGLAPIENTRY eglGetGalliumSurfacesMESA(EGLDisplay* dpy,
> EGLSurface surface, struct pipe_surface*** surfaces);
> +#endif /* EGL_EGLEXT_PROTOTYPES */
> +
> +typedef struct pipe_screen* (EGLAPIENTRYP
> PFNEGLGETGALLIUMSCREENMESA)(EGLDisplay dpy);
> +typedef struct pipe_context* (EGLAPIENTRYP
> PFNEGLCREATEGALLIUMCONTEXTMESA)(EGLDisplay dpy);
> +typedef int (EGLAPIENTRYP PFNEGLGETGALLIUMSURFACESMESA)(EGLDisplay*
> dpy, EGLSurface surface, struct pipe_surface*** surfaces);
> +
> +#endif /* EGL_MESA_gallium */
> +
>  #ifdef __cplusplus
>  }
>  #endif
> diff --git a/include/GL/glxext.h b/include/GL/glxext.h
> index 9ac0592..c65da8a 100644
> --- a/include/GL/glxext.h
> +++ b/include/GL/glxext.h
> @@ -926,6 +926,26 @@ typedef void ( * PFNGLXCOPYIMAGESUBDATANVPROC)
> (Display *dpy, GLXContext srcCtx,
>  #endif
> 
> 
> +/* GLX_MESA_gallium  >>> PRELIMINARY <<< */
> +#ifndef GLX_MESA_gallium
> +#define GLX_MESA_gallium 1
> +
> +struct pipe_screen;
> +struct pipe_context;
> +struct pipe_surface;
> +
> +#ifdef GLX_GLXEXT_PROTOTYPES
> +extern struct pipe_screen* glXGetGalliumScreenMESA(Display* dpy, int screen);
> +extern struct pipe_context* glXCreateGalliumContextMESA(Display* dpy,
> int screen);
> +extern int glXGetGalliumSurfacesMESA(Display* dpy, GLXFBConfig
> config, Drawable drawable, struct pipe_surface*** surfaces);
> +#endif /* GLX_GLXEXT_PROTOTYPES */
> +
> +typedef struct pipe_screen* (*PFNGLXGETGALLIUMSCREENMESA)(Display*
> dpy, int screen);
> +typedef struct pipe_context*
> (*PFNGLXCREATEGALLIUMCONTEXTMESA)(Display* dpy, int screen);
> +typedef int (*PFNGLXGETGALLIUMSURFACESMESA)(Display* dpy, GLXFBConfig
> config, Drawable drawable, struct pipe_surface*** surfaces);
> +
> +#endif /* GLX_MESA_gallium */
> +
>  #ifdef __cplusplus
>  }
>  #endif
> diff --git a/include/GL/internal/dri_interface.h
> b/include/GL/internal/dri_interface.h
> index 910c916..94a8683 100644
> --- a/include/GL/internal/dri_interface.h
> +++ b/include/GL/internal/dri_interface.h
> @@ -73,6 +73,7 @@ typedef struct
> __DRIframeTrackingExtensionRec  __DRIframeTrackingExtension;
>  typedef struct
> __DRImediaStreamCounterExtensionRec     __DRImediaStreamCounterExtension;
>  typedef struct __DRItexOffsetExtensionRec      __DRItexOffsetExtension;
>  typedef struct __DRItexBufferExtensionRec      __DRItexBufferExtension;
> +typedef struct __DRIgalliumExtensionRec                __DRIgalliumExtension;
>  typedef struct __DRIlegacyExtensionRec         __DRIlegacyExtension;
>  typedef struct __DRIswrastExtensionRec         __DRIswrastExtension;
>  typedef struct __DRIbufferRec                  __DRIbuffer;
> @@ -405,6 +406,24 @@ struct __DRIswrastLoaderExtensionRec {
>  };
> 
>  /**
> + * This extension provides direct access to the underlying Gallium driver
> + */
> +#define __DRI_GALLIUM "DRI_Gallium"
> +#define __DRI_GALLIUM_VERSION 1
> +
> +struct pipe_screen;
> +struct pipe_context;
> +struct pipe_surface;
> +
> +struct __DRIgalliumExtensionRec {
> +    __DRIextension base;
> +
> +    struct pipe_screen* (*getGalliumScreen)(__DRIscreen* screen);;
> +    struct pipe_context* (*createGalliumContext)(__DRIscreen* screen);
> +    int (*getGalliumSurfaces)(__DRIdrawable* drawable, struct
> pipe_surface*** surfaces);
> +};
> +
> +/**
>   * The remaining extensions describe driver extensions, immediately
>   * available interfaces provided by the driver.  To start using the
>   * driver, dlsym() for the __DRI_DRIVER_EXTENSIONS symbol and look for
> diff --git a/src/egl/drivers/glx/egl_glx.c b/src/egl/drivers/glx/egl_glx.c
> index 55f99b5..4e51558 100644
> --- a/src/egl/drivers/glx/egl_glx.c
> +++ b/src/egl/drivers/glx/egl_glx.c
> @@ -617,6 +617,7 @@ GLX_eglInitialize(_EGLDriver *drv, _EGLDisplay *disp,
>     disp->ClientAPIsMask = GLX_EGL_APIS;
> 
>     disp->Extensions.MESA_screen_surface = EGL_TRUE;
> +   disp->Extensions.MESA_gallium = EGL_TRUE;
> 
>     /* we're supporting EGL 1.4 */
>     *major = 1;
> @@ -971,6 +972,30 @@ GLX_eglShowScreenSurfaceMESA(_EGLDriver *drv,
> EGLDisplay disp,
>     return EGL_TRUE;
>  }
> 
> +static struct pipe_screen*
> +GLX_eglGetGalliumScreenMESA(_EGLDriver *drv, _EGLDisplay* disp)
> +{
> +       struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp);
> +       return glXGetGalliumScreenMESA(GLX_dpy->dpy, 
> DefaultScreen(GLX_dpy->dpy));
> +}
> +
> +static struct pipe_context*
> +GLX_eglCreateGalliumContextMESA(_EGLDriver *drv, _EGLDisplay* disp,
> +                             EGLScreenMESA screen)
> +{
> +       struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp);
> +       return glXCreateGalliumContextMESA(GLX_dpy->dpy, 
> DefaultScreen(GLX_dpy->dpy));
> +}
> +
> +static int
> +GLX_eglGetGalliumSurfacesMESA(_EGLDriver *drv, _EGLDisplay* disp,
> _EGLSurface* surf, struct pipe_surface*** surfaces)
> +{
> +   struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp);
> +   struct GLX_egl_surface *GLX_surf = GLX_egl_surface(surf);
> +
> +   return glXGetGalliumSurfacesMESA(GLX_dpy->dpy,
> GLX_dpy->fbconfigs[GLX_egl_config_index(surf->Config)],
> GLX_surf->drawable, surfaces);
> +}
> +
>  static EGLBoolean
>  GLX_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
>  {
> @@ -1094,6 +1119,9 @@ _eglMain(const char *args)
>     GLX_drv->Base.API.WaitNative = GLX_eglWaitNative;
>     GLX_drv->Base.API.CreateScreenSurfaceMESA = 
> GLX_eglCreateScreenSurfaceMESA;
>     GLX_drv->Base.API.ShowScreenSurfaceMESA = GLX_eglShowScreenSurfaceMESA;
> +   GLX_drv->Base.API.GetGalliumScreenMESA = GLX_eglGetGalliumScreenMESA;
> +   GLX_drv->Base.API.CreateGalliumContextMESA =
> GLX_eglCreateGalliumContextMESA;
> +   GLX_drv->Base.API.GetGalliumSurfacesMESA = GLX_eglGetGalliumSurfacesMESA;
> 
>     GLX_drv->Base.Name = "GLX";
>     GLX_drv->Base.Unload = GLX_Unload;
> diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
> index 14cc5fa..9870670 100644
> --- a/src/egl/main/eglapi.c
> +++ b/src/egl/main/eglapi.c
> @@ -538,12 +538,15 @@ eglSwapInterval(EGLDisplay dpy, EGLint interval)
>  EGLBoolean EGLAPIENTRY
>  eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
>  {
> -   _EGLContext *ctx = _eglGetCurrentContext();
> +   /* remove binding requirement for EGL_MESA_gallium */
> +   /* _EGLContext *ctx = _eglGetCurrentContext(); */
>     _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
> 
>     /* surface must be bound to current context in EGL 1.4 */
> +   /*
>     if (!ctx || !_eglIsContextLinked(ctx) || surf != ctx->DrawSurface)
>        return _eglError(EGL_BAD_SURFACE, __FUNCTION__);
> +   */
> 
>     return drv->API.SwapBuffers(drv, disp, surf);
>  }
> @@ -991,5 +994,40 @@ eglReleaseThread(void)
>     return EGL_TRUE;
>  }
> 
> +struct pipe_screen* eglGetGalliumScreenMESA(EGLDisplay dpy)
> +{
> +   _EGLDisplay *disp = _eglLookupDisplay(dpy);
> +   _EGLDriver *drv = _eglCheckDisplay(disp, __FUNCTION__);
> +   if (!drv)
> +      return EGL_FALSE;
> +
> +   return drv->API.GetGalliumScreenMESA ?
> drv->API.GetGalliumScreenMESA(drv, disp) : 0;
> +}
> +
> +struct pipe_context* eglCreateGalliumContextMESA(EGLDisplay dpy)
> +{
> +   _EGLDisplay *disp = _eglLookupDisplay(dpy);
> +   _EGLDriver *drv = _eglCheckDisplay(disp, __FUNCTION__);
> +   if (!drv)
> +      return EGL_FALSE;
> +
> +   return drv->API.CreateGalliumContextMESA ?
> drv->API.CreateGalliumContextMESA(drv, disp) : 0;
> +}
> +
> +int eglGetGalliumSurfacesMESA(EGLDisplay* dpy, EGLSurface surface,
> struct pipe_surface*** surfaces)
> +{
> +   _EGLDisplay *disp = _eglLookupDisplay(dpy);
> +   _EGLDriver *drv = _eglCheckDisplay(disp, __FUNCTION__);
> +   _EGLSurface* surf;
> +   *surfaces = 0;
> +   if (!drv || !drv->API.GetGalliumSurfacesMESA)
> +      return 0;
> +
> +   surf = _eglLookupSurface(surface, disp);
> +   if(!surf)
> +      return 0;
> +
> +   return drv->API.GetGalliumSurfacesMESA(drv, disp, surf, surfaces);
> +}
> 
>  #endif /* EGL_VERSION_1_2 */
> diff --git a/src/egl/main/eglapi.h b/src/egl/main/eglapi.h
> index aa0abe3..e18829e 100644
> --- a/src/egl/main/eglapi.h
> +++ b/src/egl/main/eglapi.h
> @@ -69,6 +69,13 @@ typedef _EGLSurface
> *(*CreatePbufferFromClientBuffer_t)(_EGLDriver *drv, _EGLDis
>  #endif /* EGL_VERSION_1_2 */
> 
> 
> +struct pipe_screen;
> +struct pipe_context;
> +struct pipe_surface;
> +typedef struct pipe_screen* (*GetGalliumScreenMESA_t)(_EGLDriver
> *drv, _EGLDisplay *dpy);
> +typedef struct pipe_context* (*CreateGalliumContextMESA_t)(_EGLDriver
> *drv, _EGLDisplay *dpy);
> +typedef int (*GetGalliumSurfacesMESA_t)(_EGLDriver *drv, _EGLDisplay*
> dpy, _EGLSurface* surf, struct pipe_surface*** surfaces);
> +
> 
>  /**
>   * The API dispatcher jumps through these functions
> @@ -120,6 +127,10 @@ struct _egl_api
> 
>  #ifdef EGL_VERSION_1_2
>     CreatePbufferFromClientBuffer_t CreatePbufferFromClientBuffer;
> +
> +   GetGalliumScreenMESA_t GetGalliumScreenMESA;
> +   CreateGalliumContextMESA_t CreateGalliumContextMESA;
> +   GetGalliumSurfacesMESA_t GetGalliumSurfacesMESA;
>  #endif
>  };
> 
> diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
> index ea4e35a..c711ca3 100644
> --- a/src/egl/main/egldisplay.h
> +++ b/src/egl/main/egldisplay.h
> @@ -14,6 +14,7 @@ struct _egl_extensions
>  {
>     EGLBoolean MESA_screen_surface;
>     EGLBoolean MESA_copy_context;
> +   EGLBoolean MESA_gallium;
> 
>     char String[_EGL_MAX_EXTENSIONS_LEN];
>  };
> diff --git a/src/egl/main/eglmisc.c b/src/egl/main/eglmisc.c
> index e669133..5bd128d 100644
> --- a/src/egl/main/eglmisc.c
> +++ b/src/egl/main/eglmisc.c
> @@ -50,10 +50,12 @@ _eglUpdateExtensionsString(_EGLDisplay *dpy)
>     if (exts[0])
>        return;
> 
> -   if (dpy->Extensions.MESA_screen_surface)
> -      strcat(exts, "EGL_MESA_screen_surface ");
>     if (dpy->Extensions.MESA_copy_context)
>        strcat(exts, "EGL_MESA_copy_context ");
> +   if (dpy->Extensions.MESA_gallium)
> +      strcat(exts, "EGL_MESA_gallium ");
> +   if (dpy->Extensions.MESA_screen_surface)
> +      strcat(exts, "EGL_MESA_screen_surface ");
>     assert(strlen(exts) < _EGL_MAX_EXTENSIONS_LEN);
>  }
> 
> diff --git a/src/gallium/state_trackers/dri/dri_drawable.c
> b/src/gallium/state_trackers/dri/dri_drawable.c
> index 4b12243..4a4edbf 100644
> --- a/src/gallium/state_trackers/dri/dri_drawable.c
> +++ b/src/gallium/state_trackers/dri/dri_drawable.c
> @@ -47,7 +47,7 @@
>  #include "util/u_format.h"
>  #include "util/u_memory.h"
>  #include "util/u_rect.h"
> -
> +
>  static struct pipe_surface *
>  dri_surface_from_handle(struct drm_api *api,
>                         struct pipe_screen *screen,
> @@ -233,7 +233,7 @@ dri_get_buffers(__DRIdrawablePrivate * dPriv)
>        pipe_surface_reference(&surface, NULL);
>     }
>     /* this needed, or else the state tracker fails to pick the new buffers */
> -   st_resize_framebuffer(drawable->stfb, dri_drawable->w, dri_drawable->h);
> +   st_resize_framebuffer_screen(screen, drawable->stfb,
> dri_drawable->w, dri_drawable->h);
>  }
> 
>  /**
> diff --git a/src/gallium/state_trackers/dri/dri_screen.c
> b/src/gallium/state_trackers/dri/dri_screen.c
> index cb864d4..bc5eb93 100644
> --- a/src/gallium/state_trackers/dri/dri_screen.c
> +++ b/src/gallium/state_trackers/dri/dri_screen.c
> @@ -63,6 +63,43 @@ static const __DRItexBufferExtension
> dri2TexBufferExtension = {
>     dri2_set_tex_buffer2,
>  };
> 
> +static struct pipe_screen*
> +dri_get_gallium_screen(__DRIscreenPrivate* sPriv)
> +{
> +   return dri_screen(sPriv)->pipe_screen;
> +}
> +
> +static struct pipe_context*
> +dri_create_gallium_context(__DRIscreenPrivate* sPriv)
> +{
> +   struct dri_screen* screen = dri_screen(sPriv);
> +   return screen->api->create_context(screen->api, screen->pipe_screen);
> +}
> +
> +static int
> +dri_get_gallium_surfaces(__DRIdrawablePrivate* dPriv, struct
> pipe_surface*** psurfaces)
> +{
> +   struct dri_drawable *drawable = dri_drawable(dPriv);
> +   struct pipe_surface** surfaces;
> +
> +   if (__dri1_api_hooks) /* TODO: DRI1 */
> +   {
> +      *psurfaces = 0;
> +       return 0;
> +   }
> +
> +   dri_get_buffers(dPriv);
> +
> +   return st_get_framebuffer_surfaces(drawable->stfb, psurfaces);
> +}
> +
> +static const __DRIgalliumExtension driGalliumExtension = {
> +    { __DRI_GALLIUM, __DRI_GALLIUM_VERSION },
> +   dri_get_gallium_screen,
> +   dri_create_gallium_context,
> +   dri_get_gallium_surfaces
> +};
> +
>     static const __DRIextension *dri_screen_extensions[] = {
>        &driReadDrawableExtension,
>        &driCopySubBufferExtension.base,
> @@ -70,6 +107,7 @@ static const __DRItexBufferExtension
> dri2TexBufferExtension = {
>        &driFrameTrackingExtension.base,
>        &driMediaStreamCounterExtension.base,
>        &dri2TexBufferExtension.base,
> +      &driGalliumExtension.base,
>        NULL
>     };
> 
> diff --git a/src/gallium/state_trackers/egl/egl_tracker.c
> b/src/gallium/state_trackers/egl/egl_tracker.c
> index 745803c..c06e7ef 100644
> --- a/src/gallium/state_trackers/egl/egl_tracker.c
> +++ b/src/gallium/state_trackers/egl/egl_tracker.c
> @@ -12,6 +12,7 @@
>  #include "state_tracker/drm_api.h"
> 
>  #include "pipe/p_screen.h"
> +#include "pipe/p_state.h"
>  #include "pipe/internal/p_winsys_screen.h"
> 
>  /** HACK */
> @@ -30,6 +31,27 @@ drm_unload(_EGLDriver *drv)
>         free(drv);
>  }
> 
> +static struct pipe_screen*
> +drm_get_gallium_screen_mesa(_EGLDriver *drv, _EGLDisplay *dpy)
> +{
> +       struct drm_device *dev = lookup_drm_device(dpy);
> +       return dev->screen;
> +}
> +
> +static struct pipe_context*
> +drm_create_gallium_context_mesa(_EGLDriver *drv, _EGLDisplay *dpy)
> +{
> +       struct drm_device *dev = lookup_drm_device(dpy);
> +       return dev->api->create_context(dev->api, dev->screen);
> +}
> +
> +static int
> +drm_get_gallium_surfaces_mesa(_EGLDriver *drv, _EGLDisplay *dpy,
> _EGLSurface* draw, struct pipe_surface*** psurfaces)
> +{
> +       struct drm_surface *surf = lookup_drm_surface(draw);
> +       return st_get_framebuffer_surfaces(surf->stfb, psurfaces);
> +}
> +
>  /**
>   * The bootstrap function.  Return a new drm_driver object and
>   * plug in API functions.
> @@ -61,6 +83,9 @@ _eglMain(const char *args)
>         drv->API.CreateScreenSurfaceMESA = drm_create_screen_surface_mesa;
>         drv->API.ShowScreenSurfaceMESA = drm_show_screen_surface_mesa;
>         drv->API.SwapBuffers = drm_swap_buffers;
> +       drv->API.GetGalliumScreenMESA = drm_get_gallium_screen_mesa;
> +       drv->API.CreateGalliumContextMESA = drm_create_gallium_context_mesa;
> +       drv->API.GetGalliumSurfacesMESA = drm_get_gallium_surfaces_mesa;
> 
>         drv->Name = "DRM/Gallium/Win";
>         drv->Unload = drm_unload;
> @@ -223,6 +248,7 @@ drm_initialize(_EGLDriver *drv, _EGLDisplay *disp,
> EGLint *major, EGLint *minor)
>         /* enable supported extensions */
>         disp->Extensions.MESA_screen_surface = EGL_TRUE;
>         disp->Extensions.MESA_copy_context = EGL_TRUE;
> +       disp->Extensions.MESA_gallium = EGL_TRUE;
> 
>         *major = 1;
>         *minor = 4;
> diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c
> b/src/gallium/winsys/egl_xlib/egl_xlib.c
> index 25ca31c..190ea33 100644
> --- a/src/gallium/winsys/egl_xlib/egl_xlib.c
> +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c
> @@ -325,9 +325,8 @@ get_drawable_size(Display *dpy, Drawable d, uint
> *width, uint *height)
>     return stat;
>  }
> 
> -
>  static void
> -check_and_update_buffer_size(struct xlib_egl_surface *surface)
> +check_and_update_buffer_size(struct xlib_egl_display* xdpy, struct
> xlib_egl_surface *surface)
>  {
>     uint width, height;
>     if (surface->Base.Type == EGL_PBUFFER_BIT) {
> @@ -337,7 +336,7 @@ check_and_update_buffer_size(struct
> xlib_egl_surface *surface)
>     else {
>        get_drawable_size(surface->Dpy, surface->Win, &width, &height);
>     }
> -   st_resize_framebuffer(surface->Framebuffer, width, height);
> +   st_resize_framebuffer_screen(xdpy->screen, surface->Framebuffer,
> width, height);
>     surface->Base.Width = width;
>     surface->Base.Height = height;
>  }
> @@ -376,7 +375,7 @@ display_surface(struct pipe_winsys *pws,
>     ximage->width = psurf->width;
>     ximage->height = psurf->height;
>     ximage->bytes_per_line = spt->stride[psurf->level];
> -
> +
>     XPutImage(xsurf->Dpy, xsurf->Win, xsurf->Gc,
>               ximage, 0, 0, 0, 0, psurf->width, psurf->height);
> 
> @@ -479,6 +478,7 @@ xlib_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy,
>                      _EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx)
>  {
>     struct xlib_egl_context *context = lookup_context(ctx);
> +   struct xlib_egl_display *xdpy = xlib_egl_display(dpy);
>     struct xlib_egl_surface *draw_surf = lookup_surface(draw);
>     struct xlib_egl_surface *read_surf = lookup_surface(read);
>     struct st_context *oldcontext = NULL;
> @@ -499,9 +499,9 @@ xlib_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy,
>                     (read_surf ? read_surf->Framebuffer : NULL));
> 
>     if (draw_surf)
> -      check_and_update_buffer_size(draw_surf);
> +      check_and_update_buffer_size(xdpy, draw_surf);
>     if (read_surf && read_surf != draw_surf)
> -      check_and_update_buffer_size(draw_surf);
> +      check_and_update_buffer_size(xdpy, draw_surf);
> 
>     return EGL_TRUE;
>  }
> @@ -591,8 +591,6 @@ xlib_eglCreateWindowSurface(_EGLDriver *drv,
> _EGLDisplay *disp, _EGLConfig *conf
>                                               width, height,
>                                               (void *) surf);
> 
> -   st_resize_framebuffer(surf->Framebuffer, width, height);
> -
>     return &surf->Base;
>  }
> 
> @@ -655,6 +653,12 @@ xlib_eglCreatePbufferSurface(_EGLDriver *drv,
> _EGLDisplay *disp, _EGLConfig *con
>                                               choose_color_format(&visual),
>                                               choose_depth_format(&visual),
>                                               choose_stencil_format(&visual),
> +                                             width, height,
> +                                             (void *) surf);
> +
> +   return &surf->Base;
> +}
> +
>  /**
>   * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
>   */
> @@ -737,13 +741,33 @@ xlib_eglShowScreenSurfaceMESA(_EGLDriver *drv,
> EGLDisplay disp,
> 
>     return EGL_TRUE;
>  }
> -                                             width, height,
> -                                             (void *) surf);
> -   st_resize_framebuffer(surf->Framebuffer, width, height);
> 
> -   return &surf->Base;
> +static struct pipe_screen*
> +xlib_eglGetGalliumScreenMESA(_EGLDriver *drv, _EGLDisplay* disp)
> +{
> +       struct xlib_egl_display *xdpy = xlib_egl_display(disp);
> +       return xdpy->screen;
> +}
> +
> +static struct pipe_context*
> +xlib_eglCreateGalliumContextMESA(_EGLDriver *drv, _EGLDisplay* disp,
> +                             EGLScreenMESA screen)
> +{
> +       struct xlib_egl_display *xdpy = xlib_egl_display(disp);
> +       return softpipe_create(xdpy->screen);
>  }
> 
> +static int
> +xlib_eglGetGalliumSurfacesMESA(_EGLDriver *drv, _EGLDisplay* disp,
> _EGLSurface* surf, struct pipe_surface*** psurfaces)
> +{
> +       struct xlib_egl_display* xdpy = xlib_egl_display(disp);
> +       struct xlib_egl_surface *xsurf = lookup_surface(surf);
> +       *psurfaces = 0;
> +       if (!xsurf)
> +               return 0;
> +       check_and_update_buffer_size(xdpy, xsurf);
> +       return st_get_framebuffer_surfaces(xsurf->Framebuffer, psurfaces);
> +}
> 
>  static EGLBoolean
>  xlib_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface 
> *surface)
> @@ -847,6 +871,7 @@ xlib_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay
> *dpy, _EGLSurface *draw)
>        return EGL_FALSE;
> 
>     {
> +      struct xlib_egl_display* xdpy = xlib_egl_display(dpy);
>        struct xlib_egl_surface *xsurf = lookup_surface(draw);
>        struct pipe_winsys *pws = xsurf->winsys;
>        struct pipe_surface *psurf;
> @@ -858,7 +883,7 @@ xlib_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay
> *dpy, _EGLSurface *draw)
> 
>        display_surface(pws, psurf, xsurf);
> 
> -      check_and_update_buffer_size(xsurf);
> +      check_and_update_buffer_size(xdpy, xsurf);
>     }
> 
>     return EGL_TRUE;
> @@ -935,6 +960,9 @@ _eglMain(const char *args)
>     xdrv->Base.API.SwapBuffers = xlib_eglSwapBuffers;
>     xdrv->Base.API.CreateScreenSurfaceMESA = xlib_eglCreateScreenSurfaceMESA;
>     xdrv->Base.API.ShowScreenSurfaceMESA = xlib_eglShowScreenSurfaceMESA;
> +   xdrv->Base.API.GetGalliumScreenMESA = xlib_eglGetGalliumScreenMESA;
> +   xdrv->Base.API.CreateGalliumContextMESA = 
> xlib_eglCreateGalliumContextMESA;
> +   xdrv->Base.API.GetGalliumSurfacesMESA = xlib_eglGetGalliumSurfacesMESA;
> 
>     xdrv->apis = find_supported_apis();
>     if (xdrv->apis == 0x0) {
> diff --git a/src/glx/x11/dri_common.c b/src/glx/x11/dri_common.c
> index 9c825ad..a135f00 100644
> --- a/src/glx/x11/dri_common.c
> +++ b/src/glx/x11/dri_common.c
> @@ -403,6 +403,13 @@ driBindExtensions(__GLXscreenConfigs * psc, int dri2)
>        }
>  #endif
> 
> +#ifdef __DRI_GALLIUM
> +      if ((strcmp(extensions[i]->name, __DRI_GALLIUM) == 0)) {
> +         psc->gallium = (__DRIgalliumExtension *) extensions[i];
> +         __glXEnableDirectExtension(psc, "GLX_MESA_gallium");
> +      }
> +#endif
> +
>  #ifdef __DRI2_FLUSH
>        if ((strcmp(extensions[i]->name, __DRI2_FLUSH) == 0) && dri2) {
>           psc->f = (__DRI2flushExtension *) extensions[i];
> diff --git a/src/glx/x11/glxclient.h b/src/glx/x11/glxclient.h
> index 00ee14f..f0e3acf 100644
> --- a/src/glx/x11/glxclient.h
> +++ b/src/glx/x11/glxclient.h
> @@ -533,6 +533,10 @@ struct __GLXscreenConfigsRec
>     const __DRItexBufferExtension *texBuffer;
>  #endif
> 
> +#ifdef __DRI_GALLIUM
> +   const __DRIgalliumExtension *gallium;
> +#endif
> +
>  #ifdef __DRI2_FLUSH
>     const __DRI2flushExtension *f;
>  #endif
> @@ -786,4 +790,7 @@ __driGetMscRateOML(__DRIdrawable * draw,
>                     int32_t * numerator, int32_t * denominator, void 
> *private);
>  #endif
> 
> +extern __GLXDRIdrawable *
> +__glXFetchDRIDrawable(Display * dpy, GLXDrawable glxDrawable, const
> __GLcontextModes * const mode);
> +
>  #endif /* !__GLX_client_h__ */
> diff --git a/src/glx/x11/glxcmds.c b/src/glx/x11/glxcmds.c
> index daa9076..b3499b4 100644
> --- a/src/glx/x11/glxcmds.c
> +++ b/src/glx/x11/glxcmds.c
> @@ -977,11 +977,18 @@ glXSwapBuffers(Display * dpy, GLXDrawable drawable)
>     xGLXSwapBuffersReq *req;
>  #endif
> 
> +   gc = __glXGetCurrentContext();
> +   if (gc && (dpy != gc->currentDpy) ||
> +                      ((drawable != gc->currentDrawable)
> +                       && (drawable != gc->currentReadable)))
> +          gc = 0;
> +
>  #ifdef GLX_DIRECT_RENDERING
>     __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL);
> 
>     if (pdraw != NULL) {
> -      glFlush();
> +      if(gc) /* for GLX_MESA_gallium */
> +        glFlush();
>        (*pdraw->psc->driScreen->swapBuffers) (pdraw);
>        return;
>     }
> @@ -996,15 +1003,7 @@ glXSwapBuffers(Display * dpy, GLXDrawable drawable)
>      ** The calling thread may or may not have a current context.  If it
>      ** does, send the context tag so the server can do a flush.
>      */
> -   gc = __glXGetCurrentContext();
> -   if ((gc != NULL) && (dpy == gc->currentDpy) &&
> -       ((drawable == gc->currentDrawable)
> -        || (drawable == gc->currentReadable))) {
> -      tag = gc->currentContextTag;
> -   }
> -   else {
> -      tag = 0;
> -   }
> +   tag = gc ? gc->currentContextTag : 0;
> 
>  #ifdef USE_XCB
>     c = XGetXCBConnection(dpy);
> @@ -2859,6 +2858,50 @@ __glXReleaseTexImageEXT(Display * dpy,
> GLXDrawable drawable, int buffer)
>     SyncHandle();
>  }
> 
> +#ifdef GLX_DIRECT_RENDERING
> +PUBLIC struct pipe_screen*
> +glXGetGalliumScreenMESA(Display * dpy, int screen)
> +{
> +   __GLXdisplayPrivate *const priv = __glXInitialize(dpy);
> +   __GLXscreenConfigs *psc;
> +
> +   if (priv == NULL)
> +      return NULL;
> +
> +   psc = &priv->screenConfigs[screen];
> +   if(!psc->gallium)
> +          return NULL;
> +
> +   return psc->gallium->getGalliumScreen(psc->__driScreen);
> +}
> +
> +PUBLIC struct pipe_context*
> +glXCreateGalliumContextMESA(Display * dpy, int screen)
> +{
> +   __GLXdisplayPrivate *const priv = __glXInitialize(dpy);
> +   __GLXscreenConfigs *psc;
> +
> +   if (priv == NULL)
> +      return NULL;
> +
> +   psc = &priv->screenConfigs[screen];
> +   if(!psc->gallium)
> +          return NULL;
> +   return psc->gallium->createGalliumContext(psc->__driScreen);
> +}
> +
> +PUBLIC int
> +glXGetGalliumSurfacesMESA(Display * dpy, GLXFBConfig fbconfig,
> Drawable drawable, struct pipe_surface*** surfaces)
> +{
> +      __GLXDRIdrawable *pdraw = __glXFetchDRIDrawable(dpy, drawable,
> (const __GLcontextModes * const)fbconfig);
> +
> +      if(!pdraw || !pdraw->psc->gallium)
> +          return 0;
> +
> +      return pdraw->psc->gallium->getGalliumSurfaces(pdraw->driDrawable,
> surfaces);
> +}
> +#endif
> +
>  /*...@}*/
> 
>  /**
> @@ -3023,6 +3066,11 @@ static const struct name_address_pair GLX_functions[] 
> = {
>     /*** DRI configuration ***/
>     GLX_FUNCTION(glXGetScreenDriver),
>     GLX_FUNCTION(glXGetDriverConfig),
> +
> +   /*** GLX_MESA_gallium ***/
> +   GLX_FUNCTION(glXGetGalliumScreenMESA),
> +   GLX_FUNCTION(glXCreateGalliumContextMESA),
> +   GLX_FUNCTION(glXGetGalliumSurfacesMESA),
>  #endif
> 
>     {NULL, NULL}                 /* end of list */
> @@ -3127,3 +3175,4 @@ __glXGetUST(int64_t * ust)
>     }
>  }
>  #endif /* GLX_DIRECT_RENDERING */
> +
> diff --git a/src/glx/x11/glxcurrent.c b/src/glx/x11/glxcurrent.c
> index f1e3e16..53fc739 100644
> --- a/src/glx/x11/glxcurrent.c
> +++ b/src/glx/x11/glxcurrent.c
> @@ -273,8 +273,8 @@ SendMakeCurrentRequest(Display * dpy, CARD8 opcode,
> 
> 
>  #ifdef GLX_DIRECT_RENDERING
> -static __GLXDRIdrawable *
> -FetchDRIDrawable(Display * dpy, GLXDrawable glxDrawable, GLXContext gc)
> +__GLXDRIdrawable *
> +__glXFetchDRIDrawable(Display * dpy, GLXDrawable glxDrawable, const
> __GLcontextModes * const mode)
>  {
>     __GLXdisplayPrivate *const priv = __glXInitialize(dpy);
>     __GLXDRIdrawable *pdraw;
> @@ -283,7 +283,7 @@ FetchDRIDrawable(Display * dpy, GLXDrawable
> glxDrawable, GLXContext gc)
>     if (priv == NULL)
>        return NULL;
> 
> -   psc = &priv->screenConfigs[gc->screen];
> +   psc = &priv->screenConfigs[mode->screen];
>     if (psc->drawHash == NULL)
>        return NULL;
> 
> @@ -291,7 +291,7 @@ FetchDRIDrawable(Display * dpy, GLXDrawable
> glxDrawable, GLXContext gc)
>        return pdraw;
> 
>     pdraw = psc->driScreen->createDrawable(psc, glxDrawable,
> -                                          glxDrawable, gc->mode);
> +                                          glxDrawable, mode);
>     if (__glxHashInsert(psc->drawHash, glxDrawable, pdraw)) {
>        (*pdraw->destroyDrawable) (pdraw);
>        return NULL;
> @@ -299,6 +299,7 @@ FetchDRIDrawable(Display * dpy, GLXDrawable
> glxDrawable, GLXContext gc)
> 
>     return pdraw;
>  }
> +
>  #endif /* GLX_DIRECT_RENDERING */
> 
>  static void
> @@ -366,8 +367,8 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw,
>  #ifdef GLX_DIRECT_RENDERING
>     /* Bind the direct rendering context to the drawable */
>     if (gc && gc->driContext) {
> -      __GLXDRIdrawable *pdraw = FetchDRIDrawable(dpy, draw, gc);
> -      __GLXDRIdrawable *pread = FetchDRIDrawable(dpy, read, gc);
> +      __GLXDRIdrawable *pdraw = __glXFetchDRIDrawable(dpy, draw, gc->mode);
> +      __GLXDRIdrawable *pread = __glXFetchDRIDrawable(dpy, read, gc->mode);
> 
>        if ((pdraw == NULL) || (pread == NULL)) {
>           __glXGenerateError(dpy, gc, (pdraw == NULL) ? draw : read,
> diff --git a/src/glx/x11/glxextensions.c b/src/glx/x11/glxextensions.c
> index 6852128..d8c139d 100644
> --- a/src/glx/x11/glxextensions.c
> +++ b/src/glx/x11/glxextensions.c
> @@ -82,6 +82,7 @@ static const struct extension_info known_glx_extensions[] = 
> {
>     { GLX(MESA_agp_offset),             VER(0,0), N, N, N, Y }, /* Deprecated 
> */
>     { GLX(MESA_allocate_memory),        VER(0,0), Y, N, N, Y },
>     { GLX(MESA_copy_sub_buffer),        VER(0,0), Y, N, N, N },
> +   { GLX(MESA_gallium),                VER(0,0), Y, N, N, Y },
>     { GLX(MESA_pixmap_colormap),        VER(0,0), N, N, N, N }, /* Deprecated 
> */
>     { GLX(MESA_release_buffers),        VER(0,0), N, N, N, N }, /* Deprecated 
> */
>     { GLX(MESA_swap_control),           VER(0,0), Y, N, N, Y },
> diff --git a/src/glx/x11/glxextensions.h b/src/glx/x11/glxextensions.h
> index 652c5db..d589c6b 100644
> --- a/src/glx/x11/glxextensions.h
> +++ b/src/glx/x11/glxextensions.h
> @@ -44,6 +44,7 @@ enum
>     MESA_allocate_memory_bit,    /* Replaces MESA_agp_offset &
> NV_vertex_array_range */
>     MESA_copy_sub_buffer_bit,
>     MESA_depth_float_bit,
> +   MESA_gallium_bit,
>     MESA_pixmap_colormap_bit,
>     MESA_release_buffers_bit,
>     MESA_swap_control_bit,
> diff --git a/src/mesa/state_tracker/st_cb_fbo.c
> b/src/mesa/state_tracker/st_cb_fbo.c
> index 45ce34a..740aa87 100644
> --- a/src/mesa/state_tracker/st_cb_fbo.c
> +++ b/src/mesa/state_tracker/st_cb_fbo.c
> @@ -77,19 +77,17 @@ init_renderbuffer_bits(struct st_renderbuffer *strb,
>   * This is called to allocate the original drawing surface, and
>   * during window resize.
>   */
> -static GLboolean
> -st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
> +GLboolean
> +st_renderbuffer_alloc_storage(struct pipe_screen* screen, struct
> st_renderbuffer *strb,
>                                GLenum internalFormat,
>                                GLuint width, GLuint height)
>  {
> -   struct pipe_context *pipe = ctx->st->pipe;
> -   struct st_renderbuffer *strb = st_renderbuffer(rb);
>     enum pipe_format format;
> 
>     if (strb->format != PIPE_FORMAT_NONE)
>        format = strb->format;
>     else
> -      format = st_choose_renderbuffer_format(pipe->screen, internalFormat);
> +      format = st_choose_renderbuffer_format(screen, internalFormat);
> 
>     /* init renderbuffer fields */
>     strb->Base.Width  = width;
> @@ -130,7 +128,7 @@ st_renderbuffer_alloc_storage(GLcontext * ctx,
> struct gl_renderbuffer *rb,
>        template.height0 = height;
>        template.depth0 = 1;
>        template.last_level = 0;
> -      template.nr_samples = rb->NumSamples;
> +      template.nr_samples = strb->Base.NumSamples;
>        if (util_format_is_depth_or_stencil(format)) {
>           template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
>        }
> @@ -148,13 +146,13 @@ st_renderbuffer_alloc_storage(GLcontext * ctx,
> struct gl_renderbuffer *rb,
>                         PIPE_BUFFER_USAGE_CPU_WRITE);
>  #endif
> 
> -      strb->texture = pipe->screen->texture_create( pipe->screen,
> +      strb->texture = screen->texture_create( screen,
>                                                      &template );
> 
>        if (!strb->texture)
>           return FALSE;
> 
> -      strb->surface = pipe->screen->get_tex_surface( pipe->screen,
> +      strb->surface = screen->get_tex_surface( screen,
>                                                       strb->texture,
>                                                       0, 0, 0,
>                                                       surface_usage );
> @@ -169,6 +167,14 @@ st_renderbuffer_alloc_storage(GLcontext * ctx,
> struct gl_renderbuffer *rb,
>     }
>  }
> 
> +static GLboolean
> +st_renderbuffer_alloc_storage_gl(GLcontext* ctx, struct gl_renderbuffer *rb,
> +                              GLenum internalFormat,
> +                              GLuint width, GLuint height)
> +{
> +       return st_renderbuffer_alloc_storage(ctx->st->pipe->screen,
> st_renderbuffer(rb), internalFormat, width, height);
> +}
> +
> 
>  /**
>   * gl_renderbuffer::Delete()
> @@ -223,7 +229,7 @@ st_new_renderbuffer(GLcontext *ctx, GLuint name)
>     if (strb) {
>        _mesa_init_renderbuffer(&strb->Base, name);
>        strb->Base.Delete = st_renderbuffer_delete;
> -      strb->Base.AllocStorage = st_renderbuffer_alloc_storage;
> +      strb->Base.AllocStorage = st_renderbuffer_alloc_storage_gl;
>        strb->Base.GetPointer = null_get_pointer;
>        strb->format = PIPE_FORMAT_NONE;
>        return &strb->Base;
> @@ -291,7 +297,7 @@ st_new_renderbuffer_fb(enum pipe_format format,
> int samples, boolean sw)
> 
>     /* st-specific methods */
>     strb->Base.Delete = st_renderbuffer_delete;
> -   strb->Base.AllocStorage = st_renderbuffer_alloc_storage;
> +   strb->Base.AllocStorage = st_renderbuffer_alloc_storage_gl;
>     strb->Base.GetPointer = null_get_pointer;
> 
>     /* surface is allocated in st_renderbuffer_alloc_storage() */
> diff --git a/src/mesa/state_tracker/st_cb_fbo.h
> b/src/mesa/state_tracker/st_cb_fbo.h
> index bea6eb8..8abebd2 100644
> --- a/src/mesa/state_tracker/st_cb_fbo.h
> +++ b/src/mesa/state_tracker/st_cb_fbo.h
> @@ -71,5 +71,9 @@ st_new_renderbuffer_fb(enum pipe_format format, int
> samples, boolean sw);
>  extern void
>  st_init_fbo_functions(struct dd_function_table *functions);
> 
> +GLboolean
> +st_renderbuffer_alloc_storage(struct pipe_screen* screen, struct
> st_renderbuffer *strb,
> +                              GLenum internalFormat,
> +                              GLuint width, GLuint height);
> 
>  #endif /* ST_CB_FBO_H */
> diff --git a/src/mesa/state_tracker/st_framebuffer.c
> b/src/mesa/state_tracker/st_framebuffer.c
> index a5d1ae3..ea7a246 100644
> --- a/src/mesa/state_tracker/st_framebuffer.c
> +++ b/src/mesa/state_tracker/st_framebuffer.c
> @@ -151,6 +151,40 @@ void st_resize_framebuffer( struct st_framebuffer *stfb,
>     }
>  }
> 
> +/* This version does not require a GL context */
> +void
> +st_resize_framebuffer_screen( struct pipe_screen* screen, struct
> st_framebuffer *stfb,
> +                         GLuint width, GLuint height)
> +{
> +   GLuint i;
> +
> +   for (i = 0; i < BUFFER_COUNT; i++) {
> +      struct gl_renderbuffer_attachment *att = &stfb->Base.Attachment[i];
> +      if (att->Type == GL_RENDERBUFFER_EXT && att->Renderbuffer) {
> +         struct gl_renderbuffer *rb = att->Renderbuffer;
> +         /* only resize if size is changing */
> +         if (rb->Width != width || rb->Height != height)
> +            st_renderbuffer_alloc_storage(screen,
> st_renderbuffer(rb), rb->InternalFormat, width, height);
> +      }
> +   }
> +
> +   if (stfb->Base._DepthBuffer) {
> +      struct gl_renderbuffer *rb = stfb->Base._DepthBuffer;
> +      if (rb->Width != width || rb->Height != height)
> +         st_renderbuffer_alloc_storage(screen, st_renderbuffer(rb),
> rb->InternalFormat, width, height);
> +   }
> +
> +   if (stfb->Base._StencilBuffer) {
> +      struct gl_renderbuffer *rb = stfb->Base._StencilBuffer;
> +      if (rb->Width != width || rb->Height != height) {
> +         st_renderbuffer_alloc_storage(screen, st_renderbuffer(rb),
> rb->InternalFormat, width, height);
> +      }
> +   }
> +
> +   stfb->Base.Width = width;
> +   stfb->Base.Height = height;
> +}
> +
> 
>  void st_unreference_framebuffer( struct st_framebuffer *stfb )
>  {
> @@ -262,6 +296,23 @@ st_get_framebuffer_surface(struct st_framebuffer
> *stfb, uint surfIndex, struct p
>     return GL_FALSE;
>  }
> 
> +int st_get_framebuffer_surfaces(struct st_framebuffer *stfb, struct
> pipe_surface*** psurfaces)
> +{
> +       int i;
> +       int attachments = 8;
> +       struct pipe_surface** surfaces = malloc(sizeof(struct pipe_surface*)
> * attachments);
> +
> +       for(i = 0; i < attachments; ++i)
> +       {
> +               surfaces[i] = 0;
> +               st_get_framebuffer_surface(stfb, i, &surfaces[i]);
> +               if(surfaces[i])
> +                       pipe_reference(0, &surfaces[i]->reference);
> +       }
> +       *psurfaces = surfaces;
> +       return attachments;
> +}
> +
>  int
>  st_get_framebuffer_texture(struct st_framebuffer *stfb, uint
> surfIndex, struct pipe_texture **texture)
>  {
> diff --git a/src/mesa/state_tracker/st_public.h
> b/src/mesa/state_tracker/st_public.h
> index a5fdac3..77158de 100644
> --- a/src/mesa/state_tracker/st_public.h
> +++ b/src/mesa/state_tracker/st_public.h
> @@ -54,7 +54,7 @@ struct pipe_context;
>  struct pipe_fence_handle;
>  struct pipe_surface;
>  struct pipe_texture;
> -
> +struct pipe_screen;
> 
>  struct st_context *st_create_context(struct pipe_context *pipe,
>                                       const __GLcontextModes *visual,
> @@ -75,6 +75,9 @@ struct st_framebuffer *st_create_framebuffer( const
> __GLcontextModes *visual,
>  void st_resize_framebuffer( struct st_framebuffer *stfb,
>                              uint width, uint height );
> 
> +void st_resize_framebuffer_screen( struct pipe_screen* screen, struct
> st_framebuffer *stfb,
> +                         GLuint width, GLuint height);
> +
>  void st_set_framebuffer_surface(struct st_framebuffer *stfb,
>                                  uint surfIndex, struct pipe_surface *surf);
> 
> @@ -84,6 +87,9 @@ void st_get_framebuffer_dimensions( struct
> st_framebuffer *stfb,
>  int st_get_framebuffer_surface(struct st_framebuffer *stfb,
>                                 uint surfIndex, struct pipe_surface 
> **surface);
> 
> +int st_get_framebuffer_surfaces(struct st_framebuffer *stfb,
> +                               struct pipe_surface*** psurfaces);
> +
>  int st_get_framebuffer_texture(struct st_framebuffer *stfb,
>                                 uint surfIndex, struct pipe_texture 
> **texture);
> 
> --
> 1.6.3.3
> 
> ------------------------------------------------------------------------------
> This SF.Net email is sponsored by the Verizon Developer Community
> Take advantage of Verizon's best-in-class app development support
> A streamlined, 14 day to market process makes app distribution fast and easy
> Join now and get one step closer to millions of Verizon customers
> http://p.sf.net/sfu/verizon-dev2dev
> _______________________________________________
> Mesa3d-dev mailing list
> Mesa3d-dev@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/mesa3d-dev



------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev 
_______________________________________________
Mesa3d-dev mailing list
Mesa3d-dev@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mesa3d-dev

Reply via email to