X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fstate_trackers%2Fglx%2Fxlib%2Fxm_api.c;h=ab4f6753e116b47cf5ded90f6284131768583000;hb=9f2f5b3d7fd70663b98da5d302fcdfd5bc93db05;hp=919497be5f5a5a469e15f5991d126f975f1ac4ba;hpb=733df0059f04e3fd7e3265d3c80dd8029f939c60;p=mesa.git diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.c b/src/gallium/state_trackers/glx/xlib/xm_api.c index 919497be5f5..ab4f6753e11 100644 --- a/src/gallium/state_trackers/glx/xlib/xm_api.c +++ b/src/gallium/state_trackers/glx/xlib/xm_api.c @@ -56,7 +56,6 @@ #include "xm_api.h" #include "xm_st.h" -#include "main/context.h" #include "pipe/p_defines.h" #include "pipe/p_screen.h" #include "pipe/p_context.h" @@ -72,10 +71,35 @@ static struct xm_driver driver; static struct st_api *stapi; +/* Default strict invalidate to false. This means we will not call + * XGetGeometry after every swapbuffers, which allows swapbuffers to + * remain asynchronous. For apps running at 100fps with synchronous + * swapping, a 10% boost is typical. For gears, I see closer to 20% + * speedup. + * + * Note that the work of copying data on swapbuffers doesn't disappear + * - this change just allows the X server to execute the PutImage + * asynchronously without us effectively blocked until its completion. + * + * This speeds up even llvmpipe's threaded rasterization as the + * swapbuffers operation was a large part of the serial component of + * an llvmpipe frame. + * + * The downside of this is correctness - applications which don't call + * glViewport on window resizes will get incorrect rendering. A + * better solution would be to have per-frame but asynchronous + * invalidation. Xcb almost looks as if it could provide this, but + * the API doesn't seem to quite be there. + */ +boolean xmesa_strict_invalidate = FALSE; + void xmesa_set_driver( const struct xm_driver *templ ) { driver = *templ; stapi = driver.create_st_api(); + + xmesa_strict_invalidate = + debug_get_bool_option("XMESA_STRICT_INVALIDATE", FALSE); } @@ -87,6 +111,17 @@ void xmesa_set_driver( const struct xm_driver *templ ) static struct xmesa_display Displays[MAX_DISPLAYS]; static int NumDisplays = 0; +static int +xmesa_get_param(struct st_manager *smapi, + enum st_manager_param param) +{ + switch(param) { + case ST_MANAGER_BROKEN_INVALIDATE: + return !xmesa_strict_invalidate; + default: + return 0; + } +} static XMesaDisplay xmesa_init_display( Display *display ) @@ -116,8 +151,10 @@ xmesa_init_display( Display *display ) xmdpy->display = display; xmdpy->screen = driver.create_pipe_screen(display); xmdpy->smapi = CALLOC_STRUCT(st_manager); - if (xmdpy->smapi) + if (xmdpy->smapi) { xmdpy->smapi->screen = xmdpy->screen; + xmdpy->smapi->get_param = xmesa_get_param; + } if (xmdpy->screen && xmdpy->smapi) { pipe_mutex_init(xmdpy->mutex); @@ -255,7 +292,6 @@ xmesa_get_window_size(Display *dpy, XMesaBuffer b, Status stat; pipe_mutex_lock(xmdpy->mutex); - XSync(b->xm_visual->display, 0); /* added for Chromium */ stat = get_drawable_size(dpy, b->ws.drawable, width, height); pipe_mutex_unlock(xmdpy->mutex); @@ -327,8 +363,7 @@ choose_pixel_format(XMesaVisual v) return PIPE_FORMAT_B5G6R5_UNORM; } - assert(0); - return 0; + return PIPE_FORMAT_NONE; } @@ -340,9 +375,8 @@ static enum pipe_format choose_depth_stencil_format(XMesaDisplay xmdpy, int depth, int stencil) { const enum pipe_texture_target target = PIPE_TEXTURE_2D; - const unsigned tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL; - const unsigned geom_flags = (PIPE_TEXTURE_GEOM_NON_SQUARE | - PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO); + const unsigned tex_usage = PIPE_BIND_DEPTH_STENCIL; + const unsigned sample_count = 0; enum pipe_format formats[8], fmt; int count, i; @@ -366,7 +400,8 @@ choose_depth_stencil_format(XMesaDisplay xmdpy, int depth, int stencil) fmt = PIPE_FORMAT_NONE; for (i = 0; i < count; i++) { if (xmdpy->screen->is_format_supported(xmdpy->screen, formats[i], - target, tex_usage, geom_flags)) { + target, sample_count, + tex_usage)) { fmt = formats[i]; break; } @@ -386,7 +421,7 @@ static XMesaBuffer XMesaBufferList = NULL; /** * Allocate a new XMesaBuffer object which corresponds to the given drawable. - * Note that XMesaBuffer is derived from GLframebuffer. + * Note that XMesaBuffer is derived from struct gl_framebuffer. * The new XMesaBuffer will not have any size (Width=Height=0). * * \param d the corresponding X drawable (window or pixmap) @@ -532,7 +567,7 @@ initialize_visual_and_buffer(XMesaVisual v, XMesaBuffer b, /* RGB WINDOW: * We support RGB rendering into almost any kind of visual. */ - const int xclass = v->mesa_visual.visualType; + const int xclass = v->visualType; if (xclass != GLX_TRUE_COLOR && xclass == !GLX_DIRECT_COLOR) { _mesa_warning(NULL, "XMesa: RGB mode rendering not supported in given visual.\n"); @@ -679,13 +714,13 @@ XMesaVisual XMesaCreateVisual( Display *display, v->mesa_visual.redMask = visinfo->red_mask; v->mesa_visual.greenMask = visinfo->green_mask; v->mesa_visual.blueMask = visinfo->blue_mask; - v->mesa_visual.visualID = visinfo->visualid; - v->mesa_visual.screen = visinfo->screen; + v->visualID = visinfo->visualid; + v->screen = visinfo->screen; #if !(defined(__cplusplus) || defined(c_plusplus)) - v->mesa_visual.visualType = xmesa_convert_from_x_visual_type(visinfo->class); + v->visualType = xmesa_convert_from_x_visual_type(visinfo->class); #else - v->mesa_visual.visualType = xmesa_convert_from_x_visual_type(visinfo->c_class); + v->visualType = xmesa_convert_from_x_visual_type(visinfo->c_class); #endif v->mesa_visual.visualRating = visualCaveat; @@ -696,7 +731,7 @@ XMesaVisual XMesaCreateVisual( Display *display, (void) initialize_visual_and_buffer( v, NULL, rgb_flag, 0, 0 ); { - const int xclass = v->mesa_visual.visualType; + const int xclass = v->visualType; if (xclass == GLX_TRUE_COLOR || xclass == GLX_DIRECT_COLOR) { red_bits = _mesa_bitcount(GET_REDMASK(v)); green_bits = _mesa_bitcount(GET_GREENMASK(v)); @@ -717,15 +752,38 @@ XMesaVisual XMesaCreateVisual( Display *display, alpha_bits = v->mesa_visual.alphaBits; } - _mesa_initialize_visual( &v->mesa_visual, - db_flag, stereo_flag, - red_bits, green_bits, - blue_bits, alpha_bits, - depth_size, - stencil_size, - accum_red_size, accum_green_size, - accum_blue_size, accum_alpha_size, - 0 ); + /* initialize visual */ + { + struct gl_config *vis = &v->mesa_visual; + + vis->rgbMode = GL_TRUE; + vis->doubleBufferMode = db_flag; + vis->stereoMode = stereo_flag; + + vis->redBits = red_bits; + vis->greenBits = green_bits; + vis->blueBits = blue_bits; + vis->alphaBits = alpha_bits; + vis->rgbBits = red_bits + green_bits + blue_bits; + + vis->indexBits = 0; + vis->depthBits = depth_size; + vis->stencilBits = stencil_size; + + vis->accumRedBits = accum_red_size; + vis->accumGreenBits = accum_green_size; + vis->accumBlueBits = accum_blue_size; + vis->accumAlphaBits = accum_alpha_size; + + vis->haveAccumBuffer = accum_red_size > 0; + vis->haveDepthBuffer = depth_size > 0; + vis->haveStencilBuffer = stencil_size > 0; + + vis->numAuxBuffers = 0; + vis->level = 0; + vis->sampleBuffers = 0; + vis->samples = 0; + } v->stvis.buffer_mask = ST_ATTACHMENT_FRONT_LEFT_MASK; if (db_flag) @@ -737,6 +795,12 @@ XMesaVisual XMesaCreateVisual( Display *display, } v->stvis.color_format = choose_pixel_format(v); + if (v->stvis.color_format == PIPE_FORMAT_NONE) { + FREE(v->visinfo); + FREE(v); + return NULL; + } + v->stvis.depth_stencil_format = choose_depth_stencil_format(xmdpy, depth_size, stencil_size); @@ -761,6 +825,16 @@ void XMesaDestroyVisual( XMesaVisual v ) } +/** + * Return the informative name. + */ +const char * +xmesa_get_name(void) +{ + return stapi->name; +} + + /** * Do per-display initializations. */ @@ -779,15 +853,18 @@ xmesa_init( Display *display ) * \return an XMesaContext or NULL if error. */ PUBLIC -XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) +XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list, + GLuint major, GLuint minor, + GLuint profileMask, GLuint contextFlags) { XMesaDisplay xmdpy = xmesa_init_display(v->display); + struct st_context_attribs attribs; XMesaContext c; if (!xmdpy) return NULL; - /* Note: the XMesaContext contains a Mesa GLcontext struct (inheritance) */ + /* Note: the XMesaContext contains a Mesa struct gl_context struct (inheritance) */ c = (XMesaContext) CALLOC_STRUCT(xmesa_context); if (!c) return NULL; @@ -796,8 +873,24 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) c->xm_buffer = NULL; /* set later by XMesaMakeCurrent */ c->xm_read_buffer = NULL; + memset(&attribs, 0, sizeof(attribs)); + attribs.profile = ST_PROFILE_DEFAULT; + attribs.visual = v->stvis; + attribs.major = major; + attribs.minor = minor; + if (contextFlags & GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB) + attribs.flags |= ST_CONTEXT_FLAG_FORWARD_COMPATIBLE; + if (contextFlags & GLX_CONTEXT_DEBUG_BIT_ARB) + attribs.flags |= ST_CONTEXT_FLAG_DEBUG; + if (contextFlags & GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB) + attribs.flags |= ST_CONTEXT_FLAG_ROBUST_ACCESS; + if (profileMask & GLX_CONTEXT_CORE_PROFILE_BIT_ARB) + attribs.flags |= ST_CONTEXT_FLAG_CORE_PROFILE; + if (profileMask & GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB) + attribs.flags |= ST_CONTEXT_FLAG_COMPATIBLE_PROFILE; + c->st = stapi->create_context(stapi, xmdpy->smapi, - &v->stvis, (share_list) ? share_list->st : NULL); + &attribs, (share_list) ? share_list->st : NULL); if (c->st == NULL) goto fail; @@ -1015,19 +1108,29 @@ XMesaDestroyBuffer(XMesaBuffer b) /** - * Query the current drawable size and notify the binding context. + * Notify the binding context to validate the buffer. */ void -xmesa_check_buffer_size(XMesaBuffer b) +xmesa_notify_invalid_buffer(XMesaBuffer b) { XMesaContext xmctx = XMesaGetCurrentContext(); + if (xmctx && xmctx->xm_buffer == b) + xmctx->st->notify_invalid_framebuffer(xmctx->st, b->stfb); +} + + +/** + * Query the current drawable size and notify the binding context. + */ +void +xmesa_check_buffer_size(XMesaBuffer b) +{ if (b->type == PBUFFER) return; xmesa_get_window_size(b->xm_visual->display, b, &b->width, &b->height); - if (xmctx && xmctx->xm_buffer == b) - xmctx->st->notify_invalid_framebuffer(xmctx->st, b->stfb); + xmesa_notify_invalid_buffer(b); } @@ -1104,11 +1207,7 @@ void XMesaSwapBuffers( XMesaBuffer b ) XMesaContext xmctx = XMesaGetCurrentContext(); if (xmctx && xmctx->xm_buffer == b) { - xmctx->st->flush( xmctx->st, - PIPE_FLUSH_RENDER_CACHE | - PIPE_FLUSH_SWAPBUFFERS | - PIPE_FLUSH_FRAME, - NULL); + xmctx->st->flush( xmctx->st, ST_FLUSH_FRONT, NULL); } xmesa_swap_st_framebuffer(b->stfb); @@ -1134,12 +1233,13 @@ void XMesaFlush( XMesaContext c ) XMesaDisplay xmdpy = xmesa_init_display(c->xm_visual->display); struct pipe_fence_handle *fence = NULL; - c->st->flush(c->st, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, &fence); + c->st->flush(c->st, ST_FLUSH_FRONT, &fence); if (fence) { - xmdpy->screen->fence_finish(xmdpy->screen, fence, 0); + xmdpy->screen->fence_finish(xmdpy->screen, fence, + PIPE_TIMEOUT_INFINITE); xmdpy->screen->fence_reference(xmdpy->screen, &fence, NULL); } - XSync( c->xm_visual->display, False ); + XFlush( c->xm_visual->display ); } } @@ -1169,6 +1269,10 @@ void xmesa_destroy_buffers_on_display(Display *dpy) next = b->Next; if (b->xm_visual->display == dpy) { xmesa_free_buffer(b); + /* delete head of list? */ + if (XMesaBufferList == b) { + XMesaBufferList = next; + } } } }