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
> [email protected]
> 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
[email protected]
https://lists.sourceforge.net/lists/listinfo/mesa3d-dev