diff options
author | Alan Hourihane <[email protected]> | 2008-06-10 20:17:16 +0100 |
---|---|---|
committer | Alan Hourihane <[email protected]> | 2008-06-11 14:10:08 +0100 |
commit | 4566b006f1a6bbdb96871e511e10e16f18bad23e (patch) | |
tree | 6938da5e79dec0f33ca93ac0bef68d6d56f71f00 /src | |
parent | bd9264210097d08073a4ea3619ca25db56245280 (diff) |
Bring in DRI2 changes
Diffstat (limited to 'src')
30 files changed, 3101 insertions, 3282 deletions
diff --git a/src/gallium/winsys/dri/intel/intel_context.c b/src/gallium/winsys/dri/intel/intel_context.c index 8284e0edbb9..ecc4b0aa53e 100644 --- a/src/gallium/winsys/dri/intel/intel_context.c +++ b/src/gallium/winsys/dri/intel/intel_context.c @@ -67,7 +67,6 @@ int __intel_debug = 0; #define need_GL_NV_vertex_program #include "extension_helper.h" - /** * Extension strings exported by the intel driver. * @@ -75,7 +74,7 @@ int __intel_debug = 0; * It appears that ARB_texture_env_crossbar has "disappeared" compared to the * old i830-specific driver. */ -const struct dri_extension card_extensions[] = { +static const struct dri_extension card_extensions[] = { {"GL_ARB_multisample", GL_ARB_multisample_functions}, {"GL_ARB_multitexture", NULL}, {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions}, @@ -86,22 +85,27 @@ const struct dri_extension card_extensions[] = { {"GL_ARB_texture_env_combine", NULL}, {"GL_ARB_texture_env_dot3", NULL}, {"GL_ARB_texture_mirrored_repeat", NULL}, + {"GL_ARB_texture_non_power_of_two", NULL }, {"GL_ARB_texture_rectangle", NULL}, + {"GL_NV_texture_rectangle", NULL}, + {"GL_EXT_texture_rectangle", NULL}, + {"GL_ARB_point_parameters", NULL}, {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, - {"GL_ARB_pixel_buffer_object", NULL}, {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, {"GL_ARB_window_pos", GL_ARB_window_pos_functions}, {"GL_EXT_blend_color", GL_EXT_blend_color_functions}, - {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions}, + {"GL_EXT_blend_equation_separate", + GL_EXT_blend_equation_separate_functions}, {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, + {"GL_EXT_blend_logic_op", NULL}, {"GL_EXT_blend_subtract", NULL}, {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions}, {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions}, - {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions}, +#if 1 /* XXX FBO temporary? */ {"GL_EXT_packed_depth_stencil", NULL}, - {"GL_EXT_pixel_buffer_object", NULL}, +#endif {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions}, {"GL_EXT_stencil_wrap", NULL}, {"GL_EXT_texture_edge_clamp", NULL}, @@ -116,10 +120,67 @@ const struct dri_extension card_extensions[] = { {"GL_NV_blend_square", NULL}, {"GL_NV_vertex_program", GL_NV_vertex_program_functions}, {"GL_NV_vertex_program1_1", NULL}, - {"GL_SGIS_generate_mipmap", NULL }, + { "GL_SGIS_generate_mipmap", NULL }, {NULL, NULL} }; +#if 0 +static const struct dri_extension brw_extensions[] = { + { "GL_ARB_shading_language_100", GL_VERSION_2_0_functions}, + { "GL_ARB_shading_language_120", GL_VERSION_2_1_functions}, + { "GL_ARB_shader_objects", GL_ARB_shader_objects_functions}, + { "GL_ARB_vertex_shader", GL_ARB_vertex_shader_functions}, + { "GL_ARB_point_sprite", NULL}, + { "GL_ARB_fragment_shader", NULL }, + { "GL_ARB_draw_buffers", NULL }, + { "GL_ARB_depth_texture", NULL }, + { "GL_ARB_fragment_program", NULL }, + { "GL_ARB_shadow", NULL }, + { "GL_EXT_shadow_funcs", NULL }, + /* ARB extn won't work if not enabled */ + { "GL_SGIX_depth_texture", NULL }, + { "GL_ARB_texture_env_crossbar", NULL }, + { "GL_EXT_texture_sRGB", NULL}, + { NULL, NULL } +}; + +static const struct dri_extension arb_oc_extensions[] = { + {"GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions}, + {NULL, NULL} +}; + +static const struct dri_extension ttm_extensions[] = { + {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, + {"GL_ARB_pixel_buffer_object", NULL}, + {NULL, NULL} +}; +#endif + +/** + * Initializes potential list of extensions if ctx == NULL, or actually enables + * extensions for a context. + */ +void intelInitExtensions(GLcontext *ctx, GLboolean enable_imaging) +{ + /* Disable imaging extension until convolution is working in teximage paths. + */ + enable_imaging = GL_FALSE; + + driInitExtensions(ctx, card_extensions, enable_imaging); + +#if 0 + if (intel == NULL || intel->ttm) + driInitExtensions(ctx, ttm_extensions, GL_FALSE); + + if (intel == NULL || + (IS_965(intel->intelScreen->deviceID) && + intel->intelScreen->drmMinor >= 8)) + driInitExtensions(ctx, arb_oc_extensions, GL_FALSE); + + if (intel == NULL || IS_965(intel->intelScreen->deviceID)) + driInitExtensions(ctx, brw_extensions, GL_FALSE); +#endif +} #ifdef DEBUG @@ -204,10 +265,10 @@ intelCreateContext(const __GLcontextModes * visual, /* * memory pools */ - DRM_LIGHT_LOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); + DRM_LIGHT_LOCK(sPriv->fd, &sPriv->lock, driContextPriv->hHWContext); // ZZZ JB should be per screen and not be done per context havePools = intelCreatePools(sPriv); - DRM_UNLOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); + DRM_UNLOCK(sPriv->fd, &sPriv->lock, driContextPriv->hHWContext); if (!havePools) return GL_FALSE; @@ -215,7 +276,7 @@ intelCreateContext(const __GLcontextModes * visual, /* Dri stuff */ intel->hHWContext = driContextPriv->hHWContext; intel->driFd = sPriv->fd; - intel->driHwLock = (drmLock *) & sPriv->pSAREA->lock; + intel->driHwLock = (drmLock *) & sPriv->lock; fthrottle_mode = driQueryOptioni(&intel->optionCache, "fthrottle_mode"); intel->iw.irq_seq = -1; @@ -265,7 +326,7 @@ intelCreateContext(const __GLcontextModes * visual, intel->st = st_create_context(pipe, visual, st_share); - driInitExtensions( intel->st->ctx, card_extensions, GL_TRUE ); + intelInitExtensions( intel->st->ctx, GL_TRUE ); return GL_TRUE; } diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index 8817a80a5a5..23889c80b8c 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -60,7 +60,190 @@ static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; extern const struct dri_extension card_extensions[]; +static GLboolean +intel_get_param(__DRIscreenPrivate *psp, int param, int *value) +{ + int ret; + struct drm_i915_getparam gp; + + gp.param = param; + gp.value = value; + + ret = drmCommandWriteRead(psp->fd, DRM_I915_GETPARAM, &gp, sizeof(gp)); + if (ret) { + fprintf(stderr, "drm_i915_getparam: %d\n", ret); + return GL_FALSE; + } + + return GL_TRUE; +} + +static void +intelSetTexOffset(__DRIcontext *pDRICtx, int texname, + unsigned long long offset, int depth, uint pitch) +{ + abort(); +#if 0 + struct intel_context *intel = (struct intel_context*) + ((__DRIcontextPrivate*)pDRICtx->private)->driverPrivate; + struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname); + struct st_texture_object *stObj = st_texture_object(tObj); + + if (!stObj) + return; + + if (stObj->pt) + st->pipe->texture_release(intel->st->pipe, &stObj->pt); + + stObj->imageOverride = GL_TRUE; + stObj->depthOverride = depth; + stObj->pitchOverride = pitch; + + if (offset) + stObj->textureOffset = offset; +#endif +} + + +static void +intelHandleDrawableConfig(__DRIdrawablePrivate *dPriv, + __DRIcontextPrivate *pcp, + __DRIDrawableConfigEvent *event) +{ + struct intel_framebuffer *intel_fb = dPriv->driverPrivate; + struct intel_region *region = NULL; + struct intel_renderbuffer *rb, *depth_rb, *stencil_rb; + struct intel_context *intel = pcp->driverPrivate; + struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv); + int cpp, pitch; + +#if 0 + cpp = intelScreen->front.cpp; + pitch = ((cpp * dPriv->w + 63) & ~63) / cpp; + + back_surf = st_get_framebuffer_surface(intel_fb->stfb, + ST_SURFACE_BACK_LEFT); + rb = intel_fb->color_rb[1]; + if (rb) { + region = intel_region_alloc(intel, cpp, pitch, dPriv->h); + intel_renderbuffer_set_region(rb, region); + } + + rb = intel_fb->color_rb[2]; + if (rb) { + region = intel_region_alloc(intel, cpp, pitch, dPriv->h); + intel_renderbuffer_set_region(rb, region); + } + + depth_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH); + stencil_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL); + if (depth_rb || stencil_rb) + region = intel_region_alloc(intel, cpp, pitch, dPriv->h); + if (depth_rb) + intel_renderbuffer_set_region(depth_rb, region); + if (stencil_rb) + intel_renderbuffer_set_region(stencil_rb, region); + + /* FIXME: Tell the X server about the regions we just allocated and + * attached. */ +#endif + +} + +#define BUFFER_FLAG_TILED 0x0100 + +static void +intelHandleBufferAttach(__DRIdrawablePrivate *dPriv, + __DRIcontextPrivate *pcp, + __DRIBufferAttachEvent *ba) +{ + struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv); + struct intel_framebuffer *intel_fb = dPriv->driverPrivate; + struct intel_renderbuffer *rb; + struct intel_region *region; + struct intel_context *intel = pcp->driverPrivate; + struct pipe_surface *surf; + GLuint tiled; + + switch (ba->buffer.attachment) { + case DRI_DRAWABLE_BUFFER_FRONT_LEFT: + #if 0 + intelScreen->front.width = ba->width; + intelScreen->front.height = ba->height; + intelScreen->front.offset = sarea->front_offset; + #endif + intelScreen->front.pitch = ba->buffer.pitch * ba->buffer.cpp; + #if 0 + intelScreen->front.size = sarea->front_size; + #endif + driGenBuffers(intelScreen->base.staticPool, "front", 1, &intelScreen->front.buffer, 0, 0, 0); + driBOSetReferenced(intelScreen->front.buffer, ba->buffer.handle); + + break; + +#if 0 + case DRI_DRAWABLE_BUFFER_BACK_LEFT: + rb = intel_fb->color_rb[0]; + break; + + case DRI_DRAWABLE_BUFFER_DEPTH: + rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH); + break; + + case DRI_DRAWABLE_BUFFER_STENCIL: + rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL); + break; +#endif + + case DRI_DRAWABLE_BUFFER_ACCUM: + default: + fprintf(stderr, "unhandled buffer attach event, attacment type %d\n", + ba->buffer.attachment); + return; + } + +#if 0 + /* FIXME: Add this so we can filter out when the X server sends us + * attachment events for the buffers we just allocated. Need to + * get the BO handle for a render buffer. */ + if (intel_renderbuffer_get_region_handle(rb) == ba->buffer.handle) + return; +#endif + +#if 0 + tiled = (ba->buffer.flags & BUFFER_FLAG_TILED) > 0; + + region = intel_region_alloc_for_handle(intel, ba->buffer.cpp, + ba->buffer.pitch / ba->buffer.cpp, + dPriv->h, tiled, + ba->buffer.handle); + + intel_renderbuffer_set_region(rb, region); +#endif +} + +static const __DRItexOffsetExtension intelTexOffsetExtension = { + { __DRI_TEX_OFFSET }, + intelSetTexOffset, +}; + +#if 0 +static const __DRItexBufferExtension intelTexBufferExtension = { + { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION }, + intelSetTexBuffer, +}; +#endif +static const __DRIextension *intelScreenExtensions[] = { + &driReadDrawableExtension, + &driCopySubBufferExtension.base, + &driSwapControlExtension.base, + &driFrameTrackingExtension.base, + &driMediaStreamCounterExtension.base, + &intelTexOffsetExtension.base, +// &intelTexBufferExtension.base, + NULL +}; static void @@ -177,7 +360,8 @@ intelCreatePools(__DRIscreenPrivate * sPriv) intelScreen->havePools = GL_TRUE; - intelUpdateScreenRotation(sPriv, intelScreen->sarea); + if (intelScreen->sarea) + intelUpdateScreenRotation(sPriv, intelScreen->sarea); return GL_TRUE; } @@ -210,11 +394,6 @@ intelInitDriver(__DRIscreenPrivate * sPriv) struct intel_screen *intelScreen; I830DRIPtr gDRIPriv = (I830DRIPtr) sPriv->pDevPriv; - PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = - (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface-> - getProcAddress("glxEnableExtension")); - void *const psc = sPriv->psc->screenConfigs; - if (sPriv->devPrivSize != sizeof(I830DRIRec)) { fprintf(stderr, "\nERROR! sizeof(I830DRIRec) does not match passed size from device driver\n"); @@ -231,28 +410,17 @@ intelInitDriver(__DRIscreenPrivate * sPriv) __driConfigOptions, __driNConfigOptions); sPriv->private = (void *) intelScreen; - intelScreen->sarea = (drmI830Sarea *) (((GLubyte *) sPriv->pSAREA) + - gDRIPriv->sarea_priv_offset); - intelScreen->deviceID = gDRIPriv->deviceID; - intelScreen->front.cpp = gDRIPriv->cpp; - intelScreen->drmMinor = sPriv->drmMinor; + gDRIPriv->sarea_priv_offset); - assert(gDRIPriv->bitsPerPixel == 16 || - gDRIPriv->bitsPerPixel == 32); + intelScreen->deviceID = gDRIPriv->deviceID; intelUpdateScreenRotation(sPriv, intelScreen->sarea); if (0) intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv); - if (glx_enable_extension != NULL) { - (*glx_enable_extension) (psc, "GLX_SGI_swap_control"); - (*glx_enable_extension) (psc, "GLX_SGI_video_sync"); - (*glx_enable_extension) (psc, "GLX_MESA_swap_control"); - (*glx_enable_extension) (psc, "GLX_MESA_swap_frame_usage"); - (*glx_enable_extension) (psc, "GLX_SGI_make_current_read"); - } + sPriv->extensions = intelScreenExtensions; intel_be_init_device(&intelScreen->base, sPriv->fd); intelScreen->base.base.flush_frontbuffer = intel_flush_frontbuffer; @@ -351,65 +519,19 @@ intelGetSwapInfo(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo) return 0; } - -static void -intelSetTexOffset(__DRIcontext *pDRICtx, int texname, - unsigned long long offset, int depth, uint pitch) +static __DRIconfig ** +intelFillInModes(__DRIscreenPrivate *psp, + unsigned pixel_bits, unsigned depth_bits, + unsigned stencil_bits, GLboolean have_back_buffer) { - abort(); -#if 0 - struct intel_context *intel = (struct intel_context*) - ((__DRIcontextPrivate*)pDRICtx->private)->driverPrivate; - struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname); - struct st_texture_object *stObj = st_texture_object(tObj); - - if (!stObj) - return; - - if (stObj->pt) - st->pipe->texture_release(intel->st->pipe, &stObj->pt); - - stObj->imageOverride = GL_TRUE; - stObj->depthOverride = depth; - stObj->pitchOverride = pitch; - - if (offset) - stObj->textureOffset = offset; -#endif -} - - -static const struct __DriverAPIRec intelAPI = { - .InitDriver = intelInitDriver, - .DestroyScreen = intelDestroyScreen, - .CreateContext = intelCreateContext, - .DestroyContext = intelDestroyContext, - .CreateBuffer = intelCreateBuffer, - .DestroyBuffer = intelDestroyBuffer, - .SwapBuffers = intelSwapBuffers, - .MakeCurrent = intelMakeCurrent, - .UnbindContext = intelUnbindContext, - .GetSwapInfo = intelGetSwapInfo, - .GetMSC = driGetMSC32, - .WaitForMSC = driWaitForMSC32, - .WaitForSBC = NULL, - .SwapBuffersMSC = NULL, - .CopySubBuffer = intelCopySubBuffer, - .setTexOffset = intelSetTexOffset, -}; - - -static __GLcontextModes * -intelFillInModes(unsigned pixel_bits, unsigned depth_bits, - unsigned stencil_bits, boolean have_back_buffer) -{ - __GLcontextModes *modes; + __DRIconfig **configs; __GLcontextModes *m; unsigned num_modes; unsigned depth_buffer_factor; unsigned back_buffer_factor; GLenum fb_format; GLenum fb_type; + int i; /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't * support pageflipping at all. @@ -451,100 +573,143 @@ intelFillInModes(unsigned pixel_bits, unsigned depth_bits, fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; } - modes = - (*dri_interface->createContextModes) (num_modes, - sizeof(__GLcontextModes)); - m = modes; - if (!driFillInModes(&m, fb_format, fb_type, - depth_bits_array, stencil_bits_array, - depth_buffer_factor, back_buffer_modes, - back_buffer_factor, GLX_TRUE_COLOR)) { - fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, - __LINE__); - return NULL; - } - if (!driFillInModes(&m, fb_format, fb_type, - depth_bits_array, stencil_bits_array, - depth_buffer_factor, back_buffer_modes, - back_buffer_factor, GLX_DIRECT_COLOR)) { - fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, + configs = driCreateConfigs(fb_format, fb_type, + depth_bits_array, stencil_bits_array, + depth_buffer_factor, back_buffer_modes, + back_buffer_factor); + if (configs == NULL) { + fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, __LINE__); return NULL; } /* Mark the visual as slow if there are "fake" stencil bits. */ - for (m = modes; m != NULL; m = m->next) { + for (i = 0; configs[i]; i++) { + m = &configs[i]->modes; if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) { m->visualRating = GLX_SLOW_CONFIG; } } - return modes; + return configs; } - /** - * This is the bootstrap function for the driver. libGL supplies all of the - * requisite information about the system, and the driver initializes itself. - * This routine also fills in the linked list pointed to by \c driver_modes - * with the \c __GLcontextModes that the driver can support for windows or - * pbuffers. + * This is the driver specific part of the createNewScreen entry point. + * + * \todo maybe fold this into intelInitDriver * - * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on - * failure. + * \return the __GLcontextModes supported by this driver */ -PUBLIC void * -__driCreateNewScreen_20050727(__DRInativeDisplay * dpy, int scrn, - __DRIscreen * psc, - const __GLcontextModes * modes, - const __DRIversion * ddx_version, - const __DRIversion * dri_version, - const __DRIversion * drm_version, - const __DRIframebuffer * frame_buffer, - drmAddress pSAREA, int fd, - int internal_api_version, - const __DRIinterfaceMethods * interface, - __GLcontextModes ** driver_modes) +static const __DRIconfig **intelInitScreen(__DRIscreenPrivate *psp) { - __DRIscreenPrivate *psp; - static const __DRIversion ddx_expected = { 1, 7, 0 }; +#ifdef I915 + static const __DRIversion ddx_expected = { 1, 5, 0 }; +#else + static const __DRIversion ddx_expected = { 1, 6, 0 }; +#endif static const __DRIversion dri_expected = { 4, 0, 0 }; - static const __DRIversion drm_expected = { 1, 7, 0 }; - - dri_interface = interface; + static const __DRIversion drm_expected = { 1, 5, 0 }; + I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv; if (!driCheckDriDdxDrmVersions2("i915", - dri_version, &dri_expected, - ddx_version, &ddx_expected, - drm_version, &drm_expected)) { + &psp->dri_version, &dri_expected, + &psp->ddx_version, &ddx_expected, + &psp->drm_version, &drm_expected)) { return NULL; } - psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, - ddx_version, dri_version, drm_version, - frame_buffer, pSAREA, fd, - internal_api_version, &intelAPI); - - if (psp != NULL) { - I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv; - *driver_modes = intelFillInModes(dri_priv->cpp * 8, - (dri_priv->cpp == 2) ? 16 : 24, - (dri_priv->cpp == 2) ? 0 : 8, 1); - - /* Calling driInitExtensions here, with a NULL context pointer, - * does not actually enable the extensions. It just makes sure - * that all the dispatch offsets for all the extensions that - * *might* be enables are known. This is needed because the - * dispatch offsets need to be known when _mesa_context_create - * is called, but we can't enable the extensions until we have a - * context pointer. - * - * Hello chicken. Hello egg. How are you two today? - */ - driInitExtensions(NULL, card_extensions, GL_FALSE); + /* Calling driInitExtensions here, with a NULL context pointer, + * does not actually enable the extensions. It just makes sure + * that all the dispatch offsets for all the extensions that + * *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create is + * called, but we can't enable the extensions until we have a + * context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + intelInitExtensions(NULL, GL_TRUE); + + if (!intelInitDriver(psp)) + return NULL; + + psp->extensions = intelScreenExtensions; + + return (const __DRIconfig **) + intelFillInModes(psp, dri_priv->cpp * 8, + (dri_priv->cpp == 2) ? 16 : 24, + (dri_priv->cpp == 2) ? 0 : 8, 1); +} + +/** + * This is the driver specific part of the createNewScreen entry point. + * + * \return the __GLcontextModes supported by this driver + */ +static const +__DRIconfig **intelInitScreen2(__DRIscreenPrivate *psp) +{ + struct intel_screen *intelScreen; + + /* Calling driInitExtensions here, with a NULL context pointer, + * does not actually enable the extensions. It just makes sure + * that all the dispatch offsets for all the extensions that + * *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create is + * called, but we can't enable the extensions until we have a + * context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + intelInitExtensions(NULL, GL_TRUE); + + /* Allocate the private area */ + intelScreen = CALLOC_STRUCT(intel_screen); + if (!intelScreen) { + fprintf(stderr, "\nERROR! Allocating private area failed\n"); + return GL_FALSE; } + /* parse information in __driConfigOptions */ + driParseOptionInfo(&intelScreen->optionCache, + __driConfigOptions, __driNConfigOptions); - return (void *) psp; + psp->private = (void *) intelScreen; + + intelScreen->drmMinor = psp->drm_version.minor; + + /* Determine chipset ID? */ + if (!intel_get_param(psp, I915_PARAM_CHIPSET_ID, + &intelScreen->deviceID)) + return GL_FALSE; + + psp->extensions = intelScreenExtensions; + + intel_be_init_device(&intelScreen->base, psp->fd); + intelScreen->base.base.flush_frontbuffer = intel_flush_frontbuffer; + intelScreen->base.base.get_name = intel_get_name; + + return driConcatConfigs(intelFillInModes(psp, 16, 16, 0, 1), + intelFillInModes(psp, 32, 24, 8, 1)); } +const struct __DriverAPIRec driDriverAPI = { + .InitScreen = intelInitScreen, + .DestroyScreen = intelDestroyScreen, + .CreateContext = intelCreateContext, + .DestroyContext = intelDestroyContext, + .CreateBuffer = intelCreateBuffer, + .DestroyBuffer = intelDestroyBuffer, + .SwapBuffers = intelSwapBuffers, + .MakeCurrent = intelMakeCurrent, + .UnbindContext = intelUnbindContext, + .GetSwapInfo = intelGetSwapInfo, + .GetDrawableMSC = driDrawableGetMSC32, + .WaitForMSC = driWaitForMSC32, + .CopySubBuffer = intelCopySubBuffer, + + .InitScreen2 = intelInitScreen2, + .HandleDrawableConfig = intelHandleDrawableConfig, + .HandleBufferAttach = intelHandleBufferAttach, +}; diff --git a/src/glx/x11/Makefile b/src/glx/x11/Makefile index b404727f08b..13043117947 100644 --- a/src/glx/x11/Makefile +++ b/src/glx/x11/Makefile @@ -10,12 +10,14 @@ SOURCES = \ compsize.c \ eval.c \ glxcmds.c \ + glxcurrent.c \ glxext.c \ glxextensions.c \ indirect.c \ indirect_init.c \ indirect_size.c \ indirect_window_pos.c \ + indirect_texture_compression.c \ indirect_transpose_matrix.c \ indirect_vertex_array.c \ indirect_vertex_program.c \ @@ -29,13 +31,16 @@ SOURCES = \ xfont.c \ glx_pbuffer.c \ glx_query.c \ - glx_texture_compression.c \ + dri_common.c \ dri_glx.c \ - XF86dri.c + XF86dri.c \ + glxhash.c \ + dri2_glx.c \ + dri2.c include $(TOP)/src/mesa/sources -MESA_GLAPI_ASM_SOURCES = $(addprefix $(TOP)/src/mesa/, $(GLAPI_ASM_SOURCES)) +MESA_ASM_API = $(addprefix $(TOP)/src/mesa/, $(ASM_API)) MESA_GLAPI_SOURCES = $(addprefix $(TOP)/src/mesa/, $(GLAPI_SOURCES)) MESA_GLAPI_OBJECTS = $(addprefix $(TOP)/src/mesa/, $(GLAPI_OBJECTS)) @@ -46,8 +51,8 @@ INCLUDES = -I. \ -I$(TOP)/include/GL/internal \ -I$(TOP)/src/mesa \ -I$(TOP)/src/mesa/main \ - -I$(TOP)/src/mesa/glapi \ $(LIBDRM_CFLAGS) \ + $(DRI2PROTO_CFLAGS) \ $(X11_INCLUDES) @@ -65,29 +70,28 @@ default: depend $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) # Make libGL $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(OBJECTS) Makefile - $(TOP)/bin/mklib -o $(GL_LIB) -linker '$(CC)' \ + $(TOP)/bin/mklib -o $(GL_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \ -major 1 -minor 2 $(MKLIB_OPTIONS) \ -install $(TOP)/$(LIB_DIR) $(GL_LIB_DEPS) $(OBJECTS) -depend: $(SOURCES) $(MESA_GLAPI_SOURCES) $(MESA_GLAPI_ASM_SOURCES) Makefile - rm -f depend +depend: $(SOURCES) $(MESA_GLAPI_SOURCES) $(MESA_ASM_API) Makefile touch depend $(MKDEP) $(MKDEP_OPTIONS) $(INCLUDES) $(SOURCES) \ - $(MESA_GLAPI_SOURCES) $(MESA_GLAPI_ASM_SOURCES) + $(MESA_GLAPI_SOURCES) $(MESA_ASM_API) # Emacs tags tags: etags `find . -name \*.[ch]` `find $(TOP)/include` -# Dummy install target -install: +install: $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) + $(MAKE) -C $(TOP)/src/mesa install-libgl # Remove .o and backup files clean: -rm -f $(TOP)/$(LIB_DIR)/libGL.so* -rm -f *.o *~ - -rm -f depend + -rm -f depend depend.bak include depend diff --git a/src/glx/x11/XF86dri.c b/src/glx/x11/XF86dri.c index 9919a409771..ba38949c0b4 100644 --- a/src/glx/x11/XF86dri.c +++ b/src/glx/x11/XF86dri.c @@ -374,10 +374,9 @@ PUBLIC Bool XF86DRICreateContext(dpy, screen, visual, context, hHWContext) context, hHWContext ); } -PUBLIC GLboolean XF86DRIDestroyContext( __DRInativeDisplay * ndpy, int screen, - __DRIid context ) +PUBLIC GLboolean XF86DRIDestroyContext(Display *dpy, int screen, + XID context ) { - Display * const dpy = (Display *) ndpy; XExtDisplayInfo *info = find_display (dpy); xXF86DRIDestroyContextReq *req; @@ -396,10 +395,9 @@ PUBLIC GLboolean XF86DRIDestroyContext( __DRInativeDisplay * ndpy, int screen, return True; } -PUBLIC GLboolean XF86DRICreateDrawable( __DRInativeDisplay * ndpy, int screen, - __DRIid drawable, drm_drawable_t * hHWDrawable ) +PUBLIC GLboolean XF86DRICreateDrawable(Display *dpy, int screen, + XID drawable, drm_drawable_t * hHWDrawable ) { - Display * const dpy = (Display *) ndpy; XExtDisplayInfo *info = find_display (dpy); xXF86DRICreateDrawableReply rep; xXF86DRICreateDrawableReq *req; @@ -426,16 +424,36 @@ PUBLIC GLboolean XF86DRICreateDrawable( __DRInativeDisplay * ndpy, int screen, return True; } -PUBLIC GLboolean XF86DRIDestroyDrawable( __DRInativeDisplay * ndpy, int screen, - __DRIid drawable ) +static int noopErrorHandler(Display *dpy, XErrorEvent *xerr) +{ + return 0; +} + +PUBLIC GLboolean XF86DRIDestroyDrawable(Display *dpy, int screen, + XID drawable ) { - Display * const dpy = (Display *) ndpy; XExtDisplayInfo *info = find_display (dpy); xXF86DRIDestroyDrawableReq *req; + int (*oldXErrorHandler)(Display *, XErrorEvent *); TRACE("DestroyDrawable..."); XF86DRICheckExtension (dpy, info, False); + /* This is called from the DRI driver, which used call it like this + * + * if (windowExists(drawable)) + * destroyDrawable(drawable); + * + * which is a textbook race condition - the window may disappear + * from the server between checking for its existance and + * destroying it. Instead we change the semantics of + * __DRIinterfaceMethodsRec::destroyDrawable() to succeed even if + * the windows is gone, by wrapping the destroy call in an error + * handler. */ + + XSync(dpy, GL_FALSE); + oldXErrorHandler = XSetErrorHandler(noopErrorHandler); + LockDisplay(dpy); GetReq(XF86DRIDestroyDrawable, req); req->reqType = info->codes->major_opcode; @@ -444,6 +462,9 @@ PUBLIC GLboolean XF86DRIDestroyDrawable( __DRInativeDisplay * ndpy, int screen, req->drawable = drawable; UnlockDisplay(dpy); SyncHandle(); + + XSetErrorHandler(oldXErrorHandler); + TRACE("DestroyDrawable... return True"); return True; } diff --git a/src/glx/x11/dri_glx.c b/src/glx/x11/dri_glx.c index 21e07c19355..1cb3204d4c7 100644 --- a/src/glx/x11/dri_glx.c +++ b/src/glx/x11/dri_glx.c @@ -34,260 +34,47 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifdef GLX_DIRECT_RENDERING -#include <unistd.h> -#include <X11/Xlibint.h> -#include <X11/extensions/Xext.h> -#include <X11/extensions/extutil.h> +#include <X11/Xlib.h> +#include <X11/extensions/Xfixes.h> +#include <X11/extensions/Xdamage.h> #include "glheader.h" #include "glxclient.h" +#include "glcontextmodes.h" #include "xf86dri.h" #include "sarea.h" -#include <stdio.h> #include <dlfcn.h> -#include "dri_glx.h" #include <sys/types.h> -#include <stdarg.h> - -#ifndef RTLD_NOW -#define RTLD_NOW 0 -#endif -#ifndef RTLD_GLOBAL -#define RTLD_GLOBAL 0 -#endif - - -#ifndef DEFAULT_DRIVER_DIR -/* this is normally defined in Mesa/configs/default with DRI_DRIVER_SEARCH_PATH */ -#define DEFAULT_DRIVER_DIR "/usr/X11R6/lib/modules/dri" -#endif - -static __DRIdriver *Drivers = NULL; - - -/* - * printf wrappers - */ - -static void InfoMessageF(const char *f, ...) -{ - va_list args; - const char *env; - - if ((env = getenv("LIBGL_DEBUG")) && strstr(env, "verbose")) { - fprintf(stderr, "libGL: "); - va_start(args, f); - vfprintf(stderr, f, args); - va_end(args); - } -} - -/** - * Print error to stderr, unless LIBGL_DEBUG=="quiet". - */ -static void ErrorMessageF(const char *f, ...) -{ - va_list args; - const char *env; - - if ((env = getenv("LIBGL_DEBUG")) && !strstr(env, "quiet")) { - fprintf(stderr, "libGL error: "); - va_start(args, f); - vfprintf(stderr, f, args); - va_end(args); - } -} - - -/** - * Extract the ith directory path out of a colon-separated list of paths. No - * more than \c dirLen characters, including the terminating \c NUL, will be - * written to \c dir. - * - * \param index Index of path to extract (starting at zero) - * \param paths The colon-separated list of paths - * \param dirLen Maximum length of result to store in \c dir - * \param dir Buffer to hold the extracted directory path - * - * \returns - * The number of characters that would have been written to \c dir had there - * been enough room. This does not include the terminating \c NUL. When - * extraction fails, zero will be returned. - * - * \todo - * It seems like this function could be rewritten to use \c strchr. - */ -static size_t -ExtractDir(int index, const char *paths, int dirLen, char *dir) -{ - int i, len; - const char *start, *end; - - /* find ith colon */ - start = paths; - i = 0; - while (i < index) { - if (*start == ':') { - i++; - start++; - } - else if (*start == 0) { - /* end of string and couldn't find ith colon */ - dir[0] = 0; - return 0; - } - else { - start++; - } - } - - while (*start == ':') - start++; - - /* find next colon, or end of string */ - end = start + 1; - while (*end != ':' && *end != 0) { - end++; - } - - /* copy string between <start> and <end> into result string */ - len = end - start; - if (len > dirLen - 1) - len = dirLen - 1; - strncpy(dir, start, len); - dir[len] = 0; - - return( end - start ); -} - - -/** - * Versioned name of the expected \c __driCreateNewScreen function. - * - * The version of the last incompatible loader/driver inteface change is - * appended to the name of the \c __driCreateNewScreen function. This - * prevents loaders from trying to load drivers that are too old. - * - * \todo - * Create a macro or something so that this is automatically updated. - */ -static const char createNewScreenName[] = "__driCreateNewScreen_20050727"; - - -/** - * Try to \c dlopen the named driver. - * - * This function adds the "_dri.so" suffix to the driver name and searches the - * directories specified by the \c LIBGL_DRIVERS_PATH environment variable in - * order to find the driver. - * - * \param driverName - a name like "tdfx", "i810", "mga", etc. - * - * \returns - * A handle from \c dlopen, or \c NULL if driver file not found. - */ -static __DRIdriver *OpenDriver(const char *driverName) -{ - void *glhandle = NULL; - char *libPaths = NULL; - char libDir[1000]; - int i; - __DRIdriver *driver; - - /* First, search Drivers list to see if we've already opened this driver */ - for (driver = Drivers; driver; driver = driver->next) { - if (strcmp(driver->name, driverName) == 0) { - /* found it */ - return driver; - } - } - - /* Attempt to make sure libGL symbols will be visible to the driver */ - glhandle = dlopen("libGL.so.1", RTLD_NOW | RTLD_GLOBAL); - - if (geteuid() == getuid()) { - /* don't allow setuid apps to use LIBGL_DRIVERS_PATH */ - libPaths = getenv("LIBGL_DRIVERS_PATH"); - if (!libPaths) - libPaths = getenv("LIBGL_DRIVERS_DIR"); /* deprecated */ - } - if (!libPaths) - libPaths = DEFAULT_DRIVER_DIR; - - for ( i = 0 ; ExtractDir(i, libPaths, 1000, libDir) != 0 ; i++ ) { - char realDriverName[200]; - void *handle = NULL; - - - /* If TLS support is enabled, try to open the TLS version of the driver - * binary first. If that fails, try the non-TLS version. - */ -#ifdef GLX_USE_TLS - snprintf(realDriverName, 200, "%s/tls/%s_dri.so", libDir, driverName); - InfoMessageF("OpenDriver: trying %s\n", realDriverName); - handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL); -#endif - - if ( handle == NULL ) { - snprintf(realDriverName, 200, "%s/%s_dri.so", libDir, driverName); - InfoMessageF("OpenDriver: trying %s\n", realDriverName); - handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL); - } - - if ( handle != NULL ) { - /* allocate __DRIdriver struct */ - driver = (__DRIdriver *) Xmalloc(sizeof(__DRIdriver)); - if (!driver) - break; /* out of memory! */ - /* init the struct */ - driver->name = __glXstrdup(driverName); - if (!driver->name) { - Xfree(driver); - driver = NULL; - break; /* out of memory! */ - } - - driver->createNewScreenFunc = (PFNCREATENEWSCREENFUNC) - dlsym(handle, createNewScreenName); - - if ( driver->createNewScreenFunc == NULL ) { - /* If the driver doesn't have this symbol then something's - * really, really wrong. - */ - ErrorMessageF("%s not defined in %s_dri.so!\n" - "Your driver may be too old for this libGL.\n", - createNewScreenName, driverName); - Xfree(driver); - driver = NULL; - dlclose(handle); - continue; - } - driver->handle = handle; - /* put at head of linked list */ - driver->next = Drivers; - Drivers = driver; - break; - } - else { - ErrorMessageF("dlopen %s failed (%s)\n", realDriverName, dlerror()); - } - } - - if (!driver) - ErrorMessageF("unable to load driver: %s_dri.so\n", driverName); - - if (glhandle) - dlclose(glhandle); - - return driver; -} - +#include <sys/mman.h> +#include "xf86drm.h" +#include "dri_common.h" + +typedef struct __GLXDRIdisplayPrivateRec __GLXDRIdisplayPrivate; +typedef struct __GLXDRIcontextPrivateRec __GLXDRIcontextPrivate; + +struct __GLXDRIdisplayPrivateRec { + __GLXDRIdisplay base; + + /* + ** XFree86-DRI version information + */ + int driMajor; + int driMinor; + int driPatch; +}; + +struct __GLXDRIcontextPrivateRec { + __GLXDRIcontext base; + __DRIcontext *driContext; + XID hwContextID; + __GLXscreenConfigs *psc; +}; /* * Given a display pointer and screen number, determine the name of * the DRI driver for the screen. (I.e. "r128", "tdfx", etc). * Return True for success, False for failure. */ -static Bool GetDriverName(Display *dpy, int scrNum, char **driverName) +static Bool driGetDriverName(Display *dpy, int scrNum, char **driverName) { int directCapable; Bool b; @@ -317,25 +104,6 @@ static Bool GetDriverName(Display *dpy, int scrNum, char **driverName) return True; } - -/* - * Given a display pointer and screen number, return a __DRIdriver handle. - * Return NULL if anything goes wrong. - */ -__DRIdriver *driGetDriver(Display *dpy, int scrNum) -{ - char *driverName; - if (GetDriverName(dpy, scrNum, &driverName)) { - __DRIdriver *ret; - ret = OpenDriver(driverName); - if (driverName) - Xfree(driverName); - return ret; - } - return NULL; -} - - /* * Exported function for querying the DRI driver for a given screen. * @@ -345,7 +113,7 @@ __DRIdriver *driGetDriver(Display *dpy, int scrNum) PUBLIC const char *glXGetScreenDriver (Display *dpy, int scrNum) { static char ret[32]; char *driverName; - if (GetDriverName(dpy, scrNum, &driverName)) { + if (driGetDriverName(dpy, scrNum, &driverName)) { int len; if (!driverName) return NULL; @@ -359,7 +127,6 @@ PUBLIC const char *glXGetScreenDriver (Display *dpy, int scrNum) { return NULL; } - /* * Exported function for obtaining a driver's option list (UTF-8 encoded XML). * @@ -371,71 +138,532 @@ PUBLIC const char *glXGetScreenDriver (Display *dpy, int scrNum) { * * Note: The driver remains opened after this function returns. */ -PUBLIC const char *glXGetDriverConfig (const char *driverName) { - __DRIdriver *driver = OpenDriver (driverName); - if (driver) - return dlsym (driver->handle, "__driConfigOptions"); +PUBLIC const char *glXGetDriverConfig (const char *driverName) +{ + void *handle = driOpenDriver (driverName); + if (handle) + return dlsym (handle, "__driConfigOptions"); else return NULL; } +#ifdef XDAMAGE_1_1_INTERFACE -/* Called from __glXFreeDisplayPrivate. +static GLboolean has_damage_post(Display *dpy) +{ + static GLboolean inited = GL_FALSE; + static GLboolean has_damage; + + if (!inited) { + int major, minor; + + if (XDamageQueryVersion(dpy, &major, &minor) && + major == 1 && minor >= 1) + { + has_damage = GL_TRUE; + } else { + has_damage = GL_FALSE; + } + inited = GL_TRUE; + } + + return has_damage; +} + +static void __glXReportDamage(__DRIdrawable *driDraw, + int x, int y, + drm_clip_rect_t *rects, int num_rects, + GLboolean front_buffer, + void *loaderPrivate) +{ + XRectangle *xrects; + XserverRegion region; + int i; + int x_off, y_off; + __GLXDRIdrawable *glxDraw = loaderPrivate; + __GLXscreenConfigs *psc = glxDraw->psc; + Display *dpy = psc->dpy; + Drawable drawable; + + if (!has_damage_post(dpy)) + return; + + if (front_buffer) { + x_off = x; + y_off = y; + drawable = RootWindow(dpy, psc->scr); + } else{ + x_off = 0; + y_off = 0; + drawable = glxDraw->xDrawable; + } + + xrects = malloc(sizeof(XRectangle) * num_rects); + if (xrects == NULL) + return; + + for (i = 0; i < num_rects; i++) { + xrects[i].x = rects[i].x1 + x_off; + xrects[i].y = rects[i].y1 + y_off; + xrects[i].width = rects[i].x2 - rects[i].x1; + xrects[i].height = rects[i].y2 - rects[i].y1; + } + region = XFixesCreateRegion(dpy, xrects, num_rects); + free(xrects); + XDamageAdd(dpy, drawable, region); + XFixesDestroyRegion(dpy, region); +} + +static const __DRIdamageExtension damageExtension = { + { __DRI_DAMAGE, __DRI_DAMAGE_VERSION }, + __glXReportDamage, +}; + +#endif + +static GLboolean +__glXDRIGetDrawableInfo(__DRIdrawable *drawable, + unsigned int *index, unsigned int *stamp, + int *X, int *Y, int *W, int *H, + int *numClipRects, drm_clip_rect_t ** pClipRects, + int *backX, int *backY, + int *numBackClipRects, drm_clip_rect_t **pBackClipRects, + void *loaderPrivate) +{ + __GLXDRIdrawable *glxDraw = loaderPrivate; + __GLXscreenConfigs *psc = glxDraw->psc; + Display *dpy = psc->dpy; + + return XF86DRIGetDrawableInfo(dpy, psc->scr, glxDraw->drawable, + index, stamp, X, Y, W, H, + numClipRects, pClipRects, + backX, backY, + numBackClipRects, pBackClipRects); +} + +static const __DRIgetDrawableInfoExtension getDrawableInfoExtension = { + { __DRI_GET_DRAWABLE_INFO, __DRI_GET_DRAWABLE_INFO_VERSION }, + __glXDRIGetDrawableInfo +}; + +static const __DRIextension *loader_extensions[] = { + &systemTimeExtension.base, + &getDrawableInfoExtension.base, +#ifdef XDAMAGE_1_1_INTERFACE + &damageExtension.base, +#endif + NULL +}; + +#ifndef GLX_USE_APPLEGL + +/** + * Perform the required libGL-side initialization and call the client-side + * driver's \c __driCreateNewScreen function. + * + * \param dpy Display pointer. + * \param scrn Screen number on the display. + * \param psc DRI screen information. + * \param driDpy DRI display information. + * \param createNewScreen Pointer to the client-side driver's + * \c __driCreateNewScreen function. + * \returns A pointer to the \c __DRIscreenPrivate structure returned by + * the client-side driver on success, or \c NULL on failure. */ -static void driDestroyDisplay(Display *dpy, void *private) +static void * +CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc, + __GLXDRIdisplayPrivate * driDpy) +{ + void *psp = NULL; + drm_handle_t hSAREA; + drmAddress pSAREA = MAP_FAILED; + char *BusID; + __DRIversion ddx_version; + __DRIversion dri_version; + __DRIversion drm_version; + __DRIframebuffer framebuffer; + int fd = -1; + int status; + + drm_magic_t magic; + drmVersionPtr version; + int newlyopened; + char *driverName; + drm_handle_t hFB; + int junk; + const __DRIconfig **driver_configs; + + /* DRI protocol version. */ + dri_version.major = driDpy->driMajor; + dri_version.minor = driDpy->driMinor; + dri_version.patch = driDpy->driPatch; + + framebuffer.base = MAP_FAILED; + framebuffer.dev_priv = NULL; + + if (!XF86DRIOpenConnection(dpy, scrn, &hSAREA, &BusID)) { + fprintf(stderr, "libGL error: XF86DRIOpenConnection failed\n"); + goto handle_error; + } + + fd = drmOpenOnce(NULL, BusID, &newlyopened); + + Xfree(BusID); /* No longer needed */ + + if (fd < 0) { + fprintf(stderr, "libGL error: drmOpenOnce failed (%s)\n", + strerror(-fd)); + goto handle_error; + } + + if (drmGetMagic(fd, &magic)) { + fprintf(stderr, "libGL error: drmGetMagic failed\n"); + goto handle_error; + } + + version = drmGetVersion(fd); + if (version) { + drm_version.major = version->version_major; + drm_version.minor = version->version_minor; + drm_version.patch = version->version_patchlevel; + drmFreeVersion(version); + } + else { + drm_version.major = -1; + drm_version.minor = -1; + drm_version.patch = -1; + } + + if (newlyopened && !XF86DRIAuthConnection(dpy, scrn, magic)) { + fprintf(stderr, "libGL error: XF86DRIAuthConnection failed\n"); + goto handle_error; + } + + /* Get device name (like "tdfx") and the ddx version numbers. + * We'll check the version in each DRI driver's "createNewScreen" + * function. */ + if (!XF86DRIGetClientDriverName(dpy, scrn, + &ddx_version.major, + &ddx_version.minor, + &ddx_version.patch, + &driverName)) { + fprintf(stderr, "libGL error: XF86DRIGetClientDriverName failed\n"); + goto handle_error; + } + + Xfree(driverName); /* No longer needed. */ + + /* + * Get device-specific info. pDevPriv will point to a struct + * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) that + * has information about the screen size, depth, pitch, ancilliary + * buffers, DRM mmap handles, etc. + */ + if (!XF86DRIGetDeviceInfo(dpy, scrn, &hFB, &junk, + &framebuffer.size, &framebuffer.stride, + &framebuffer.dev_priv_size, &framebuffer.dev_priv)) { + fprintf(stderr, "libGL error: XF86DRIGetDeviceInfo failed"); + goto handle_error; + } + + framebuffer.width = DisplayWidth(dpy, scrn); + framebuffer.height = DisplayHeight(dpy, scrn); + + /* Map the framebuffer region. */ + status = drmMap(fd, hFB, framebuffer.size, + (drmAddressPtr)&framebuffer.base); + if (status != 0) { + fprintf(stderr, "libGL error: drmMap of framebuffer failed (%s)", + strerror(-status)); + goto handle_error; + } + + /* Map the SAREA region. Further mmap regions may be setup in + * each DRI driver's "createNewScreen" function. + */ + status = drmMap(fd, hSAREA, SAREA_MAX, &pSAREA); + if (status != 0) { + fprintf(stderr, "libGL error: drmMap of SAREA failed (%s)", + strerror(-status)); + goto handle_error; + } + + psp = (*psc->legacy->createNewScreen)(scrn, + &ddx_version, + &dri_version, + &drm_version, + &framebuffer, + pSAREA, + fd, + loader_extensions, + &driver_configs, + psc); + + if (psp == NULL) { + fprintf(stderr, "libGL error: Calling driver entry point failed"); + goto handle_error; + } + + psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs); + psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs); + + return psp; + + handle_error: + if (pSAREA != MAP_FAILED) + drmUnmap(pSAREA, SAREA_MAX); + + if (framebuffer.base != MAP_FAILED) + drmUnmap((drmAddress)framebuffer.base, framebuffer.size); + + if (framebuffer.dev_priv != NULL) + Xfree(framebuffer.dev_priv); + + if (fd >= 0) + drmCloseOnce(fd); + + XF86DRICloseConnection(dpy, scrn); + + fprintf(stderr, "libGL error: reverting to (slow) indirect rendering\n"); + + return NULL; +} + +#else /* !GLX_USE_APPLEGL */ + +static void * +CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc, + __GLXDRIdisplayPrivate * driDpy) { - __DRIdisplayPrivate *pdpyp = (__DRIdisplayPrivate *)private; - - if (pdpyp) { - const int numScreens = ScreenCount(dpy); - int i; - for (i = 0; i < numScreens; i++) { - if (pdpyp->libraryHandles[i]) { - __DRIdriver *driver, *prev; - - /* Remove driver from Drivers list */ - for (prev = NULL, driver = Drivers; driver; - prev = driver, driver = driver->next) { - if (driver->handle == pdpyp->libraryHandles[i]) { - if (prev) - prev->next = driver->next; - else - Drivers = driver->next; - - Xfree(driver->name); - Xfree(driver); - break; - } - } - - dlclose(pdpyp->libraryHandles[i]); - } - } - Xfree(pdpyp->libraryHandles); - Xfree(pdpyp); + return NULL; +} + +#endif /* !GLX_USE_APPLEGL */ + +static void driDestroyContext(__GLXDRIcontext *context, + __GLXscreenConfigs *psc, Display *dpy) +{ + __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context; + + (*psc->core->destroyContext)(pcp->driContext); + + XF86DRIDestroyContext(psc->dpy, psc->scr, pcp->hwContextID); +} + +static Bool driBindContext(__GLXDRIcontext *context, + __GLXDRIdrawable *draw, __GLXDRIdrawable *read) +{ + __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context; + const __DRIcoreExtension *core = pcp->psc->core; + + return (*core->bindContext)(pcp->driContext, + draw->driDrawable, + read->driDrawable); +} + +static void driUnbindContext(__GLXDRIcontext *context) +{ + __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context; + const __DRIcoreExtension *core = pcp->psc->core; + + (*core->unbindContext)(pcp->driContext); +} + +static __GLXDRIcontext *driCreateContext(__GLXscreenConfigs *psc, + const __GLcontextModes *mode, + GLXContext gc, + GLXContext shareList, int renderType) +{ + __GLXDRIcontextPrivate *pcp, *pcp_shared; + drm_context_t hwContext; + __DRIcontext *shared = NULL; + __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) mode; + + if (!psc || !psc->driScreen) + return NULL; + + if (shareList) { + pcp_shared = (__GLXDRIcontextPrivate *) shareList->driContext; + shared = pcp_shared->driContext; + } + + pcp = Xmalloc(sizeof *pcp); + if (pcp == NULL) + return NULL; + + pcp->psc = psc; + if (!XF86DRICreateContextWithConfig(psc->dpy, psc->scr, + mode->visualID, + &pcp->hwContextID, &hwContext)) { + Xfree(pcp); + return NULL; } + + pcp->driContext = + (*psc->legacy->createNewContext)(psc->__driScreen, + config->driConfig, + renderType, + shared, + hwContext, + pcp); + if (pcp->driContext == NULL) { + XF86DRIDestroyContext(psc->dpy, psc->scr, pcp->hwContextID); + Xfree(pcp); + return NULL; + } + + pcp->base.destroyContext = driDestroyContext; + pcp->base.bindContext = driBindContext; + pcp->base.unbindContext = driUnbindContext; + + return &pcp->base; } +static void driDestroyDrawable(__GLXDRIdrawable *pdraw) +{ + __GLXscreenConfigs *psc = pdraw->psc; + + (*psc->core->destroyDrawable)(pdraw->driDrawable); + XF86DRIDestroyDrawable(psc->dpy, psc->scr, pdraw->drawable); + Xfree(pdraw); +} + +static __GLXDRIdrawable *driCreateDrawable(__GLXscreenConfigs *psc, + XID xDrawable, + GLXDrawable drawable, + const __GLcontextModes *modes) +{ + __GLXDRIdrawable *pdraw; + drm_drawable_t hwDrawable; + void *empty_attribute_list = NULL; + __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes; + + /* Old dri can't handle GLX 1.3+ drawable constructors. */ + if (xDrawable != drawable) + return NULL; + + pdraw = Xmalloc(sizeof(*pdraw)); + if (!pdraw) + return NULL; + + pdraw->drawable = drawable; + pdraw->psc = psc; + + if (!XF86DRICreateDrawable(psc->dpy, psc->scr, drawable, &hwDrawable)) + return NULL; + + /* Create a new drawable */ + pdraw->driDrawable = + (*psc->legacy->createNewDrawable)(psc->__driScreen, + config->driConfig, + hwDrawable, + GLX_WINDOW_BIT, + empty_attribute_list, + pdraw); + + if (!pdraw->driDrawable) { + XF86DRIDestroyDrawable(psc->dpy, psc->scr, drawable); + Xfree(pdraw); + return NULL; + } + + pdraw->destroyDrawable = driDestroyDrawable; + + return pdraw; +} + +static void driDestroyScreen(__GLXscreenConfigs *psc) +{ + /* Free the direct rendering per screen data */ + if (psc->__driScreen) + (*psc->core->destroyScreen)(psc->__driScreen); + psc->__driScreen = NULL; + if (psc->driver) + dlclose(psc->driver); +} + +static __GLXDRIscreen *driCreateScreen(__GLXscreenConfigs *psc, int screen, + __GLXdisplayPrivate *priv) +{ + __GLXDRIdisplayPrivate *pdp; + __GLXDRIscreen *psp; + const __DRIextension **extensions; + char *driverName; + int i; + + psp = Xmalloc(sizeof *psp); + if (psp == NULL) + return NULL; + + /* Initialize per screen dynamic client GLX extensions */ + psc->ext_list_first_time = GL_TRUE; + + if (!driGetDriverName(priv->dpy, screen, &driverName)) { + Xfree(psp); + return NULL; + } + + psc->driver = driOpenDriver(driverName); + Xfree(driverName); + if (psc->driver == NULL) { + Xfree(psp); + return NULL; + } + + extensions = dlsym(psc->driver, __DRI_DRIVER_EXTENSIONS); + if (extensions == NULL) { + ErrorMessageF("driver exports no extensions (%s)\n", dlerror()); + Xfree(psp); + return NULL; + } + + for (i = 0; extensions[i]; i++) { + if (strcmp(extensions[i]->name, __DRI_CORE) == 0) + psc->core = (__DRIcoreExtension *) extensions[i]; + if (strcmp(extensions[i]->name, __DRI_LEGACY) == 0) + psc->legacy = (__DRIlegacyExtension *) extensions[i]; + } + + if (psc->core == NULL || psc->legacy == NULL) { + Xfree(psp); + return NULL; + } + + pdp = (__GLXDRIdisplayPrivate *) priv->driDisplay; + psc->__driScreen = + CallCreateNewScreen(psc->dpy, screen, psc, pdp); + if (psc->__driScreen == NULL) { + dlclose(psc->driver); + Xfree(psp); + return NULL; + } + + driBindExtensions(psc); + + psp->destroyScreen = driDestroyScreen; + psp->createContext = driCreateContext; + psp->createDrawable = driCreateDrawable; + + return psp; +} + +/* Called from __glXFreeDisplayPrivate. + */ +static void driDestroyDisplay(__GLXDRIdisplay *dpy) +{ + Xfree(dpy); +} /* * Allocate, initialize and return a __DRIdisplayPrivate object. * This is called from __glXInitialize() when we are given a new * display pointer. */ -void *driCreateDisplay(Display *dpy, __DRIdisplay *pdisp) +_X_HIDDEN __GLXDRIdisplay *driCreateDisplay(Display *dpy) { - const int numScreens = ScreenCount(dpy); - __DRIdisplayPrivate *pdpyp; + __GLXDRIdisplayPrivate *pdpyp; int eventBase, errorBase; int major, minor, patch; - int scrn; - - /* Initialize these fields to NULL in case we fail. - * If we don't do this we may later get segfaults trying to free random - * addresses when the display is closed. - */ - pdisp->private = NULL; - pdisp->destroyDisplay = NULL; if (!XF86DRIQueryExtension(dpy, &eventBase, &errorBase)) { return NULL; @@ -445,7 +673,7 @@ void *driCreateDisplay(Display *dpy, __DRIdisplay *pdisp) return NULL; } - pdpyp = (__DRIdisplayPrivate *)Xmalloc(sizeof(__DRIdisplayPrivate)); + pdpyp = Xmalloc(sizeof *pdpyp); if (!pdpyp) { return NULL; } @@ -454,41 +682,10 @@ void *driCreateDisplay(Display *dpy, __DRIdisplay *pdisp) pdpyp->driMinor = minor; pdpyp->driPatch = patch; - pdisp->destroyDisplay = driDestroyDisplay; - - /* allocate array of pointers to createNewScreen funcs */ - pdisp->createNewScreen = (PFNCREATENEWSCREENFUNC *) - Xmalloc(numScreens * sizeof(void *)); - if (!pdisp->createNewScreen) { - Xfree(pdpyp); - return NULL; - } - - /* allocate array of library handles */ - pdpyp->libraryHandles = (void **) Xmalloc(numScreens * sizeof(void*)); - if (!pdpyp->libraryHandles) { - Xfree(pdisp->createNewScreen); - Xfree(pdpyp); - return NULL; - } - - /* dynamically discover DRI drivers for all screens, saving each - * driver's "__driCreateScreen" function pointer. That's the bootstrap - * entrypoint for all DRI drivers. - */ - for (scrn = 0; scrn < numScreens; scrn++) { - __DRIdriver *driver = driGetDriver(dpy, scrn); - if (driver) { - pdisp->createNewScreen[scrn] = driver->createNewScreenFunc; - pdpyp->libraryHandles[scrn] = driver->handle; - } - else { - pdisp->createNewScreen[scrn] = NULL; - pdpyp->libraryHandles[scrn] = NULL; - } - } + pdpyp->base.destroyDisplay = driDestroyDisplay; + pdpyp->base.createScreen = driCreateScreen; - return (void *)pdpyp; + return &pdpyp->base; } #endif /* GLX_DIRECT_RENDERING */ diff --git a/src/glx/x11/glcontextmodes.c b/src/glx/x11/glcontextmodes.c index 788ecf6a3aa..326c8b2357c 100644 --- a/src/glx/x11/glcontextmodes.c +++ b/src/glx/x11/glcontextmodes.c @@ -336,7 +336,8 @@ _gl_get_context_mode_data(const __GLcontextModes *mode, int attribute, *value_return = mode->bindToTextureRgba; return 0; case GLX_BIND_TO_MIPMAP_TEXTURE_EXT: - *value_return = mode->bindToMipmapTexture; + *value_return = mode->bindToMipmapTexture == GL_TRUE ? GL_TRUE : + GL_FALSE; return 0; case GLX_BIND_TO_TEXTURE_TARGETS_EXT: *value_return = mode->bindToTextureTargets; @@ -417,7 +418,7 @@ _gl_context_modes_create( unsigned count, size_t minimum_size ) (*next)->bindToTextureRgb = GLX_DONT_CARE; (*next)->bindToTextureRgba = GLX_DONT_CARE; (*next)->bindToMipmapTexture = GLX_DONT_CARE; - (*next)->bindToTextureTargets = 0; + (*next)->bindToTextureTargets = GLX_DONT_CARE; (*next)->yInverted = GLX_DONT_CARE; next = & ((*next)->next); @@ -456,19 +457,28 @@ _gl_context_modes_destroy( __GLcontextModes * modes ) */ __GLcontextModes * -_gl_context_modes_find_visual( __GLcontextModes * modes, int vid ) +_gl_context_modes_find_visual(__GLcontextModes *modes, int vid) { - while ( modes != NULL ) { - if ( modes->visualID == vid ) { - break; - } + __GLcontextModes *m; - modes = modes->next; - } + for (m = modes; m != NULL; m = m->next) + if (m->visualID == vid) + return m; - return modes; + return NULL; } +__GLcontextModes * +_gl_context_modes_find_fbconfig(__GLcontextModes *modes, int fbid) +{ + __GLcontextModes *m; + + for (m = modes; m != NULL; m = m->next) + if (m->fbconfigID == fbid) + return m; + + return NULL; +} /** * Determine if two context-modes are the same. This is intended to be used diff --git a/src/glx/x11/glcontextmodes.h b/src/glx/x11/glcontextmodes.h index 4b5c6f68b8f..afd09cd7fbd 100644 --- a/src/glx/x11/glcontextmodes.h +++ b/src/glx/x11/glcontextmodes.h @@ -44,8 +44,10 @@ extern int _gl_get_context_mode_data( const __GLcontextModes *mode, extern __GLcontextModes * _gl_context_modes_create( unsigned count, size_t minimum_size ); extern void _gl_context_modes_destroy( __GLcontextModes * modes ); -extern __GLcontextModes * _gl_context_modes_find_visual( - __GLcontextModes * modes, int vid ); +extern __GLcontextModes * + _gl_context_modes_find_visual(__GLcontextModes *modes, int vid); +extern __GLcontextModes * + _gl_context_modes_find_fbconfig(__GLcontextModes *modes, int fbid); extern GLboolean _gl_context_modes_are_same( const __GLcontextModes * a, const __GLcontextModes * b ); diff --git a/src/glx/x11/glx_pbuffer.c b/src/glx/x11/glx_pbuffer.c index 1df2d0f342a..0f878f223f8 100644 --- a/src/glx/x11/glx_pbuffer.c +++ b/src/glx/x11/glx_pbuffer.c @@ -164,6 +164,33 @@ DestroyPbuffer( Display * dpy, GLXDrawable drawable ) } +#ifdef GLX_DIRECT_RENDERING +extern __GLXDRIdrawable * +GetGLXDRIDrawable(Display *dpy, GLXDrawable drawable, int * const scrn_num); + +static GLenum +determineTextureTarget(const int *attribs, int numAttribs) +{ + GLenum target = 0; + int i; + + for (i = 0; i < numAttribs; i++) { + if (attribs[2 * i] == GLX_TEXTURE_TARGET_EXT) { + switch (attribs[2 * i + 1]) { + case GLX_TEXTURE_2D_EXT: + target = GL_TEXTURE_2D; + break; + case GLX_TEXTURE_RECTANGLE_EXT: + target = GL_TEXTURE_RECTANGLE_ARB; + break; + } + } + } + + return target; +} +#endif + /** * Get a drawable's attribute. * @@ -261,6 +288,16 @@ GetDrawableAttribute( Display *dpy, GLXDrawable drawable, } } +#ifdef GLX_DIRECT_RENDERING + { + __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL); + + if (pdraw != NULL && !pdraw->textureTarget) + pdraw->textureTarget = determineTextureTarget((const int *)data, + num_attributes); + } +#endif + Xfree( data ); } } @@ -271,7 +308,6 @@ GetDrawableAttribute( Display *dpy, GLXDrawable drawable, return 0; } - /** * Create a non-pbuffer GLX drawable. * @@ -306,7 +342,7 @@ CreateDrawable( Display *dpy, const __GLcontextModes * fbconfig, req->glxCode = glxCode; req->screen = (CARD32) fbconfig->screen; req->fbconfig = fbconfig->fbconfigID; - req->window = (GLXPbuffer) drawable; + req->window = (CARD32) drawable; req->glxwindow = (GLXWindow) XAllocID(dpy); req->numAttribs = (CARD32) i; @@ -315,6 +351,34 @@ CreateDrawable( Display *dpy, const __GLcontextModes * fbconfig, UnlockDisplay(dpy); SyncHandle(); +#ifdef GLX_DIRECT_RENDERING + do { + /* FIXME: Maybe delay __DRIdrawable creation until the drawable + * is actually bound to a context... */ + + __GLXdisplayPrivate * const priv = __glXInitialize(dpy); + __GLXDRIdrawable *pdraw; + __GLXscreenConfigs *psc; + + psc = &priv->screenConfigs[fbconfig->screen]; + if (psc->driScreen == NULL) + break; + pdraw = psc->driScreen->createDrawable(psc, drawable, + req->glxwindow, fbconfig); + if (pdraw == NULL) { + fprintf(stderr, "failed to create drawable\n"); + break; + } + + if (__glxHashInsert(psc->drawHash, req->glxwindow, pdraw)) { + (*pdraw->destroyDrawable)(pdraw); + return None; /* FIXME: Check what we're supposed to do here... */ + } + + pdraw->textureTarget = determineTextureTarget(attrib_list, i); + } while (0); +#endif + return (GLXDrawable)req->glxwindow; } @@ -350,6 +414,20 @@ DestroyDrawable( Display * dpy, GLXDrawable drawable, CARD32 glxCode ) UnlockDisplay(dpy); SyncHandle(); +#ifdef GLX_DIRECT_RENDERING + { + int screen; + __GLXdisplayPrivate * const priv = __glXInitialize(dpy); + __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen); + __GLXscreenConfigs *psc = &priv->screenConfigs[screen]; + + if (pdraw != NULL) { + (*pdraw->destroyDrawable)(pdraw); + __glxHashDelete(psc->drawHash, drawable); + } + } +#endif + return; } @@ -460,8 +538,24 @@ glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, PUBLIC GLXPbuffer glXCreatePbuffer(Display *dpy, GLXFBConfig config, const int *attrib_list) { + int i, width, height; + + width = 0; + height = 0; + + for (i = 0; attrib_list[i * 2]; i++) { + switch (attrib_list[i * 2]) { + case GLX_PBUFFER_WIDTH: + width = attrib_list[i * 2 + 1]; + break; + case GLX_PBUFFER_HEIGHT: + height = attrib_list[i * 2 + 1]; + break; + } + } + return (GLXPbuffer) CreatePbuffer( dpy, (__GLcontextModes *) config, - 0, 0, + width, height, attrib_list, GL_TRUE ); } diff --git a/src/glx/x11/glx_texture_compression.c b/src/glx/x11/glx_texture_compression.c deleted file mode 100644 index 56768580177..00000000000 --- a/src/glx/x11/glx_texture_compression.c +++ /dev/null @@ -1,347 +0,0 @@ -/* - * (C) Copyright IBM Corporation 2004 - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/** - * \file glx_texture_compression.c - * Contains the routines required to implement GLX protocol for - * ARB_texture_compression and related extensions. - * - * \sa http://oss.sgi.com/projects/ogl-sample/registry/ARB/texture_compression.txt - * - * \author Ian Romanick <[email protected]> - */ - -#include "packrender.h" -#include "packsingle.h" -#include "indirect.h" - -#include <assert.h> - - -void -__indirect_glGetCompressedTexImageARB( GLenum target, GLint level, - GLvoid * img ) -{ - __GLX_SINGLE_DECLARE_VARIABLES(); - xGLXGetTexImageReply reply; - size_t image_bytes; - - __GLX_SINGLE_LOAD_VARIABLES(); - __GLX_SINGLE_BEGIN( X_GLsop_GetCompressedTexImage, 8 ); - __GLX_SINGLE_PUT_LONG( 0, target ); - __GLX_SINGLE_PUT_LONG( 4, level ); - __GLX_SINGLE_READ_XREPLY(); - - image_bytes = reply.width; - assert( image_bytes <= ((4 * reply.length) - 0) ); - assert( image_bytes >= ((4 * reply.length) - 3) ); - - if ( image_bytes != 0 ) { - _XRead( dpy, (char *) img, image_bytes ); - if ( image_bytes < (4 * reply.length) ) { - _XEatData( dpy, (4 * reply.length) - image_bytes ); - } - } - - __GLX_SINGLE_END(); -} - - -/** - * Internal function used for \c glCompressedTexImage1D and - * \c glCompressedTexImage2D. - */ -static void -CompressedTexImage1D2D( GLenum target, GLint level, - GLenum internal_format, - GLsizei width, GLsizei height, - GLint border, GLsizei image_size, - const GLvoid *data, CARD32 rop ) -{ - __GLX_DECLARE_VARIABLES(); - - __GLX_LOAD_VARIABLES(); - if ( gc->currentDpy == NULL ) { - return; - } - - if ( (target == GL_PROXY_TEXTURE_1D) - || (target == GL_PROXY_TEXTURE_2D) - || (target == GL_PROXY_TEXTURE_CUBE_MAP) ) { - compsize = 0; - } - else { - compsize = image_size; - } - - cmdlen = __GLX_PAD( __GLX_COMPRESSED_TEXIMAGE_CMD_HDR_SIZE - + compsize ); - if ( cmdlen <= gc->maxSmallRenderCommandSize ) { - __GLX_BEGIN_VARIABLE( rop, cmdlen ); - __GLX_PUT_LONG( 4, target ); - __GLX_PUT_LONG( 8, level ); - __GLX_PUT_LONG( 12, internal_format ); - __GLX_PUT_LONG( 16, width ); - __GLX_PUT_LONG( 20, height ); - __GLX_PUT_LONG( 24, border ); - __GLX_PUT_LONG( 28, image_size ); - if ( compsize != 0 ) { - __GLX_PUT_CHAR_ARRAY( __GLX_COMPRESSED_TEXIMAGE_CMD_HDR_SIZE, - data, image_size ); - } - __GLX_END( cmdlen ); - } - else { - assert( compsize != 0 ); - - __GLX_BEGIN_VARIABLE_LARGE( rop, cmdlen + 4 ); - __GLX_PUT_LONG( 8, target ); - __GLX_PUT_LONG( 12, level ); - __GLX_PUT_LONG( 16, internal_format ); - __GLX_PUT_LONG( 20, width ); - __GLX_PUT_LONG( 24, height ); - __GLX_PUT_LONG( 28, border ); - __GLX_PUT_LONG( 32, image_size ); - __glXSendLargeCommand( gc, gc->pc, - __GLX_COMPRESSED_TEXIMAGE_CMD_HDR_SIZE + 4, - data, image_size ); - } -} - - -/** - * Internal function used for \c glCompressedTexSubImage1D and - * \c glCompressedTexSubImage2D. - */ -static void -CompressedTexSubImage1D2D( GLenum target, GLint level, - GLsizei xoffset, GLsizei yoffset, - GLsizei width, GLsizei height, - GLenum format, GLsizei image_size, - const GLvoid *data, CARD32 rop ) -{ - __GLX_DECLARE_VARIABLES(); - - __GLX_LOAD_VARIABLES(); - if ( gc->currentDpy == NULL ) { - return; - } - - if ( target == GL_PROXY_TEXTURE_3D ) { - compsize = 0; - } - else { - compsize = image_size; - } - - cmdlen = __GLX_PAD( __GLX_COMPRESSED_TEXSUBIMAGE_CMD_HDR_SIZE - + compsize ); - if ( cmdlen <= gc->maxSmallRenderCommandSize ) { - __GLX_BEGIN_VARIABLE( rop, cmdlen ); - __GLX_PUT_LONG( 4, target ); - __GLX_PUT_LONG( 8, level ); - __GLX_PUT_LONG( 12, xoffset ); - __GLX_PUT_LONG( 16, yoffset ); - __GLX_PUT_LONG( 20, width ); - __GLX_PUT_LONG( 24, height ); - __GLX_PUT_LONG( 28, format ); - __GLX_PUT_LONG( 32, image_size ); - if ( compsize != 0 ) { - __GLX_PUT_CHAR_ARRAY( __GLX_COMPRESSED_TEXSUBIMAGE_CMD_HDR_SIZE, - data, image_size ); - } - __GLX_END( cmdlen ); - } - else { - assert( compsize != 0 ); - - __GLX_BEGIN_VARIABLE_LARGE( rop, cmdlen + 4 ); - __GLX_PUT_LONG( 8, target ); - __GLX_PUT_LONG( 12, level ); - __GLX_PUT_LONG( 16, xoffset ); - __GLX_PUT_LONG( 20, yoffset ); - __GLX_PUT_LONG( 24, width ); - __GLX_PUT_LONG( 28, height ); - __GLX_PUT_LONG( 32, format ); - __GLX_PUT_LONG( 36, image_size ); - __glXSendLargeCommand( gc, gc->pc, - __GLX_COMPRESSED_TEXSUBIMAGE_CMD_HDR_SIZE + 4, - data, image_size ); - } -} - - -void -__indirect_glCompressedTexImage1DARB( GLenum target, GLint level, - GLenum internal_format, GLsizei width, - GLint border, GLsizei image_size, - const GLvoid *data ) -{ - CompressedTexImage1D2D( target, level, internal_format, width, 0, - border, image_size, data, - X_GLrop_CompressedTexImage1D ); -} - - -void -__indirect_glCompressedTexImage2DARB( GLenum target, GLint level, - GLenum internal_format, - GLsizei width, GLsizei height, - GLint border, GLsizei image_size, - const GLvoid *data ) -{ - CompressedTexImage1D2D( target, level, internal_format, width, height, - border, image_size, data, - X_GLrop_CompressedTexImage2D ); -} - - -void -__indirect_glCompressedTexImage3DARB( GLenum target, GLint level, - GLenum internal_format, - GLsizei width, GLsizei height, GLsizei depth, - GLint border, GLsizei image_size, - const GLvoid *data ) -{ - __GLX_DECLARE_VARIABLES(); - - __GLX_LOAD_VARIABLES(); - if ( gc->currentDpy == NULL ) { - return; - } - - cmdlen = __GLX_PAD( __GLX_COMPRESSED_TEXIMAGE_3D_CMD_HDR_SIZE - + image_size ); - if ( cmdlen <= gc->maxSmallRenderCommandSize ) { - __GLX_BEGIN_VARIABLE( X_GLrop_CompressedTexImage3D, cmdlen ); - __GLX_PUT_LONG( 4, target ); - __GLX_PUT_LONG( 8, level ); - __GLX_PUT_LONG( 12, internal_format ); - __GLX_PUT_LONG( 16, width ); - __GLX_PUT_LONG( 20, height ); - __GLX_PUT_LONG( 24, depth ); - __GLX_PUT_LONG( 28, border ); - __GLX_PUT_LONG( 32, image_size ); - if ( image_size != 0 ) { - __GLX_PUT_CHAR_ARRAY( __GLX_COMPRESSED_TEXIMAGE_3D_CMD_HDR_SIZE, - data, image_size ); - } - __GLX_END( cmdlen ); - } - else { - __GLX_BEGIN_VARIABLE_LARGE( X_GLrop_CompressedTexImage3D, - cmdlen + 4 ); - __GLX_PUT_LONG( 8, target ); - __GLX_PUT_LONG( 12, level ); - __GLX_PUT_LONG( 16, internal_format ); - __GLX_PUT_LONG( 20, width ); - __GLX_PUT_LONG( 24, height ); - __GLX_PUT_LONG( 28, depth ); - __GLX_PUT_LONG( 32, border ); - __GLX_PUT_LONG( 36, image_size ); - __glXSendLargeCommand( gc, gc->pc, - __GLX_COMPRESSED_TEXIMAGE_3D_CMD_HDR_SIZE + 4, - data, image_size ); - } -} - - -void -__indirect_glCompressedTexSubImage1DARB( GLenum target, GLint level, - GLint xoffset, - GLsizei width, - GLenum format, GLsizei image_size, - const GLvoid *data ) -{ - CompressedTexSubImage1D2D( target, level, xoffset, 0, width, 0, - format, image_size, data, - X_GLrop_CompressedTexSubImage1D ); -} - - -void -__indirect_glCompressedTexSubImage2DARB( GLenum target, GLint level, - GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, - GLenum format, GLsizei image_size, - const GLvoid *data ) -{ - CompressedTexSubImage1D2D( target, level, xoffset, yoffset, width, height, - format, image_size, data, - X_GLrop_CompressedTexSubImage2D ); -} - - -void -__indirect_glCompressedTexSubImage3DARB( GLenum target, GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLsizei image_size, - const GLvoid *data ) -{ - __GLX_DECLARE_VARIABLES(); - - __GLX_LOAD_VARIABLES(); - if ( gc->currentDpy == NULL ) { - return; - } - - cmdlen = __GLX_PAD( __GLX_COMPRESSED_TEXSUBIMAGE_3D_CMD_HDR_SIZE - + image_size ); - if ( cmdlen <= gc->maxSmallRenderCommandSize ) { - __GLX_BEGIN_VARIABLE( X_GLrop_CompressedTexSubImage3D, cmdlen ); - __GLX_PUT_LONG( 4, target ); - __GLX_PUT_LONG( 8, level ); - __GLX_PUT_LONG( 12, xoffset ); - __GLX_PUT_LONG( 16, yoffset ); - __GLX_PUT_LONG( 20, zoffset ); - __GLX_PUT_LONG( 24, width ); - __GLX_PUT_LONG( 28, height ); - __GLX_PUT_LONG( 32, depth ); - __GLX_PUT_LONG( 36, format ); - __GLX_PUT_LONG( 40, image_size ); - if ( image_size != 0 ) { - __GLX_PUT_CHAR_ARRAY( __GLX_COMPRESSED_TEXSUBIMAGE_3D_CMD_HDR_SIZE, - data, image_size ); - } - __GLX_END( cmdlen ); - } - else { - __GLX_BEGIN_VARIABLE_LARGE( X_GLrop_CompressedTexSubImage3D, - cmdlen + 4 ); - __GLX_PUT_LONG( 8, target ); - __GLX_PUT_LONG( 12, level ); - __GLX_PUT_LONG( 16, xoffset ); - __GLX_PUT_LONG( 20, yoffset ); - __GLX_PUT_LONG( 24, zoffset ); - __GLX_PUT_LONG( 28, width ); - __GLX_PUT_LONG( 32, height ); - __GLX_PUT_LONG( 36, depth ); - __GLX_PUT_LONG( 40, format ); - __GLX_PUT_LONG( 44, image_size ); - __glXSendLargeCommand( gc, gc->pc, - __GLX_COMPRESSED_TEXSUBIMAGE_3D_CMD_HDR_SIZE + 4, - data, image_size ); - } -} diff --git a/src/glx/x11/glxclient.h b/src/glx/x11/glxclient.h index 03e44e5d048..73c278ee386 100644 --- a/src/glx/x11/glxclient.h +++ b/src/glx/x11/glxclient.h @@ -58,7 +58,7 @@ #include "GL/glxproto.h" #include "GL/internal/glcore.h" #include "glapitable.h" -#include "glxextensions.h" +#include "glxhash.h" #if defined( USE_XTHREADS ) # include <X11/Xthreads.h> #elif defined( PTHREADS ) @@ -70,7 +70,9 @@ #define __GLX_MAX_TEXTURE_UNITS 32 +typedef struct __GLXscreenConfigsRec __GLXscreenConfigs; typedef struct __GLXcontextRec __GLXcontext; +typedef struct __GLXdrawableRec __GLXdrawable; typedef struct __GLXdisplayPrivateRec __GLXdisplayPrivate; typedef struct _glapi_table __GLapi; @@ -78,6 +80,9 @@ typedef struct _glapi_table __GLapi; #ifdef GLX_DIRECT_RENDERING +#define containerOf(ptr, type, member) \ + (type *)( (char *)ptr - offsetof(type,member) ) + #include <GL/internal/dri_interface.h> @@ -85,43 +90,64 @@ typedef struct _glapi_table __GLapi; * Display dependent methods. This structure is initialized during the * \c driCreateDisplay call. */ -struct __DRIdisplayRec { +typedef struct __GLXDRIdisplayRec __GLXDRIdisplay; +typedef struct __GLXDRIscreenRec __GLXDRIscreen; +typedef struct __GLXDRIdrawableRec __GLXDRIdrawable; +typedef struct __GLXDRIcontextRec __GLXDRIcontext; + +#include "glxextensions.h" + +struct __GLXDRIdisplayRec { /** * Method to destroy the private DRI display data. */ - void (*destroyDisplay)(Display *dpy, void *displayPrivate); + void (*destroyDisplay)(__GLXDRIdisplay *display); - /** - * Opaque pointer to private per display direct rendering data. - * \c NULL if direct rendering is not supported on this display. - */ - struct __DRIdisplayPrivateRec *private; + __GLXDRIscreen *(*createScreen)(__GLXscreenConfigs *psc, int screen, + __GLXdisplayPrivate *priv); +}; - /** - * Array of pointers to methods to create and initialize the private DRI - * screen data. - */ - PFNCREATENEWSCREENFUNC * createNewScreen; +struct __GLXDRIscreenRec { + + void (*destroyScreen)(__GLXscreenConfigs *psc); + + __GLXDRIcontext *(*createContext)(__GLXscreenConfigs *psc, + const __GLcontextModes *mode, + GLXContext gc, + GLXContext shareList, int renderType); + + __GLXDRIdrawable *(*createDrawable)(__GLXscreenConfigs *psc, + XID drawable, + GLXDrawable glxDrawable, + const __GLcontextModes *modes); }; +struct __GLXDRIcontextRec { + void (*destroyContext)(__GLXDRIcontext *context, __GLXscreenConfigs *psc, + Display *dpy); + Bool (*bindContext)(__GLXDRIcontext *context, + __GLXDRIdrawable *pdraw, + __GLXDRIdrawable *pread); + + void (*unbindContext)(__GLXDRIcontext *context); +}; -/* -** We keep a linked list of these structures, one per DRI device driver. -*/ -struct __DRIdriverRec { - const char *name; - void *handle; - PFNCREATENEWSCREENFUNC createNewScreenFunc; - struct __DRIdriverRec *next; +struct __GLXDRIdrawableRec { + void (*destroyDrawable)(__GLXDRIdrawable *drawable); + + XID xDrawable; + XID drawable; + __GLXscreenConfigs *psc; + __DRIdrawable *driDrawable; + GLenum textureTarget; }; /* ** Function to create and DRI display data and initialize the display ** dependent methods. */ -extern void *driCreateDisplay(Display *dpy, __DRIdisplay *pdisp); - -extern __DRIdriver *driGetDriver(Display *dpy, int scrNum); +extern __GLXDRIdisplay *driCreateDisplay(Display *dpy); +extern __GLXDRIdisplay *dri2CreateDisplay(Display *dpy); extern void DRI_glXUseXFont( Font font, int first, int count, int listbase ); @@ -133,8 +159,6 @@ extern const char *glXGetScreenDriver (Display *dpy, int scrNum); extern const char *glXGetDriverConfig (const char *driverName); -extern Bool __glXWindowExists(Display *dpy, GLXDrawable draw); - #endif /************************************************************************/ @@ -226,18 +250,10 @@ struct __GLXcontextRec { XID share_xid; /** - * Visual id. - * - * \deprecated - * This filed has been largely been replaced by the \c mode field, but - * the work is not quite done. - */ - VisualID vid; - - /** * Screen number. */ GLint screen; + __GLXscreenConfigs *psc; /** * \c GL_TRUE if the context was created with ImportContext, which @@ -343,24 +359,15 @@ struct __GLXcontextRec { */ GLint majorOpcode; -#ifdef GLX_DIRECT_RENDERING /** - * Per context direct rendering interface functions and data. + * Pointer to the mode used to create this context. */ - __DRIcontext driContext; + const __GLcontextModes * mode; + +#ifdef GLX_DIRECT_RENDERING + __GLXDRIcontext *driContext; + __DRIcontext *__driContext; #endif - - /** - * \c GLXFBConfigID used to create this context. May be \c None. This - * field has been replaced by the \c mode field. - * - * \since Internal API version 20030317. - * - * \deprecated - * This filed has been largely been replaced by the \c mode field, but - * the work is not quite done. - */ - GLXFBConfigID fbconfigID; /** * The current read-drawable for this context. Will be None if this @@ -438,7 +445,7 @@ extern void __glFreeAttributeState(__GLXcontext *); * One of these records exists per screen of the display. It contains * a pointer to the config data for that screen (if the screen supports GL). */ -typedef struct __GLXscreenConfigsRec { +struct __GLXscreenConfigsRec { /** * GLX extension string reported by the X-server. */ @@ -454,13 +461,46 @@ typedef struct __GLXscreenConfigsRec { /** * Per screen direct rendering interface functions and data. */ - __DRIscreen driScreen; + __DRIscreen *__driScreen; + const __DRIcoreExtension *core; + const __DRIlegacyExtension *legacy; + __glxHashTable *drawHash; + Display *dpy; + int scr, fd; + void *driver; + + __GLXDRIscreen *driScreen; + +#ifdef __DRI_COPY_SUB_BUFFER + const __DRIcopySubBufferExtension *copySubBuffer; +#endif + +#ifdef __DRI_SWAP_CONTROL + const __DRIswapControlExtension *swapControl; +#endif + +#ifdef __DRI_ALLOCATE + const __DRIallocateExtension *allocate; +#endif + +#ifdef __DRI_FRAME_TRACKING + const __DRIframeTrackingExtension *frameTracking; +#endif + +#ifdef __DRI_MEDIA_STREAM_COUNTER + const __DRImediaStreamCounterExtension *msc; +#endif + +#ifdef __DRI_TEX_BUFFER + const __DRItexBufferExtension *texBuffer; +#endif + #endif /** - * Linked list of configurations for this screen. + * Linked list of glx visuals and fbconfigs for this screen. */ - __GLcontextModes *configs; + __GLcontextModes *visuals, *configs; /** * Per-screen dynamic GLX extension tracking. The \c direct_support @@ -474,7 +514,7 @@ typedef struct __GLXscreenConfigsRec { GLboolean ext_list_first_time; /*@}*/ -} __GLXscreenConfigs; +}; /** * Per display private data. One of these records exists for each display @@ -523,11 +563,11 @@ struct __GLXdisplayPrivateRec { /** * Per display direct rendering interface functions and data. */ - __DRIdisplay driDisplay; + __GLXDRIdisplay *driDisplay; + __GLXDRIdisplay *dri2Display; #endif }; -void __glXFreeContext(__GLXcontext*); extern GLubyte *__glXFlushRenderBuffer(__GLXcontext*, GLubyte*); @@ -571,6 +611,10 @@ extern __GLXcontext *__glXcurrentContext; #endif /* defined( USE_XTHREADS ) || defined( PTHREADS ) */ +extern void __glXSetCurrentContextNull(void); + +extern void __glXFreeContext(__GLXcontext*); + /* ** Global lock for all threads in this address space using the GLX @@ -680,13 +724,16 @@ extern char *__glXstrdup(const char *str); extern const char __glXGLClientVersion[]; extern const char __glXGLClientExtensions[]; -/* Determine the internal API version */ -extern int __glXGetInternalVersion(void); - /* Get the unadjusted system time */ extern int __glXGetUST( int64_t * ust ); -extern Bool __glXGetMscRateOML(Display * dpy, GLXDrawable drawable, - int32_t * numerator, int32_t * denominator); +extern GLboolean __glXGetMscRateOML(Display * dpy, GLXDrawable drawable, + int32_t * numerator, int32_t * denominator); + +#ifdef GLX_DIRECT_RENDERING +GLboolean +__driGetMscRateOML(__DRIdrawable *draw, + int32_t *numerator, int32_t *denominator, void *private); +#endif #endif /* !__GLX_client_h__ */ diff --git a/src/glx/x11/glxcmds.c b/src/glx/x11/glxcmds.c index 80281896f69..4345678a98c 100644 --- a/src/glx/x11/glxcmds.c +++ b/src/glx/x11/glxcmds.c @@ -38,63 +38,110 @@ * Client-side GLX interface. */ -#include <inttypes.h> #include "glxclient.h" -#include <X11/extensions/extutil.h> -#include <X11/extensions/Xext.h> -#include <assert.h> -#include <string.h> #include "glapi.h" -#ifdef GLX_DIRECT_RENDERING -#include "indirect_init.h" -#include <X11/extensions/xf86vmode.h> -#include "xf86dri.h" -#endif #include "glxextensions.h" #include "glcontextmodes.h" #include "glheader.h" + +#ifdef GLX_DIRECT_RENDERING #include <sys/time.h> +#include <X11/extensions/xf86vmode.h> +#include "xf86dri.h" +#endif static const char __glXGLXClientVendorName[] = "SGI"; static const char __glXGLXClientVersion[] = "1.4"; /****************************************************************************/ + +#ifdef GLX_DIRECT_RENDERING + +static Bool windowExistsFlag; +static int windowExistsErrorHandler(Display *dpy, XErrorEvent *xerr) +{ + if (xerr->error_code == BadWindow) { + windowExistsFlag = GL_FALSE; + } + return 0; +} + +/** + * Find drawables in the local hash that have been destroyed on the + * server. + * + * \param dpy Display to destroy drawables for + * \param screen Screen number to destroy drawables for + */ +static void GarbageCollectDRIDrawables(Display *dpy, __GLXscreenConfigs *sc) +{ + XID draw; + __GLXDRIdrawable *pdraw; + XWindowAttributes xwa; + int (*oldXErrorHandler)(Display *, XErrorEvent *); + + /* Set no-op error handler so Xlib doesn't bail out if the windows + * has alreay been destroyed on the server. */ + XSync(dpy, GL_FALSE); + oldXErrorHandler = XSetErrorHandler(windowExistsErrorHandler); + + if (__glxHashFirst(sc->drawHash, &draw, (void *)&pdraw) == 1) { + do { + windowExistsFlag = GL_TRUE; + XGetWindowAttributes(dpy, draw, &xwa); /* dummy request */ + if (!windowExistsFlag) { + /* Destroy the local drawable data, if the drawable no + longer exists in the Xserver */ + (*pdraw->destroyDrawable)(pdraw); + __glxHashDelete(sc->drawHash, draw); + } + } while (__glxHashNext(sc->drawHash, &draw, (void *)&pdraw) == 1); + } + + XSync(dpy, GL_FALSE); + XSetErrorHandler(oldXErrorHandler); +} + +extern __GLXDRIdrawable * +GetGLXDRIDrawable(Display *dpy, GLXDrawable drawable, int * const scrn_num); + /** * Get the __DRIdrawable for the drawable associated with a GLXContext * * \param dpy The display associated with \c drawable. * \param drawable GLXDrawable whose __DRIdrawable part is to be retrieved. + * \param scrn_num If non-NULL, the drawables screen is stored there * \returns A pointer to the context's __DRIdrawable on success, or NULL if * the drawable is not associated with a direct-rendering context. */ - -#ifdef GLX_DIRECT_RENDERING -static __DRIdrawable * -GetDRIDrawable( Display *dpy, GLXDrawable drawable, int * const scrn_num ) +_X_HIDDEN __GLXDRIdrawable * +GetGLXDRIDrawable(Display *dpy, GLXDrawable drawable, int * const scrn_num) { - __GLXdisplayPrivate * const priv = __glXInitialize(dpy); - - if ( (priv != NULL) && (priv->driDisplay.private != NULL) ) { - const unsigned screen_count = ScreenCount(dpy); - unsigned i; - - for ( i = 0 ; i < screen_count ; i++ ) { - __DRIscreen * const psc = &priv->screenConfigs[i].driScreen; - __DRIdrawable * const pdraw = (psc->private != NULL) - ? (*psc->getDrawable)(dpy, drawable, psc->private) : NULL; + __GLXdisplayPrivate *priv = __glXInitialize(dpy); + __GLXDRIdrawable *pdraw; + const unsigned screen_count = ScreenCount(dpy); + unsigned i; + __GLXscreenConfigs *psc; - if ( pdraw != NULL ) { - if ( scrn_num != NULL ) { - *scrn_num = i; - } - return pdraw; - } + if (priv == NULL) + return NULL; + + for (i = 0; i < screen_count; i++) { + psc = &priv->screenConfigs[i]; + if (psc->drawHash == NULL) + continue; + + if (__glxHashLookup(psc->drawHash, drawable, (void *) &pdraw) == 0) { + if (scrn_num != NULL) + *scrn_num = i; + return pdraw; } } return NULL; } + #endif @@ -264,9 +311,9 @@ GLXContext AllocateGLXContext( Display *dpy ) */ gc->fastImageUnpack = GL_FALSE; gc->fillImage = __glFillImage; - gc->isDirect = GL_FALSE; gc->pc = gc->buf; gc->bufEnd = gc->buf + bufSize; + gc->isDirect = GL_FALSE; if (__glXDebug) { /* ** Set limit register so that there will be one command per packet @@ -312,6 +359,10 @@ CreateContext(Display *dpy, XVisualInfo *vis, Bool use_glx_1_3, int renderType) { GLXContext gc; +#ifdef GLX_DIRECT_RENDERING + int screen = (fbconfig == NULL) ? vis->screen : fbconfig->screen; + __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen); +#endif if ( dpy == NULL ) return NULL; @@ -325,41 +376,36 @@ CreateContext(Display *dpy, XVisualInfo *vis, return NULL; #ifdef GLX_DIRECT_RENDERING - if (allowDirect) { - int screen = (fbconfig == NULL) ? vis->screen : fbconfig->screen; - __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen); + if (allowDirect && psc->driScreen) { const __GLcontextModes * mode; - /* The value of fbconfig cannot change because it is tested - * later in the function. - */ - if ( fbconfig == NULL ) { - /* FIXME: Is it possible for the __GLcontextModes structure - * FIXME: to not be found? - */ - mode = _gl_context_modes_find_visual( psc->configs, - vis->visualid ); - assert( mode != NULL ); - assert( mode->screen == screen ); + if (fbconfig == NULL) { + mode = _gl_context_modes_find_visual(psc->visuals, vis->visualid); + if (mode == NULL) { + xError error; + + error.errorCode = BadValue; + error.resourceID = vis->visualid; + error.sequenceNumber = dpy->request; + error.type = X_Error; + error.majorCode = gc->majorOpcode; + error.minorCode = X_GLXCreateContext; + _XError(dpy, &error); + return None; + } } else { mode = fbconfig; } - if (psc && psc->driScreen.private) { - void * const shared = (shareList != NULL) - ? shareList->driContext.private : NULL; - gc->driContext.private = - (*psc->driScreen.createNewContext)( dpy, mode, renderType, - shared, - &gc->driContext ); - if (gc->driContext.private) { - gc->isDirect = GL_TRUE; - gc->screen = mode->screen; - gc->vid = mode->visualID; - gc->fbconfigID = mode->fbconfigID; - gc->driContext.mode = mode; - } + gc->driContext = psc->driScreen->createContext(psc, mode, gc, + shareList, + renderType); + if (gc->driContext != NULL) { + gc->screen = mode->screen; + gc->psc = psc; + gc->mode = mode; + gc->isDirect = GL_TRUE; } } #endif @@ -376,7 +422,7 @@ CreateContext(Display *dpy, XVisualInfo *vis, req->visual = vis->visualid; req->screen = vis->screen; req->shareList = shareList ? shareList->xid : None; - req->isDirect = gc->isDirect; + req->isDirect = gc->driContext != NULL; } else if ( use_glx_1_3 ) { xGLXCreateNewContextReq *req; @@ -390,7 +436,7 @@ CreateContext(Display *dpy, XVisualInfo *vis, req->screen = fbconfig->screen; req->renderType = renderType; req->shareList = shareList ? shareList->xid : None; - req->isDirect = gc->isDirect; + req->isDirect = gc->driContext != NULL; } else { xGLXVendorPrivateWithReplyReq *vpreq; @@ -408,7 +454,7 @@ CreateContext(Display *dpy, XVisualInfo *vis, req->screen = fbconfig->screen; req->renderType = renderType; req->shareList = shareList ? shareList->xid : None; - req->isDirect = gc->isDirect; + req->isDirect = gc->driContext != NULL; } UnlockDisplay(dpy); @@ -430,7 +476,7 @@ PUBLIC GLXContext glXCreateContext(Display *dpy, XVisualInfo *vis, False, 0); } -void __glXFreeContext(__GLXcontext *gc) +_X_HIDDEN void __glXFreeContext(__GLXcontext *gc) { if (gc->vendor) XFree((char *) gc->vendor); if (gc->renderer) XFree((char *) gc->renderer); @@ -466,12 +512,10 @@ DestroyContext(Display *dpy, GLXContext gc) #ifdef GLX_DIRECT_RENDERING /* Destroy the direct rendering context */ - if (gc->isDirect) { - if (gc->driContext.private) { - (*gc->driContext.destroyContext)(dpy, gc->screen, - gc->driContext.private); - gc->driContext.private = NULL; - } + if (gc->driContext) { + (*gc->driContext->destroyContext)(gc->driContext, gc->psc, dpy); + gc->driContext = NULL; + GarbageCollectDRIDrawables(dpy, gc->psc); } #endif @@ -552,7 +596,7 @@ PUBLIC void glXWaitGL(void) __glXFlushRenderBuffer(gc, gc->pc); #ifdef GLX_DIRECT_RENDERING - if (gc->isDirect) { + if (gc->driContext) { /* This bit of ugliness unwraps the glFinish function */ #ifdef glFinish #undef glFinish @@ -588,7 +632,7 @@ PUBLIC void glXWaitX(void) __glXFlushRenderBuffer(gc, gc->pc); #ifdef GLX_DIRECT_RENDERING - if (gc->isDirect) { + if (gc->driContext) { XSync(dpy, False); return; } @@ -618,7 +662,7 @@ PUBLIC void glXUseXFont(Font font, int first, int count, int listBase) (void) __glXFlushRenderBuffer(gc, gc->pc); #ifdef GLX_DIRECT_RENDERING - if (gc->isDirect) { + if (gc->driContext) { DRI_glXUseXFont(font, first, count, listBase); return; } @@ -658,7 +702,7 @@ PUBLIC void glXCopyContext(Display *dpy, GLXContext source, } #ifdef GLX_DIRECT_RENDERING - if (gc->isDirect) { + if (gc->driContext) { /* NOT_DONE: This does not work yet */ } #endif @@ -730,7 +774,7 @@ PUBLIC Bool glXIsDirect(Display *dpy, GLXContext gc) if (!gc) { return GL_FALSE; #ifdef GLX_DIRECT_RENDERING - } else if (gc->isDirect) { + } else if (gc->driContext) { return GL_TRUE; #endif } @@ -793,10 +837,10 @@ PUBLIC void glXSwapBuffers(Display *dpy, GLXDrawable drawable) GLXContextTag tag; CARD8 opcode; #ifdef GLX_DIRECT_RENDERING - __DRIdrawable *pdraw = GetDRIDrawable( dpy, drawable, NULL ); + __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL); - if ( pdraw != NULL ) { - (*pdraw->swapBuffers)(dpy, pdraw->private); + if (pdraw != NULL) { + (*pdraw->psc->core->swapBuffers)(pdraw->driDrawable); return; } #endif @@ -840,12 +884,12 @@ PUBLIC int glXGetConfig(Display *dpy, XVisualInfo *vis, int attribute, { __GLXdisplayPrivate *priv; __GLXscreenConfigs *psc; + __GLcontextModes *modes; int status; status = GetGLXPrivScreenConfig( dpy, vis->screen, & priv, & psc ); if ( status == Success ) { - const __GLcontextModes * const modes = _gl_context_modes_find_visual( - psc->configs, vis->visualid ); + modes = _gl_context_modes_find_visual(psc->visuals, vis->visualid); /* Lookup attribute after first finding a match on the visual */ if ( modes != NULL ) { @@ -1223,7 +1267,7 @@ PUBLIC XVisualInfo *glXChooseVisual(Display *dpy, int screen, int *attribList) ** Compute a score for those that do ** Remember which visual, if any, got the highest score */ - for ( modes = psc->configs ; modes != NULL ; modes = modes->next ) { + for ( modes = psc->visuals ; modes != NULL ; modes = modes->next ) { if ( fbconfigs_compatible( & test_config, modes ) && ((best_config == NULL) || (fbconfig_compare( (const __GLcontextModes * const * const)&modes, &best_config ) < 0)) ) { @@ -1268,7 +1312,7 @@ PUBLIC const char *glXQueryExtensionsString( Display *dpy, int screen ) __glXCalculateUsableExtensions(psc, #ifdef GLX_DIRECT_RENDERING - (psc->driScreen.private != NULL), + (psc->driScreen != NULL), #else GL_FALSE, #endif @@ -1447,13 +1491,15 @@ static int __glXQueryContextInfo(Display *dpy, GLXContext ctx) ctx->share_xid = *pProp++; break; case GLX_VISUAL_ID_EXT: - ctx->vid = *pProp++; + ctx->mode = + _gl_context_modes_find_visual(ctx->psc->visuals, *pProp++); break; case GLX_SCREEN: ctx->screen = *pProp++; break; case GLX_FBCONFIG_ID: - ctx->fbconfigID = *pProp++; + ctx->mode = + _gl_context_modes_find_fbconfig(ctx->psc->configs, *pProp++); break; case GLX_RENDER_TYPE: ctx->renderType = *pProp++; @@ -1478,7 +1524,7 @@ glXQueryContext(Display *dpy, GLXContext ctx, int attribute, int *value) int retVal; /* get the information from the server if we don't have it already */ - if (!ctx->isDirect && (ctx->vid == None)) { + if (!ctx->driContext && (ctx->mode == NULL)) { retVal = __glXQueryContextInfo(dpy, ctx); if (Success != retVal) return retVal; } @@ -1487,13 +1533,13 @@ glXQueryContext(Display *dpy, GLXContext ctx, int attribute, int *value) *value = (int)(ctx->share_xid); break; case GLX_VISUAL_ID_EXT: - *value = (int)(ctx->vid); + *value = ctx->mode ? ctx->mode->visualID : None; break; case GLX_SCREEN: *value = (int)(ctx->screen); break; case GLX_FBCONFIG_ID: - *value = (int)(ctx->fbconfigID); + *value = ctx->mode ? ctx->mode->fbconfigID : None; break; case GLX_RENDER_TYPE: *value = (int)(ctx->renderType); @@ -1591,6 +1637,7 @@ PUBLIC GLXFBConfig *glXGetFBConfigs(Display *dpy, int screen, int *nelements) __GLcontextModes ** config = NULL; int i; + *nelements = 0; if ( (priv->screenConfigs != NULL) && (screen >= 0) && (screen <= ScreenCount(dpy)) && (priv->screenConfigs[screen].configs != NULL) @@ -1615,8 +1662,10 @@ PUBLIC GLXFBConfig *glXGetFBConfigs(Display *dpy, int screen, int *nelements) for ( modes = priv->screenConfigs[screen].configs ; modes != NULL ; modes = modes->next ) { - config[i] = modes; - i++; + if ( modes->fbconfigID != GLX_DONT_CARE ) { + config[i] = modes; + i++; + } } } } @@ -1668,16 +1717,15 @@ static int __glXSwapIntervalSGI(int interval) return GLX_BAD_VALUE; } -#ifdef GLX_DIRECT_RENDERING - if ( gc->isDirect ) { +#ifdef __DRI_SWAP_CONTROL + if (gc->driContext) { __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen ); - __DRIdrawable * const pdraw = GetDRIDrawable( gc->currentDpy, - gc->currentDrawable, - NULL ); - if ( __glXExtensionBitIsEnabled( psc, SGI_swap_control_bit ) - && (pdraw != NULL) ) { - pdraw->swap_interval = interval; + __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy, + gc->currentDrawable, + NULL); + if (psc->swapControl != NULL && pdraw != NULL) { + psc->swapControl->setSwapInterval(pdraw->driDrawable, interval); return 0; } else { @@ -1715,25 +1763,22 @@ static int __glXSwapIntervalSGI(int interval) */ static int __glXSwapIntervalMESA(unsigned int interval) { -#ifdef GLX_DIRECT_RENDERING +#ifdef __DRI_SWAP_CONTROL GLXContext gc = __glXGetCurrentContext(); if ( interval < 0 ) { return GLX_BAD_VALUE; } - if ( (gc != NULL) && gc->isDirect ) { + if (gc != NULL && gc->driContext) { __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen ); - if ( (psc != NULL) && (psc->driScreen.private != NULL) - && __glXExtensionBitIsEnabled( psc, MESA_swap_control_bit ) ) { - __DRIdrawable * const pdraw = - (*psc->driScreen.getDrawable)(gc->currentDpy, - gc->currentDrawable, - psc->driScreen.private); - if ( pdraw != NULL ) { - pdraw->swap_interval = interval; + if ( (psc != NULL) && (psc->driScreen != NULL) ) { + __GLXDRIdrawable *pdraw = + GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL); + if (psc->swapControl != NULL && pdraw != NULL) { + psc->swapControl->setSwapInterval(pdraw->driDrawable, interval); return 0; } } @@ -1748,21 +1793,18 @@ static int __glXSwapIntervalMESA(unsigned int interval) static int __glXGetSwapIntervalMESA(void) { -#ifdef GLX_DIRECT_RENDERING +#ifdef __DRI_SWAP_CONTROL GLXContext gc = __glXGetCurrentContext(); - if ( (gc != NULL) && gc->isDirect ) { + if (gc != NULL && gc->driContext) { __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen ); - if ( (psc != NULL) && (psc->driScreen.private != NULL) - && __glXExtensionBitIsEnabled( psc, MESA_swap_control_bit ) ) { - __DRIdrawable * const pdraw = - (*psc->driScreen.getDrawable)(gc->currentDpy, - gc->currentDrawable, - psc->driScreen.private); - if ( pdraw != NULL ) { - return pdraw->swap_interval; + if ( (psc != NULL) && (psc->driScreen != NULL) ) { + __GLXDRIdrawable *pdraw = + GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL); + if (psc->swapControl != NULL && pdraw != NULL) { + return psc->swapControl->getSwapInterval(pdraw->driDrawable); } } } @@ -1779,15 +1821,13 @@ static int __glXGetSwapIntervalMESA(void) static GLint __glXBeginFrameTrackingMESA(Display *dpy, GLXDrawable drawable) { int status = GLX_BAD_CONTEXT; -#ifdef GLX_DIRECT_RENDERING +#ifdef __DRI_FRAME_TRACKING int screen; - __DRIdrawable * const pdraw = GetDRIDrawable(dpy, drawable, & screen); + __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen); __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen); - if ( (pdraw != NULL) && (pdraw->frameTracking != NULL) - && __glXExtensionBitIsEnabled( psc, MESA_swap_frame_usage_bit ) ) { - status = pdraw->frameTracking( dpy, pdraw->private, GL_TRUE ); - } + if (pdraw != NULL && psc->frameTracking != NULL) + status = psc->frameTracking->frameTracking(pdraw->driDrawable, GL_TRUE); #else (void) dpy; (void) drawable; @@ -1799,15 +1839,14 @@ static GLint __glXBeginFrameTrackingMESA(Display *dpy, GLXDrawable drawable) static GLint __glXEndFrameTrackingMESA(Display *dpy, GLXDrawable drawable) { int status = GLX_BAD_CONTEXT; -#ifdef GLX_DIRECT_RENDERING +#ifdef __DRI_FRAME_TRACKING int screen; - __DRIdrawable * const pdraw = GetDRIDrawable(dpy, drawable, & screen); - __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen); + __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, & screen); + __GLXscreenConfigs *psc = GetGLXScreenConfigs(dpy, screen); - if ( (pdraw != NULL) && (pdraw->frameTracking != NULL) - && __glXExtensionBitIsEnabled( psc, MESA_swap_frame_usage_bit ) ) { - status = pdraw->frameTracking( dpy, pdraw->private, GL_FALSE ); - } + if (pdraw != NULL && psc->frameTracking != NULL) + status = psc->frameTracking->frameTracking(pdraw->driDrawable, + GL_FALSE); #else (void) dpy; (void) drawable; @@ -1820,19 +1859,20 @@ static GLint __glXGetFrameUsageMESA(Display *dpy, GLXDrawable drawable, GLfloat *usage) { int status = GLX_BAD_CONTEXT; -#ifdef GLX_DIRECT_RENDERING +#ifdef __DRI_FRAME_TRACKING int screen; - __DRIdrawable * const pdraw = GetDRIDrawable(dpy, drawable, & screen); + __GLXDRIdrawable * const pdraw = GetGLXDRIDrawable(dpy, drawable, & screen); __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen); - if ( (pdraw != NULL ) && (pdraw->queryFrameTracking != NULL) - && __glXExtensionBitIsEnabled( psc, MESA_swap_frame_usage_bit ) ) { - int64_t sbc, missedFrames; - float lastMissedUsage; + if (pdraw != NULL && psc->frameTracking != NULL) { + int64_t sbc, missedFrames; + float lastMissedUsage; - status = pdraw->queryFrameTracking( dpy, pdraw->private, &sbc, - &missedFrames, &lastMissedUsage, - usage ); + status = psc->frameTracking->queryFrameTracking(pdraw->driDrawable, + &sbc, + &missedFrames, + &lastMissedUsage, + usage); } #else (void) dpy; @@ -1848,18 +1888,17 @@ static GLint __glXQueryFrameTrackingMESA(Display *dpy, GLXDrawable drawable, GLfloat *lastMissedUsage) { int status = GLX_BAD_CONTEXT; -#ifdef GLX_DIRECT_RENDERING +#ifdef __DRI_FRAME_TRACKING int screen; - __DRIdrawable * const pdraw = GetDRIDrawable(dpy, drawable, & screen); + __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, & screen); __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen); - if ( (pdraw != NULL ) && (pdraw->queryFrameTracking != NULL) - && __glXExtensionBitIsEnabled( psc, MESA_swap_frame_usage_bit ) ) { + if (pdraw != NULL && psc->frameTracking != NULL) { float usage; - status = pdraw->queryFrameTracking( dpy, pdraw->private, sbc, - missedFrames, lastMissedUsage, - & usage ); + status = psc->frameTracking->queryFrameTracking(pdraw->driDrawable, + sbc, missedFrames, + lastMissedUsage, &usage); } #else (void) dpy; @@ -1881,21 +1920,24 @@ static int __glXGetVideoSyncSGI(unsigned int *count) * FIXME: there should be a GLX encoding for this call. I can find no * FIXME: documentation for the GLX encoding. */ -#ifdef GLX_DIRECT_RENDERING +#ifdef __DRI_MEDIA_STREAM_COUNTER GLXContext gc = __glXGetCurrentContext(); - if ( (gc != NULL) && gc->isDirect ) { + if (gc != NULL && gc->driContext) { __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen ); - if ( __glXExtensionBitIsEnabled( psc, SGI_video_sync_bit ) - && psc->driScreen.private && psc->driScreen.getMSC) { - int ret; - int64_t temp; + if ( psc->msc && psc->driScreen ) { + __GLXDRIdrawable *pdraw = + GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL); + int64_t temp; + int ret; + + ret = (*psc->msc->getDrawableMSC)(psc->__driScreen, + pdraw->driDrawable, &temp); + *count = (unsigned) temp; - ret = psc->driScreen.getMSC( psc->driScreen.private, & temp ); - *count = (unsigned) temp; - return (ret == 0) ? 0 : GLX_BAD_CONTEXT; + return (ret == 0) ? 0 : GLX_BAD_CONTEXT; } } #else @@ -1906,32 +1948,26 @@ static int __glXGetVideoSyncSGI(unsigned int *count) static int __glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count) { -#ifdef GLX_DIRECT_RENDERING +#ifdef __DRI_MEDIA_STREAM_COUNTER GLXContext gc = __glXGetCurrentContext(); if ( divisor <= 0 || remainder < 0 ) return GLX_BAD_VALUE; - if ( (gc != NULL) && gc->isDirect ) { + if (gc != NULL && gc->driContext) { __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen ); - if ( __glXExtensionBitIsEnabled( psc, SGI_video_sync_bit ) - && psc->driScreen.private ) { - __DRIdrawable * const pdraw = - (*psc->driScreen.getDrawable)(gc->currentDpy, - gc->currentDrawable, - psc->driScreen.private); - if ( (pdraw != NULL) && (pdraw->waitForMSC != NULL) ) { - int ret; - int64_t msc; - int64_t sbc; - - ret = (*pdraw->waitForMSC)( gc->currentDpy, pdraw->private, - 0, divisor, remainder, - & msc, & sbc ); - *count = (unsigned) msc; - return (ret == 0) ? 0 : GLX_BAD_CONTEXT; - } + if (psc->msc != NULL && psc->driScreen ) { + __GLXDRIdrawable *pdraw = + GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL); + int ret; + int64_t msc; + int64_t sbc; + + ret = (*psc->msc->waitForMSC)(pdraw->driDrawable, 0, + divisor, remainder, &msc, &sbc); + *count = (unsigned) msc; + return (ret == 0) ? 0 : GLX_BAD_CONTEXT; } } #else @@ -2083,20 +2119,19 @@ static Bool __glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max) static Bool __glXGetSyncValuesOML(Display *dpy, GLXDrawable drawable, int64_t *ust, int64_t *msc, int64_t *sbc) { -#ifdef GLX_DIRECT_RENDERING +#if defined(__DRI_SWAP_BUFFER_COUNTER) && defined(__DRI_MEDIA_STREAM_COUNTER) __GLXdisplayPrivate * const priv = __glXInitialize(dpy); if ( priv != NULL ) { int i; - __DRIdrawable * const pdraw = GetDRIDrawable( dpy, drawable, & i ); + __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &i); __GLXscreenConfigs * const psc = &priv->screenConfigs[i]; assert( (pdraw == NULL) || (i != -1) ); - return ( (pdraw && pdraw->getSBC && psc->driScreen.getMSC) - && __glXExtensionBitIsEnabled( psc, OML_sync_control_bit ) - && ((*psc->driScreen.getMSC)( psc->driScreen.private, msc ) == 0) - && ((*pdraw->getSBC)( dpy, psc->driScreen.private, sbc ) == 0) - && (__glXGetUST( ust ) == 0) ); + return ( (pdraw && psc->sbc && psc->msc) + && ((*psc->msc->getMSC)(psc->driScreen, msc) == 0) + && ((*psc->sbc->getSBC)(pdraw->driDrawable, sbc) == 0) + && (__glXGetUST(ust) == 0) ); } #else (void) dpy; @@ -2108,6 +2143,68 @@ static Bool __glXGetSyncValuesOML(Display *dpy, GLXDrawable drawable, return False; } +#ifdef GLX_DIRECT_RENDERING +_X_HIDDEN GLboolean +__driGetMscRateOML(__DRIdrawable *draw, + int32_t *numerator, int32_t *denominator, void *private) +{ +#ifdef XF86VIDMODE + __GLXscreenConfigs *psc; + XF86VidModeModeLine mode_line; + int dot_clock; + int i; + __GLXDRIdrawable *glxDraw = private; + + psc = glxDraw->psc; + if (XF86VidModeQueryVersion(psc->dpy, &i, &i) && + XF86VidModeGetModeLine(psc->dpy, psc->scr, &dot_clock, &mode_line) ) { + unsigned n = dot_clock * 1000; + unsigned d = mode_line.vtotal * mode_line.htotal; + +# define V_INTERLACE 0x010 +# define V_DBLSCAN 0x020 + + if (mode_line.flags & V_INTERLACE) + n *= 2; + else if (mode_line.flags & V_DBLSCAN) + d *= 2; + + /* The OML_sync_control spec requires that if the refresh rate is a + * whole number, that the returned numerator be equal to the refresh + * rate and the denominator be 1. + */ + + if (n % d == 0) { + n /= d; + d = 1; + } + else { + static const unsigned f[] = { 13, 11, 7, 5, 3, 2, 0 }; + + /* This is a poor man's way to reduce a fraction. It's far from + * perfect, but it will work well enough for this situation. + */ + + for (i = 0; f[i] != 0; i++) { + while (n % f[i] == 0 && d % f[i] == 0) { + d /= f[i]; + n /= f[i]; + } + } + } + + *numerator = n; + *denominator = d; + + return True; + } + else + return False; +#else + return False; +#endif +} +#endif /** * Determine the refresh rate of the specified drawable and display. @@ -2125,70 +2222,17 @@ static Bool __glXGetSyncValuesOML(Display *dpy, GLXDrawable drawable, * when GLX_OML_sync_control appears in the client extension string. */ -Bool __glXGetMscRateOML(Display * dpy, GLXDrawable drawable, - int32_t * numerator, int32_t * denominator) +_X_HIDDEN GLboolean __glXGetMscRateOML(Display * dpy, GLXDrawable drawable, + int32_t * numerator, + int32_t * denominator) { #if defined( GLX_DIRECT_RENDERING ) && defined( XF86VIDMODE ) - __GLXdisplayPrivate * const priv = __glXInitialize(dpy); - - - if ( priv != NULL ) { - XF86VidModeModeLine mode_line; - int dot_clock; - int screen_num; - int i; - - - GetDRIDrawable( dpy, drawable, & screen_num ); - if ( (screen_num != -1) - && XF86VidModeQueryVersion( dpy, & i, & i ) - && XF86VidModeGetModeLine( dpy, screen_num, & dot_clock, - & mode_line ) ) { - unsigned n = dot_clock * 1000; - unsigned d = mode_line.vtotal * mode_line.htotal; - -# define V_INTERLACE 0x010 -# define V_DBLSCAN 0x020 - - if ( (mode_line.flags & V_INTERLACE) ) { - n *= 2; - } - else if ( (mode_line.flags & V_DBLSCAN) ) { - d *= 2; - } - - /* The OML_sync_control spec requires that if the refresh rate is a - * whole number, that the returned numerator be equal to the refresh - * rate and the denominator be 1. - */ + __GLXDRIdrawable *draw = GetGLXDRIDrawable(dpy, drawable, NULL); - if ( (n % d) == 0 ) { - n /= d; - d = 1; - } - else { - static const unsigned f[] = { 13, 11, 7, 5, 3, 2, 0 }; - - - /* This is a poor man's way to reduce a fraction. It's far from - * perfect, but it will work well enough for this situation. - */ - - for ( i = 0 ; f[i] != 0 ; i++ ) { - while ( ((n % f[i]) == 0) && ((d % f[i]) == 0) ) { - d /= f[i]; - n /= f[i]; - } - } - } - - *numerator = n; - *denominator = d; + if (draw == NULL) + return False; - (void) drawable; - return True; - } - } + return __driGetMscRateOML(draw->driDrawable, numerator, denominator, draw); #else (void) dpy; (void) drawable; @@ -2203,9 +2247,9 @@ static int64_t __glXSwapBuffersMscOML(Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder) { -#ifdef GLX_DIRECT_RENDERING +#ifdef __DRI_SWAP_BUFFER_COUNTER int screen; - __DRIdrawable *pdraw = GetDRIDrawable( dpy, drawable, & screen ); + __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen); __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen ); /* The OML_sync_control spec says these should "generate a GLX_BAD_VALUE @@ -2218,11 +2262,10 @@ static int64_t __glXSwapBuffersMscOML(Display *dpy, GLXDrawable drawable, if ( divisor > 0 && remainder >= divisor ) return -1; - if ( (pdraw != NULL) && (pdraw->swapBuffersMSC != NULL) - && __glXExtensionBitIsEnabled( psc, OML_sync_control_bit ) ) { - return (*pdraw->swapBuffersMSC)(dpy, pdraw->private, target_msc, - divisor, remainder); - } + if (pdraw != NULL && psc->counters != NULL) + return (*psc->sbc->swapBuffersMSC)(pdraw->driDrawable, target_msc, + divisor, remainder); + #else (void) dpy; (void) drawable; @@ -2239,9 +2282,9 @@ static Bool __glXWaitForMscOML(Display * dpy, GLXDrawable drawable, int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc) { -#ifdef GLX_DIRECT_RENDERING +#ifdef __DRI_MEDIA_STREAM_COUNTER int screen; - __DRIdrawable *pdraw = GetDRIDrawable( dpy, drawable, & screen ); + __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen); __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen ); int ret; @@ -2253,10 +2296,9 @@ static Bool __glXWaitForMscOML(Display * dpy, GLXDrawable drawable, if ( divisor > 0 && remainder >= divisor ) return False; - if ( (pdraw != NULL) && (pdraw->waitForMSC != NULL) - && __glXExtensionBitIsEnabled( psc, OML_sync_control_bit ) ) { - ret = (*pdraw->waitForMSC)( dpy, pdraw->private, target_msc, - divisor, remainder, msc, sbc ); + if (pdraw != NULL && psc->msc != NULL) { + ret = (*psc->msc->waitForMSC)(pdraw->driDrawable, target_msc, + divisor, remainder, msc, sbc); /* __glXGetUST returns zero on success and non-zero on failure. * This function returns True on success and False on failure. @@ -2281,9 +2323,9 @@ static Bool __glXWaitForSbcOML(Display * dpy, GLXDrawable drawable, int64_t target_sbc, int64_t *ust, int64_t *msc, int64_t *sbc ) { -#ifdef GLX_DIRECT_RENDERING +#ifdef __DRI_SWAP_BUFFER_COUNTER int screen; - __DRIdrawable *pdraw = GetDRIDrawable( dpy, drawable, & screen ); + __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen); __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen ); int ret; @@ -2293,9 +2335,8 @@ static Bool __glXWaitForSbcOML(Display * dpy, GLXDrawable drawable, if ( target_sbc < 0 ) return False; - if ( (pdraw != NULL) && (pdraw->waitForSBC != NULL) - && __glXExtensionBitIsEnabled( psc, OML_sync_control_bit )) { - ret = (*pdraw->waitForSBC)( dpy, pdraw->private, target_sbc, msc, sbc ); + if (pdraw != NULL && psc->sbc != NULL) { + ret = (*psc->sbc->waitForSBC)(pdraw->driDrawable, target_sbc, msc, sbc); /* __glXGetUST returns zero on success and non-zero on failure. * This function returns True on success and False on failure. @@ -2323,16 +2364,13 @@ PUBLIC void *glXAllocateMemoryMESA(Display *dpy, int scrn, size_t size, float readFreq, float writeFreq, float priority) { -#ifdef GLX_DIRECT_RENDERING +#ifdef __DRI_ALLOCATE __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, scrn ); - if ( __glXExtensionBitIsEnabled( psc, MESA_allocate_memory_bit ) ) { - if (psc && psc->driScreen.private && psc->driScreen.allocateMemory) { - return (*psc->driScreen.allocateMemory)( dpy, scrn, size, - readFreq, writeFreq, - priority ); - } - } + if (psc && psc->allocate) + return (*psc->allocate->allocateMemory)(psc->__driScreen, size, + readFreq, writeFreq, priority); + #else (void) dpy; (void) scrn; @@ -2348,14 +2386,12 @@ PUBLIC void *glXAllocateMemoryMESA(Display *dpy, int scrn, PUBLIC void glXFreeMemoryMESA(Display *dpy, int scrn, void *pointer) { -#ifdef GLX_DIRECT_RENDERING +#ifdef __DRI_ALLOCATE __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, scrn ); - if ( __glXExtensionBitIsEnabled( psc, MESA_allocate_memory_bit ) ) { - if (psc && psc->driScreen.private && psc->driScreen.freeMemory) { - (*psc->driScreen.freeMemory)( dpy, scrn, pointer ); - } - } + if (psc && psc->allocate) + (*psc->allocate->freeMemory)(psc->__driScreen, pointer); + #else (void) dpy; (void) scrn; @@ -2367,14 +2403,12 @@ PUBLIC void glXFreeMemoryMESA(Display *dpy, int scrn, void *pointer) PUBLIC GLuint glXGetMemoryOffsetMESA( Display *dpy, int scrn, const void *pointer ) { -#ifdef GLX_DIRECT_RENDERING +#ifdef __DRI_ALLOCATE __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, scrn ); - if ( __glXExtensionBitIsEnabled( psc, MESA_allocate_memory_bit ) ) { - if (psc && psc->driScreen.private && psc->driScreen.memoryOffset) { - return (*psc->driScreen.memoryOffset)( dpy, scrn, pointer ); - } - } + if (psc && psc->allocate) + return (*psc->allocate->memoryOffset)(psc->__driScreen, pointer); + #else (void) dpy; (void) scrn; @@ -2447,13 +2481,14 @@ static void __glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable, INT32 *x_ptr, *y_ptr, *w_ptr, *h_ptr; CARD8 opcode; -#ifdef GLX_DIRECT_RENDERING +#ifdef __DRI_COPY_SUB_BUFFER int screen; - __DRIdrawable *pdraw = GetDRIDrawable( dpy, drawable, & screen ); + __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen); if ( pdraw != NULL ) { __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen ); - if ( __glXExtensionBitIsEnabled( psc, MESA_copy_sub_buffer_bit ) ) { - (*pdraw->copySubBuffer)(dpy, pdraw->private, x, y, width, height); + if (psc->copySubBuffer != NULL) { + (*psc->copySubBuffer->copySubBuffer)(pdraw->driDrawable, + x, y, width, height); } return; @@ -2529,8 +2564,16 @@ static void __glXBindTexImageEXT(Display *dpy, } #ifdef GLX_DIRECT_RENDERING - if (gc->isDirect) + if (gc->driContext) { + __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL); + + if (pdraw != NULL) + (*pdraw->psc->texBuffer->setTexBuffer)(gc->__driContext, + pdraw->textureTarget, + pdraw->driDrawable); + return; + } #endif opcode = __glXSetupForCommand(dpy); @@ -2581,7 +2624,7 @@ static void __glXReleaseTexImageEXT(Display *dpy, return; #ifdef GLX_DIRECT_RENDERING - if (gc->isDirect) + if (gc->driContext) return; #endif @@ -2613,7 +2656,7 @@ static void __glXReleaseTexImageEXT(Display *dpy, * * \sa strdup */ -char * +_X_HIDDEN char * __glXstrdup(const char *str) { char *copy; @@ -2841,98 +2884,6 @@ PUBLIC void (*glXGetProcAddress(const GLubyte *procName))( void ) #ifdef GLX_DIRECT_RENDERING /** - * Retrieves the verion of the internal libGL API in YYYYMMDD format. This - * might be used by the DRI drivers to determine how new libGL is at runtime. - * Drivers should not call this function directly. They should instead use - * \c glXGetProcAddress to obtain a pointer to the function. - * - * \returns An 8-digit decimal number representing the internal libGL API in - * YYYYMMDD format. - * - * \sa glXGetProcAddress, PFNGLXGETINTERNALVERSIONPROC - * - * \since Internal API version 20021121. - */ -int __glXGetInternalVersion(void) -{ - /* History: - * 20021121 - Initial version - * 20021128 - Added __glXWindowExists() function - * 20021207 - Added support for dynamic GLX extensions, - * GLX_SGI_swap_control, GLX_SGI_video_sync, - * GLX_OML_sync_control, and GLX_MESA_swap_control. - * Never officially released. Do NOT test against - * this version. Use 20030317 instead. - * 20030317 - Added support GLX_SGIX_fbconfig, - * GLX_MESA_swap_frame_usage, GLX_OML_swap_method, - * GLX_{ARB,SGIS}_multisample, and - * GLX_SGIX_visual_select_group. - * 20030606 - Added support for GLX_SGI_make_current_read. - * 20030813 - Made support for dynamic extensions multi-head aware. - * 20030818 - Added support for GLX_MESA_allocate_memory in place of the - * deprecated GLX_NV_vertex_array_range & GLX_MESA_agp_offset - * interfaces. - * 20031201 - Added support for the first round of DRI interface changes. - * Do NOT test against this version! It has binary - * compatibility bugs, use 20040317 instead. - * 20040317 - Added the 'mode' field to __DRIcontextRec. - * 20040415 - Added support for bindContext3 and unbindContext3. - * 20040602 - Add __glXGetDrawableInfo. I though that was there - * months ago. :( - * 20050727 - Gut all the old interfaces. This breaks compatability with - * any DRI driver built to any previous version. - * 20060314 - Added support for GLX_MESA_copy_sub_buffer. - * 20070105 - Added support for damage reporting. - */ - return 20070105; -} - - - -static Bool windowExistsFlag; - -static int windowExistsErrorHandler(Display *dpy, XErrorEvent *xerr) -{ - if (xerr->error_code == BadWindow) { - windowExistsFlag = GL_FALSE; - } - return 0; -} - -/** - * Determine if a window associated with a \c GLXDrawable exists on the - * X-server. This function is not used internally by libGL. It is provided - * as a utility function for DRI drivers. - * Drivers should not call this function directly. They should instead use - * \c glXGetProcAddress to obtain a pointer to the function. - * - * \param dpy Display associated with the drawable to be queried. - * \param draw \c GLXDrawable to test. - * - * \returns \c GL_TRUE if a window exists that is associated with \c draw, - * otherwise \c GL_FALSE is returned. - * - * \warning This function is not currently thread-safe. - * - * \sa glXGetProcAddress - * - * \since Internal API version 20021128. - */ -Bool __glXWindowExists(Display *dpy, GLXDrawable draw) -{ - XWindowAttributes xwa; - int (*oldXErrorHandler)(Display *, XErrorEvent *); - - XSync(dpy, GL_FALSE); - windowExistsFlag = GL_TRUE; - oldXErrorHandler = XSetErrorHandler(windowExistsErrorHandler); - XGetWindowAttributes(dpy, draw, &xwa); /* dummy request */ - XSetErrorHandler(oldXErrorHandler); - return windowExistsFlag; -} - - -/** * Get the unadjusted system time (UST). Currently, the UST is measured in * microseconds since Epoc. The actual resolution of the UST may vary from * system to system, and the units may vary from release to release. @@ -2946,7 +2897,7 @@ Bool __glXWindowExists(Display *dpy, GLXDrawable draw) * * \since Internal API version 20030317. */ -int __glXGetUST( int64_t * ust ) +_X_HIDDEN int __glXGetUST( int64_t * ust ) { struct timeval tv; diff --git a/src/glx/x11/glxext.c b/src/glx/x11/glxext.c index 6403cbd56df..4d814744cda 100644 --- a/src/glx/x11/glxext.c +++ b/src/glx/x11/glxext.c @@ -44,57 +44,25 @@ */ #include "glxclient.h" -#include <stdio.h> #include <X11/extensions/Xext.h> #include <X11/extensions/extutil.h> -#include <X11/extensions/Xfixes.h> -#include <X11/extensions/Xdamage.h> -#include <assert.h> -#include "indirect_init.h" #include "glapi.h" #include "glxextensions.h" #include "glcontextmodes.h" #include "glheader.h" -#ifdef GLX_DIRECT_RENDERING -#include <inttypes.h> -#include <sys/mman.h> -#include "xf86dri.h" -#include "sarea.h" -#include "dri_glx.h" -#endif - #ifdef USE_XCB #include <X11/Xlib-xcb.h> #include <xcb/xcb.h> #include <xcb/glx.h> #endif -#include <assert.h> #ifdef DEBUG void __glXDumpDrawBuffer(__GLXcontext *ctx); #endif #ifdef USE_SPARC_ASM -/* - * This is where our dispatch table's bounds are. - * And the static mesa_init is taken directly from - * Mesa's 'sparc.c' initializer. - * - * We need something like this here, because this version - * of openGL/glx never initializes a Mesa context, and so - * the address of the dispatch table pointer never gets stuffed - * into the dispatch jump table otherwise. - * - * It matters only on SPARC, and only if you are using assembler - * code instead of C-code indirect dispatch. - * - * -- FEM, 04.xii.03 - */ -extern unsigned int _mesa_sparc_glapi_begin; -extern unsigned int _mesa_sparc_glapi_end; -extern void __glapi_sparc_icache_flush(unsigned int *); static void _glx_mesa_init_sparc_glapi_relocs(void); static int _mesa_sparc_needs_init = 1; #define INIT_MESA_SPARC { \ @@ -107,173 +75,11 @@ static int _mesa_sparc_needs_init = 1; #define INIT_MESA_SPARC #endif -#ifdef GLX_DIRECT_RENDERING -static __DRIscreen *__glXFindDRIScreen(__DRInativeDisplay *dpy, int scrn); -#endif /* GLX_DIRECT_RENDERING */ - -static Bool MakeContextCurrent(Display *dpy, GLXDrawable draw, - GLXDrawable read, GLXContext gc); - -/* -** We setup some dummy structures here so that the API can be used -** even if no context is current. -*/ - -static GLubyte dummyBuffer[__GLX_BUFFER_LIMIT_SIZE]; - -/* -** Dummy context used by small commands when there is no current context. -** All the -** gl and glx entry points are designed to operate as nop's when using -** the dummy context structure. -*/ -static __GLXcontext dummyContext = { - &dummyBuffer[0], - &dummyBuffer[0], - &dummyBuffer[0], - &dummyBuffer[__GLX_BUFFER_LIMIT_SIZE], - sizeof(dummyBuffer), -}; - - -/* -** All indirect rendering contexts will share the same indirect dispatch table. -*/ -static __GLapi *IndirectAPI = NULL; - - -/* - * Current context management and locking - */ - -#if defined( USE_XTHREADS ) - -/* thread safe */ -static GLboolean TSDinitialized = GL_FALSE; -static xthread_key_t ContextTSD; - -__GLXcontext *__glXGetCurrentContext(void) -{ - if (!TSDinitialized) { - xthread_key_create(&ContextTSD, NULL); - TSDinitialized = GL_TRUE; - return &dummyContext; - } - else { - void *p; - xthread_get_specific(ContextTSD, &p); - if (!p) - return &dummyContext; - else - return (__GLXcontext *) p; - } -} - -void __glXSetCurrentContext(__GLXcontext *c) -{ - if (!TSDinitialized) { - xthread_key_create(&ContextTSD, NULL); - TSDinitialized = GL_TRUE; - } - xthread_set_specific(ContextTSD, c); -} - - -/* Used by the __glXLock() and __glXUnlock() macros */ -xmutex_rec __glXmutex; - -#elif defined( PTHREADS ) - -pthread_mutex_t __glXmutex = PTHREAD_MUTEX_INITIALIZER; - -# if defined( GLX_USE_TLS ) - -/** - * Per-thread GLX context pointer. - * - * \c __glXSetCurrentContext is written is such a way that this pointer can - * \b never be \c NULL. This is important! Because of this - * \c __glXGetCurrentContext can be implemented as trivial macro. - */ -__thread void * __glX_tls_Context __attribute__((tls_model("initial-exec"))) - = &dummyContext; - -void __glXSetCurrentContext( __GLXcontext * c ) -{ - __glX_tls_Context = (c != NULL) ? c : &dummyContext; -} - -# else - -static pthread_once_t once_control = PTHREAD_ONCE_INIT; - -/** - * Per-thread data key. - * - * Once \c init_thread_data has been called, the per-thread data key will - * take a value of \c NULL. As each new thread is created the default - * value, in that thread, will be \c NULL. - */ -static pthread_key_t ContextTSD; - -/** - * Initialize the per-thread data key. - * - * This function is called \b exactly once per-process (not per-thread!) to - * initialize the per-thread data key. This is ideally done using the - * \c pthread_once mechanism. - */ -static void init_thread_data( void ) -{ - if ( pthread_key_create( & ContextTSD, NULL ) != 0 ) { - perror( "pthread_key_create" ); - exit( -1 ); - } -} - -void __glXSetCurrentContext( __GLXcontext * c ) -{ - pthread_once( & once_control, init_thread_data ); - pthread_setspecific( ContextTSD, c ); -} - -__GLXcontext * __glXGetCurrentContext( void ) -{ - void * v; - - pthread_once( & once_control, init_thread_data ); - - v = pthread_getspecific( ContextTSD ); - return (v == NULL) ? & dummyContext : (__GLXcontext *) v; -} - -# endif /* defined( GLX_USE_TLS ) */ - -#elif defined( THREADS ) - -#error Unknown threading method specified. - -#else - -/* not thread safe */ -__GLXcontext *__glXcurrentContext = &dummyContext; - -#endif - - /* ** You can set this cell to 1 to force the gl drawing stuff to be ** one command per packet */ -int __glXDebug = 0; - -/* -** forward prototype declarations -*/ -int __glXCloseDisplay(Display *dpy, XExtCodes *codes); - - -/************************************************************************/ +_X_HIDDEN int __glXDebug = 0; /* Extension required boiler plate */ @@ -296,16 +102,13 @@ static /* const */ char *error_list[] = { "GLXBadWindow", }; -int __glXCloseDisplay(Display *dpy, XExtCodes *codes) +static int __glXCloseDisplay(Display *dpy, XExtCodes *codes) { GLXContext gc; gc = __glXGetCurrentContext(); if (dpy == gc->currentDpy) { - __glXSetCurrentContext(&dummyContext); -#ifdef GLX_DIRECT_RENDERING - _glapi_set_dispatch(NULL); /* no-op functions */ -#endif + __glXSetCurrentContextNull(); __glXFreeContext(gc); } @@ -360,11 +163,10 @@ static void FreeScreenConfigs(__GLXdisplayPrivate *priv) Xfree((char*) psc->serverGLXexts); #ifdef GLX_DIRECT_RENDERING - /* Free the direct rendering per screen data */ - if (psc->driScreen.private) - (*psc->driScreen.destroyScreen)(priv->dpy, i, - psc->driScreen.private); - psc->driScreen.private = NULL; + if (psc->driScreen) { + psc->driScreen->destroyScreen(psc); + __glxHashDestroy(psc->drawHash); + } #endif } XFree((char*) priv->screenConfigs); @@ -391,14 +193,12 @@ static int __glXFreeDisplayPrivate(XExtData *extension) #ifdef GLX_DIRECT_RENDERING /* Free the direct rendering per display data */ - if (priv->driDisplay.private) - (*priv->driDisplay.destroyDisplay)(priv->dpy, - priv->driDisplay.private); - priv->driDisplay.private = NULL; - if (priv->driDisplay.createNewScreen) { - Xfree(priv->driDisplay.createNewScreen); /* free array of ptrs */ - priv->driDisplay.createNewScreen = NULL; - } + if (priv->driDisplay) + (*priv->driDisplay->destroyDisplay)(priv->driDisplay); + priv->driDisplay = NULL; + if (priv->dri2Display) + (*priv->dri2Display->destroyDisplay)(priv->dri2Display); + priv->dri2Display = NULL; #endif Xfree((char*) priv); @@ -440,7 +240,7 @@ static Bool QueryVersion(Display *dpy, int opcode, int *major, int *minor) } -void +_X_HIDDEN void __glXInitializeVisualConfigFromTags( __GLcontextModes *config, int count, const INT32 *bp, Bool tagged_only, Bool fbconfig_style_tags ) @@ -634,371 +434,128 @@ __glXInitializeVisualConfigFromTags( __GLcontextModes *config, int count, config->haveStencilBuffer = (config->stencilBits > 0); } - -#ifdef GLX_DIRECT_RENDERING -static unsigned -filter_modes( __GLcontextModes ** server_modes, - const __GLcontextModes * driver_modes ) +static __GLcontextModes * +createConfigsFromProperties(Display *dpy, int nvisuals, int nprops, + int screen, GLboolean tagged_only) { - __GLcontextModes * m; - __GLcontextModes ** prev_next; - const __GLcontextModes * check; - unsigned modes_count = 0; - - if ( driver_modes == NULL ) { - fprintf(stderr, "libGL warning: 3D driver returned no fbconfigs.\n"); - return 0; - } - - /* For each mode in server_modes, check to see if a matching mode exists - * in driver_modes. If not, then the mode is not available. - */ + INT32 buf[__GLX_TOTAL_CONFIG], *props; + unsigned prop_size; + __GLcontextModes *modes, *m; + int i; - prev_next = server_modes; - for ( m = *prev_next ; m != NULL ; m = *prev_next ) { - GLboolean do_delete = GL_TRUE; + if (nprops == 0) + return NULL; - for ( check = driver_modes ; check != NULL ; check = check->next ) { - if ( _gl_context_modes_are_same( m, check ) ) { - do_delete = GL_FALSE; - break; - } - } + /* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for FBconfigs? */ - /* The 3D has to support all the modes that match the GLX visuals - * sent from the X server. - */ - if ( do_delete && (m->visualID != 0) ) { - do_delete = GL_FALSE; + /* Check number of properties */ + if (nprops < __GLX_MIN_CONFIG_PROPS || nprops > __GLX_MAX_CONFIG_PROPS) + return NULL; - if (getenv("LIBGL_DEBUG")) { - fprintf(stderr, "libGL warning: 3D driver claims to not support " - "visual 0x%02x\n", m->visualID); - } - } + /* Allocate memory for our config structure */ + modes = _gl_context_modes_create(nvisuals, sizeof(__GLcontextModes)); + if (!modes) + return NULL; - if ( do_delete ) { - *prev_next = m->next; + prop_size = nprops * __GLX_SIZE_INT32; + if (prop_size <= sizeof(buf)) + props = buf; + else + props = Xmalloc(prop_size); - m->next = NULL; - _gl_context_modes_destroy( m ); - } - else { - modes_count++; - prev_next = & m->next; - } + /* Read each config structure and convert it into our format */ + m = modes; + for (i = 0; i < nvisuals; i++) { + _XRead(dpy, (char *)props, prop_size); + /* Older X servers don't send this so we default it here. */ + m->drawableType = GLX_WINDOW_BIT; + __glXInitializeVisualConfigFromTags(m, nprops, props, + tagged_only, GL_TRUE); + m->screen = screen; + m = m->next; } - return modes_count; -} + if (props != buf) + Xfree(props); - -/** - * Implement \c __DRIinterfaceMethods::getProcAddress. - */ -static __DRIfuncPtr get_proc_address( const char * proc_name ) -{ - if (strcmp( proc_name, "glxEnableExtension" ) == 0) { - return (__DRIfuncPtr) __glXScrEnableExtension; - } - - return NULL; + return modes; } -#ifdef XDAMAGE_1_1_INTERFACE -static GLboolean has_damage_post(__DRInativeDisplay *dpy) +static GLboolean +getVisualConfigs(Display *dpy, __GLXdisplayPrivate *priv, int screen) { - static GLboolean inited = GL_FALSE; - static GLboolean has_damage; - - if (!inited) { - int major, minor; - - if (XDamageQueryVersion(dpy, &major, &minor) && - major == 1 && minor >= 1) - { - has_damage = GL_TRUE; - } else { - has_damage = GL_FALSE; - } - inited = GL_TRUE; - } + xGLXGetVisualConfigsReq *req; + __GLXscreenConfigs *psc; + xGLXGetVisualConfigsReply reply; + + LockDisplay(dpy); - return has_damage; -} -#endif /* XDAMAGE_1_1_INTERFACE */ + psc = priv->screenConfigs + screen; + psc->visuals = NULL; + GetReq(GLXGetVisualConfigs, req); + req->reqType = priv->majorOpcode; + req->glxCode = X_GLXGetVisualConfigs; + req->screen = screen; -static void __glXReportDamage(__DRInativeDisplay *dpy, int screen, - __DRIid drawable, - int x, int y, - drm_clip_rect_t *rects, int num_rects, - GLboolean front_buffer) -{ -#ifdef XDAMAGE_1_1_INTERFACE - XRectangle *xrects; - XserverRegion region; - int i; - int x_off, y_off; - - if (!has_damage_post(dpy)) - return; - - if (front_buffer) { - x_off = x; - y_off = y; - drawable = RootWindow(dpy, screen); - } else{ - x_off = 0; - y_off = 0; - } + if (!_XReply(dpy, (xReply*) &reply, 0, False)) + goto out; - xrects = malloc(sizeof(XRectangle) * num_rects); - if (xrects == NULL) - return; + psc->visuals = createConfigsFromProperties(dpy, + reply.numVisuals, + reply.numProps, + screen, GL_FALSE); - for (i = 0; i < num_rects; i++) { - xrects[i].x = rects[i].x1 + x_off; - xrects[i].y = rects[i].y1 + y_off; - xrects[i].width = rects[i].x2 - rects[i].x1; - xrects[i].height = rects[i].y2 - rects[i].y1; - } - region = XFixesCreateRegion(dpy, xrects, num_rects); - free(xrects); - XDamageAdd(dpy, drawable, region); - XFixesDestroyRegion(dpy, region); -#endif + out: + UnlockDisplay(dpy); + return psc->visuals != NULL; } -/** - * Table of functions exported by the loader to the driver. - */ -static const __DRIinterfaceMethods interface_methods = { - get_proc_address, - - _gl_context_modes_create, - _gl_context_modes_destroy, - - __glXFindDRIScreen, - __glXWindowExists, - - XF86DRICreateContextWithConfig, - XF86DRIDestroyContext, - - XF86DRICreateDrawable, - XF86DRIDestroyDrawable, - XF86DRIGetDrawableInfo, - - __glXGetUST, - __glXGetMscRateOML, - - __glXReportDamage, -}; - - - -/** - * Perform the required libGL-side initialization and call the client-side - * driver's \c __driCreateNewScreen function. - * - * \param dpy Display pointer. - * \param scrn Screen number on the display. - * \param psc DRI screen information. - * \param driDpy DRI display information. - * \param createNewScreen Pointer to the client-side driver's - * \c __driCreateNewScreen function. - * \returns A pointer to the \c __DRIscreenPrivate structure returned by - * the client-side driver on success, or \c NULL on failure. - * - * \todo This function needs to be modified to remove context-modes from the - * list stored in the \c __GLXscreenConfigsRec to match the list - * returned by the client-side driver. - */ -static void * -CallCreateNewScreen(Display *dpy, int scrn, __DRIscreen *psc, - __DRIdisplay * driDpy, - PFNCREATENEWSCREENFUNC createNewScreen) +static GLboolean +getFBConfigs(Display *dpy, __GLXdisplayPrivate *priv, int screen) { - __DRIscreenPrivate *psp = NULL; -#ifndef GLX_USE_APPLEGL - drm_handle_t hSAREA; - drmAddress pSAREA = MAP_FAILED; - char *BusID; - __DRIversion ddx_version; - __DRIversion dri_version; - __DRIversion drm_version; - __DRIframebuffer framebuffer; - int fd = -1; - int status; - const char * err_msg; - const char * err_extra; - int api_ver = __glXGetInternalVersion(); - - - dri_version.major = driDpy->private->driMajor; - dri_version.minor = driDpy->private->driMinor; - dri_version.patch = driDpy->private->driPatch; - - - err_msg = "XF86DRIOpenConnection"; - err_extra = NULL; - - framebuffer.base = MAP_FAILED; - framebuffer.dev_priv = NULL; - - if (XF86DRIOpenConnection(dpy, scrn, &hSAREA, &BusID)) { - int newlyopened; - fd = drmOpenOnce(NULL,BusID, &newlyopened); - Xfree(BusID); /* No longer needed */ - - err_msg = "open DRM"; - err_extra = strerror( -fd ); - - if (fd >= 0) { - drm_magic_t magic; - - err_msg = "drmGetMagic"; - err_extra = NULL; - - if (!drmGetMagic(fd, &magic)) { - drmVersionPtr version = drmGetVersion(fd); - if (version) { - drm_version.major = version->version_major; - drm_version.minor = version->version_minor; - drm_version.patch = version->version_patchlevel; - drmFreeVersion(version); - } - else { - drm_version.major = -1; - drm_version.minor = -1; - drm_version.patch = -1; - } - - err_msg = "XF86DRIAuthConnection"; - if (!newlyopened || XF86DRIAuthConnection(dpy, scrn, magic)) { - char *driverName; - - /* - * Get device name (like "tdfx") and the ddx version - * numbers. We'll check the version in each DRI driver's - * "createNewScreen" function. - */ - err_msg = "XF86DRIGetClientDriverName"; - if (XF86DRIGetClientDriverName(dpy, scrn, - &ddx_version.major, - &ddx_version.minor, - &ddx_version.patch, - &driverName)) { - drm_handle_t hFB; - int junk; - - /* No longer needed. */ - Xfree( driverName ); - - - /* - * Get device-specific info. pDevPriv will point to a struct - * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) - * that has information about the screen size, depth, pitch, - * ancilliary buffers, DRM mmap handles, etc. - */ - err_msg = "XF86DRIGetDeviceInfo"; - if (XF86DRIGetDeviceInfo(dpy, scrn, - &hFB, - &junk, - &framebuffer.size, - &framebuffer.stride, - &framebuffer.dev_priv_size, - &framebuffer.dev_priv)) { - framebuffer.width = DisplayWidth(dpy, scrn); - framebuffer.height = DisplayHeight(dpy, scrn); - - /* - * Map the framebuffer region. - */ - status = drmMap(fd, hFB, framebuffer.size, - (drmAddressPtr)&framebuffer.base); - - err_msg = "drmMap of framebuffer"; - err_extra = strerror( -status ); - - if ( status == 0 ) { - /* - * Map the SAREA region. Further mmap regions - * may be setup in each DRI driver's - * "createNewScreen" function. - */ - status = drmMap(fd, hSAREA, SAREA_MAX, - &pSAREA); - - err_msg = "drmMap of sarea"; - err_extra = strerror( -status ); - - if ( status == 0 ) { - __GLcontextModes * driver_modes = NULL; - __GLXscreenConfigs *configs = psc->screenConfigs; - - err_msg = "InitDriver"; - err_extra = NULL; - psp = (*createNewScreen)(dpy, scrn, - psc, - configs->configs, - & ddx_version, - & dri_version, - & drm_version, - & framebuffer, - pSAREA, - fd, - api_ver, - & interface_methods, - & driver_modes ); - - filter_modes( & configs->configs, - driver_modes ); - _gl_context_modes_destroy( driver_modes ); - } - } - } - } - } - } - } - } - - if ( psp == NULL ) { - if ( pSAREA != MAP_FAILED ) { - (void)drmUnmap(pSAREA, SAREA_MAX); - } - - if ( framebuffer.base != MAP_FAILED ) { - (void)drmUnmap((drmAddress)framebuffer.base, framebuffer.size); - } + xGLXGetFBConfigsReq *fb_req; + xGLXGetFBConfigsSGIXReq *sgi_req; + xGLXVendorPrivateWithReplyReq *vpreq; + xGLXGetFBConfigsReply reply; + __GLXscreenConfigs *psc; - if ( framebuffer.dev_priv != NULL ) { - Xfree(framebuffer.dev_priv); - } + psc = priv->screenConfigs + screen; + psc->serverGLXexts = __glXGetStringFromServer(dpy, priv->majorOpcode, + X_GLXQueryServerString, + screen, GLX_EXTENSIONS); - if ( fd >= 0 ) { - (void)drmCloseOnce(fd); - } + LockDisplay(dpy); - (void)XF86DRICloseConnection(dpy, scrn); + psc->configs = NULL; + if (atof(priv->serverGLXversion) >= 1.3) { + GetReq(GLXGetFBConfigs, fb_req); + fb_req->reqType = priv->majorOpcode; + fb_req->glxCode = X_GLXGetFBConfigs; + fb_req->screen = screen; + } else if (strstr(psc->serverGLXexts, "GLX_SGIX_fbconfig") != NULL) { + GetReqExtra(GLXVendorPrivateWithReply, + sz_xGLXGetFBConfigsSGIXReq + + sz_xGLXVendorPrivateWithReplyReq, vpreq); + sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq; + sgi_req->reqType = priv->majorOpcode; + sgi_req->glxCode = X_GLXVendorPrivateWithReply; + sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX; + sgi_req->screen = screen; + } else + goto out; - if ( err_extra != NULL ) { - fprintf(stderr, "libGL error: %s failed (%s)\n", err_msg, - err_extra); - } - else { - fprintf(stderr, "libGL error: %s failed\n", err_msg ); - } + if (!_XReply(dpy, (xReply*) &reply, 0, False)) + goto out; - fprintf(stderr, "libGL error: reverting to (slow) indirect rendering\n"); - } -#endif /* !GLX_USE_APPLEGL */ + psc->configs = createConfigsFromProperties(dpy, + reply.numFBConfigs, + reply.numAttribs * 2, + screen, GL_TRUE); - return psp; + out: + UnlockDisplay(dpy); + return psc->configs != NULL; } -#endif /* GLX_DIRECT_RENDERING */ - /* ** Allocate the memory for the per screen configs for each screen. @@ -1006,17 +563,8 @@ CallCreateNewScreen(Display *dpy, int scrn, __DRIscreen *psc, */ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv) { - xGLXGetVisualConfigsReq *req; - xGLXGetFBConfigsReq *fb_req; - xGLXVendorPrivateWithReplyReq *vpreq; - xGLXGetFBConfigsSGIXReq *sgi_req; - xGLXGetVisualConfigsReply reply; __GLXscreenConfigs *psc; - __GLcontextModes *config; - GLint i, j, nprops, screens; - INT32 buf[__GLX_TOTAL_CONFIG], *props; - unsigned supported_request = 0; - unsigned prop_size; + GLint i, screens; /* ** First allocate memory for the array of per screen configs. @@ -1030,159 +578,30 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv) priv->screenConfigs = psc; priv->serverGLXversion = __glXGetStringFromServer(dpy, priv->majorOpcode, - X_GLXQueryServerString, - 0, GLX_VERSION); + X_GLXQueryServerString, + 0, GLX_VERSION); if ( priv->serverGLXversion == NULL ) { FreeScreenConfigs(priv); return GL_FALSE; } - if ( atof( priv->serverGLXversion ) >= 1.3 ) { - supported_request = 1; - } - - /* - ** Now fetch each screens configs structures. If a screen supports - ** GL (by returning a numVisuals > 0) then allocate memory for our - ** config structure and then fill it in. - */ for (i = 0; i < screens; i++, psc++) { - if ( supported_request != 1 ) { - psc->serverGLXexts = __glXGetStringFromServer(dpy, priv->majorOpcode, - X_GLXQueryServerString, - i, GLX_EXTENSIONS); - if ( strstr( psc->serverGLXexts, "GLX_SGIX_fbconfig" ) != NULL ) { - supported_request = 2; - } - else { - supported_request = 3; - } - } - - - LockDisplay(dpy); - switch( supported_request ) { - case 1: - GetReq(GLXGetFBConfigs,fb_req); - fb_req->reqType = priv->majorOpcode; - fb_req->glxCode = X_GLXGetFBConfigs; - fb_req->screen = i; - break; - - case 2: - GetReqExtra(GLXVendorPrivateWithReply, - sz_xGLXGetFBConfigsSGIXReq-sz_xGLXVendorPrivateWithReplyReq,vpreq); - sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq; - sgi_req->reqType = priv->majorOpcode; - sgi_req->glxCode = X_GLXVendorPrivateWithReply; - sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX; - sgi_req->screen = i; - break; - - case 3: - GetReq(GLXGetVisualConfigs,req); - req->reqType = priv->majorOpcode; - req->glxCode = X_GLXGetVisualConfigs; - req->screen = i; - break; - } - - if (!_XReply(dpy, (xReply*) &reply, 0, False)) { - /* Something is busted. Punt. */ - UnlockDisplay(dpy); - SyncHandle(); - FreeScreenConfigs(priv); - return GL_FALSE; - } - - if (!reply.numVisuals) { - /* This screen does not support GL rendering */ - UnlockDisplay(dpy); - continue; - } - - /* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for - * FIXME: FBconfigs? - */ - /* Check number of properties */ - nprops = reply.numProps; - if ((nprops < __GLX_MIN_CONFIG_PROPS) || - (nprops > __GLX_MAX_CONFIG_PROPS)) { - /* Huh? Not in protocol defined limits. Punt */ - UnlockDisplay(dpy); - SyncHandle(); - FreeScreenConfigs(priv); - return GL_FALSE; - } - - /* Allocate memory for our config structure */ - psc->configs = _gl_context_modes_create(reply.numVisuals, - sizeof(__GLcontextModes)); - if (!psc->configs) { - UnlockDisplay(dpy); - SyncHandle(); - FreeScreenConfigs(priv); - return GL_FALSE; - } - - /* Allocate memory for the properties, if needed */ - if ( supported_request != 3 ) { - nprops *= 2; - } - - prop_size = nprops * __GLX_SIZE_INT32; - - if (prop_size <= sizeof(buf)) { - props = buf; - } else { - props = (INT32 *) Xmalloc(prop_size); - } - - /* Read each config structure and convert it into our format */ - config = psc->configs; - for (j = 0; j < reply.numVisuals; j++) { - assert( config != NULL ); - _XRead(dpy, (char *)props, prop_size); - - if ( supported_request != 3 ) { - config->rgbMode = GL_TRUE; - config->drawableType = GLX_WINDOW_BIT; - } - else { - config->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT; - } - - __glXInitializeVisualConfigFromTags( config, nprops, props, - (supported_request != 3), - GL_TRUE ); - if ( config->fbconfigID == GLX_DONT_CARE ) { - config->fbconfigID = config->visualID; - } - config->screen = i; - config = config->next; - } - if (props != buf) { - Xfree((char *)props); - } - UnlockDisplay(dpy); + getVisualConfigs(dpy, priv, i); + getFBConfigs(dpy, priv, i); + psc->scr = i; + psc->dpy = dpy; #ifdef GLX_DIRECT_RENDERING - /* Initialize per screen dynamic client GLX extensions */ - psc->ext_list_first_time = GL_TRUE; - /* Initialize the direct rendering per screen data and functions */ - if (priv->driDisplay.private != NULL) { - /* FIXME: Should it be some sort of an error if createNewScreen[i] - * FIXME: is NULL? - */ - if (priv->driDisplay.createNewScreen && - priv->driDisplay.createNewScreen[i]) { - - psc->driScreen.screenConfigs = (void *)psc; - psc->driScreen.private = - CallCreateNewScreen(dpy, i, & psc->driScreen, - & priv->driDisplay, - priv->driDisplay.createNewScreen[i] ); - } + psc->drawHash = __glxHashCreate(); + if (psc->drawHash == NULL) + continue; + if (priv->dri2Display) + psc->driScreen = (*priv->dri2Display->createScreen)(psc, i, priv); + if (psc->driScreen == NULL && priv->driDisplay) + psc->driScreen = (*priv->driDisplay->createScreen)(psc, i, priv); + if (psc->driScreen == NULL) { + __glxHashDestroy(psc->drawHash); + psc->drawHash = NULL; } #endif } @@ -1193,7 +612,7 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv) /* ** Initialize the client side extension code. */ -__GLXdisplayPrivate *__glXInitialize(Display* dpy) +_X_HIDDEN __GLXdisplayPrivate *__glXInitialize(Display* dpy) { XExtDisplayInfo *info = __glXFindDisplay(dpy); XExtData **privList, *private, *found; @@ -1273,8 +692,8 @@ __GLXdisplayPrivate *__glXInitialize(Display* dpy) ** (e.g., those called in AllocAndFetchScreenConfigs). */ if (getenv("LIBGL_ALWAYS_INDIRECT") == NULL) { - dpyPriv->driDisplay.private = - driCreateDisplay(dpy, &dpyPriv->driDisplay); + dpyPriv->dri2Display = dri2CreateDisplay(dpy); + dpyPriv->driDisplay = driCreateDisplay(dpy); } #endif @@ -1308,7 +727,7 @@ __GLXdisplayPrivate *__glXInitialize(Display* dpy) ** Setup for sending a GLX command on dpy. Make sure the extension is ** initialized. Try to avoid calling __glXInitialize as its kinda slow. */ -CARD8 __glXSetupForCommand(Display *dpy) +_X_HIDDEN CARD8 __glXSetupForCommand(Display *dpy) { GLXContext gc; __GLXdisplayPrivate *priv; @@ -1349,7 +768,7 @@ CARD8 __glXSetupForCommand(Display *dpy) * Modify this function to use \c ctx->pc instead of the explicit * \c pc parameter. */ -GLubyte *__glXFlushRenderBuffer(__GLXcontext *ctx, GLubyte *pc) +_X_HIDDEN GLubyte *__glXFlushRenderBuffer(__GLXcontext *ctx, GLubyte *pc) { Display * const dpy = ctx->currentDpy; #ifdef USE_XCB @@ -1361,7 +780,8 @@ GLubyte *__glXFlushRenderBuffer(__GLXcontext *ctx, GLubyte *pc) if ( (dpy != NULL) && (size > 0) ) { #ifdef USE_XCB - xcb_glx_render(c, ctx->currentContextTag, size, (char *)ctx->buf); + xcb_glx_render(c, ctx->currentContextTag, size, + (const uint8_t *)ctx->buf); #else /* Send the entire buffer as an X request */ LockDisplay(dpy); @@ -1398,9 +818,9 @@ GLubyte *__glXFlushRenderBuffer(__GLXcontext *ctx, GLubyte *pc) * \param data Command data. * \param dataLen Size, in bytes, of the command data. */ -void __glXSendLargeChunk(__GLXcontext *gc, GLint requestNumber, - GLint totalRequests, - const GLvoid * data, GLint dataLen) +_X_HIDDEN void __glXSendLargeChunk(__GLXcontext *gc, GLint requestNumber, + GLint totalRequests, + const GLvoid * data, GLint dataLen) { Display *dpy = gc->currentDpy; #ifdef USE_XCB @@ -1446,9 +866,9 @@ void __glXSendLargeChunk(__GLXcontext *gc, GLint requestNumber, * \param data Command data. * \param dataLen Size, in bytes, of the command data. */ -void __glXSendLargeCommand(__GLXcontext *ctx, - const GLvoid *header, GLint headerLen, - const GLvoid *data, GLint dataLen) +_X_HIDDEN void __glXSendLargeCommand(__GLXcontext *ctx, + const GLvoid *header, GLint headerLen, + const GLvoid *data, GLint dataLen) { GLint maxSize; GLint totalRequests, requestNumber; @@ -1484,330 +904,8 @@ void __glXSendLargeCommand(__GLXcontext *ctx, /************************************************************************/ -PUBLIC GLXContext glXGetCurrentContext(void) -{ - GLXContext cx = __glXGetCurrentContext(); - - if (cx == &dummyContext) { - return NULL; - } else { - return cx; - } -} - -PUBLIC GLXDrawable glXGetCurrentDrawable(void) -{ - GLXContext gc = __glXGetCurrentContext(); - return gc->currentDrawable; -} - - -/************************************************************************/ - -#ifdef GLX_DIRECT_RENDERING -/* Return the DRI per screen structure */ -__DRIscreen *__glXFindDRIScreen(__DRInativeDisplay *dpy, int scrn) -{ - __DRIscreen *pDRIScreen = NULL; - XExtDisplayInfo *info = __glXFindDisplay(dpy); - XExtData **privList, *found; - __GLXdisplayPrivate *dpyPriv; - XEDataObject dataObj; - - __glXLock(); - dataObj.display = dpy; - privList = XEHeadOfExtensionList(dataObj); - found = XFindOnExtensionList(privList, info->codes->extension); - __glXUnlock(); - - if (found) { - dpyPriv = (__GLXdisplayPrivate *)found->private_data; - pDRIScreen = &dpyPriv->screenConfigs[scrn].driScreen; - } - - return pDRIScreen; -} -#endif - -/************************************************************************/ - -static Bool SendMakeCurrentRequest( Display *dpy, CARD8 opcode, - GLXContextID gc, GLXContextTag old_gc, GLXDrawable draw, GLXDrawable read, - xGLXMakeCurrentReply * reply ); - -/** - * Sends a GLX protocol message to the specified display to make the context - * and the drawables current. - * - * \param dpy Display to send the message to. - * \param opcode Major opcode value for the display. - * \param gc_id Context tag for the context to be made current. - * \param draw Drawable ID for the "draw" drawable. - * \param read Drawable ID for the "read" drawable. - * \param reply Space to store the X-server's reply. - * - * \warning - * This function assumes that \c dpy is locked with \c LockDisplay on entry. - */ -static Bool SendMakeCurrentRequest(Display *dpy, CARD8 opcode, - GLXContextID gc_id, GLXContextTag gc_tag, - GLXDrawable draw, GLXDrawable read, - xGLXMakeCurrentReply *reply) -{ - Bool ret; - - - LockDisplay(dpy); - - if (draw == read) { - xGLXMakeCurrentReq *req; - - GetReq(GLXMakeCurrent,req); - req->reqType = opcode; - req->glxCode = X_GLXMakeCurrent; - req->drawable = draw; - req->context = gc_id; - req->oldContextTag = gc_tag; - } - else { - __GLXdisplayPrivate *priv = __glXInitialize(dpy); - - /* If the server can support the GLX 1.3 version, we should - * perfer that. Not only that, some servers support GLX 1.3 but - * not the SGI extension. - */ - - if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) { - xGLXMakeContextCurrentReq *req; - - GetReq(GLXMakeContextCurrent,req); - req->reqType = opcode; - req->glxCode = X_GLXMakeContextCurrent; - req->drawable = draw; - req->readdrawable = read; - req->context = gc_id; - req->oldContextTag = gc_tag; - } - else { - xGLXVendorPrivateWithReplyReq *vpreq; - xGLXMakeCurrentReadSGIReq *req; - - GetReqExtra(GLXVendorPrivateWithReply, - sz_xGLXMakeCurrentReadSGIReq-sz_xGLXVendorPrivateWithReplyReq,vpreq); - req = (xGLXMakeCurrentReadSGIReq *)vpreq; - req->reqType = opcode; - req->glxCode = X_GLXVendorPrivateWithReply; - req->vendorCode = X_GLXvop_MakeCurrentReadSGI; - req->drawable = draw; - req->readable = read; - req->context = gc_id; - req->oldContextTag = gc_tag; - } - } - - ret = _XReply(dpy, (xReply*) reply, 0, False); - - UnlockDisplay(dpy); - SyncHandle(); - - return ret; -} - - -#ifdef GLX_DIRECT_RENDERING -static Bool BindContextWrapper( Display *dpy, GLXContext gc, - GLXDrawable draw, GLXDrawable read ) -{ - return (*gc->driContext.bindContext)(dpy, gc->screen, draw, read, - & gc->driContext); -} - - -static Bool UnbindContextWrapper( GLXContext gc ) -{ - return (*gc->driContext.unbindContext)(gc->currentDpy, gc->screen, - gc->currentDrawable, - gc->currentReadable, - & gc->driContext ); -} -#endif /* GLX_DIRECT_RENDERING */ - - -/** - * Make a particular context current. - * - * \note This is in this file so that it can access dummyContext. - */ -USED static Bool MakeContextCurrent(Display *dpy, GLXDrawable draw, - GLXDrawable read, GLXContext gc) -{ - xGLXMakeCurrentReply reply; - const GLXContext oldGC = __glXGetCurrentContext(); - const CARD8 opcode = __glXSetupForCommand(dpy); - const CARD8 oldOpcode = ((gc == oldGC) || (oldGC == &dummyContext)) - ? opcode : __glXSetupForCommand(oldGC->currentDpy); - Bool bindReturnValue; - - - if (!opcode || !oldOpcode) { - return GL_FALSE; - } - - /* Make sure that the new context has a nonzero ID. In the request, - * a zero context ID is used only to mean that we bind to no current - * context. - */ - if ((gc != NULL) && (gc->xid == None)) { - return GL_FALSE; - } - -#ifndef GLX_DIRECT_RENDERING - if (gc && gc->isDirect) { - return GL_FALSE; - } -#endif - - _glapi_check_multithread(); - -#ifdef GLX_DIRECT_RENDERING - /* Bind the direct rendering context to the drawable */ - if (gc && gc->isDirect) { - bindReturnValue = (gc->driContext.private) - ? BindContextWrapper(dpy, gc, draw, read) - : False; - } else -#endif - { - /* Send a glXMakeCurrent request to bind the new context. */ - bindReturnValue = - SendMakeCurrentRequest(dpy, opcode, gc ? gc->xid : None, - ((dpy != oldGC->currentDpy) || oldGC->isDirect) - ? None : oldGC->currentContextTag, - draw, read, &reply); - } - - - if (!bindReturnValue) { - return False; - } - - if ((dpy != oldGC->currentDpy || (gc && gc->isDirect)) && - !oldGC->isDirect && oldGC != &dummyContext) { - xGLXMakeCurrentReply dummy_reply; - - /* We are either switching from one dpy to another and have to - * send a request to the previous dpy to unbind the previous - * context, or we are switching away from a indirect context to - * a direct context and have to send a request to the dpy to - * unbind the previous context. - */ - (void) SendMakeCurrentRequest(oldGC->currentDpy, oldOpcode, None, - oldGC->currentContextTag, None, None, - & dummy_reply); - } -#ifdef GLX_DIRECT_RENDERING - else if (oldGC->isDirect && oldGC->driContext.private) { - (void) UnbindContextWrapper(oldGC); - } -#endif - - - /* Update our notion of what is current */ - __glXLock(); - if (gc == oldGC) { - /* Even though the contexts are the same the drawable might have - * changed. Note that gc cannot be the dummy, and that oldGC - * cannot be NULL, therefore if they are the same, gc is not - * NULL and not the dummy. - */ - gc->currentDrawable = draw; - gc->currentReadable = read; - } else { - if (oldGC != &dummyContext) { - /* Old current context is no longer current to anybody */ - oldGC->currentDpy = 0; - oldGC->currentDrawable = None; - oldGC->currentReadable = None; - oldGC->currentContextTag = 0; - - if (oldGC->xid == None) { - /* We are switching away from a context that was - * previously destroyed, so we need to free the memory - * for the old handle. - */ -#ifdef GLX_DIRECT_RENDERING - /* Destroy the old direct rendering context */ - if (oldGC->isDirect) { - if (oldGC->driContext.private) { - (*oldGC->driContext.destroyContext) - (dpy, oldGC->screen, oldGC->driContext.private); - oldGC->driContext.private = NULL; - } - } -#endif - __glXFreeContext(oldGC); - } - } - if (gc) { - __glXSetCurrentContext(gc); - - gc->currentDpy = dpy; - gc->currentDrawable = draw; - gc->currentReadable = read; - - if (!gc->isDirect) { - if (!IndirectAPI) - IndirectAPI = __glXNewIndirectAPI(); - _glapi_set_dispatch(IndirectAPI); - -#ifdef GLX_USE_APPLEGL - do { - extern void XAppleDRIUseIndirectDispatch(void); - XAppleDRIUseIndirectDispatch(); - } while (0); -#endif - - __GLXattribute *state = - (__GLXattribute *)(gc->client_state_private); - - gc->currentContextTag = reply.contextTag; - if (state->array_state == NULL) { - (void) glGetString(GL_EXTENSIONS); - (void) glGetString(GL_VERSION); - __glXInitVertexArrayState(gc); - } - } - else { - gc->currentContextTag = -1; - } - } else { - __glXSetCurrentContext(&dummyContext); -#ifdef GLX_DIRECT_RENDERING - _glapi_set_dispatch(NULL); /* no-op functions */ -#endif - } - } - __glXUnlock(); - return GL_TRUE; -} - - -PUBLIC Bool glXMakeCurrent(Display *dpy, GLXDrawable draw, GLXContext gc) -{ - return MakeContextCurrent( dpy, draw, draw, gc ); -} - -PUBLIC GLX_ALIAS(Bool, glXMakeCurrentReadSGI, - (Display *dpy, GLXDrawable d, GLXDrawable r, GLXContext ctx), - (dpy, d, r, ctx), MakeContextCurrent) - -PUBLIC GLX_ALIAS(Bool, glXMakeContextCurrent, - (Display *dpy, GLXDrawable d, GLXDrawable r, GLXContext ctx), - (dpy, d, r, ctx), MakeContextCurrent) - - #ifdef DEBUG -void __glXDumpDrawBuffer(__GLXcontext *ctx) +_X_HIDDEN void __glXDumpDrawBuffer(__GLXcontext *ctx) { GLubyte *p = ctx->buf; GLubyte *end = ctx->pc; @@ -1832,9 +930,23 @@ void __glXDumpDrawBuffer(__GLXcontext *ctx) #ifdef USE_SPARC_ASM /* - * Used only when we are sparc, using sparc assembler. + * This is where our dispatch table's bounds are. + * And the static mesa_init is taken directly from + * Mesa's 'sparc.c' initializer. * + * We need something like this here, because this version + * of openGL/glx never initializes a Mesa context, and so + * the address of the dispatch table pointer never gets stuffed + * into the dispatch jump table otherwise. + * + * It matters only on SPARC, and only if you are using assembler + * code instead of C-code indirect dispatch. + * + * -- FEM, 04.xii.03 */ +extern unsigned int _mesa_sparc_glapi_begin; +extern unsigned int _mesa_sparc_glapi_end; +extern void __glapi_sparc_icache_flush(unsigned int *); static void _glx_mesa_init_sparc_glapi_relocs(void) diff --git a/src/glx/x11/glxextensions.c b/src/glx/x11/glxextensions.c index 1d99b61db08..e8437184722 100644 --- a/src/glx/x11/glxextensions.c +++ b/src/glx/x11/glxextensions.c @@ -356,28 +356,15 @@ __glXProcessServerString( const struct extension_info * ext, } } - -/** - * Enable a named GLX extension on a given screen. - * Drivers should not call this function directly. They should instead use - * \c glXGetProcAddress to obtain a pointer to the function. - * - * \param psc Pointer to GLX per-screen record. - * \param name Name of the extension to enable. - * - * \sa glXGetProcAddress - * - * \since Internal API version 20030813. - */ void -__glXScrEnableExtension( __GLXscreenConfigs *psc, const char * name ) +__glXEnableDirectExtension(__GLXscreenConfigs *psc, const char *name) { - __glXExtensionsCtr(); - __glXExtensionsCtrScreen(psc); - set_glx_extension( known_glx_extensions, name, strlen( name ), GL_TRUE, - psc->direct_support ); -} + __glXExtensionsCtr(); + __glXExtensionsCtrScreen(psc); + set_glx_extension(known_glx_extensions, + name, strlen(name), GL_TRUE, psc->direct_support); +} /** * Initialize global extension support tables. diff --git a/src/glx/x11/glxextensions.h b/src/glx/x11/glxextensions.h index a4241b6b7f9..9cdd05ed761 100644 --- a/src/glx/x11/glxextensions.h +++ b/src/glx/x11/glxextensions.h @@ -234,7 +234,7 @@ extern GLboolean __glXExtensionBitIsEnabled( struct __GLXscreenConfigsRec *psc, extern const char * __glXGetClientExtensions( void ); extern void __glXCalculateUsableExtensions( struct __GLXscreenConfigsRec *psc, GLboolean display_is_direct_capable, int server_minor_version ); -extern void __glXScrEnableExtension( struct __GLXscreenConfigsRec *psc, const char * name ); + extern void __glXCalculateUsableGLExtensions( struct __GLXcontextRec * gc, const char * server_string, int major_version, int minor_version ); extern void __glXGetGLVersion( int * major_version, int * minor_version ); @@ -243,6 +243,8 @@ extern char * __glXGetClientGLExtensionString( void ); extern GLboolean __glExtensionBitIsEnabled( const struct __GLXcontextRec * gc, unsigned bit ); +extern void +__glXEnableDirectExtension(__GLXscreenConfigs *psc, const char *name); /* Source-level backwards compatibility with old drivers. They won't * find the respective functions, though. diff --git a/src/glx/x11/indirect.c b/src/glx/x11/indirect.c index fbb2a91956c..871adddb953 100644 --- a/src/glx/x11/indirect.c +++ b/src/glx/x11/indirect.c @@ -300,7 +300,9 @@ __indirect_glNewList(GLuint list, GLenum mode) { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 8; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -324,7 +326,9 @@ __indirect_glEndList(void) { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 0; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -360,6 +364,10 @@ __indirect_glCallLists(GLsizei n, GLenum type, const GLvoid * lists) __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint compsize = __glCallLists_size(type); const GLuint cmdlen = 12 + __GLX_PAD((compsize * n)); + if (n < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect((n >= 0) && (gc->currentDpy != NULL), 1)) { if (cmdlen <= gc->maxSmallRenderCommandSize) { if ((gc->pc + cmdlen) > gc->bufEnd) { @@ -393,7 +401,9 @@ __indirect_glDeleteLists(GLuint list, GLsizei range) { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 8; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -418,7 +428,9 @@ __indirect_glGenLists(GLsizei range) __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; GLuint retval = (GLuint) 0; +#ifndef USE_XCB const GLuint cmdlen = 4; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -3582,6 +3594,10 @@ __indirect_glPixelMapfv(GLenum map, GLsizei mapsize, const GLfloat * values) { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12 + __GLX_PAD((mapsize * 4)); + if (mapsize < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect((mapsize >= 0) && (gc->currentDpy != NULL), 1)) { if (cmdlen <= gc->maxSmallRenderCommandSize) { if ((gc->pc + cmdlen) > gc->bufEnd) { @@ -3615,6 +3631,10 @@ __indirect_glPixelMapuiv(GLenum map, GLsizei mapsize, const GLuint * values) { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12 + __GLX_PAD((mapsize * 4)); + if (mapsize < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect((mapsize >= 0) && (gc->currentDpy != NULL), 1)) { if (cmdlen <= gc->maxSmallRenderCommandSize) { if ((gc->pc + cmdlen) > gc->bufEnd) { @@ -3648,6 +3668,10 @@ __indirect_glPixelMapusv(GLenum map, GLsizei mapsize, const GLushort * values) { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12 + __GLX_PAD((mapsize * 2)); + if (mapsize < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect((mapsize >= 0) && (gc->currentDpy != NULL), 1)) { if (cmdlen <= gc->maxSmallRenderCommandSize) { if ((gc->pc + cmdlen) > gc->bufEnd) { @@ -3716,7 +3740,9 @@ __indirect_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, __GLXcontext *const gc = __glXGetCurrentContext(); const __GLXattribute *const state = gc->client_state_private; Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 28; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -3808,7 +3834,9 @@ __indirect_glGetClipPlane(GLenum plane, GLdouble * equation) { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 4; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -3841,7 +3869,9 @@ __indirect_glGetLightfv(GLenum light, GLenum pname, GLfloat * params) { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 8; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -3879,7 +3909,9 @@ __indirect_glGetLightiv(GLenum light, GLenum pname, GLint * params) { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 8; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -3917,7 +3949,9 @@ __indirect_glGetMapdv(GLenum target, GLenum query, GLdouble * v) { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 8; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -3953,7 +3987,9 @@ __indirect_glGetMapfv(GLenum target, GLenum query, GLfloat * v) { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 8; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -3989,7 +4025,9 @@ __indirect_glGetMapiv(GLenum target, GLenum query, GLint * v) { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 8; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -4025,7 +4063,9 @@ __indirect_glGetMaterialfv(GLenum face, GLenum pname, GLfloat * params) { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 8; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -4063,7 +4103,9 @@ __indirect_glGetMaterialiv(GLenum face, GLenum pname, GLint * params) { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 8; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -4101,7 +4143,9 @@ __indirect_glGetPixelMapfv(GLenum map, GLfloat * values) { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 4; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -4137,7 +4181,9 @@ __indirect_glGetPixelMapuiv(GLenum map, GLuint * values) { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 4; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -4174,7 +4220,9 @@ __indirect_glGetPixelMapusv(GLenum map, GLushort * values) { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 4; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -4210,9 +4258,10 @@ void __indirect_glGetPolygonStipple(GLubyte *mask) { __GLXcontext *const gc = __glXGetCurrentContext(); - const __GLXattribute *const state = gc->client_state_private; Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 4; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -4247,7 +4296,9 @@ __indirect_glGetTexEnvfv(GLenum target, GLenum pname, GLfloat * params) { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 8; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -4285,7 +4336,9 @@ __indirect_glGetTexEnviv(GLenum target, GLenum pname, GLint * params) { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 8; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -4323,7 +4376,9 @@ __indirect_glGetTexGendv(GLenum coord, GLenum pname, GLdouble * params) { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 8; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -4361,7 +4416,9 @@ __indirect_glGetTexGenfv(GLenum coord, GLenum pname, GLfloat * params) { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 8; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -4399,7 +4456,9 @@ __indirect_glGetTexGeniv(GLenum coord, GLenum pname, GLint * params) { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 8; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -4439,7 +4498,9 @@ __indirect_glGetTexImage(GLenum target, GLint level, GLenum format, __GLXcontext *const gc = __glXGetCurrentContext(); const __GLXattribute *const state = gc->client_state_private; Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 20; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -4483,7 +4544,9 @@ __indirect_glGetTexParameterfv(GLenum target, GLenum pname, GLfloat * params) { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 8; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -4522,7 +4585,9 @@ __indirect_glGetTexParameteriv(GLenum target, GLenum pname, GLint * params) { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 8; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -4562,7 +4627,9 @@ __indirect_glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 12; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -4603,7 +4670,9 @@ __indirect_glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 12; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -4644,7 +4713,9 @@ __indirect_glIsList(GLuint list) __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; GLboolean retval = (GLboolean) 0; +#ifndef USE_XCB const GLuint cmdlen = 4; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -5012,7 +5083,13 @@ __indirect_glAreTexturesResident(GLsizei n, const GLuint * textures, __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; GLboolean retval = (GLboolean) 0; +#ifndef USE_XCB const GLuint cmdlen = 4 + __GLX_PAD((n * 4)); +#endif + if (n < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return 0; + } if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -5047,7 +5124,7 @@ glAreTexturesResidentEXT(GLsizei n, const GLuint * textures, { __GLXcontext *const gc = __glXGetCurrentContext(); - if (gc->isDirect) { + if (gc->driContext) { return CALL_AreTexturesResident(GET_DISPATCH(), (n, textures, residences)); } else { @@ -5055,6 +5132,10 @@ glAreTexturesResidentEXT(GLsizei n, const GLuint * textures, Display *const dpy = gc->currentDpy; GLboolean retval = (GLboolean) 0; const GLuint cmdlen = 4 + __GLX_PAD((n * 4)); + if (n < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return 0; + } if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) { GLubyte const *pc = __glXSetupVendorRequest(gc, X_GLXVendorPrivateWithReply, @@ -5163,7 +5244,13 @@ __indirect_glDeleteTextures(GLsizei n, const GLuint * textures) { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 4 + __GLX_PAD((n * 4)); +#endif + if (n < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -5187,12 +5274,16 @@ glDeleteTexturesEXT(GLsizei n, const GLuint * textures) { __GLXcontext *const gc = __glXGetCurrentContext(); - if (gc->isDirect) { + if (gc->driContext) { CALL_DeleteTextures(GET_DISPATCH(), (n, textures)); } else { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 4 + __GLX_PAD((n * 4)); + if (n < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) { GLubyte const *pc = __glXSetupVendorRequest(gc, X_GLXVendorPrivate, @@ -5212,7 +5303,13 @@ __indirect_glGenTextures(GLsizei n, GLuint * textures) { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 4; +#endif + if (n < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -5245,12 +5342,16 @@ glGenTexturesEXT(GLsizei n, GLuint * textures) { __GLXcontext *const gc = __glXGetCurrentContext(); - if (gc->isDirect) { + if (gc->driContext) { CALL_GenTextures(GET_DISPATCH(), (n, textures)); } else { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 4; + if (n < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) { GLubyte const *pc = __glXSetupVendorRequest(gc, X_GLXVendorPrivateWithReply, @@ -5271,7 +5372,9 @@ __indirect_glIsTexture(GLuint texture) __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; GLboolean retval = (GLboolean) 0; +#ifndef USE_XCB const GLuint cmdlen = 4; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -5301,7 +5404,7 @@ glIsTextureEXT(GLuint texture) { __GLXcontext *const gc = __glXGetCurrentContext(); - if (gc->isDirect) { + if (gc->driContext) { return CALL_IsTexture(GET_DISPATCH(), (texture)); } else { __GLXcontext *const gc = __glXGetCurrentContext(); @@ -5328,6 +5431,10 @@ __indirect_glPrioritizeTextures(GLsizei n, const GLuint * textures, { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8 + __GLX_PAD((n * 4)) + __GLX_PAD((n * 4)); + if (n < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect(n >= 0, 1)) { emit_header(gc->pc, X_GLrop_PrioritizeTextures, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&n), 4); @@ -5565,7 +5672,9 @@ __indirect_glGetColorTable(GLenum target, GLenum format, GLenum type, __GLXcontext *const gc = __glXGetCurrentContext(); const __GLXattribute *const state = gc->client_state_private; Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 16; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -5609,7 +5718,7 @@ glGetColorTableEXT(GLenum target, GLenum format, GLenum type, GLvoid * table) { __GLXcontext *const gc = __glXGetCurrentContext(); - if (gc->isDirect) { + if (gc->driContext) { CALL_GetColorTable(GET_DISPATCH(), (target, format, type, table)); } else { __GLXcontext *const gc = __glXGetCurrentContext(); @@ -5641,7 +5750,9 @@ __indirect_glGetColorTableParameterfv(GLenum target, GLenum pname, { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 8; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -5680,7 +5791,7 @@ glGetColorTableParameterfvEXT(GLenum target, GLenum pname, GLfloat * params) { __GLXcontext *const gc = __glXGetCurrentContext(); - if (gc->isDirect) { + if (gc->driContext) { CALL_GetColorTableParameterfv(GET_DISPATCH(), (target, pname, params)); } else { @@ -5709,7 +5820,9 @@ __indirect_glGetColorTableParameteriv(GLenum target, GLenum pname, { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 8; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -5748,7 +5861,7 @@ glGetColorTableParameterivEXT(GLenum target, GLenum pname, GLint * params) { __GLXcontext *const gc = __glXGetCurrentContext(); - if (gc->isDirect) { + if (gc->driContext) { CALL_GetColorTableParameteriv(GET_DISPATCH(), (target, pname, params)); } else { @@ -6029,7 +6142,9 @@ __indirect_glGetConvolutionFilter(GLenum target, GLenum format, GLenum type, __GLXcontext *const gc = __glXGetCurrentContext(); const __GLXattribute *const state = gc->client_state_private; Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 16; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -6069,7 +6184,7 @@ gl_dispatch_stub_356(GLenum target, GLenum format, GLenum type, { __GLXcontext *const gc = __glXGetCurrentContext(); - if (gc->isDirect) { + if (gc->driContext) { CALL_GetConvolutionFilter(GET_DISPATCH(), (target, format, type, image)); } else { @@ -6103,7 +6218,9 @@ __indirect_glGetConvolutionParameterfv(GLenum target, GLenum pname, { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 8; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -6142,7 +6259,7 @@ gl_dispatch_stub_357(GLenum target, GLenum pname, GLfloat * params) { __GLXcontext *const gc = __glXGetCurrentContext(); - if (gc->isDirect) { + if (gc->driContext) { CALL_GetConvolutionParameterfv(GET_DISPATCH(), (target, pname, params)); } else { @@ -6171,7 +6288,9 @@ __indirect_glGetConvolutionParameteriv(GLenum target, GLenum pname, { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 8; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -6210,7 +6329,7 @@ gl_dispatch_stub_358(GLenum target, GLenum pname, GLint * params) { __GLXcontext *const gc = __glXGetCurrentContext(); - if (gc->isDirect) { + if (gc->driContext) { CALL_GetConvolutionParameteriv(GET_DISPATCH(), (target, pname, params)); } else { @@ -6240,7 +6359,9 @@ __indirect_glGetHistogram(GLenum target, GLboolean reset, GLenum format, __GLXcontext *const gc = __glXGetCurrentContext(); const __GLXattribute *const state = gc->client_state_private; Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 16; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -6285,7 +6406,7 @@ gl_dispatch_stub_361(GLenum target, GLboolean reset, GLenum format, { __GLXcontext *const gc = __glXGetCurrentContext(); - if (gc->isDirect) { + if (gc->driContext) { CALL_GetHistogram(GET_DISPATCH(), (target, reset, format, type, values)); } else { @@ -6319,7 +6440,9 @@ __indirect_glGetHistogramParameterfv(GLenum target, GLenum pname, { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 8; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -6357,7 +6480,7 @@ gl_dispatch_stub_362(GLenum target, GLenum pname, GLfloat * params) { __GLXcontext *const gc = __glXGetCurrentContext(); - if (gc->isDirect) { + if (gc->driContext) { CALL_GetHistogramParameterfv(GET_DISPATCH(), (target, pname, params)); } else { __GLXcontext *const gc = __glXGetCurrentContext(); @@ -6385,7 +6508,9 @@ __indirect_glGetHistogramParameteriv(GLenum target, GLenum pname, { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 8; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -6423,7 +6548,7 @@ gl_dispatch_stub_363(GLenum target, GLenum pname, GLint * params) { __GLXcontext *const gc = __glXGetCurrentContext(); - if (gc->isDirect) { + if (gc->driContext) { CALL_GetHistogramParameteriv(GET_DISPATCH(), (target, pname, params)); } else { __GLXcontext *const gc = __glXGetCurrentContext(); @@ -6452,7 +6577,9 @@ __indirect_glGetMinmax(GLenum target, GLboolean reset, GLenum format, __GLXcontext *const gc = __glXGetCurrentContext(); const __GLXattribute *const state = gc->client_state_private; Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 16; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -6493,7 +6620,7 @@ gl_dispatch_stub_364(GLenum target, GLboolean reset, GLenum format, { __GLXcontext *const gc = __glXGetCurrentContext(); - if (gc->isDirect) { + if (gc->driContext) { CALL_GetMinmax(GET_DISPATCH(), (target, reset, format, type, values)); } else { __GLXcontext *const gc = __glXGetCurrentContext(); @@ -6526,7 +6653,9 @@ __indirect_glGetMinmaxParameterfv(GLenum target, GLenum pname, { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 8; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -6562,7 +6691,7 @@ gl_dispatch_stub_365(GLenum target, GLenum pname, GLfloat * params) { __GLXcontext *const gc = __glXGetCurrentContext(); - if (gc->isDirect) { + if (gc->driContext) { CALL_GetMinmaxParameterfv(GET_DISPATCH(), (target, pname, params)); } else { __GLXcontext *const gc = __glXGetCurrentContext(); @@ -6589,7 +6718,9 @@ __indirect_glGetMinmaxParameteriv(GLenum target, GLenum pname, GLint * params) { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 8; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -6625,7 +6756,7 @@ gl_dispatch_stub_366(GLenum target, GLenum pname, GLint * params) { __GLXcontext *const gc = __glXGetCurrentContext(); - if (gc->isDirect) { + if (gc->driContext) { CALL_GetMinmaxParameteriv(GET_DISPATCH(), (target, pname, params)); } else { __GLXcontext *const gc = __glXGetCurrentContext(); @@ -7470,6 +7601,26 @@ __indirect_glGetProgramivARB(GLenum target, GLenum pname, GLint * params) #define X_GLrop_ProgramEnvParameter4dvARB 4185 void +__indirect_glProgramEnvParameter4dARB(GLenum target, GLuint index, GLdouble x, + GLdouble y, GLdouble z, GLdouble w) +{ + __GLXcontext *const gc = __glXGetCurrentContext(); + const GLuint cmdlen = 44; + emit_header(gc->pc, X_GLrop_ProgramEnvParameter4dvARB, cmdlen); + (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); + (void) memcpy((void *) (gc->pc + 8), (void *) (&index), 4); + (void) memcpy((void *) (gc->pc + 12), (void *) (&x), 8); + (void) memcpy((void *) (gc->pc + 20), (void *) (&y), 8); + (void) memcpy((void *) (gc->pc + 28), (void *) (&z), 8); + (void) memcpy((void *) (gc->pc + 36), (void *) (&w), 8); + gc->pc += cmdlen; + if (__builtin_expect(gc->pc > gc->limit, 0)) { + (void) __glXFlushRenderBuffer(gc, gc->pc); + } +} + +#define X_GLrop_ProgramEnvParameter4dvARB 4185 +void __indirect_glProgramEnvParameter4dvARB(GLenum target, GLuint index, const GLdouble * params) { @@ -7487,6 +7638,26 @@ __indirect_glProgramEnvParameter4dvARB(GLenum target, GLuint index, #define X_GLrop_ProgramEnvParameter4fvARB 4184 void +__indirect_glProgramEnvParameter4fARB(GLenum target, GLuint index, GLfloat x, + GLfloat y, GLfloat z, GLfloat w) +{ + __GLXcontext *const gc = __glXGetCurrentContext(); + const GLuint cmdlen = 28; + emit_header(gc->pc, X_GLrop_ProgramEnvParameter4fvARB, cmdlen); + (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); + (void) memcpy((void *) (gc->pc + 8), (void *) (&index), 4); + (void) memcpy((void *) (gc->pc + 12), (void *) (&x), 4); + (void) memcpy((void *) (gc->pc + 16), (void *) (&y), 4); + (void) memcpy((void *) (gc->pc + 20), (void *) (&z), 4); + (void) memcpy((void *) (gc->pc + 24), (void *) (&w), 4); + gc->pc += cmdlen; + if (__builtin_expect(gc->pc > gc->limit, 0)) { + (void) __glXFlushRenderBuffer(gc, gc->pc); + } +} + +#define X_GLrop_ProgramEnvParameter4fvARB 4184 +void __indirect_glProgramEnvParameter4fvARB(GLenum target, GLuint index, const GLfloat * params) { @@ -7585,6 +7756,10 @@ __indirect_glProgramStringARB(GLenum target, GLenum format, GLsizei len, { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16 + __GLX_PAD(len); + if (len < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect((len >= 0) && (gc->currentDpy != NULL), 1)) { if (cmdlen <= gc->maxSmallRenderCommandSize) { if ((gc->pc + cmdlen) > gc->bufEnd) { @@ -8200,7 +8375,13 @@ __indirect_glDeleteQueriesARB(GLsizei n, const GLuint * ids) { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 4 + __GLX_PAD((n * 4)); +#endif + if (n < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -8238,7 +8419,13 @@ __indirect_glGenQueriesARB(GLsizei n, GLuint * ids) { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 4; +#endif + if (n < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -8271,7 +8458,9 @@ __indirect_glGetQueryObjectivARB(GLuint id, GLenum pname, GLint * params) { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 8; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -8307,7 +8496,9 @@ __indirect_glGetQueryObjectuivARB(GLuint id, GLenum pname, GLuint * params) { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 8; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -8343,7 +8534,9 @@ __indirect_glGetQueryivARB(GLenum target, GLenum pname, GLint * params) { __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; +#ifndef USE_XCB const GLuint cmdlen = 8; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -8383,7 +8576,9 @@ __indirect_glIsQueryARB(GLuint id) __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; GLboolean retval = (GLboolean) 0; +#ifndef USE_XCB const GLuint cmdlen = 4; +#endif if (__builtin_expect(dpy != NULL, 1)) { #ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); @@ -8414,6 +8609,10 @@ __indirect_glDrawBuffersARB(GLsizei n, const GLenum * bufs) { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8 + __GLX_PAD((n * 4)); + if (n < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect((n >= 0) && (gc->currentDpy != NULL), 1)) { if (cmdlen <= gc->maxSmallRenderCommandSize) { if ((gc->pc + cmdlen) > gc->bufEnd) { @@ -8774,6 +8973,10 @@ __indirect_glAreProgramsResidentNV(GLsizei n, const GLuint * ids, Display *const dpy = gc->currentDpy; GLboolean retval = (GLboolean) 0; const GLuint cmdlen = 4 + __GLX_PAD((n * 4)); + if (n < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return 0; + } if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) { GLubyte const *pc = __glXSetupVendorRequest(gc, X_GLXVendorPrivateWithReply, @@ -8809,6 +9012,10 @@ __indirect_glDeleteProgramsNV(GLsizei n, const GLuint * programs) __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 4 + __GLX_PAD((n * 4)); + if (n < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) { GLubyte const *pc = __glXSetupVendorRequest(gc, X_GLXVendorPrivate, @@ -8845,6 +9052,10 @@ __indirect_glGenProgramsNV(GLsizei n, GLuint * programs) __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 4; + if (n < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) { GLubyte const *pc = __glXSetupVendorRequest(gc, X_GLXVendorPrivateWithReply, @@ -9051,6 +9262,10 @@ __indirect_glLoadProgramNV(GLenum target, GLuint id, GLsizei len, { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16 + __GLX_PAD(len); + if (len < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect(len >= 0, 1)) { emit_header(gc->pc, X_GLrop_LoadProgramNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -9071,6 +9286,10 @@ __indirect_glProgramParameters4dvNV(GLenum target, GLuint index, GLuint num, { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16 + __GLX_PAD((num * 32)); + if (num < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect(num >= 0, 1)) { emit_header(gc->pc, X_GLrop_ProgramParameters4dvNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -9091,6 +9310,10 @@ __indirect_glProgramParameters4fvNV(GLenum target, GLuint index, GLuint num, { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16 + __GLX_PAD((num * 16)); + if (num < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect(num >= 0, 1)) { emit_header(gc->pc, X_GLrop_ProgramParameters4fvNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -9110,6 +9333,10 @@ __indirect_glRequestResidentProgramsNV(GLsizei n, const GLuint * ids) { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8 + __GLX_PAD((n * 4)); + if (n < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect(n >= 0, 1)) { emit_header(gc->pc, X_GLrop_RequestResidentProgramsNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&n), 4); @@ -9561,6 +9788,10 @@ __indirect_glVertexAttribs1dvNV(GLuint index, GLsizei n, const GLdouble * v) { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12 + __GLX_PAD((n * 8)); + if (n < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect(n >= 0, 1)) { emit_header(gc->pc, X_GLrop_VertexAttribs1dvNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9579,6 +9810,10 @@ __indirect_glVertexAttribs1fvNV(GLuint index, GLsizei n, const GLfloat * v) { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12 + __GLX_PAD((n * 4)); + if (n < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect(n >= 0, 1)) { emit_header(gc->pc, X_GLrop_VertexAttribs1fvNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9597,6 +9832,10 @@ __indirect_glVertexAttribs1svNV(GLuint index, GLsizei n, const GLshort * v) { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12 + __GLX_PAD((n * 2)); + if (n < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect(n >= 0, 1)) { emit_header(gc->pc, X_GLrop_VertexAttribs1svNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9615,6 +9854,10 @@ __indirect_glVertexAttribs2dvNV(GLuint index, GLsizei n, const GLdouble * v) { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12 + __GLX_PAD((n * 16)); + if (n < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect(n >= 0, 1)) { emit_header(gc->pc, X_GLrop_VertexAttribs2dvNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9633,6 +9876,10 @@ __indirect_glVertexAttribs2fvNV(GLuint index, GLsizei n, const GLfloat * v) { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12 + __GLX_PAD((n * 8)); + if (n < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect(n >= 0, 1)) { emit_header(gc->pc, X_GLrop_VertexAttribs2fvNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9651,6 +9898,10 @@ __indirect_glVertexAttribs2svNV(GLuint index, GLsizei n, const GLshort * v) { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12 + __GLX_PAD((n * 4)); + if (n < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect(n >= 0, 1)) { emit_header(gc->pc, X_GLrop_VertexAttribs2svNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9669,6 +9920,10 @@ __indirect_glVertexAttribs3dvNV(GLuint index, GLsizei n, const GLdouble * v) { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12 + __GLX_PAD((n * 24)); + if (n < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect(n >= 0, 1)) { emit_header(gc->pc, X_GLrop_VertexAttribs3dvNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9687,6 +9942,10 @@ __indirect_glVertexAttribs3fvNV(GLuint index, GLsizei n, const GLfloat * v) { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12 + __GLX_PAD((n * 12)); + if (n < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect(n >= 0, 1)) { emit_header(gc->pc, X_GLrop_VertexAttribs3fvNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9705,6 +9964,10 @@ __indirect_glVertexAttribs3svNV(GLuint index, GLsizei n, const GLshort * v) { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12 + __GLX_PAD((n * 6)); + if (n < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect(n >= 0, 1)) { emit_header(gc->pc, X_GLrop_VertexAttribs3svNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9723,6 +9986,10 @@ __indirect_glVertexAttribs4dvNV(GLuint index, GLsizei n, const GLdouble * v) { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12 + __GLX_PAD((n * 32)); + if (n < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect(n >= 0, 1)) { emit_header(gc->pc, X_GLrop_VertexAttribs4dvNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9741,6 +10008,10 @@ __indirect_glVertexAttribs4fvNV(GLuint index, GLsizei n, const GLfloat * v) { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12 + __GLX_PAD((n * 16)); + if (n < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect(n >= 0, 1)) { emit_header(gc->pc, X_GLrop_VertexAttribs4fvNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9759,6 +10030,10 @@ __indirect_glVertexAttribs4svNV(GLuint index, GLsizei n, const GLshort * v) { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12 + __GLX_PAD((n * 8)); + if (n < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect(n >= 0, 1)) { emit_header(gc->pc, X_GLrop_VertexAttribs4svNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9777,6 +10052,10 @@ __indirect_glVertexAttribs4ubvNV(GLuint index, GLsizei n, const GLubyte *v) { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12 + __GLX_PAD((n * 4)); + if (n < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect(n >= 0, 1)) { emit_header(gc->pc, X_GLrop_VertexAttribs4ubvNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9843,6 +10122,10 @@ __indirect_glGetProgramNamedParameterdvNV(GLuint id, GLsizei len, __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 8 + __GLX_PAD(len); + if (len < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect((len >= 0) && (dpy != NULL), 1)) { GLubyte const *pc = __glXSetupVendorRequest(gc, X_GLXVendorPrivateWithReply, @@ -9867,6 +10150,10 @@ __indirect_glGetProgramNamedParameterfvNV(GLuint id, GLsizei len, __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 8 + __GLX_PAD(len); + if (len < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect((len >= 0) && (dpy != NULL), 1)) { GLubyte const *pc = __glXSetupVendorRequest(gc, X_GLXVendorPrivateWithReply, @@ -9890,6 +10177,10 @@ __indirect_glProgramNamedParameter4dNV(GLuint id, GLsizei len, { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 44 + __GLX_PAD(len); + if (len < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect(len >= 0, 1)) { emit_header(gc->pc, X_GLrop_ProgramNamedParameter4dvNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x), 8); @@ -9914,6 +10205,10 @@ __indirect_glProgramNamedParameter4dvNV(GLuint id, GLsizei len, { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 44 + __GLX_PAD(len); + if (len < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect(len >= 0, 1)) { emit_header(gc->pc, X_GLrop_ProgramNamedParameter4dvNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (v), 32); @@ -9935,6 +10230,10 @@ __indirect_glProgramNamedParameter4fNV(GLuint id, GLsizei len, { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 28 + __GLX_PAD(len); + if (len < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect(len >= 0, 1)) { emit_header(gc->pc, X_GLrop_ProgramNamedParameter4fvNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&id), 4); @@ -9959,6 +10258,10 @@ __indirect_glProgramNamedParameter4fvNV(GLuint id, GLsizei len, { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 28 + __GLX_PAD(len); + if (len < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect(len >= 0, 1)) { emit_header(gc->pc, X_GLrop_ProgramNamedParameter4fvNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&id), 4); @@ -10044,6 +10347,10 @@ __indirect_glDeleteFramebuffersEXT(GLsizei n, const GLuint * framebuffers) { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8 + __GLX_PAD((n * 4)); + if (n < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect(n >= 0, 1)) { emit_header(gc->pc, X_GLrop_DeleteFramebuffersEXT, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&n), 4); @@ -10062,6 +10369,10 @@ __indirect_glDeleteRenderbuffersEXT(GLsizei n, const GLuint * renderbuffers) { __GLXcontext *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8 + __GLX_PAD((n * 4)); + if (n < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect(n >= 0, 1)) { emit_header(gc->pc, X_GLrop_DeleteRenderbuffersEXT, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&n), 4); @@ -10161,6 +10472,10 @@ __indirect_glGenFramebuffersEXT(GLsizei n, GLuint * framebuffers) __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 4; + if (n < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) { GLubyte const *pc = __glXSetupVendorRequest(gc, X_GLXVendorPrivateWithReply, @@ -10180,6 +10495,10 @@ __indirect_glGenRenderbuffersEXT(GLsizei n, GLuint * renderbuffers) __GLXcontext *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 4; + if (n < 0) { + __glXSetError(gc, GL_INVALID_VALUE); + return; + } if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) { GLubyte const *pc = __glXSetupVendorRequest(gc, X_GLXVendorPrivateWithReply, diff --git a/src/glx/x11/indirect.h b/src/glx/x11/indirect.h index f8c88b36bb8..0719a1b3024 100644 --- a/src/glx/x11/indirect.h +++ b/src/glx/x11/indirect.h @@ -517,7 +517,9 @@ extern HIDDEN void __indirect_glGetProgramivARB(GLenum target, GLenum pname, GLi extern HIDDEN void __indirect_glGetVertexAttribdvARB(GLuint index, GLenum pname, GLdouble * params); extern HIDDEN void __indirect_glGetVertexAttribfvARB(GLuint index, GLenum pname, GLfloat * params); extern HIDDEN void __indirect_glGetVertexAttribivARB(GLuint index, GLenum pname, GLint * params); +extern HIDDEN void __indirect_glProgramEnvParameter4dARB(GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); extern HIDDEN void __indirect_glProgramEnvParameter4dvARB(GLenum target, GLuint index, const GLdouble * params); +extern HIDDEN void __indirect_glProgramEnvParameter4fARB(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); extern HIDDEN void __indirect_glProgramEnvParameter4fvARB(GLenum target, GLuint index, const GLfloat * params); extern HIDDEN void __indirect_glProgramLocalParameter4dARB(GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); extern HIDDEN void __indirect_glProgramLocalParameter4dvARB(GLenum target, GLuint index, const GLdouble * params); diff --git a/src/glx/x11/indirect_init.c b/src/glx/x11/indirect_init.c index 479184337c1..852fe712c66 100644 --- a/src/glx/x11/indirect_init.c +++ b/src/glx/x11/indirect_init.c @@ -526,7 +526,9 @@ __GLapi * __glXNewIndirectAPI( void ) glAPI->GetVertexAttribdvARB = __indirect_glGetVertexAttribdvARB; glAPI->GetVertexAttribfvARB = __indirect_glGetVertexAttribfvARB; glAPI->GetVertexAttribivARB = __indirect_glGetVertexAttribivARB; + glAPI->ProgramEnvParameter4dARB = __indirect_glProgramEnvParameter4dARB; glAPI->ProgramEnvParameter4dvARB = __indirect_glProgramEnvParameter4dvARB; + glAPI->ProgramEnvParameter4fARB = __indirect_glProgramEnvParameter4fARB; glAPI->ProgramEnvParameter4fvARB = __indirect_glProgramEnvParameter4fvARB; glAPI->ProgramLocalParameter4dARB = __indirect_glProgramLocalParameter4dARB; glAPI->ProgramLocalParameter4dvARB = __indirect_glProgramLocalParameter4dvARB; diff --git a/src/glx/x11/indirect_vertex_array.c b/src/glx/x11/indirect_vertex_array.c index 90ec277c41b..09d7244ba92 100644 --- a/src/glx/x11/indirect_vertex_array.c +++ b/src/glx/x11/indirect_vertex_array.c @@ -32,7 +32,7 @@ #include <GL/glxproto.h> #include "glxextensions.h" #include "indirect_vertex_array.h" -#include "indirect_va_private.h" +#include "indirect_vertex_array_priv.h" #define __GLX_PAD(n) (((n)+3) & ~3) @@ -485,14 +485,14 @@ emit_DrawArrays_none( GLenum mode, GLint first, GLsizei count ) for ( i = 0 ; i < count ; i++ ) { if ( (pc + single_vertex_size) >= gc->bufEnd ) { - pc = __glXFlushRenderBuffer(gc, gc->pc); + pc = __glXFlushRenderBuffer(gc, pc); } pc = emit_element_none( pc, arrays, first + i ); } if ( (pc + 4) >= gc->bufEnd ) { - pc = __glXFlushRenderBuffer(gc, gc->pc); + pc = __glXFlushRenderBuffer(gc, pc); } (void) memcpy( pc, end_cmd, 4 ); @@ -527,7 +527,7 @@ static GLubyte * emit_DrawArrays_header_old( __GLXcontext * gc, struct array_state_vector * arrays, size_t * elements_per_request, - size_t * total_requests, + unsigned int * total_requests, GLenum mode, GLsizei count ) { size_t command_size; @@ -640,7 +640,7 @@ emit_DrawArrays_old( GLenum mode, GLint first, GLsizei count ) GLubyte * pc; size_t elements_per_request; - size_t total_requests = 0; + unsigned total_requests = 0; unsigned i; size_t total_sent = 0; @@ -726,7 +726,7 @@ emit_DrawElements_none( GLenum mode, GLsizei count, GLenum type, unsigned index = 0; if ( (pc + single_vertex_size) >= gc->bufEnd ) { - pc = __glXFlushRenderBuffer(gc, gc->pc); + pc = __glXFlushRenderBuffer(gc, pc); } switch( type ) { @@ -744,7 +744,7 @@ emit_DrawElements_none( GLenum mode, GLsizei count, GLenum type, } if ( (pc + 4) >= gc->bufEnd ) { - pc = __glXFlushRenderBuffer(gc, gc->pc); + pc = __glXFlushRenderBuffer(gc, pc); } (void) memcpy( pc, end_cmd, 4 ); @@ -770,9 +770,10 @@ emit_DrawElements_old( GLenum mode, GLsizei count, GLenum type, GLubyte * pc; size_t elements_per_request; - size_t total_requests = 0; + unsigned total_requests = 0; unsigned i; unsigned req; + unsigned req_element=0; pc = emit_DrawArrays_header_old( gc, arrays, & elements_per_request, @@ -790,7 +791,7 @@ emit_DrawElements_old( GLenum mode, GLsizei count, GLenum type, switch( type ) { case GL_UNSIGNED_INT: { - const GLuint * ui_ptr = (const GLuint *) indices; + const GLuint * ui_ptr = (const GLuint *) indices + req_element; for ( i = 0 ; i < elements_per_request ; i++ ) { const GLint index = (GLint) *(ui_ptr++); @@ -799,7 +800,7 @@ emit_DrawElements_old( GLenum mode, GLsizei count, GLenum type, break; } case GL_UNSIGNED_SHORT: { - const GLushort * us_ptr = (const GLushort *) indices; + const GLushort * us_ptr = (const GLushort *) indices + req_element; for ( i = 0 ; i < elements_per_request ; i++ ) { const GLint index = (GLint) *(us_ptr++); @@ -808,7 +809,7 @@ emit_DrawElements_old( GLenum mode, GLsizei count, GLenum type, break; } case GL_UNSIGNED_BYTE: { - const GLubyte * ub_ptr = (const GLubyte *) indices; + const GLubyte * ub_ptr = (const GLubyte *) indices + req_element; for ( i = 0 ; i < elements_per_request ; i++ ) { const GLint index = (GLint) *(ub_ptr++); @@ -826,6 +827,7 @@ emit_DrawElements_old( GLenum mode, GLsizei count, GLenum type, } count -= elements_per_request; + req_element += elements_per_request; } diff --git a/src/glx/x11/singlepix.c b/src/glx/x11/singlepix.c index cd88684f709..144e5df7431 100644 --- a/src/glx/x11/singlepix.c +++ b/src/glx/x11/singlepix.c @@ -117,7 +117,7 @@ void NAME(_gloffset_GetSeparableFilter)(GLenum target, GLenum format, GLenum typ { __GLXcontext * const gc = __glXGetCurrentContext(); - if (gc->isDirect) { + if (gc->driContext) { CALL_GetSeparableFilter(GET_DISPATCH(), (target, format, type, row, column, span)); return; diff --git a/src/glx/x11/xf86dri.h b/src/glx/x11/xf86dri.h index c8c878f1274..a6a57c31356 100644 --- a/src/glx/x11/xf86dri.h +++ b/src/glx/x11/xf86dri.h @@ -64,8 +64,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef _XF86DRI_SERVER_ -#include <GL/internal/dri_interface.h> - _XFUNCPROTOBEGIN Bool XF86DRIQueryExtension( Display *dpy, int *event_base, int *error_base ); @@ -93,14 +91,14 @@ Bool XF86DRICreateContext( Display *dpy, int screen, Visual *visual, Bool XF86DRICreateContextWithConfig( Display *dpy, int screen, int configID, XID *ptr_to_returned_context_id, drm_context_t *hHWContext ); -extern GLboolean XF86DRIDestroyContext( __DRInativeDisplay *dpy, int screen, - __DRIid context_id ); +extern GLboolean XF86DRIDestroyContext( Display *dpy, int screen, + XID context_id ); -extern GLboolean XF86DRICreateDrawable( __DRInativeDisplay *dpy, int screen, - __DRIid drawable, drm_drawable_t *hHWDrawable ); +extern GLboolean XF86DRICreateDrawable( Display *dpy, int screen, + XID drawable, drm_drawable_t *hHWDrawable ); -extern GLboolean XF86DRIDestroyDrawable( __DRInativeDisplay *dpy, int screen, - __DRIid drawable); +extern GLboolean XF86DRIDestroyDrawable( Display *dpy, int screen, + XID drawable); Bool XF86DRIGetDrawableInfo( Display *dpy, int screen, Drawable drawable, unsigned int *index, unsigned int *stamp, diff --git a/src/glx/x11/xfont.c b/src/glx/x11/xfont.c index f3e3da3e790..6ec8c2d6bf6 100644 --- a/src/glx/x11/xfont.c +++ b/src/glx/x11/xfont.c @@ -33,6 +33,7 @@ called by that routine when direct rendering is enabled. */ +#ifdef GLX_DIRECT_RENDERING #include "glxclient.h" @@ -208,8 +209,7 @@ static XCharStruct *isvalid(XFontStruct *fs, int which) return(NULL); } - -void DRI_glXUseXFont( Font font, int first, int count, int listbase ) +_X_HIDDEN void DRI_glXUseXFont( Font font, int first, int count, int listbase ) { GLXContext CC; Display *dpy; @@ -373,4 +373,4 @@ bm_height); glPixelStorei(GL_UNPACK_ALIGNMENT, alignment); } -/* The End. */ +#endif diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c index fff79c36ad6..2013125efe6 100644 --- a/src/mesa/drivers/dri/common/dri_util.c +++ b/src/mesa/drivers/dri/common/dri_util.c @@ -55,39 +55,19 @@ #include "dri_util.h" #include "drm_sarea.h" +#include "utils.h" #ifndef GLX_OML_sync_control -typedef GLboolean ( * PFNGLXGETMSCRATEOMLPROC) (__DRInativeDisplay *dpy, __DRIid drawable, int32_t *numerator, int32_t *denominator); +typedef GLboolean ( * PFNGLXGETMSCRATEOMLPROC) (__DRIdrawable *drawable, int32_t *numerator, int32_t *denominator); #endif -/* This pointer *must* be set by the driver's __driCreateNewScreen funciton! - */ -const __DRIinterfaceMethods * dri_interface = NULL; - /** - * This is used in a couple of places that call \c driCreateNewDrawable. + * This is just a token extension used to signal that the driver + * supports setting a read drawable. */ -static const int empty_attribute_list[1] = { None }; - - -/** - * Cached copy of the internal API version used by libGL and the client-side - * DRI driver. - */ -static int api_ver = 0; - -/* forward declarations */ -static int driQueryFrameTracking( __DRInativeDisplay *dpy, void *priv, - int64_t *sbc, int64_t *missedFrames, - float *lastMissedUsage, float *usage ); - -static void *driCreateNewDrawable(__DRInativeDisplay *dpy, - const __GLcontextModes *modes, - __DRIid draw, __DRIdrawable *pdraw, - int renderType, const int *attrs); - -static void driDestroyDrawable(__DRInativeDisplay *dpy, void *drawablePrivate); - +const __DRIextension driReadDrawableExtension = { + __DRI_READ_DRAWABLE, __DRI_READ_DRAWABLE_VERSION +}; /** * Print message to \c stderr if the \c LIBGL_DEBUG environment variable @@ -111,64 +91,19 @@ __driUtilMessage(const char *f, ...) } } - -/*****************************************************************/ -/** \name Drawable list management */ -/*****************************************************************/ -/*@{*/ - -static GLboolean __driAddDrawable(void *drawHash, __DRIdrawable *pdraw) +GLint +driIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 ) { - __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)pdraw->private; + if (rect2.x1 > rect1.x1) rect1.x1 = rect2.x1; + if (rect2.x2 < rect1.x2) rect1.x2 = rect2.x2; + if (rect2.y1 > rect1.y1) rect1.y1 = rect2.y1; + if (rect2.y2 < rect1.y2) rect1.y2 = rect2.y2; - if (drmHashInsert(drawHash, pdp->draw, pdraw)) - return GL_FALSE; + if (rect1.x1 > rect1.x2 || rect1.y1 > rect1.y2) return 0; - return GL_TRUE; -} - -static __DRIdrawable *__driFindDrawable(void *drawHash, __DRIid draw) -{ - int retcode; - __DRIdrawable *pdraw; - - retcode = drmHashLookup(drawHash, draw, (void *)&pdraw); - if (retcode) - return NULL; - - return pdraw; -} - - -/** - * Find drawables in the local hash that have been destroyed on the - * server. - * - * \param drawHash Hash-table containing all known drawables. - */ -static void __driGarbageCollectDrawables(void *drawHash) -{ - __DRIid draw; - __DRInativeDisplay *dpy; - __DRIdrawable *pdraw; - - if (drmHashFirst(drawHash, &draw, (void *)&pdraw) == 1) { - do { - __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)pdraw->private; - dpy = pdp->driScreenPriv->display; - if (! (*dri_interface->windowExists)(dpy, draw)) { - /* Destroy the local drawable data, if the drawable no - longer exists in the Xserver */ - (*pdraw->destroyDrawable)(dpy, pdraw->private); - _mesa_free(pdraw); - } - } while (drmHashNext(drawHash, &draw, (void *)&pdraw) == 1); - } + return (rect1.x2 - rect1.x1) * (rect1.y2 - rect1.y1); } -/*@}*/ - - /*****************************************************************/ /** \name Context (un)binding functions */ /*****************************************************************/ @@ -177,10 +112,7 @@ static void __driGarbageCollectDrawables(void *drawHash) /** * Unbind context. * - * \param dpy the display handle. - * \param scrn the screen number. - * \param draw drawable. - * \param read Current reading drawable. + * \param scrn the screen. * \param gc context. * * \return \c GL_TRUE on success, or \c GL_FALSE on failure. @@ -193,56 +125,27 @@ static void __driGarbageCollectDrawables(void *drawHash) * While casting the opaque private pointers associated with the parameters * into their respective real types it also assures they are not \c NULL. */ -static GLboolean driUnbindContext(__DRInativeDisplay *dpy, int scrn, - __DRIid draw, __DRIid read, - __DRIcontext *ctx) +static int driUnbindContext(__DRIcontext *pcp) { - __DRIscreen *pDRIScreen; - __DRIdrawable *pdraw; - __DRIdrawable *pread; - __DRIcontextPrivate *pcp; - __DRIscreenPrivate *psp; - __DRIdrawablePrivate *pdp; - __DRIdrawablePrivate *prp; + __DRIscreen *psp; + __DRIdrawable *pdp; + __DRIdrawable *prp; /* ** Assume error checking is done properly in glXMakeCurrent before ** calling driUnbindContext. */ - if (ctx == NULL || draw == None || read == None) { - /* ERROR!!! */ - return GL_FALSE; - } - - pDRIScreen = (*dri_interface->getScreen)(dpy, scrn); - if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) { - /* ERROR!!! */ - return GL_FALSE; - } - - psp = (__DRIscreenPrivate *)pDRIScreen->private; - pcp = (__DRIcontextPrivate *)ctx->private; - - pdraw = __driFindDrawable(psp->drawHash, draw); - if (!pdraw) { - /* ERROR!!! */ - return GL_FALSE; - } - pdp = (__DRIdrawablePrivate *)pdraw->private; - - pread = __driFindDrawable(psp->drawHash, read); - if (!pread) { - /* ERROR!!! */ - return GL_FALSE; - } - prp = (__DRIdrawablePrivate *)pread->private; + if (pcp == NULL) + return GL_FALSE; + psp = pcp->driScreenPriv; + pdp = pcp->driDrawablePriv; + prp = pcp->driReadablePriv; /* Let driver unbind drawable from context */ (*psp->DriverAPI.UnbindContext)(pcp); - if (pdp->refcount == 0) { /* ERROR!!! */ return GL_FALSE; @@ -259,12 +162,6 @@ static GLboolean driUnbindContext(__DRInativeDisplay *dpy, int scrn, prp->refcount--; } - /* destroy the drawables if they no longer exist on the server */ - if ((pdp->refcount == 0) || (prp->refcount == 0)) { - /* probably shouldn't need the collector here, - as we know the affected drawables (or could there be others?) */ - __driGarbageCollectDrawables(pdp->driScreenPriv->drawHash); - } /* XXX this is disabled so that if we call SwapBuffers on an unbound * window we can determine the last context bound to the window and @@ -284,72 +181,20 @@ static GLboolean driUnbindContext(__DRInativeDisplay *dpy, int scrn, * This function takes both a read buffer and a draw buffer. This is needed * for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent * function. - * - * \bug This function calls \c driCreateNewDrawable in two places with the - * \c renderType hard-coded to \c GLX_WINDOW_BIT. Some checking might - * be needed in those places when support for pbuffers and / or pixmaps - * is added. Is it safe to assume that the drawable is a window? */ -static GLboolean DoBindContext(__DRInativeDisplay *dpy, - __DRIid draw, __DRIid read, - __DRIcontext *ctx, const __GLcontextModes * modes, - __DRIscreenPrivate *psp) +static int driBindContext(__DRIcontext *pcp, + __DRIdrawable *pdp, + __DRIdrawable *prp) { - __DRIdrawable *pdraw; - __DRIdrawablePrivate *pdp; - __DRIdrawable *pread; - __DRIdrawablePrivate *prp; - __DRIcontextPrivate * const pcp = ctx->private; - - - /* Find the _DRIdrawable which corresponds to the writing drawable. */ - pdraw = __driFindDrawable(psp->drawHash, draw); - if (!pdraw) { - /* Allocate a new drawable */ - pdraw = (__DRIdrawable *)_mesa_malloc(sizeof(__DRIdrawable)); - if (!pdraw) { - /* ERROR!!! */ - return GL_FALSE; - } - - /* Create a new drawable */ - driCreateNewDrawable(dpy, modes, draw, pdraw, GLX_WINDOW_BIT, - empty_attribute_list); - if (!pdraw->private) { - /* ERROR!!! */ - _mesa_free(pdraw); - return GL_FALSE; - } + __DRIscreenPrivate *psp = pcp->driScreenPriv; - } - pdp = (__DRIdrawablePrivate *) pdraw->private; + /* + ** Assume error checking is done properly in glXMakeCurrent before + ** calling driBindContext. + */ - /* Find the _DRIdrawable which corresponds to the reading drawable. */ - if (read == draw) { - /* read buffer == draw buffer */ - prp = pdp; - } - else { - pread = __driFindDrawable(psp->drawHash, read); - if (!pread) { - /* Allocate a new drawable */ - pread = (__DRIdrawable *)_mesa_malloc(sizeof(__DRIdrawable)); - if (!pread) { - /* ERROR!!! */ - return GL_FALSE; - } - - /* Create a new drawable */ - driCreateNewDrawable(dpy, modes, read, pread, GLX_WINDOW_BIT, - empty_attribute_list); - if (!pread->private) { - /* ERROR!!! */ - _mesa_free(pread); - return GL_FALSE; - } - } - prp = (__DRIdrawablePrivate *) pread->private; - } + if (pcp == NULL || pdp == None || prp == None) + return GL_FALSE; /* Bind the drawable to the context */ pcp->driDrawablePriv = pdp; @@ -364,16 +209,22 @@ static GLboolean DoBindContext(__DRInativeDisplay *dpy, ** Now that we have a context associated with this drawable, we can ** initialize the drawable information if has not been done before. */ - if (!pdp->pStamp || *pdp->pStamp != pdp->lastStamp) { - DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); - __driUtilUpdateDrawableInfo(pdp); - DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); - } - if ((pdp != prp) && (!prp->pStamp || *prp->pStamp != prp->lastStamp)) { - DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); - __driUtilUpdateDrawableInfo(prp); - DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); + if (psp->dri2.enabled) { + __driParseEvents(pcp, pdp); + __driParseEvents(pcp, prp); + } else { + if (!pdp->pStamp || *pdp->pStamp != pdp->lastStamp) { + DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); + __driUtilUpdateDrawableInfo(pdp); + DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); + } + + if ((pdp != prp) && (!prp->pStamp || *prp->pStamp != prp->lastStamp)) { + DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); + __driUtilUpdateDrawableInfo(prp); + DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); + } } /* Call device-specific MakeCurrent */ @@ -382,37 +233,6 @@ static GLboolean DoBindContext(__DRInativeDisplay *dpy, return GL_TRUE; } - -/** - * This function takes both a read buffer and a draw buffer. This is needed - * for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent - * function. - */ -static GLboolean driBindContext(__DRInativeDisplay *dpy, int scrn, - __DRIid draw, __DRIid read, - __DRIcontext * ctx) -{ - __DRIscreen *pDRIScreen; - - /* - ** Assume error checking is done properly in glXMakeCurrent before - ** calling driBindContext. - */ - - if (ctx == NULL || draw == None || read == None) { - /* ERROR!!! */ - return GL_FALSE; - } - - pDRIScreen = (*dri_interface->getScreen)(dpy, scrn); - if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) { - /* ERROR!!! */ - return GL_FALSE; - } - - return DoBindContext( dpy, draw, read, ctx, ctx->mode, - (__DRIscreenPrivate *)pDRIScreen->private ); -} /*@}*/ @@ -436,7 +256,7 @@ static GLboolean driBindContext(__DRInativeDisplay *dpy, int scrn, void __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp) { - __DRIscreenPrivate *psp; + __DRIscreenPrivate *psp = pdp->driScreenPriv; __DRIcontextPrivate *pcp = pdp->driContextPriv; if (!pcp @@ -447,15 +267,6 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp) */ } - psp = pdp->driScreenPriv; - if (!psp) { - /* ERROR!!! */ - _mesa_problem(NULL, "Warning! Possible infinite loop due to bug " - "in file %s, line %d\n", - __FILE__, __LINE__); - return; - } - if (pdp->pClipRects) { _mesa_free(pdp->pClipRects); pdp->pClipRects = NULL; @@ -468,15 +279,15 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp) DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); - if (!__driFindDrawable(psp->drawHash, pdp->draw) || - ! (*dri_interface->getDrawableInfo)(pdp->display, pdp->screen, pdp->draw, + if (! (*psp->getDrawableInfo->getDrawableInfo)(pdp, &pdp->index, &pdp->lastStamp, &pdp->x, &pdp->y, &pdp->w, &pdp->h, &pdp->numClipRects, &pdp->pClipRects, &pdp->backX, &pdp->backY, &pdp->numBackClipRects, - &pdp->pBackClipRects )) { + &pdp->pBackClipRects, + pdp->loaderPrivate)) { /* Error -- eg the window may have been destroyed. Keep going * with no cliprects. */ @@ -493,6 +304,138 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp) } +int +__driParseEvents(__DRIcontextPrivate *pcp, __DRIdrawablePrivate *pdp) +{ + __DRIscreenPrivate *psp = pcp->driScreenPriv; + __DRIDrawableConfigEvent *dc, *last_dc; + __DRIBufferAttachEvent *ba, *last_ba; + unsigned int tail, mask, *p, end, total, size, changed; + unsigned char *data; + size_t rect_size; + + /* Check for wraparound. */ + if (psp->dri2.buffer->prealloc - pdp->dri2.tail > psp->dri2.buffer->size) { + /* If prealloc overlaps into what we just parsed, the + * server overwrote it and we have to reset our tail + * pointer. */ + DRM_UNLOCK(psp->fd, psp->lock, pcp->hHWContext); + (*psp->dri2.loader->reemitDrawableInfo)(pdp, &pdp->dri2.tail, + pdp->loaderPrivate); + DRM_LIGHT_LOCK(psp->fd, psp->lock, pcp->hHWContext); + } + + total = psp->dri2.buffer->head - pdp->dri2.tail; + mask = psp->dri2.buffer->size - 1; + end = psp->dri2.buffer->head; + data = psp->dri2.buffer->data; + + changed = 0; + last_dc = NULL; + last_ba = NULL; + + for (tail = pdp->dri2.tail; tail != end; tail += size) { + p = (unsigned int *) (data + (tail & mask)); + size = DRI2_EVENT_SIZE(*p); + if (size > total || (tail & mask) + size > psp->dri2.buffer->size) { + /* illegal data, bail out. */ + fprintf(stderr, "illegal event size\n"); + break; + } + + switch (DRI2_EVENT_TYPE(*p)) { + case DRI2_EVENT_DRAWABLE_CONFIG: + dc = (__DRIDrawableConfigEvent *) p; + if (dc->drawable == pdp->dri2.drawable_id) + last_dc = dc; + break; + + case DRI2_EVENT_BUFFER_ATTACH: + ba = (__DRIBufferAttachEvent *) p; + if (ba->drawable == pdp->dri2.drawable_id && + ba->buffer.attachment == DRI_DRAWABLE_BUFFER_FRONT_LEFT) + last_ba = ba; + break; + } + } + + if (last_dc) { + if (pdp->w != last_dc->width || pdp->h != last_dc->height) + changed = 1; + + pdp->x = last_dc->x; + pdp->y = last_dc->y; + pdp->w = last_dc->width; + pdp->h = last_dc->height; + + pdp->backX = 0; + pdp->backY = 0; + pdp->numBackClipRects = 1; + pdp->pBackClipRects[0].x1 = 0; + pdp->pBackClipRects[0].y1 = 0; + pdp->pBackClipRects[0].x2 = pdp->w; + pdp->pBackClipRects[0].y2 = pdp->h; + + pdp->numClipRects = last_dc->num_rects; + _mesa_free(pdp->pClipRects); + rect_size = last_dc->num_rects * sizeof last_dc->rects[0]; + pdp->pClipRects = _mesa_malloc(rect_size); + memcpy(pdp->pClipRects, last_dc->rects, rect_size); + } + + /* We only care about the most recent drawable config. */ + if (last_dc && changed) + (*psp->DriverAPI.HandleDrawableConfig)(pdp, pcp, last_dc); + + /* Front buffer attachments are special, they typically mean that + * we're rendering to a redirected window (or a child window of a + * redirected window) and that it got resized. Resizing the root + * window on randr events is a special case of this. Other causes + * may be a window transitioning between redirected and + * non-redirected, or a window getting reparented between parents + * with different window pixmaps (eg two redirected windows). + * These events are special in that the X server allocates the + * buffer and that the buffer may be shared by other child + * windows. When our window share the window pixmap with its + * parent, drawable config events doesn't affect the front buffer. + * We only care about the last such event in the buffer; in fact, + * older events will refer to invalid buffer objects.*/ + if (last_ba) + (*psp->DriverAPI.HandleBufferAttach)(pdp, pcp, last_ba); + + /* If there was a drawable config event in the buffer and it + * changed the size of the window, all buffer auxillary buffer + * attachments prior to that are invalid (as opposed to the front + * buffer case discussed above). In that case we can start + * looking for buffer attachment after the last drawable config + * event. If there is no drawable config event in this batch of + * events, we have to assume that the last batch might have had + * one and process all buffer attach events.*/ + if (last_dc && changed) + tail = (unsigned char *) last_dc - data; + else + tail = pdp->dri2.tail; + + for ( ; tail != end; tail += size) { + ba = (__DRIBufferAttachEvent *) (data + (tail & mask)); + size = DRI2_EVENT_SIZE(ba->event_header); + + if (DRI2_EVENT_TYPE(ba->event_header) != DRI2_EVENT_BUFFER_ATTACH) + continue; + if (ba->drawable != pdp->dri2.drawable_id) + continue; + if (last_ba == ba) + continue; + + (*psp->DriverAPI.HandleBufferAttach)(pdp, pcp, ba); + changed = 1; + } + + pdp->dri2.tail = tail; + + return changed || last_ba; +} + /*@}*/ /*****************************************************************/ @@ -500,10 +443,33 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp) /*****************************************************************/ /*@{*/ +static void driReportDamage(__DRIdrawable *pdp, + struct drm_clip_rect *pClipRects, int numClipRects) +{ + __DRIscreen *psp = pdp->driScreenPriv; + + /* Check that we actually have the new damage report method */ + if (psp->dri2.enabled) { + (*psp->dri2.loader->postDamage)(pdp, + pClipRects, + numClipRects, + pdp->loaderPrivate); + } else if (psp->damage) { + /* Report the damage. Currently, all our drivers draw + * directly to the front buffer, so we report the damage there + * rather than to the backing storein (if any). + */ + (*psp->damage->reportDamage)(pdp, + pdp->x, pdp->y, + pClipRects, numClipRects, + GL_TRUE, pdp->loaderPrivate); + } +} + + /** * Swap buffers. * - * \param dpy the display handle. * \param drawablePrivate opaque pointer to the per-drawable private info. * * \internal @@ -511,74 +477,28 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp) * * Is called directly from glXSwapBuffers(). */ -static void driSwapBuffers( __DRInativeDisplay *dpy, void *drawablePrivate ) -{ - __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate; - drm_clip_rect_t rect; - - dPriv->swapBuffers(dPriv); - - /* Check that we actually have the new damage report method */ - if (api_ver < 20070105 || dri_interface->reportDamage == NULL) - return; - - /* Assume it's affecting the whole drawable for now */ - rect.x1 = 0; - rect.y1 = 0; - rect.x2 = rect.x1 + dPriv->w; - rect.y2 = rect.y1 + dPriv->h; - - /* Report the damage. Currently, all our drivers draw directly to the - * front buffer, so we report the damage there rather than to the backing - * store (if any). - */ - (*dri_interface->reportDamage)(dpy, dPriv->screen, dPriv->draw, - dPriv->x, dPriv->y, - &rect, 1, GL_TRUE); -} - -/** - * Called directly from a number of higher-level GLX functions. - */ -static int driGetMSC( void *screenPrivate, int64_t *msc ) -{ - __DRIscreenPrivate *sPriv = (__DRIscreenPrivate *) screenPrivate; - - return sPriv->DriverAPI.GetMSC( sPriv, msc ); -} - -/** - * Called directly from a number of higher-level GLX functions. - */ -static int driGetSBC( __DRInativeDisplay *dpy, void *drawablePrivate, int64_t *sbc ) +static void driSwapBuffers(__DRIdrawable *dPriv) { - __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate; - __DRIswapInfo sInfo; - int status; + __DRIscreen *psp = dPriv->driScreenPriv; + if (!dPriv->numClipRects) + return; - status = dPriv->driScreenPriv->DriverAPI.GetSwapInfo( dPriv, & sInfo ); - *sbc = sInfo.swap_count; + psp->DriverAPI.SwapBuffers(dPriv); - return status; + driReportDamage(dPriv, dPriv->pClipRects, dPriv->numClipRects); } -static int driWaitForSBC( __DRInativeDisplay * dpy, void *drawablePriv, - int64_t target_sbc, - int64_t * msc, int64_t * sbc ) +static int driDrawableGetMSC( __DRIscreen *sPriv, __DRIdrawable *dPriv, + int64_t *msc ) { - __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePriv; - - return dPriv->driScreenPriv->DriverAPI.WaitForSBC( dPriv, target_sbc, - msc, sbc ); + return sPriv->DriverAPI.GetDrawableMSC(sPriv, dPriv, msc); } -static int driWaitForMSC( __DRInativeDisplay * dpy, void *drawablePriv, - int64_t target_msc, - int64_t divisor, int64_t remainder, - int64_t * msc, int64_t * sbc ) +static int driWaitForMSC(__DRIdrawable *dPriv, int64_t target_msc, + int64_t divisor, int64_t remainder, + int64_t * msc, int64_t * sbc) { - __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePriv; __DRIswapInfo sInfo; int status; @@ -600,63 +520,70 @@ static int driWaitForMSC( __DRInativeDisplay * dpy, void *drawablePriv, return status; } -static int64_t driSwapBuffersMSC( __DRInativeDisplay * dpy, void *drawablePriv, - int64_t target_msc, - int64_t divisor, int64_t remainder ) +const __DRImediaStreamCounterExtension driMediaStreamCounterExtension = { + { __DRI_MEDIA_STREAM_COUNTER, __DRI_MEDIA_STREAM_COUNTER_VERSION }, + driWaitForMSC, + driDrawableGetMSC, +}; + +static void driCopySubBuffer(__DRIdrawable *dPriv, + int x, int y, int w, int h) { - __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePriv; + drm_clip_rect_t rect; - return dPriv->driScreenPriv->DriverAPI.SwapBuffersMSC( dPriv, target_msc, - divisor, - remainder ); + dPriv->driScreenPriv->DriverAPI.CopySubBuffer(dPriv, x, y, w, h); + + rect.x1 = x; + rect.y1 = dPriv->h - y - h; + rect.x2 = x + w; + rect.y2 = rect.y1 + h; + driReportDamage(dPriv, &rect, 1); } -static void driCopySubBuffer( __DRInativeDisplay *dpy, void *drawablePrivate, - int x, int y, int w, int h) +const __DRIcopySubBufferExtension driCopySubBufferExtension = { + { __DRI_COPY_SUB_BUFFER, __DRI_COPY_SUB_BUFFER_VERSION }, + driCopySubBuffer +}; + +static void driSetSwapInterval(__DRIdrawable *dPriv, unsigned int interval) { - __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate; - dPriv->driScreenPriv->DriverAPI.CopySubBuffer(dPriv, x, y, w, h); - (void) dpy; + dPriv->swap_interval = interval; } +static unsigned int driGetSwapInterval(__DRIdrawable *dPriv) +{ + return dPriv->swap_interval; +} + +const __DRIswapControlExtension driSwapControlExtension = { + { __DRI_SWAP_CONTROL, __DRI_SWAP_CONTROL_VERSION }, + driSetSwapInterval, + driGetSwapInterval +}; + + /** * This is called via __DRIscreenRec's createNewDrawable pointer. */ -static void *driCreateNewDrawable(__DRInativeDisplay *dpy, - const __GLcontextModes *modes, - __DRIid draw, - __DRIdrawable *pdraw, - int renderType, - const int *attrs) +static __DRIdrawable * +driCreateNewDrawable(__DRIscreen *psp, const __DRIconfig *config, + drm_drawable_t hwDrawable, int renderType, + const int *attrs, void *data) { - __DRIscreen * const pDRIScreen = (*dri_interface->getScreen)(dpy, modes->screen); - __DRIscreenPrivate *psp; - __DRIdrawablePrivate *pdp; - - - pdraw->private = NULL; + __DRIdrawable *pdp; /* Since pbuffers are not yet supported, no drawable attributes are * supported either. */ (void) attrs; - if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) { - return NULL; - } - - pdp = (__DRIdrawablePrivate *)_mesa_malloc(sizeof(__DRIdrawablePrivate)); + pdp = _mesa_malloc(sizeof *pdp); if (!pdp) { return NULL; } - if (!(*dri_interface->createDrawable)(dpy, modes->screen, draw, &pdp->hHWDrawable)) { - _mesa_free(pdp); - return NULL; - } - - pdp->draw = draw; - pdp->pdraw = pdraw; + pdp->loaderPrivate = data; + pdp->hHWDrawable = hwDrawable; pdp->refcount = 0; pdp->pStamp = NULL; pdp->lastStamp = 0; @@ -669,80 +596,55 @@ static void *driCreateNewDrawable(__DRInativeDisplay *dpy, pdp->numBackClipRects = 0; pdp->pClipRects = NULL; pdp->pBackClipRects = NULL; - pdp->display = dpy; - pdp->screen = modes->screen; + pdp->vblSeq = 0; + pdp->vblFlags = 0; - psp = (__DRIscreenPrivate *)pDRIScreen->private; pdp->driScreenPriv = psp; pdp->driContextPriv = &psp->dummyContextPriv; - if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, modes, + if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, &config->modes, renderType == GLX_PIXMAP_BIT)) { - (void)(*dri_interface->destroyDrawable)(dpy, modes->screen, pdp->draw); _mesa_free(pdp); return NULL; } - pdraw->private = pdp; - pdraw->destroyDrawable = driDestroyDrawable; - pdraw->swapBuffers = driSwapBuffers; /* called by glXSwapBuffers() */ - - pdraw->getSBC = driGetSBC; - pdraw->waitForSBC = driWaitForSBC; - pdraw->waitForMSC = driWaitForMSC; - pdraw->swapBuffersMSC = driSwapBuffersMSC; - pdraw->frameTracking = NULL; - pdraw->queryFrameTracking = driQueryFrameTracking; - - if (driCompareGLXAPIVersion (20060314) >= 0) - pdraw->copySubBuffer = driCopySubBuffer; + pdp->msc_base = 0; /* This special default value is replaced with the configured * default value when the drawable is first bound to a direct * rendering context. */ - pdraw->swap_interval = (unsigned)-1; - - pdp->swapBuffers = psp->DriverAPI.SwapBuffers; + pdp->swap_interval = (unsigned)-1; - /* Add pdraw to drawable list */ - if (!__driAddDrawable(psp->drawHash, pdraw)) { - /* ERROR!!! */ - (*pdraw->destroyDrawable)(dpy, pdp); - _mesa_free(pdp); - pdp = NULL; - pdraw->private = NULL; - } - - return (void *) pdp; + return pdp; } static __DRIdrawable * -driGetDrawable(__DRInativeDisplay *dpy, __DRIid draw, void *screenPrivate) +dri2CreateNewDrawable(__DRIscreen *screen, const __DRIconfig *config, + unsigned int drawable_id, unsigned int head, void *data) { - __DRIscreenPrivate *psp = (__DRIscreenPrivate *) screenPrivate; + __DRIdrawable *pdraw; - /* - ** Make sure this routine returns NULL if the drawable is not bound - ** to a direct rendering context! - */ - return __driFindDrawable(psp->drawHash, draw); + pdraw = driCreateNewDrawable(screen, config, 0, 0, NULL, data); + if (!pdraw) + return NULL; + + pdraw->dri2.drawable_id = drawable_id; + pdraw->dri2.tail = head; + pdraw->pBackClipRects = _mesa_malloc(sizeof *pdraw->pBackClipRects); + + return pdraw; } + static void -driDestroyDrawable(__DRInativeDisplay *dpy, void *drawablePrivate) +driDestroyDrawable(__DRIdrawable *pdp) { - __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *) drawablePrivate; __DRIscreenPrivate *psp; - int scrn; if (pdp) { psp = pdp->driScreenPriv; - scrn = psp->myNum; (*psp->DriverAPI.DestroyBuffer)(pdp); - if ((*dri_interface->windowExists)(dpy, pdp->draw)) - (void)(*dri_interface->destroyDrawable)(dpy, scrn, pdp->draw); - drmHashDelete(psp->drawHash, pdp->draw); if (pdp->pClipRects) { _mesa_free(pdp->pClipRects); pdp->pClipRects = NULL; @@ -766,8 +668,6 @@ driDestroyDrawable(__DRInativeDisplay *dpy, void *drawablePrivate) /** * Destroy the per-context private information. * - * \param dpy the display handle. - * \param scrn the screen number. * \param contextPrivate opaque pointer to the per-drawable private info. * * \internal @@ -775,14 +675,10 @@ driDestroyDrawable(__DRInativeDisplay *dpy, void *drawablePrivate) * drmDestroyContext(), and finally frees \p contextPrivate. */ static void -driDestroyContext(__DRInativeDisplay *dpy, int scrn, void *contextPrivate) +driDestroyContext(__DRIcontext *pcp) { - __DRIcontextPrivate *pcp = (__DRIcontextPrivate *) contextPrivate; - if (pcp) { (*pcp->driScreenPriv->DriverAPI.DestroyContext)(pcp); - __driGarbageCollectDrawables(pcp->driScreenPriv->drawHash); - (void) (*dri_interface->destroyContext)(dpy, scrn, pcp->contextID); _mesa_free(pcp); } } @@ -795,7 +691,7 @@ driDestroyContext(__DRInativeDisplay *dpy, int scrn, void *contextPrivate) * \param modes Mode used to create the new context. * \param render_type Type of rendering target. \c GLX_RGBA is the only * type likely to ever be supported for direct-rendering. - * \param sharedPrivate The shared context dependent methods or \c NULL if + * \param shared The shared context dependent methods or \c NULL if * non-existent. * \param pctx DRI context to receive the context dependent methods. * @@ -809,36 +705,18 @@ driDestroyContext(__DRInativeDisplay *dpy, int scrn, void *contextPrivate) * context. * */ -static void * -driCreateNewContext(__DRInativeDisplay *dpy, const __GLcontextModes *modes, - int render_type, void *sharedPrivate, __DRIcontext *pctx) +static __DRIcontext * +driCreateNewContext(__DRIscreen *psp, const __DRIconfig *config, + int render_type, __DRIcontext *shared, + drm_context_t hwContext, void *data) { - __DRIscreen *pDRIScreen; - __DRIcontextPrivate *pcp; - __DRIcontextPrivate *pshare = (__DRIcontextPrivate *) sharedPrivate; - __DRIscreenPrivate *psp; - void * const shareCtx = (pshare != NULL) ? pshare->driverPrivate : NULL; + __DRIcontext *pcp; + void * const shareCtx = (shared != NULL) ? shared->driverPrivate : NULL; - pDRIScreen = (*dri_interface->getScreen)(dpy, modes->screen); - if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) { - /* ERROR!!! */ + pcp = _mesa_malloc(sizeof *pcp); + if (!pcp) return NULL; - } - - psp = (__DRIscreenPrivate *)pDRIScreen->private; - pcp = (__DRIcontextPrivate *)_mesa_malloc(sizeof(__DRIcontextPrivate)); - if (!pcp) { - return NULL; - } - - if (! (*dri_interface->createContext)(dpy, modes->screen, modes->fbconfigID, - &pcp->contextID, &pcp->hHWContext)) { - _mesa_free(pcp); - return NULL; - } - - pcp->display = dpy; pcp->driScreenPriv = psp; pcp->driDrawablePriv = NULL; @@ -846,8 +724,7 @@ driCreateNewContext(__DRInativeDisplay *dpy, const __GLcontextModes *modes, * context. */ - if (!psp->dummyContextPriv.driScreenPriv) { - psp->dummyContextPriv.contextID = 0; + if (!psp->dri2.enabled && !psp->dummyContextPriv.driScreenPriv) { psp->dummyContextPriv.hHWContext = psp->pSAREA->dummy_context; psp->dummyContextPriv.driScreenPriv = psp; psp->dummyContextPriv.driDrawablePriv = NULL; @@ -855,21 +732,40 @@ driCreateNewContext(__DRInativeDisplay *dpy, const __GLcontextModes *modes, /* No other fields should be used! */ } - pctx->destroyContext = driDestroyContext; - pctx->bindContext = driBindContext; - pctx->unbindContext = driUnbindContext; + pcp->hHWContext = hwContext; - if ( !(*psp->DriverAPI.CreateContext)(modes, pcp, shareCtx) ) { - (void) (*dri_interface->destroyContext)(dpy, modes->screen, - pcp->contextID); + if ( !(*psp->DriverAPI.CreateContext)(&config->modes, pcp, shareCtx) ) { _mesa_free(pcp); return NULL; } - __driGarbageCollectDrawables(pcp->driScreenPriv->drawHash); - return pcp; } + +static __DRIcontext * +dri2CreateNewContext(__DRIscreen *screen, const __DRIconfig *config, + __DRIcontext *shared, void *data) +{ + drm_context_t hwContext; + DRM_CAS_RESULT(ret); + + /* DRI2 doesn't use kernel with context IDs, we just need an ID that's + * different from the kernel context ID to make drmLock() happy. */ + + do { + hwContext = screen->dri2.lock->next_id; + DRM_CAS(&screen->dri2.lock->next_id, hwContext, hwContext + 1, ret); + } while (ret); + + return driCreateNewContext(screen, config, 0, shared, hwContext, data); +} + +static int +driCopyContext(__DRIcontext *dest, __DRIcontext *src, unsigned long mask) +{ + return GL_FALSE; +} + /*@}*/ @@ -889,10 +785,8 @@ driCreateNewContext(__DRInativeDisplay *dpy, const __GLcontextModes *modes, * This function calls __DriverAPIRec::DestroyScreen on \p screenPrivate, calls * drmClose(), and finally frees \p screenPrivate. */ -static void driDestroyScreen(__DRInativeDisplay *dpy, int scrn, void *screenPrivate) +static void driDestroyScreen(__DRIscreen *psp) { - __DRIscreenPrivate *psp = (__DRIscreenPrivate *) screenPrivate; - if (psp) { /* No interaction with the X-server is possible at this point. This * routine is called after XCloseDisplay, so there is no protocol @@ -902,26 +796,44 @@ static void driDestroyScreen(__DRInativeDisplay *dpy, int scrn, void *screenPriv if (psp->DriverAPI.DestroyScreen) (*psp->DriverAPI.DestroyScreen)(psp); - (void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX); - (void)drmUnmap((drmAddress)psp->pFB, psp->fbSize); - _mesa_free(psp->pDevPriv); - (void)drmCloseOnce(psp->fd); - if ( psp->modes != NULL ) { - (*dri_interface->destroyContextModes)( psp->modes ); + if (psp->dri2.enabled) { + drmBOUnmap(psp->fd, &psp->dri2.sareaBO); + drmBOUnreference(psp->fd, &psp->dri2.sareaBO); + } else { + (void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX); + (void)drmUnmap((drmAddress)psp->pFB, psp->fbSize); + (void)drmCloseOnce(psp->fd); } - assert(psp->drawHash); - drmHashDestroy(psp->drawHash); - _mesa_free(psp); } } +static void +setupLoaderExtensions(__DRIscreen *psp, + const __DRIextension **extensions) +{ + int i; + + for (i = 0; extensions[i]; i++) { + if (strcmp(extensions[i]->name, __DRI_GET_DRAWABLE_INFO) == 0) + psp->getDrawableInfo = (__DRIgetDrawableInfoExtension *) extensions[i]; + if (strcmp(extensions[i]->name, __DRI_DAMAGE) == 0) + psp->damage = (__DRIdamageExtension *) extensions[i]; + if (strcmp(extensions[i]->name, __DRI_SYSTEM_TIME) == 0) + psp->systemTime = (__DRIsystemTimeExtension *) extensions[i]; + if (strcmp(extensions[i]->name, __DRI_LOADER) == 0) + psp->dri2.loader = (__DRIloaderExtension *) extensions[i]; + } +} /** - * Utility function used to create a new driver-private screen structure. + * This is the bootstrap function for the driver. libGL supplies all of the + * requisite information about the system, and the driver initializes itself. + * This routine also fills in the linked list pointed to by \c driver_modes + * with the \c __GLcontextModes that the driver can support for windows or + * pbuffers. * - * \param dpy Display pointer * \param scrn Index of the screen * \param psc DRI screen data (not driver private) * \param modes Linked list of known display modes. This list is, at a @@ -942,44 +854,29 @@ static void driDestroyScreen(__DRInativeDisplay *dpy, int scrn, void *screenPriv * driver and libGL. * \param driverAPI Driver API functions used by other routines in dri_util.c. * - * \note - * There is no need to check the minimum API version in this function. Since - * the \c __driCreateNewScreen function is versioned, it is impossible for a - * loader that is too old to even load this driver. + * \note There is no need to check the minimum API version in this + * function. Since the name of this function is versioned, it is + * impossible for a loader that is too old to even load this driver. */ -__DRIscreenPrivate * -__driUtilCreateNewScreen(__DRInativeDisplay *dpy, int scrn, __DRIscreen *psc, - __GLcontextModes * modes, - const __DRIversion * ddx_version, - const __DRIversion * dri_version, - const __DRIversion * drm_version, - const __DRIframebuffer * frame_buffer, - drm_sarea_t *pSAREA, - int fd, - int internal_api_version, - const struct __DriverAPIRec *driverAPI) +static __DRIscreen * +driCreateNewScreen(int scrn, + const __DRIversion *ddx_version, + const __DRIversion *dri_version, + const __DRIversion *drm_version, + const __DRIframebuffer *frame_buffer, + drmAddress pSAREA, int fd, + const __DRIextension **extensions, + const __DRIconfig ***driver_modes, + void *loaderPrivate) { - __DRIscreenPrivate *psp; - - - api_ver = internal_api_version; - - psp = (__DRIscreenPrivate *)_mesa_malloc(sizeof(__DRIscreenPrivate)); - if (!psp) { - return NULL; - } + static const __DRIextension *emptyExtensionList[] = { NULL }; + __DRIscreen *psp; - /* Create the hash table */ - psp->drawHash = drmHashCreate(); - if ( psp->drawHash == NULL ) { - _mesa_free( psp ); + psp = _mesa_malloc(sizeof *psp); + if (!psp) return NULL; - } - psp->display = dpy; - psp->myNum = scrn; - psp->psc = psc; - psp->modes = modes; + setupLoaderExtensions(psp, extensions); /* ** NOT_DONE: This is used by the X server to detect when the client @@ -988,20 +885,12 @@ __driUtilCreateNewScreen(__DRInativeDisplay *dpy, int scrn, __DRIscreen *psc, */ psp->drawLockID = 1; - psp->drmMajor = drm_version->major; - psp->drmMinor = drm_version->minor; - psp->drmPatch = drm_version->patch; - psp->ddxMajor = ddx_version->major; - psp->ddxMinor = ddx_version->minor; - psp->ddxPatch = ddx_version->patch; - psp->driMajor = dri_version->major; - psp->driMinor = dri_version->minor; - psp->driPatch = dri_version->patch; - - /* install driver's callback functions */ - memcpy( &psp->DriverAPI, driverAPI, sizeof(struct __DriverAPIRec) ); + psp->drm_version = *drm_version; + psp->ddx_version = *ddx_version; + psp->dri_version = *dri_version; psp->pSAREA = pSAREA; + psp->lock = (drmLock *) &psp->pSAREA->lock; psp->pFB = frame_buffer->base; psp->fbSize = frame_buffer->size; @@ -1012,7 +901,10 @@ __driUtilCreateNewScreen(__DRInativeDisplay *dpy, int scrn, __DRIscreen *psc, psp->pDevPriv = frame_buffer->dev_priv; psp->fbBPP = psp->fbStride * 8 / frame_buffer->width; + psp->extensions = emptyExtensionList; psp->fd = fd; + psp->myNum = scrn; + psp->dri2.enabled = GL_FALSE; /* ** Do not init dummy context here; actual initialization will be @@ -1021,63 +913,143 @@ __driUtilCreateNewScreen(__DRInativeDisplay *dpy, int scrn, __DRIscreen *psc, */ psp->dummyContextPriv.driScreenPriv = NULL; - psc->destroyScreen = driDestroyScreen; - psc->createNewDrawable = driCreateNewDrawable; - psc->getDrawable = driGetDrawable; - psc->getMSC = driGetMSC; - psc->createNewContext = driCreateNewContext; - - if (internal_api_version >= 20070121) - psc->setTexOffset = psp->DriverAPI.setTexOffset; + psp->DriverAPI = driDriverAPI; - if ( (psp->DriverAPI.InitDriver != NULL) - && !(*psp->DriverAPI.InitDriver)(psp) ) { - _mesa_free( psp ); + *driver_modes = driDriverAPI.InitScreen(psp); + if (*driver_modes == NULL) { + _mesa_free(psp); return NULL; } - return psp; } -/** - * Compare the current GLX API version with a driver supplied required version. - * - * The minimum required version is compared with the API version exported by - * the \c __glXGetInternalVersion function (in libGL.so). - * - * \param required_version Minimum required internal GLX API version. - * \return A tri-value return, as from strcmp is returned. A value less - * than, equal to, or greater than zero will be returned if the - * internal GLX API version is less than, equal to, or greater - * than \c required_version. - * - * \sa __glXGetInternalVersion(). - */ -int driCompareGLXAPIVersion( GLint required_version ) +static __DRIscreen * +dri2CreateNewScreen(int scrn, int fd, unsigned int sarea_handle, + const __DRIextension **extensions, + const __DRIconfig ***driver_configs, void *data) { - if ( api_ver > required_version ) { - return 1; - } - else if ( api_ver == required_version ) { - return 0; - } + static const __DRIextension *emptyExtensionList[] = { NULL }; + __DRIscreen *psp; + unsigned int *p; + drmVersionPtr version; + + if (driDriverAPI.InitScreen2 == NULL) + return NULL; + + psp = _mesa_malloc(sizeof(*psp)); + if (!psp) + return NULL; + + setupLoaderExtensions(psp, extensions); + + version = drmGetVersion(fd); + if (version) { + psp->drm_version.major = version->version_major; + psp->drm_version.minor = version->version_minor; + psp->drm_version.patch = version->version_patchlevel; + drmFreeVersion(version); + } + + psp->extensions = emptyExtensionList; + psp->fd = fd; + psp->myNum = scrn; + psp->dri2.enabled = GL_TRUE; + + if (drmBOReference(psp->fd, sarea_handle, &psp->dri2.sareaBO)) { + fprintf(stderr, "Failed to reference DRI2 sarea BO\n"); + _mesa_free(psp); + return NULL; + } + + if (drmBOMap(psp->fd, &psp->dri2.sareaBO, + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &psp->dri2.sarea)) { + drmBOUnreference(psp->fd, &psp->dri2.sareaBO); + _mesa_free(psp); + return NULL; + } + + p = psp->dri2.sarea; + while (DRI2_SAREA_BLOCK_TYPE(*p)) { + switch (DRI2_SAREA_BLOCK_TYPE(*p)) { + case DRI2_SAREA_BLOCK_LOCK: + psp->dri2.lock = (__DRILock *) p; + break; + case DRI2_SAREA_BLOCK_EVENT_BUFFER: + psp->dri2.buffer = (__DRIEventBuffer *) p; + break; + } + p = DRI2_SAREA_BLOCK_NEXT(p); + } + + psp->lock = (drmLock *) &psp->dri2.lock->lock; - return -1; + psp->DriverAPI = driDriverAPI; + *driver_configs = driDriverAPI.InitScreen2(psp); + if (*driver_configs == NULL) { + drmBOUnmap(psp->fd, &psp->dri2.sareaBO); + drmBOUnreference(psp->fd, &psp->dri2.sareaBO); + _mesa_free(psp); + return NULL; + } + + psp->DriverAPI = driDriverAPI; + + return psp; } +static const __DRIextension **driGetExtensions(__DRIscreen *psp) +{ + return psp->extensions; +} + +const __DRIlegacyExtension driLegacyExtension = { + { __DRI_LEGACY, __DRI_LEGACY_VERSION }, + driCreateNewScreen, + driCreateNewDrawable, + driCreateNewContext +}; + +const __DRIcoreExtension driCoreExtension = { + { __DRI_CORE, __DRI_CORE_VERSION }, + dri2CreateNewScreen, + driDestroyScreen, + driGetExtensions, + driGetConfigAttrib, + driIndexConfigAttrib, + dri2CreateNewDrawable, + driDestroyDrawable, + driSwapBuffers, + dri2CreateNewContext, + driCopyContext, + driDestroyContext, + driBindContext, + driUnbindContext +}; + +/* This is the table of extensions that the loader will dlsym() for. */ +PUBLIC const __DRIextension *__driDriverExtensions[] = { + &driCoreExtension.base, + &driLegacyExtension.base, + NULL +}; + +static int +driFrameTracking(__DRIdrawable *drawable, GLboolean enable) +{ + return GLX_BAD_CONTEXT; +} static int -driQueryFrameTracking( __DRInativeDisplay * dpy, void * priv, - int64_t * sbc, int64_t * missedFrames, - float * lastMissedUsage, float * usage ) +driQueryFrameTracking(__DRIdrawable *dpriv, + int64_t * sbc, int64_t * missedFrames, + float * lastMissedUsage, float * usage) { __DRIswapInfo sInfo; int status; int64_t ust; - __DRIdrawablePrivate * dpriv = (__DRIdrawablePrivate *) priv; - + __DRIscreenPrivate *psp = dpriv->driScreenPriv; status = dpriv->driScreenPriv->DriverAPI.GetSwapInfo( dpriv, & sInfo ); if ( status == 0 ) { @@ -1085,13 +1057,18 @@ driQueryFrameTracking( __DRInativeDisplay * dpy, void * priv, *missedFrames = sInfo.swap_missed_count; *lastMissedUsage = sInfo.swap_missed_usage; - (*dri_interface->getUST)( & ust ); + (*psp->systemTime->getUST)( & ust ); *usage = driCalculateSwapUsage( dpriv, sInfo.swap_ust, ust ); } return status; } +const __DRIframeTrackingExtension driFrameTrackingExtension = { + { __DRI_FRAME_TRACKING, __DRI_FRAME_TRACKING_VERSION }, + driFrameTracking, + driQueryFrameTracking +}; /** * Calculate amount of swap interval used between GLX buffer swaps. @@ -1129,11 +1106,10 @@ driCalculateSwapUsage( __DRIdrawablePrivate *dPriv, int64_t last_swap_ust, int32_t d; int interval; float usage = 1.0; + __DRIscreenPrivate *psp = dPriv->driScreenPriv; - - if ( (*dri_interface->getMSCRate)( dPriv->display, dPriv->draw, &n, &d ) ) { - interval = (dPriv->pdraw->swap_interval != 0) - ? dPriv->pdraw->swap_interval : 1; + if ( (*psp->systemTime->getMSCRate)(dPriv, &n, &d, dPriv->loaderPrivate) ) { + interval = (dPriv->swap_interval != 0) ? dPriv->swap_interval : 1; /* We want to calculate diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h index 027cb7f461e..f2bc4563075 100644 --- a/src/mesa/drivers/dri/common/dri_util.h +++ b/src/mesa/drivers/dri/common/dri_util.h @@ -1,3 +1,24 @@ +/** + * \file dri_util.h + * DRI utility functions definitions. + * + * This module acts as glue between GLX and the actual hardware driver. A DRI + * driver doesn't really \e have to use any of this - it's optional. But, some + * useful stuff is done here that otherwise would have to be duplicated in most + * drivers. + * + * Basically, these utility functions take care of some of the dirty details of + * screen initialization, context creation, context binding, DRM setup, etc. + * + * These functions are compiled into each DRI driver so libGL.so knows nothing + * about them. + * + * \sa dri_util.c. + * + * \author Kevin E. Martin <[email protected]> + * \author Brian Paul <[email protected]> + */ + /* * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. * All Rights Reserved. @@ -23,46 +44,37 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/** - * \file dri_util.h - * DRI utility functions definitions. - * - * This module acts as glue between GLX and the actual hardware driver. A DRI - * driver doesn't really \e have to use any of this - it's optional. But, some - * useful stuff is done here that otherwise would have to be duplicated in most - * drivers. - * - * Basically, these utility functions take care of some of the dirty details of - * screen initialization, context creation, context binding, DRM setup, etc. - * - * These functions are compiled into each DRI driver so libGL.so knows nothing - * about them. - * - * \sa dri_util.c. - * - * \author Kevin E. Martin <[email protected]> - * \author Brian Paul <[email protected]> - */ #ifndef _DRI_UTIL_H_ #define _DRI_UTIL_H_ #include <GL/gl.h> -#include "drm.h" -#include "drm_sarea.h" -#include "xf86drm.h" +#include <drm.h> +#include <drm_sarea.h> +#include <xf86drm.h> #include "GL/internal/glcore.h" #include "GL/internal/dri_interface.h" +#include "GL/internal/dri_sarea.h" #define GLX_BAD_CONTEXT 5 -typedef struct __DRIdisplayPrivateRec __DRIdisplayPrivate; -typedef struct __DRIscreenPrivateRec __DRIscreenPrivate; -typedef struct __DRIcontextPrivateRec __DRIcontextPrivate; -typedef struct __DRIdrawablePrivateRec __DRIdrawablePrivate; typedef struct __DRIswapInfoRec __DRIswapInfo; -typedef struct __DRIutilversionRec2 __DRIutilversion2; +/* Typedefs to avoid rewriting the world. */ +typedef struct __DRIscreenRec __DRIscreenPrivate; +typedef struct __DRIdrawableRec __DRIdrawablePrivate; +typedef struct __DRIcontextRec __DRIcontextPrivate; + +/** + * Extensions. + */ +extern const __DRIlegacyExtension driLegacyExtension; +extern const __DRIcoreExtension driCoreExtension; +extern const __DRIextension driReadDrawableExtension; +extern const __DRIcopySubBufferExtension driCopySubBufferExtension; +extern const __DRIswapControlExtension driSwapControlExtension; +extern const __DRIframeTrackingExtension driFrameTrackingExtension; +extern const __DRImediaStreamCounterExtension driMediaStreamCounterExtension; /** * Used by DRI_VALIDATE_DRAWABLE_INFO @@ -78,7 +90,7 @@ typedef struct __DRIutilversionRec2 __DRIutilversion2; /** * Utility macro to validate the drawable information. * - * See __DRIdrawablePrivate::pStamp and __DRIdrawablePrivate::lastStamp. + * See __DRIdrawable::pStamp and __DRIdrawable::lastStamp. */ #define DRI_VALIDATE_DRAWABLE_INFO(psp, pdp) \ do { \ @@ -107,94 +119,103 @@ do { \ * this structure. */ struct __DriverAPIRec { - /** - * Driver initialization callback - */ - GLboolean (*InitDriver)(__DRIscreenPrivate *driScrnPriv); - + const __DRIconfig **(*InitScreen) (__DRIscreen * priv); + /** * Screen destruction callback */ - void (*DestroyScreen)(__DRIscreenPrivate *driScrnPriv); + void (*DestroyScreen)(__DRIscreen *driScrnPriv); /** * Context creation callback */ GLboolean (*CreateContext)(const __GLcontextModes *glVis, - __DRIcontextPrivate *driContextPriv, + __DRIcontext *driContextPriv, void *sharedContextPrivate); /** * Context destruction callback */ - void (*DestroyContext)(__DRIcontextPrivate *driContextPriv); + void (*DestroyContext)(__DRIcontext *driContextPriv); /** * Buffer (drawable) creation callback */ - GLboolean (*CreateBuffer)(__DRIscreenPrivate *driScrnPriv, - __DRIdrawablePrivate *driDrawPriv, + GLboolean (*CreateBuffer)(__DRIscreen *driScrnPriv, + __DRIdrawable *driDrawPriv, const __GLcontextModes *glVis, GLboolean pixmapBuffer); /** * Buffer (drawable) destruction callback */ - void (*DestroyBuffer)(__DRIdrawablePrivate *driDrawPriv); + void (*DestroyBuffer)(__DRIdrawable *driDrawPriv); /** * Buffer swapping callback */ - void (*SwapBuffers)(__DRIdrawablePrivate *driDrawPriv); + void (*SwapBuffers)(__DRIdrawable *driDrawPriv); /** * Context activation callback */ - GLboolean (*MakeCurrent)(__DRIcontextPrivate *driContextPriv, - __DRIdrawablePrivate *driDrawPriv, - __DRIdrawablePrivate *driReadPriv); + GLboolean (*MakeCurrent)(__DRIcontext *driContextPriv, + __DRIdrawable *driDrawPriv, + __DRIdrawable *driReadPriv); /** * Context unbinding callback */ - GLboolean (*UnbindContext)(__DRIcontextPrivate *driContextPriv); + GLboolean (*UnbindContext)(__DRIcontext *driContextPriv); /** * Retrieves statistics about buffer swap operations. Required if * GLX_OML_sync_control or GLX_MESA_swap_frame_usage is supported. */ - int (*GetSwapInfo)( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo ); - + int (*GetSwapInfo)( __DRIdrawable *dPriv, __DRIswapInfo * sInfo ); - /** - * Required if GLX_SGI_video_sync or GLX_OML_sync_control is - * supported. - */ - int (*GetMSC)( __DRIscreenPrivate * priv, int64_t * count ); /** * These are required if GLX_OML_sync_control is supported. */ /*@{*/ - int (*WaitForMSC)( __DRIdrawablePrivate *priv, int64_t target_msc, + int (*WaitForMSC)( __DRIdrawable *priv, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t * msc ); - int (*WaitForSBC)( __DRIdrawablePrivate *priv, int64_t target_sbc, + int (*WaitForSBC)( __DRIdrawable *priv, int64_t target_sbc, int64_t * msc, int64_t * sbc ); - int64_t (*SwapBuffersMSC)( __DRIdrawablePrivate *priv, int64_t target_msc, + int64_t (*SwapBuffersMSC)( __DRIdrawable *priv, int64_t target_msc, int64_t divisor, int64_t remainder ); /*@}*/ - void (*CopySubBuffer)(__DRIdrawablePrivate *driDrawPriv, + void (*CopySubBuffer)(__DRIdrawable *driDrawPriv, int x, int y, int w, int h); /** - * See corresponding field in \c __DRIscreenRec. + * New version of GetMSC so we can pass drawable data to the low + * level DRM driver (e.g. pipe info). Required if + * GLX_SGI_video_sync or GLX_OML_sync_control is supported. */ - void (*setTexOffset)(__DRIcontext *pDRICtx, GLint texname, - unsigned long long offset, GLint depth, GLuint pitch); + int (*GetDrawableMSC) ( __DRIscreen * priv, + __DRIdrawable *drawablePrivate, + int64_t *count); + + + + /* DRI2 Entry points */ + const __DRIconfig **(*InitScreen2) (__DRIscreen * priv); + void (*HandleDrawableConfig)(__DRIdrawable *dPriv, + __DRIcontext *pcp, + __DRIDrawableConfigEvent *event); + + void (*HandleBufferAttach)(__DRIdrawable *dPriv, + __DRIcontext *pcp, + __DRIBufferAttachEvent *ba); + }; +extern const struct __DriverAPIRec driDriverAPI; + struct __DRIswapInfoRec { /** @@ -230,7 +251,7 @@ struct __DRIswapInfoRec { /** * Per-drawable private DRI driver information. */ -struct __DRIdrawablePrivateRec { +struct __DRIdrawableRec { /** * Kernel drawable handle */ @@ -244,10 +265,10 @@ struct __DRIdrawablePrivateRec { void *driverPrivate; /** - * X's drawable ID associated with this private drawable. + * Private data from the loader. We just hold on to it and pass + * it back when calling into loader provided functions. */ - __DRIid draw; - __DRIdrawable *pdraw; + void *loaderPrivate; /** * Reference count for number of context's currently bound to this @@ -272,7 +293,7 @@ struct __DRIdrawablePrivateRec { /** * Last value of the stamp. * - * If this differs from the value stored at __DRIdrawablePrivate::pStamp, + * If this differs from the value stored at __DRIdrawable::pStamp, * then the drawable information has been modified by the X server, and the * drawable information (below) should be retrieved from the X server. */ @@ -306,41 +327,56 @@ struct __DRIdrawablePrivateRec { /*@}*/ /** - * Pointer to context to which this drawable is currently bound. + * \name Vertical blank tracking information + * Used for waiting on vertical blank events. */ - __DRIcontextPrivate *driContextPriv; + /*@{*/ + unsigned int vblSeq; + unsigned int vblFlags; + /*@}*/ /** - * Pointer to screen on which this drawable was created. + * \name Monotonic MSC tracking + * + * Low level driver is responsible for updating msc_base and + * vblSeq values so that higher level code can calculate + * a new msc value or msc target for a WaitMSC call. The new value + * will be: + * msc = msc_base + get_vblank_count() - vblank_base; + * + * And for waiting on a value, core code will use: + * actual_target = target_msc - msc_base + vblank_base; + */ + /*@{*/ + int64_t vblank_base; + int64_t msc_base; + /*@}*/ + + /** + * Pointer to context to which this drawable is currently bound. */ - __DRIscreenPrivate *driScreenPriv; + __DRIcontext *driContextPriv; /** - * \name Display and screen information. - * - * Basically just need these for when the locking code needs to call - * \c __driUtilUpdateDrawableInfo. + * Pointer to screen on which this drawable was created. */ - /*@{*/ - __DRInativeDisplay *display; - int screen; - /*@}*/ + __DRIscreen *driScreenPriv; /** - * Called via glXSwapBuffers(). + * Controls swap interval as used by GLX_SGI_swap_control and + * GLX_MESA_swap_control. */ - void (*swapBuffers)( __DRIdrawablePrivate *dPriv ); + unsigned int swap_interval; + struct { + unsigned int tail; + unsigned int drawable_id; + } dri2; }; /** * Per-context private driver information. */ -struct __DRIcontextPrivateRec { - /** - * Kernel context handle used to access the device lock. - */ - __DRIid contextID; - +struct __DRIcontextRec { /** * Kernel context handle used to access the device lock. */ @@ -352,35 +388,30 @@ struct __DRIcontextPrivateRec { void *driverPrivate; /** - * This context's display pointer. + * Pointer back to the \c __DRIcontext that contains this structure. */ - __DRInativeDisplay *display; + __DRIcontext *pctx; /** * Pointer to drawable currently bound to this context for drawing. */ - __DRIdrawablePrivate *driDrawablePriv; + __DRIdrawable *driDrawablePriv; /** * Pointer to drawable currently bound to this context for reading. */ - __DRIdrawablePrivate *driReadablePriv; + __DRIdrawable *driReadablePriv; /** * Pointer to screen on which this context was created. */ - __DRIscreenPrivate *driScreenPriv; + __DRIscreen *driScreenPriv; }; /** * Per-screen private driver information. */ -struct __DRIscreenPrivateRec { - /** - * Display for this screen - */ - __DRInativeDisplay *display; - +struct __DRIscreenRec { /** * Current screen's number */ @@ -391,38 +422,21 @@ struct __DRIscreenPrivateRec { */ struct __DriverAPIRec DriverAPI; + const __DRIextension **extensions; /** - * \name DDX version * DDX / 2D driver version information. - * \todo Replace these fields with a \c __DRIversionRec. */ - /*@{*/ - int ddxMajor; - int ddxMinor; - int ddxPatch; - /*@}*/ + __DRIversion ddx_version; /** - * \name DRI version * DRI X extension version information. - * \todo Replace these fields with a \c __DRIversionRec. */ - /*@{*/ - int driMajor; - int driMinor; - int driPatch; - /*@}*/ + __DRIversion dri_version; /** - * \name DRM version * DRM (kernel module) version information. - * \todo Replace these fields with a \c __DRIversionRec. */ - /*@{*/ - int drmMajor; - int drmMinor; - int drmPatch; - /*@}*/ + __DRIversion drm_version; /** * ID used when the client sets the drawable lock. @@ -485,12 +499,7 @@ struct __DRIscreenPrivateRec { * context is created when the first "real" context is created on this * screen. */ - __DRIcontextPrivate dummyContextPriv; - - /** - * Hash table to hold the drawable information for this screen. - */ - void *drawHash; + __DRIcontext dummyContextPriv; /** * Device-dependent private information (not stored in the SAREA). @@ -500,65 +509,45 @@ struct __DRIscreenPrivateRec { void *private; /** - * GLX visuals / FBConfigs for this screen. These are stored as a - * linked list. - * - * \note - * This field is \b only used in conjunction with the old interfaces. If - * the new interfaces are used, this field will be set to \c NULL and will - * not be dereferenced. - */ - __GLcontextModes *modes; - - /** * Pointer back to the \c __DRIscreen that contains this structure. */ - __DRIscreen *psc; -}; - -/** - * Used to store a version which includes a major range instead of a single - * major version number. - */ -struct __DRIutilversionRec2 { - int major_min; /** min allowed Major version number. */ - int major_max; /** max allowed Major version number. */ - int minor; /**< Minor version number. */ - int patch; /**< Patch-level. */ + /* Extensions provided by the loader. */ + const __DRIgetDrawableInfoExtension *getDrawableInfo; + const __DRIsystemTimeExtension *systemTime; + const __DRIdamageExtension *damage; + + struct { + /* Flag to indicate that this is a DRI2 screen. Many of the above + * fields will not be valid or initializaed in that case. */ + int enabled; + drmBO sareaBO; + void *sarea; + __DRIEventBuffer *buffer; + __DRILock *lock; + __DRIloaderExtension *loader; + } dri2; + + /* The lock actually in use, old sarea or DRI2 */ + drmLock *lock; }; - extern void __driUtilMessage(const char *f, ...); extern void -__driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp); - - -extern __DRIscreenPrivate * __driUtilCreateNewScreen( __DRInativeDisplay *dpy, - int scrn, __DRIscreen *psc, __GLcontextModes * modes, - const __DRIversion * ddx_version, const __DRIversion * dri_version, - const __DRIversion * drm_version, const __DRIframebuffer * frame_buffer, - drm_sarea_t *pSAREA, int fd, int internal_api_version, - const struct __DriverAPIRec *driverAPI ); +__driUtilUpdateDrawableInfo(__DRIdrawable *pdp); -/* Test the version of the internal GLX API. Returns a value like strcmp. */ extern int -driCompareGLXAPIVersion( GLint required_version ); +__driParseEvents(__DRIcontext *psp, __DRIdrawable *pdp); extern float -driCalculateSwapUsage( __DRIdrawablePrivate *dPriv, +driCalculateSwapUsage( __DRIdrawable *dPriv, int64_t last_swap_ust, int64_t current_ust ); -/** - * Pointer to the \c __DRIinterfaceMethods passed to the driver by the loader. - * - * This pointer is set in the driver's \c __driCreateNewScreen function and - * is defined in dri_util.c. - */ -extern const __DRIinterfaceMethods * dri_interface; +extern GLint +driIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 ); #endif /* _DRI_UTIL_H_ */ diff --git a/src/mesa/drivers/dri/common/drirenderbuffer.c b/src/mesa/drivers/dri/common/drirenderbuffer.c index d34da53479e..d36af3e5bee 100644 --- a/src/mesa/drivers/dri/common/drirenderbuffer.c +++ b/src/mesa/drivers/dri/common/drirenderbuffer.c @@ -209,8 +209,6 @@ driUpdateFramebufferSize(GLcontext *ctx, const __DRIdrawablePrivate *dPriv) struct gl_framebuffer *fb = (struct gl_framebuffer *) dPriv->driverPrivate; if (fb && (dPriv->w != fb->Width || dPriv->h != fb->Height)) { ctx->Driver.ResizeBuffers(ctx, fb, dPriv->w, dPriv->h); - /* if the driver needs the hw lock for ResizeBuffers, the drawable - might have changed again by now */ assert(fb->Width == dPriv->w); assert(fb->Height == dPriv->h); } diff --git a/src/mesa/drivers/dri/common/spantmp2.h b/src/mesa/drivers/dri/common/spantmp2.h index 50f3cf55816..53f5f846a0b 100644 --- a/src/mesa/drivers/dri/common/spantmp2.h +++ b/src/mesa/drivers/dri/common/spantmp2.h @@ -114,7 +114,7 @@ do { \ GLuint p = *(volatile GLuint *) GET_PTR(_x, _y); \ __asm__ __volatile__( "bswap %0; rorl $8, %0" \ - : "=r" (p) : "r" (p) ); \ + : "=r" (p) : "0" (p) ); \ ((GLuint *)rgba)[0] = p; \ } while (0) # elif defined( MESA_BIG_ENDIAN ) diff --git a/src/mesa/drivers/dri/common/utils.c b/src/mesa/drivers/dri/common/utils.c index 6a189e72858..7fbe0d855d0 100644 --- a/src/mesa/drivers/dri/common/utils.c +++ b/src/mesa/drivers/dri/common/utils.c @@ -419,21 +419,6 @@ driCheckDriDdxDrmVersions2(const char * driver_name, drmActual, drmExpected); } - - -GLint -driIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 ) -{ - if (rect2.x1 > rect1.x1) rect1.x1 = rect2.x1; - if (rect2.x2 < rect1.x2) rect1.x2 = rect2.x2; - if (rect2.y1 > rect1.y1) rect1.y1 = rect2.y1; - if (rect2.y2 < rect1.y2) rect1.y2 = rect2.y2; - - if (rect1.x1 > rect1.x2 || rect1.y1 > rect1.y2) return 0; - - return (rect1.x2 - rect1.x1) * (rect1.y2 - rect1.y1); -} - GLboolean driClipRectToFramebuffer( const GLframebuffer *buffer, GLint *x, GLint *y, GLsizei *width, GLsizei *height ) @@ -467,8 +452,6 @@ GLboolean driClipRectToFramebuffer( const GLframebuffer *buffer, return GL_TRUE; } - - /** * Creates a set of \c __GLcontextModes that a driver will expose. * @@ -536,86 +519,99 @@ GLboolean driClipRectToFramebuffer( const GLframebuffer *buffer, * \c GL_UNSIGNED_3BYTE_8_8_8, \c GL_4FLOAT_32_32_32_32, * \c GL_4HALF_16_16_16_16, etc. We can cross that bridge when we come to it. */ -GLboolean -driFillInModes( __GLcontextModes ** ptr_to_modes, - GLenum fb_format, GLenum fb_type, - const u_int8_t * depth_bits, const u_int8_t * stencil_bits, - unsigned num_depth_stencil_bits, - const GLenum * db_modes, unsigned num_db_modes, - int visType ) +__DRIconfig ** +driCreateConfigs(GLenum fb_format, GLenum fb_type, + const u_int8_t * depth_bits, const u_int8_t * stencil_bits, + unsigned num_depth_stencil_bits, + const GLenum * db_modes, unsigned num_db_modes) { - static const u_int8_t bits_table[3][4] = { + static const u_int8_t bits_table[4][4] = { /* R G B A */ + { 3, 3, 2, 0 }, /* Any GL_UNSIGNED_BYTE_3_3_2 */ { 5, 6, 5, 0 }, /* Any GL_UNSIGNED_SHORT_5_6_5 */ { 8, 8, 8, 0 }, /* Any RGB with any GL_UNSIGNED_INT_8_8_8_8 */ { 8, 8, 8, 8 } /* Any RGBA with any GL_UNSIGNED_INT_8_8_8_8 */ }; - /* The following arrays are all indexed by the fb_type masked with 0x07. - * Given the four supported fb_type values, this results in valid array - * indices of 3, 4, 5, and 7. - */ - static const u_int32_t masks_table_rgb[8][4] = { - { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, + static const u_int32_t masks_table_rgb[6][4] = { + { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 3_3_2 */ + { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 2_3_3_REV */ { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5 */ { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5_REV */ { 0xFF000000, 0x00FF0000, 0x0000FF00, 0x00000000 }, /* 8_8_8_8 */ - { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000 } /* 8_8_8_8_REV */ }; - static const u_int32_t masks_table_rgba[8][4] = { - { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, + static const u_int32_t masks_table_rgba[6][4] = { + { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 3_3_2 */ + { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 2_3_3_REV */ { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5 */ { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5_REV */ { 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF }, /* 8_8_8_8 */ - { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 }, /* 8_8_8_8_REV */ }; - static const u_int32_t masks_table_bgr[8][4] = { - { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, + static const u_int32_t masks_table_bgr[6][4] = { + { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 3_3_2 */ + { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 2_3_3_REV */ { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5 */ { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5_REV */ { 0x0000FF00, 0x00FF0000, 0xFF000000, 0x00000000 }, /* 8_8_8_8 */ - { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 }, /* 8_8_8_8_REV */ }; - static const u_int32_t masks_table_bgra[8][4] = { - { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, + static const u_int32_t masks_table_bgra[6][4] = { + { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 3_3_2 */ + { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 2_3_3_REV */ { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5 */ { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5_REV */ { 0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF }, /* 8_8_8_8 */ - { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000 }, /* 8_8_8_8_REV */ }; - static const u_int8_t bytes_per_pixel[8] = { - 0, 0, 0, 2, 2, 4, 0, 4 + static const u_int8_t bytes_per_pixel[6] = { + 1, /* 3_3_2 */ + 1, /* 2_3_3_REV */ + 2, /* 5_6_5 */ + 2, /* 5_6_5_REV */ + 4, /* 8_8_8_8 */ + 4 /* 8_8_8_8_REV */ }; const u_int8_t * bits; const u_int32_t * masks; - const int index = fb_type & 0x07; - __GLcontextModes * modes = *ptr_to_modes; + int index; + __DRIconfig **configs, **c; + __GLcontextModes *modes; unsigned i; unsigned j; unsigned k; - - - if ( bytes_per_pixel[ index ] == 0 ) { - fprintf( stderr, "[%s:%u] Framebuffer type 0x%04x has 0 bytes per pixel.\n", - __FUNCTION__, __LINE__, fb_type ); - return GL_FALSE; + unsigned num_modes; + unsigned num_accum_bits = 2; + + switch ( fb_type ) { + case GL_UNSIGNED_BYTE_3_3_2: + index = 0; + break; + case GL_UNSIGNED_BYTE_2_3_3_REV: + index = 1; + break; + case GL_UNSIGNED_SHORT_5_6_5: + index = 2; + break; + case GL_UNSIGNED_SHORT_5_6_5_REV: + index = 3; + break; + case GL_UNSIGNED_INT_8_8_8_8: + index = 4; + break; + case GL_UNSIGNED_INT_8_8_8_8_REV: + index = 5; + break; + default: + fprintf( stderr, "[%s:%u] Unknown framebuffer type 0x%04x.\n", + __FUNCTION__, __LINE__, fb_type ); + return NULL; } @@ -627,40 +623,55 @@ driFillInModes( __GLcontextModes ** ptr_to_modes, switch ( fb_format ) { case GL_RGB: - bits = (bytes_per_pixel[ index ] == 2) - ? bits_table[0] : bits_table[1]; masks = masks_table_rgb[ index ]; break; case GL_RGBA: - bits = (bytes_per_pixel[ index ] == 2) - ? bits_table[0] : bits_table[2]; masks = masks_table_rgba[ index ]; break; case GL_BGR: - bits = (bytes_per_pixel[ index ] == 2) - ? bits_table[0] : bits_table[1]; masks = masks_table_bgr[ index ]; break; case GL_BGRA: - bits = (bytes_per_pixel[ index ] == 2) - ? bits_table[0] : bits_table[2]; masks = masks_table_bgra[ index ]; break; default: - fprintf( stderr, "[%s:%u] Framebuffer format 0x%04x is not GL_RGB, GL_RGBA, GL_BGR, or GL_BGRA.\n", - __FUNCTION__, __LINE__, fb_format ); - return GL_FALSE; + fprintf( stderr, "[%s:%u] Unknown framebuffer format 0x%04x.\n", + __FUNCTION__, __LINE__, fb_format ); + return NULL; + } + + switch ( bytes_per_pixel[ index ] ) { + case 1: + bits = bits_table[0]; + break; + case 2: + bits = bits_table[1]; + break; + default: + bits = ((fb_format == GL_RGB) || (fb_format == GL_BGR)) + ? bits_table[2] + : bits_table[3]; + break; } + num_modes = num_depth_stencil_bits * num_db_modes * num_accum_bits; + configs = _mesa_calloc((num_modes + 1) * sizeof *configs); + if (configs == NULL) + return NULL; + c = configs; for ( k = 0 ; k < num_depth_stencil_bits ; k++ ) { for ( i = 0 ; i < num_db_modes ; i++ ) { - for ( j = 0 ; j < 2 ; j++ ) { + for ( j = 0 ; j < num_accum_bits ; j++ ) { + *c = _mesa_malloc (sizeof **c); + modes = &(*c)->modes; + c++; + memset(modes, 0, sizeof *modes); modes->redBits = bits[0]; modes->greenBits = bits[1]; modes->blueBits = bits[2]; @@ -681,7 +692,13 @@ driFillInModes( __GLcontextModes ** ptr_to_modes, modes->stencilBits = stencil_bits[k]; modes->depthBits = depth_bits[k]; - modes->visualType = visType; + modes->transparentPixel = GLX_NONE; + modes->transparentRed = GLX_DONT_CARE; + modes->transparentGreen = GLX_DONT_CARE; + modes->transparentBlue = GLX_DONT_CARE; + modes->transparentAlpha = GLX_DONT_CARE; + modes->transparentIndex = GLX_DONT_CARE; + modes->visualType = GLX_DONT_CARE; modes->renderType = GLX_RGBA_BIT; modes->drawableType = GLX_WINDOW_BIT; modes->rgbMode = GL_TRUE; @@ -701,11 +718,155 @@ driFillInModes( __GLcontextModes ** ptr_to_modes, modes->haveDepthBuffer = (modes->depthBits > 0); modes->haveStencilBuffer = (modes->stencilBits > 0); - modes = modes->next; + modes->bindToTextureRgb = GL_TRUE; + modes->bindToTextureRgba = GL_TRUE; + modes->bindToMipmapTexture = GL_FALSE; + modes->bindToTextureTargets = modes->rgbMode ? + __DRI_ATTRIB_TEXTURE_1D_BIT | + __DRI_ATTRIB_TEXTURE_2D_BIT | + __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT : + 0; } } } + *c = NULL; + + return configs; +} + +const __DRIconfig **driConcatConfigs(__DRIconfig **a, __DRIconfig **b) +{ + const __DRIconfig **all; + int i, j, index; + + i = 0; + while (a[i] != NULL) + i++; + j = 0; + while (b[j] != NULL) + j++; + + all = _mesa_malloc((i + j + 1) * sizeof *all); + index = 0; + for (i = 0; a[i] != NULL; i++) + all[index++] = a[i]; + for (j = 0; b[j] != NULL; j++) + all[index++] = b[j]; + all[index++] = NULL; + + _mesa_free(a); + _mesa_free(b); + + return all; +} + +#define __ATTRIB(attrib, field) \ + { attrib, offsetof(__GLcontextModes, field) } + +static const struct { unsigned int attrib, offset; } attribMap[] = { + __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE, rgbBits), + __ATTRIB(__DRI_ATTRIB_LEVEL, level), + __ATTRIB(__DRI_ATTRIB_RED_SIZE, redBits), + __ATTRIB(__DRI_ATTRIB_GREEN_SIZE, greenBits), + __ATTRIB(__DRI_ATTRIB_BLUE_SIZE, blueBits), + __ATTRIB(__DRI_ATTRIB_ALPHA_SIZE, alphaBits), + __ATTRIB(__DRI_ATTRIB_DEPTH_SIZE, depthBits), + __ATTRIB(__DRI_ATTRIB_STENCIL_SIZE, stencilBits), + __ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE, accumRedBits), + __ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE, accumGreenBits), + __ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE, accumBlueBits), + __ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE, accumAlphaBits), + __ATTRIB(__DRI_ATTRIB_SAMPLE_BUFFERS, sampleBuffers), + __ATTRIB(__DRI_ATTRIB_SAMPLES, samples), + __ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER, doubleBufferMode), + __ATTRIB(__DRI_ATTRIB_STEREO, stereoMode), + __ATTRIB(__DRI_ATTRIB_AUX_BUFFERS, numAuxBuffers), + __ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE, transparentPixel), + __ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE, transparentPixel), + __ATTRIB(__DRI_ATTRIB_TRANSPARENT_RED_VALUE, transparentRed), + __ATTRIB(__DRI_ATTRIB_TRANSPARENT_GREEN_VALUE, transparentGreen), + __ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE, transparentBlue), + __ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE, transparentAlpha), + __ATTRIB(__DRI_ATTRIB_FLOAT_MODE, floatMode), + __ATTRIB(__DRI_ATTRIB_RED_MASK, redMask), + __ATTRIB(__DRI_ATTRIB_GREEN_MASK, greenMask), + __ATTRIB(__DRI_ATTRIB_BLUE_MASK, blueMask), + __ATTRIB(__DRI_ATTRIB_ALPHA_MASK, alphaMask), + __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH, maxPbufferWidth), + __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT, maxPbufferHeight), + __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS, maxPbufferPixels), + __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH, optimalPbufferWidth), + __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT, optimalPbufferHeight), + __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, swapMethod), + __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb), + __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA, bindToTextureRgba), + __ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE, bindToMipmapTexture), + __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS, bindToTextureTargets), + __ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted), + + /* The struct field doesn't matter here, these are handled by the + * switch in driGetConfigAttribIndex. We need them in the array + * so the iterator includes them though.*/ + __ATTRIB(__DRI_ATTRIB_RENDER_TYPE, level), + __ATTRIB(__DRI_ATTRIB_CONFIG_CAVEAT, level), + __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, level) +}; + +#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) + +static int +driGetConfigAttribIndex(const __DRIconfig *config, + unsigned int index, unsigned int *value) +{ + switch (attribMap[index].attrib) { + case __DRI_ATTRIB_RENDER_TYPE: + if (config->modes.rgbMode) + *value = __DRI_ATTRIB_RGBA_BIT; + else + *value = __DRI_ATTRIB_COLOR_INDEX_BIT; + break; + case __DRI_ATTRIB_CONFIG_CAVEAT: + if (config->modes.visualRating == GLX_NON_CONFORMANT_CONFIG) + *value = __DRI_ATTRIB_NON_CONFORMANT_CONFIG; + else if (config->modes.visualRating == GLX_SLOW_CONFIG) + *value = __DRI_ATTRIB_SLOW_BIT; + else + *value = 0; + break; + case __DRI_ATTRIB_SWAP_METHOD: + break; + + default: + *value = *(unsigned int *) + ((char *) &config->modes + attribMap[index].offset); + + break; + } - *ptr_to_modes = modes; return GL_TRUE; } + +int +driGetConfigAttrib(const __DRIconfig *config, + unsigned int attrib, unsigned int *value) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(attribMap); i++) + if (attribMap[i].attrib == attrib) + return driGetConfigAttribIndex(config, i, value); + + return GL_FALSE; +} + +int +driIndexConfigAttrib(const __DRIconfig *config, int index, + unsigned int *attrib, unsigned int *value) +{ + if (index >= 0 && index < ARRAY_SIZE(attribMap)) { + *attrib = attribMap[index].attrib; + return driGetConfigAttribIndex(config, index, value); + } + + return GL_FALSE; +} diff --git a/src/mesa/drivers/dri/common/utils.h b/src/mesa/drivers/dri/common/utils.h index b28b895627d..9ac3b51447d 100644 --- a/src/mesa/drivers/dri/common/utils.h +++ b/src/mesa/drivers/dri/common/utils.h @@ -28,8 +28,11 @@ #ifndef DRI_DEBUG_H #define DRI_DEBUG_H +#include <GL/gl.h> +#include <GL/internal/dri_interface.h> #include "context.h" -#include "dri_util.h" + +typedef struct __DRIutilversionRec2 __DRIutilversion2; struct dri_debug_control { const char * string; @@ -83,6 +86,17 @@ struct dri_extension { const struct dri_extension_function * functions; }; +/** + * Used to store a version which includes a major range instead of a single + * major version number. + */ +struct __DRIutilversionRec2 { + int major_min; /** min allowed Major version number. */ + int major_max; /** max allowed Major version number. */ + int minor; /**< Minor version number. */ + int patch; /**< Patch-level. */ +}; + extern unsigned driParseDebugString( const char * debug, const struct dri_debug_control * control ); @@ -105,16 +119,27 @@ extern GLboolean driCheckDriDdxDrmVersions3(const char * driver_name, const __DRIversion * ddxActual, const __DRIutilversion2 * ddxExpected, const __DRIversion * drmActual, const __DRIversion * drmExpected); -extern GLint driIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 ); - extern GLboolean driClipRectToFramebuffer( const GLframebuffer *buffer, GLint *x, GLint *y, GLsizei *width, GLsizei *height ); -extern GLboolean driFillInModes( __GLcontextModes ** modes, - GLenum fb_format, GLenum fb_type, - const u_int8_t * depth_bits, const u_int8_t * stencil_bits, - unsigned num_depth_stencil_bits, - const GLenum * db_modes, unsigned num_db_modes, int visType ); +struct __DRIconfigRec { + __GLcontextModes modes; +}; + +extern __DRIconfig ** +driCreateConfigs(GLenum fb_format, GLenum fb_type, + const u_int8_t * depth_bits, const u_int8_t * stencil_bits, + unsigned num_depth_stencil_bits, + const GLenum * db_modes, unsigned num_db_modes); + +const __DRIconfig **driConcatConfigs(__DRIconfig **a, __DRIconfig **b); + +int +driGetConfigAttrib(const __DRIconfig *config, + unsigned int attrib, unsigned int *value); +int +driIndexConfigAttrib(const __DRIconfig *config, int index, + unsigned int *attrib, unsigned int *value); #endif /* DRI_DEBUG_H */ diff --git a/src/mesa/drivers/dri/common/vblank.c b/src/mesa/drivers/dri/common/vblank.c index 094950d3626..0008ab1c34a 100644 --- a/src/mesa/drivers/dri/common/vblank.c +++ b/src/mesa/drivers/dri/common/vblank.c @@ -34,6 +34,16 @@ #include "vblank.h" #include "xmlpool.h" +static unsigned int msc_to_vblank(__DRIdrawablePrivate * dPriv, int64_t msc) +{ + return (unsigned int)(msc - dPriv->msc_base + dPriv->vblank_base); +} + +static int64_t vblank_to_msc(__DRIdrawablePrivate * dPriv, unsigned int vblank) +{ + return (int64_t)(vblank - dPriv->vblank_base + dPriv->msc_base); +} + /****************************************************************************/ /** @@ -41,7 +51,7 @@ * * Stores the 64-bit count of vertical refreshes since some (arbitrary) * point in time in \c count. Unless the value wraps around, which it - * may, it will never decrease. + * may, it will never decrease for a given drawable. * * \warning This function is called from \c glXGetVideoSyncSGI, which expects * a \c count of type \c unsigned (32-bit), and \c glXGetSyncValuesOML, which @@ -49,11 +59,14 @@ * currently always returns a \c sequence of type \c unsigned. * * \param priv Pointer to the DRI screen private struct. + * \param dPriv Pointer to the DRI drawable private struct * \param count Storage to hold MSC counter. * \return Zero is returned on success. A negative errno value * is returned on failure. */ -int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count ) +int driDrawableGetMSC32( __DRIscreenPrivate * priv, + __DRIdrawablePrivate * dPriv, + int64_t * count) { drmVBlank vbl; int ret; @@ -62,14 +75,21 @@ int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count ) vbl.request.type = DRM_VBLANK_RELATIVE; vbl.request.sequence = 0; + if ( dPriv && dPriv->vblFlags & VBLANK_FLAG_SECONDARY ) + vbl.request.type |= DRM_VBLANK_SECONDARY; ret = drmWaitVBlank( priv->fd, &vbl ); - *count = (int64_t)vbl.reply.sequence; + + if (dPriv) { + *count = vblank_to_msc(dPriv, vbl.reply.sequence); + } else { + /* Old driver (no knowledge of drawable MSC callback) */ + *count = vbl.reply.sequence; + } return ret; } - /****************************************************************************/ /** * Wait for a specified refresh count. This implements most of the @@ -122,7 +142,9 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv, */ vbl.request.type = dont_wait ? DRM_VBLANK_RELATIVE : DRM_VBLANK_ABSOLUTE; - vbl.request.sequence = next; + vbl.request.sequence = next ? msc_to_vblank(priv, next) : 0; + if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) + vbl.request.type |= DRM_VBLANK_SECONDARY; if ( drmWaitVBlank( priv->driScreenPriv->fd, &vbl ) != 0 ) { /* FIXME: This doesn't seem like the right thing to return here. @@ -130,8 +152,10 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv, return GLX_BAD_CONTEXT; } + *msc = vblank_to_msc(priv, vbl.reply.sequence); + dont_wait = 0; - if (target_msc != 0 && vbl.reply.sequence == target) + if (target_msc != 0 && *msc == target) break; /* Assuming the wait-done test fails, the next refresh to wait for @@ -141,9 +165,9 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv, * If this refresh has already happened, we add divisor to obtain * the next refresh after the current one that will satisfy it. */ - r = (vbl.reply.sequence % (unsigned int)divisor); - next = (vbl.reply.sequence - r + (unsigned int)remainder); - if (next <= vbl.reply.sequence) next += (unsigned int)divisor; + r = (*msc % (unsigned int)divisor); + next = (*msc - r + (unsigned int)remainder); + if (next <= *msc) next += (unsigned int)divisor; } while ( r != (unsigned int)remainder ); } @@ -153,7 +177,10 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv, */ vbl.request.type = DRM_VBLANK_ABSOLUTE; - vbl.request.sequence = target_msc; + vbl.request.sequence = target_msc ? msc_to_vblank(priv, target_msc) : 0; + + if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) + vbl.request.type |= DRM_VBLANK_SECONDARY; if ( drmWaitVBlank( priv->driScreenPriv->fd, &vbl ) != 0 ) { /* FIXME: This doesn't seem like the right thing to return here. @@ -162,8 +189,8 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv, } } - *msc = (target_msc & 0xffffffff00000000LL); - *msc |= vbl.reply.sequence; + *msc = vblank_to_msc(priv, vbl.reply.sequence); + if ( *msc < target_msc ) { *msc += 0x0000000100000000LL; } @@ -232,8 +259,8 @@ static int do_wait( drmVBlank * vbl, GLuint * vbl_seq, int fd ) if ( first_time ) { fprintf(stderr, "%s: drmWaitVBlank returned %d, IRQs don't seem to be" - " working correctly.\nTry running with LIBGL_THROTTLE_REFRESH" - " and LIBL_SYNC_REFRESH unset.\n", __FUNCTION__, ret); + " working correctly.\nTry adjusting the vblank_mode" + " configuration parameter.\n", __FUNCTION__, ret); first_time = GL_FALSE; } @@ -247,20 +274,42 @@ static int do_wait( drmVBlank * vbl, GLuint * vbl_seq, int fd ) /****************************************************************************/ /** + * Returns the default swap interval of the given drawable. + */ + +static unsigned +driGetDefaultVBlankInterval( const __DRIdrawablePrivate *priv ) +{ + if ( (priv->vblFlags & (VBLANK_FLAG_THROTTLE | VBLANK_FLAG_SYNC)) != 0 ) { + return 1; + } + else { + return 0; + } +} + + +/****************************************************************************/ +/** * Sets the default swap interval when the drawable is first bound to a * direct rendering context. */ -void driDrawableInitVBlank( __DRIdrawablePrivate *priv, GLuint flags, - GLuint *vbl_seq ) +void driDrawableInitVBlank( __DRIdrawablePrivate *priv ) { - if ( priv->pdraw->swap_interval == (unsigned)-1 ) { + if ( priv->swap_interval == (unsigned)-1 && + !( priv->vblFlags & VBLANK_FLAG_NO_IRQ ) ) { /* Get current vertical blank sequence */ - drmVBlank vbl = { .request={ .type = DRM_VBLANK_RELATIVE, .sequence = 0 } }; - do_wait( &vbl, vbl_seq, priv->driScreenPriv->fd ); - - priv->pdraw->swap_interval = (flags & (VBLANK_FLAG_THROTTLE | - VBLANK_FLAG_SYNC)) != 0 ? 1 : 0; + drmVBlank vbl; + + vbl.request.type = DRM_VBLANK_RELATIVE; + if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) + vbl.request.type |= DRM_VBLANK_SECONDARY; + vbl.request.sequence = 0; + do_wait( &vbl, &priv->vblSeq, priv->driScreenPriv->fd ); + priv->vblank_base = priv->vblSeq; + + priv->swap_interval = driGetDefaultVBlankInterval( priv ); } } @@ -271,21 +320,17 @@ void driDrawableInitVBlank( __DRIdrawablePrivate *priv, GLuint flags, */ unsigned -driGetVBlankInterval( const __DRIdrawablePrivate *priv, GLuint flags ) +driGetVBlankInterval( const __DRIdrawablePrivate *priv ) { - if ( (flags & VBLANK_FLAG_INTERVAL) != 0 ) { + if ( (priv->vblFlags & VBLANK_FLAG_INTERVAL) != 0 ) { /* this must have been initialized when the drawable was first bound * to a direct rendering context. */ - assert ( priv->pdraw->swap_interval != (unsigned)-1 ); + assert ( priv->swap_interval != (unsigned)-1 ); - return priv->pdraw->swap_interval; - } - else if ( (flags & (VBLANK_FLAG_THROTTLE | VBLANK_FLAG_SYNC)) != 0 ) { - return 1; - } - else { - return 0; + return priv->swap_interval; } + else + return driGetDefaultVBlankInterval( priv ); } @@ -295,18 +340,17 @@ driGetVBlankInterval( const __DRIdrawablePrivate *priv, GLuint flags ) */ void -driGetCurrentVBlank( const __DRIdrawablePrivate *priv, GLuint flags, - GLuint *vbl_seq ) +driGetCurrentVBlank( __DRIdrawablePrivate *priv ) { drmVBlank vbl; vbl.request.type = DRM_VBLANK_RELATIVE; - if ( flags & VBLANK_FLAG_SECONDARY ) { + if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) { vbl.request.type |= DRM_VBLANK_SECONDARY; } vbl.request.sequence = 0; - (void) do_wait( &vbl, vbl_seq, priv->driScreenPriv->fd ); + (void) do_wait( &vbl, &priv->vblSeq, priv->driScreenPriv->fd ); } @@ -314,19 +358,15 @@ driGetCurrentVBlank( const __DRIdrawablePrivate *priv, GLuint flags, /** * Waits for the vertical blank for use with glXSwapBuffers. * - * \param vbl_seq Vertical blank sequence number (MSC) after the last buffer - * swap. Updated after this wait. - * \param flags \c VBLANK_FLAG bits that control how long to wait. * \param missed_deadline Set to \c GL_TRUE if the MSC after waiting is later - * than the "target" based on \c flags. The idea is that if - * \c missed_deadline is set, then the application is not - * achieving its desired framerate. + * than the "target" based on \c priv->vblFlags. The idea is + * that if \c missed_deadline is set, then the application is + * not achieving its desired framerate. * \return Zero on success, -1 on error. */ int -driWaitForVBlank( const __DRIdrawablePrivate *priv, GLuint * vbl_seq, - GLuint flags, GLboolean * missed_deadline ) +driWaitForVBlank( __DRIdrawablePrivate *priv, GLboolean * missed_deadline ) { drmVBlank vbl; unsigned original_seq; @@ -335,10 +375,10 @@ driWaitForVBlank( const __DRIdrawablePrivate *priv, GLuint * vbl_seq, unsigned diff; *missed_deadline = GL_FALSE; - if ( (flags & (VBLANK_FLAG_INTERVAL | - VBLANK_FLAG_THROTTLE | - VBLANK_FLAG_SYNC)) == 0 || - (flags & VBLANK_FLAG_NO_IRQ) != 0 ) { + if ( (priv->vblFlags & (VBLANK_FLAG_INTERVAL | + VBLANK_FLAG_THROTTLE | + VBLANK_FLAG_SYNC)) == 0 || + (priv->vblFlags & VBLANK_FLAG_NO_IRQ) != 0 ) { return 0; } @@ -349,44 +389,45 @@ driWaitForVBlank( const __DRIdrawablePrivate *priv, GLuint * vbl_seq, * * VBLANK_FLAG_INTERVAL and VBLANK_FLAG_THROTTLE mean to wait for at * least one vertical blank since the last wait. Since do_wait modifies - * vbl_seq, we have to save the original value of vbl_seq for the + * priv->vblSeq, we have to save the original value of priv->vblSeq for the * VBLANK_FLAG_INTERVAL / VBLANK_FLAG_THROTTLE calculation later. */ - original_seq = *vbl_seq; - interval = driGetVBlankInterval(priv, flags); + original_seq = priv->vblSeq; + interval = driGetVBlankInterval(priv); deadline = original_seq + interval; vbl.request.type = DRM_VBLANK_RELATIVE; - if ( flags & VBLANK_FLAG_SECONDARY ) { + if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) { vbl.request.type |= DRM_VBLANK_SECONDARY; } - vbl.request.sequence = ((flags & VBLANK_FLAG_SYNC) != 0) ? 1 : 0; + vbl.request.sequence = ((priv->vblFlags & VBLANK_FLAG_SYNC) != 0) ? 1 : 0; - if ( do_wait( & vbl, vbl_seq, priv->driScreenPriv->fd ) != 0 ) { + if ( do_wait( & vbl, &priv->vblSeq, priv->driScreenPriv->fd ) != 0 ) { return -1; } - diff = *vbl_seq - deadline; + diff = priv->vblSeq - deadline; /* No need to wait again if we've already reached the target */ if (diff <= (1 << 23)) { - *missed_deadline = (flags & VBLANK_FLAG_SYNC) ? (diff > 0) : GL_TRUE; + *missed_deadline = (priv->vblFlags & VBLANK_FLAG_SYNC) ? (diff > 0) : + GL_TRUE; return 0; } /* Wait until the target vertical blank. */ vbl.request.type = DRM_VBLANK_ABSOLUTE; - if ( flags & VBLANK_FLAG_SECONDARY ) { + if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) { vbl.request.type |= DRM_VBLANK_SECONDARY; } vbl.request.sequence = deadline; - if ( do_wait( & vbl, vbl_seq, priv->driScreenPriv->fd ) != 0 ) { + if ( do_wait( & vbl, &priv->vblSeq, priv->driScreenPriv->fd ) != 0 ) { return -1; } - diff = *vbl_seq - deadline; + diff = priv->vblSeq - deadline; *missed_deadline = diff > 0 && diff <= (1 << 23); return 0; diff --git a/src/mesa/drivers/dri/common/vblank.h b/src/mesa/drivers/dri/common/vblank.h index 52c1933ca5b..b3a0dadab19 100644 --- a/src/mesa/drivers/dri/common/vblank.h +++ b/src/mesa/drivers/dri/common/vblank.h @@ -45,17 +45,17 @@ */ extern int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count ); +extern int driDrawableGetMSC32( __DRIscreenPrivate * priv, + __DRIdrawablePrivate * drawablePrivate, + int64_t * count); extern int driWaitForMSC32( __DRIdrawablePrivate *priv, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t * msc ); extern GLuint driGetDefaultVBlankFlags( const driOptionCache *optionCache ); -extern void driDrawableInitVBlank ( __DRIdrawablePrivate *priv, GLuint flags, - GLuint *vbl_seq ); -extern unsigned driGetVBlankInterval( const __DRIdrawablePrivate *priv, - GLuint flags ); -extern void driGetCurrentVBlank( const __DRIdrawablePrivate *priv, - GLuint flags, GLuint *vbl_seq ); -extern int driWaitForVBlank( const __DRIdrawablePrivate *priv, - GLuint * vbl_seq, GLuint flags, GLboolean * missed_deadline ); +extern void driDrawableInitVBlank ( __DRIdrawablePrivate *priv ); +extern unsigned driGetVBlankInterval( const __DRIdrawablePrivate *priv ); +extern void driGetCurrentVBlank( __DRIdrawablePrivate *priv ); +extern int driWaitForVBlank( __DRIdrawablePrivate *priv, + GLboolean * missed_deadline ); #undef usleep #include <unistd.h> /* for usleep() */ diff --git a/src/mesa/drivers/dri/common/xmlconfig.c b/src/mesa/drivers/dri/common/xmlconfig.c index b635894fe53..8602d47cf97 100644 --- a/src/mesa/drivers/dri/common/xmlconfig.c +++ b/src/mesa/drivers/dri/common/xmlconfig.c @@ -279,7 +279,7 @@ static GLfloat strToF (const XML_Char *string, const XML_Char **tail) { /** \brief Parse a value of a given type. */ static GLboolean parseValue (driOptionValue *v, driOptionType type, const XML_Char *string) { - const XML_Char *tail; + const XML_Char *tail = NULL; /* skip leading white-space */ string += strspn (string, " \f\n\r\t\v"); switch (type) { @@ -403,40 +403,40 @@ static GLboolean checkValue (const driOptionValue *v, const driOptionInfo *info) /** \brief Output a warning message. */ #define XML_WARNING1(msg) do {\ __driUtilMessage ("Warning in %s line %d, column %d: "msg, data->name, \ - XML_GetCurrentLineNumber(data->parser), \ - XML_GetCurrentColumnNumber(data->parser)); \ + (int) XML_GetCurrentLineNumber(data->parser), \ + (int) XML_GetCurrentColumnNumber(data->parser)); \ } while (0) #define XML_WARNING(msg,args...) do { \ __driUtilMessage ("Warning in %s line %d, column %d: "msg, data->name, \ - XML_GetCurrentLineNumber(data->parser), \ - XML_GetCurrentColumnNumber(data->parser), \ + (int) XML_GetCurrentLineNumber(data->parser), \ + (int) XML_GetCurrentColumnNumber(data->parser), \ args); \ } while (0) /** \brief Output an error message. */ #define XML_ERROR1(msg) do { \ __driUtilMessage ("Error in %s line %d, column %d: "msg, data->name, \ - XML_GetCurrentLineNumber(data->parser), \ - XML_GetCurrentColumnNumber(data->parser)); \ + (int) XML_GetCurrentLineNumber(data->parser), \ + (int) XML_GetCurrentColumnNumber(data->parser)); \ } while (0) #define XML_ERROR(msg,args...) do { \ __driUtilMessage ("Error in %s line %d, column %d: "msg, data->name, \ - XML_GetCurrentLineNumber(data->parser), \ - XML_GetCurrentColumnNumber(data->parser), \ + (int) XML_GetCurrentLineNumber(data->parser), \ + (int) XML_GetCurrentColumnNumber(data->parser), \ args); \ } while (0) /** \brief Output a fatal error message and abort. */ #define XML_FATAL1(msg) do { \ fprintf (stderr, "Fatal error in %s line %d, column %d: "msg"\n", \ data->name, \ - XML_GetCurrentLineNumber(data->parser), \ - XML_GetCurrentColumnNumber(data->parser)); \ + (int) XML_GetCurrentLineNumber(data->parser), \ + (int) XML_GetCurrentColumnNumber(data->parser)); \ abort();\ } while (0) #define XML_FATAL(msg,args...) do { \ fprintf (stderr, "Fatal error in %s line %d, column %d: "msg"\n", \ data->name, \ - XML_GetCurrentLineNumber(data->parser), \ - XML_GetCurrentColumnNumber(data->parser), \ + (int) XML_GetCurrentLineNumber(data->parser), \ + (int) XML_GetCurrentColumnNumber(data->parser), \ args); \ abort();\ } while (0) |