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